EquityChartModeller

Author: EquityChartModeller - by transcendreamer - origins from Xupypr
Price Data Components
Series array that contains close prices for each barSeries array that contains close prices for each bar
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
EquityChartModeller
#property copyright "EquityChartModeller - by transcendreamer - origins from Xupypr"
// The indicator plots virtual equity charts representing a portfolios (synthethic instruments)
// Portfolios may consist of any number of positions, long and short, currencies and CFDs, with any lots
// Example of portfolio formula syntax: EURGBP+2.5 AUDCAD-1.1 NZDJPY+1.2 #MSFT+5 #GE-3
// PLUS = long position, MINUS = short position, SPACE = separator
// Spreads, commisssions and swaps are not counted
///////////////////////////////////////////////////////////////////////////
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_level1 0
///////////////////////////////////////////////////////////////////////////
extern datetime Time_Start_Chart=D'2012.01.01 00:00';
extern datetime Time_Stop_Chart=D'2019.12.31 00:00';
extern datetime Time_Zero_Level=D'2012.01.01 00:00';
extern string   Portfolio_Formula_A="";
extern string   Portfolio_Formula_B="";
extern double   Lot_Divider=100;
extern int      Period_Zero_Level=1440;
extern bool     Plot_Difference=false;
extern bool     Plot_Inversion=false;
extern bool     Show_Grid=false;
extern int      Grid_Interval=1000;
extern color    Color_Portfolio_1=DarkViolet;
extern color    Color_Portfolio_2=Green;
extern color    Color_Difference=Red;
extern int      Update_Seconds=5;
///////////////////////////////////////////////////////////////////////////
int      Total,BlocksTotal,BlocksLastN,inv,num_A,num_B;
bool     Error;
int      OpenBar,CloseBar,ZeroBar;
int      Index[2];
string   Block[],Instrument[];
double   Lots[],OpenPrice[],ClosePrice[];
double   Portfolio1[],Portfolio2[],Difference[];
string   Missing;
int      Window;
string   currency;
datetime tick;
///////////////////////////////////////////////////////////////////////////
int init()
{
IndicatorDigits(2);
IndicatorShortName("Equity Chart");
Window=WindowFind("Equity Chart");
ObjectsDeleteAll(Window,EMPTY);
SetIndexBuffer(0,Portfolio1);
SetIndexBuffer(1,Portfolio2);
SetIndexBuffer(2,Difference);
SetIndexStyle(0,DRAW_LINE,DRAW_LINE,1,Color_Portfolio_1); SetIndexLabel(0,"Portfolio A");
SetIndexStyle(1,DRAW_LINE,DRAW_LINE,1,Color_Portfolio_2); SetIndexLabel(1,"Portfolio B");
SetIndexStyle(2,DRAW_LINE,DRAW_LINE,1,Color_Difference); SetIndexLabel(2,"Difference");
Error=false; Missing=""; Total=0; BlocksTotal=0; BlocksLastN=0;
currency=AccountCurrency();
if(Plot_Difference && Plot_Inversion) inv=-1; else inv=1;
ArrayInitialize(Portfolio1,EMPTY_VALUE);
ArrayInitialize(Portfolio2,EMPTY_VALUE);
ArrayInitialize(Difference,EMPTY_VALUE);
if(Portfolio_Formula_A!="") SetPositions(Portfolio_Formula_A,1); num_A=Total;
if(Portfolio_Formula_B!="") SetPositions(Portfolio_Formula_B,2); num_B=Total-num_A;
if(Total==0) { Alert("No data for charting!"); return(0); }
if(Error) { Alert("Missing symbols in Market Watch: "+Missing); return(0); }
int y_offset=25;
for(int j=0;j<Total;j++)
{
if(Plot_Difference && Plot_Inversion) int sign_inv=-1; else sign_inv=1;
if(Lots[j]<0) int sign_lot=-1; else sign_lot=1;
if(Index[j]==2 && Plot_Difference) int sign_2nd=-1; else sign_2nd=1;
if(sign_inv*sign_2nd*sign_lot==1) string sign="+";
if(sign_inv*sign_2nd*sign_lot==-1) sign="-";
string text=StringConcatenate(Instrument[j],sign,MathAbs(Lots[j]));
if(Index[j]==1) {int colour=Color_Portfolio_1; string prefix="A_";}
if(Index[j]==2) {colour=Color_Portfolio_2; prefix="B_";}
if(Plot_Difference) {colour=Color_Difference; prefix="X_";}
PlaceLabel(prefix+j,5,y_offset,0,text,colour);
if(!Plot_Difference && j==num_A-1) y_offset+=11;
y_offset+=11;
}
return(0);
}
///////////////////////////////////////////////////////////////////////////
int start()
{
if(Total==0) return(0);
if(TimeCurrent()-tick<Update_Seconds) return(0);
else tick=TimeCurrent();
if(Period()>Period_Zero_Level) int Period_Work=Period();
else Period_Work=Period_Zero_Level;
bool seek_history=true;
datetime Current_Time=Time_Zero_Level;
while(seek_history && Current_Time<=Time[0] && Current_Time<=Time_Stop_Chart)
   {
   seek_history=false;
   for(int i=0;i<Total;i++)
      {
      int shift=iBarShift(Instrument[i],Period_Work,Current_Time,true);
      if(shift!=-1) OpenPrice[i]=iClose(Instrument[i],Period_Work,shift);
      else seek_history=true;
      }
   if(seek_history) Current_Time+=Period()*60;
   }
if(Time_Zero_Level<Current_Time) Time_Zero_Level=Current_Time;
OpenBar=iBarShift(NULL,0,Time_Start_Chart);
CloseBar=iBarShift(NULL,0,Time_Stop_Chart);
for(i=OpenBar;i>=CloseBar;i--)
   {
   double PL1=0; double PL2=0;
   for(int j=0;j<Total;j++)
      {
      ClosePrice[j]=iClose(Instrument[j],0,iBarShift(Instrument[j],0,Time[i]));
      double result=(ClosePrice[j]-OpenPrice[j])*LotSize(Instrument[j],Time[i])*Lots[j]/Lot_Divider;
      if(Index[j]==1) PL1+=result;
      if(Index[j]==2) PL2+=result;
      }
   if(!Plot_Difference)
      {if(Portfolio_Formula_A!="") Portfolio1[i]=NormalizeDouble(PL1,2);
      if(Portfolio_Formula_B!="") Portfolio2[i]=NormalizeDouble(PL2,2);}
   else Difference[i]=NormalizeDouble(PL1-PL2,2)*inv;
   }
if(Show_Grid) Grid();
return(0);
}
///////////////////////////////////////////////////////////////////////////
void Grid()
{
if(Portfolio_Formula_A!=""&&!Plot_Difference) 
   PlaceLine("Equity_A",Portfolio1[CloseBar],Color_Portfolio_1,STYLE_DOT);
if(Portfolio_Formula_B!=""&&!Plot_Difference) 
   PlaceLine("Equity_B",Portfolio2[CloseBar],Color_Portfolio_2,STYLE_DOT);
if(Plot_Difference) 
   PlaceLine("Equity",Difference[CloseBar],Color_Difference,STYLE_DOT);
PlaceMark("Zero_point",Time_Zero_Level,Gray,STYLE_DOT);
double max=-2147483647; double min=2147483647;
for(int i=OpenBar;i>=CloseBar;i--)
   {
   if(Plot_Difference)
      {if(Difference[i]>max) max=Difference[i]; 
      if(Difference[i]<min) min=Difference[i];}
   else
      {if(Portfolio1[i]>max && Portfolio_Formula_A!="") max=Portfolio1[i]; 
      if(Portfolio1[i]<min && Portfolio_Formula_A!="") min=Portfolio1[i];
      if(Portfolio2[i]>max && Portfolio_Formula_B!="") max=Portfolio2[i]; 
      if(Portfolio2[i]<min && Portfolio_Formula_B!="") min=Portfolio2[i];}
   }
double y=0;
while(y<max) {y+=Grid_Interval;PlaceLine("Level_P"+y,y,Gray,STYLE_DOT);}
y=0;
while(y>min) {y-=Grid_Interval;PlaceLine("Level_N"+y,y,Gray,STYLE_DOT);}
}
///////////////////////////////////////////////////////////////////////////
double LotSize(string symbol, datetime tbar)
{
double size,close1,close2;
string BQ;
if(currency=="") currency="USD";
int type=MarketInfo(symbol,MODE_PROFITCALCMODE);
switch (type)
{
case 0:
   {
   int sbar=iBarShift(symbol,0,tbar);
   size=MarketInfo(symbol,MODE_LOTSIZE);
   if(StringSubstr(symbol,3,3)=="USD") break;
   if(StringSubstr(symbol,0,3)=="USD")
      {
      close1=iClose(symbol,0,sbar);
      if(close1>0) size=size/close1;
      }
   else
      {
      BQ=StringSubstr(symbol,0,3)+"USD";
      if(iClose(BQ,0,0)==0) BQ="USD"+StringSubstr(symbol,0,3);
      if(iClose(BQ,0,0)==0) break;
      int BQbar=iBarShift(BQ,0,tbar);
      close1=iClose(symbol,0,sbar);
      close2=iClose(BQ,0,BQbar);
      if(close1>0 && close2>0)
         {
         if(StringSubstr(BQ,0,3)=="USD") size=size/close2/close1;
         else size=size*close2/close1;
         }
      }
   } break;
case 1: size=MarketInfo(symbol,MODE_LOTSIZE); break;
case 2: size=MarketInfo(symbol,MODE_TICKVALUE)/MarketInfo(symbol,MODE_TICKSIZE);
}
if(currency!="USD")
   {
   BQ=currency+"USD";
   if(iClose(BQ,0,0)==0)
      {
      BQ="USD"+currency;
      close1=iClose(BQ,0,iBarShift(BQ,0,tbar));
      if(close1>0) size*=close1;
      }
   else
      {
      close1=iClose(BQ,0,iBarShift(BQ,0,tbar));
      if(close1>0) size/=close1;
      }
   }
return(size);
}
///////////////////////////////////////////////////////////////////////////
void SetPositions(string name, int number)
{
BlocksLastN=BlocksTotal;
SeparateBlocks(name);
for(int i=BlocksLastN;i<BlocksTotal;i++)
{
Total++;
ArrayResize(Lots,Total);
ArrayResize(Instrument,Total);
ArrayResize(OpenPrice,Total);
ArrayResize(ClosePrice,Total);
ArrayResize(Index,Total);
int length=StringLen(Block[i]);
int p=length-1;
while(p>=0)
   {
   string X=StringSubstr(Block[i],p,1);
   if(X=="+"||X=="-") break;
   if(p==0) break;
   else p--;
   }
Index[Total-1]=number;
Instrument[Total-1]=StringSubstr(Block[i],0,p);
if(p==0) Lots[Total-1]=1; 
else Lots[Total-1]=StrToDouble(StringSubstr(Block[i],p,length-p));
if(MarketInfo(Instrument[Total-1],MODE_POINT)==0) 
{Missing=StringConcatenate(Missing," ",Instrument[Total-1]);Error=true;}
}
}
///////////////////////////////////////////////////////////////////////////
void SeparateBlocks(string text)
{
string fragment="";
int length=StringLen(text);
for(int position=0;position<length;position++)
{
int sym=StringGetChar(text,position);
if(sym!=32&&sym!=9&&sym!=10&&sym!=13) fragment=fragment+StringSubstr(text,position,1);
if(sym==32||sym==9||sym==10||sym==13||position==length-1) 
if(StringLen(fragment)>0) 
{BlocksTotal++;ArrayResize(Block,BlocksTotal); 
Block[BlocksTotal-1]=fragment;fragment="";}
}
}
///////////////////////////////////////////////////////////////////////////
void PlaceLabel(string name, int x, int y, int corner, string text, int colour)
{
ObjectCreate(name,OBJ_LABEL,Window,0,0);
ObjectSet(name,OBJPROP_CORNER,corner);
ObjectSet(name,OBJPROP_XDISTANCE,x); 
ObjectSet(name,OBJPROP_YDISTANCE,y);
ObjectSetText(name,text,8,"Tahoma",colour);
}
///////////////////////////////////////////////////////////////////////////
void PlaceLine(string name, int price, int colour, int style)
{
ObjectCreate(name,OBJ_HLINE,Window,0,price);
ObjectSet(name,OBJPROP_COLOR,colour);
ObjectSet(name,OBJPROP_STYLE,style);
}
///////////////////////////////////////////////////////////////////////////
void PlaceMark(string name, datetime mark, int colour, int style)
{
ObjectCreate(name,OBJ_VLINE,Window,mark,0);
ObjectSet(name,OBJPROP_COLOR,colour);
ObjectSet(name,OBJPROP_STYLE,style);
}
///////////////////////////////////////////////////////////////////////////

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---