spreadchart

spreadchart
3 Views
0 Downloads
0 Favorites
spreadchart
#property indicator_chart_window
#property indicator_buffers 6

/// keycodes for manual chart movement
#define VK_LEFT 0x25
#define VK_RIGHT 0x27
#define VK_UP 0x26
#define VK_DOWN 0x28
#define VK_PRIOR 0x21
#define VK_NEXT 0x22  

extern string SymbolSpread = "";  // Symbol B name to be overlayed
extern double SpreadFactor = 1.0; // Spread = Symbol A price - spreadfactor x Symbol B price
extern color ColorSpread=Aqua;
extern int IndicatorWidthThick= 2;
extern int IndicatorWidthThin = 1;
extern bool PriceLabel=true;
extern color ColorUp=Blue;
extern color ColorDown = Tomato;
extern bool AlertPopup = false;
extern bool Sound=false;
extern bool EmailAlert=false;

//--- buffers
double SpreadLowHighBuffer[];
double SpreadHighLowBuffer[];
double SpreadOpenBuffer[];
double SpreadCloseBuffer[];
double SpreadUpBuffer[];
double SpreadDnBuffer[];

int Fontsize=20;

datetime dtLasttime=0;
double dChartMax=0.0,dChartMin=0.0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

/// color down; lower value; open value
/// color up; higher value; close value 

   ChartSetInteger(0,CHART_SCALEFIX,0);

   IndicatorShortName("SpreadChart");
   IndicatorDigits(Digits);

   SetIndexStyle(0,DRAW_HISTOGRAM,0,IndicatorWidthThin,ColorSpread);
   SetIndexBuffer(0,SpreadLowHighBuffer);
   SetIndexStyle(1,DRAW_HISTOGRAM,0,IndicatorWidthThin,ColorSpread);
   SetIndexBuffer(1,SpreadHighLowBuffer);
   SetIndexStyle(2,DRAW_HISTOGRAM,0,IndicatorWidthThick,ColorSpread);
   SetIndexBuffer(2,SpreadOpenBuffer);
   SetIndexStyle(3,DRAW_HISTOGRAM,0,IndicatorWidthThick,ColorSpread);
   SetIndexBuffer(3,SpreadCloseBuffer);

   SetIndexStyle(4,DRAW_ARROW,EMPTY,1,ColorUp);
   SetIndexArrow(4,174);
   SetIndexBuffer(4,SpreadUpBuffer);
   SetIndexStyle(5,DRAW_ARROW,EMPTY,1,ColorDown);
   SetIndexArrow(5,174);
   SetIndexBuffer(5,SpreadDnBuffer);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   ObjectDelete("QuoteMain");
   ObjectDelete("SymbolMain");
   ObjectDelete("QuoteSpread");
   ObjectDelete("SymbolSpread");
   ObjectDelete("Time");
   ObjectDelete("SpreadLabel");
   ObjectDelete("SpreadValue");

  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---

   if(PriceLabel) DisplaySpotPrice();

   if( SymbolSpread=="" || iClose(SymbolSpread,Period(),0)==0 ) return(0);

   DrawSpreadChart();


//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void OnChartEvent(const int id,         // Event identifier  
                  const long& lparam,   // Event parameter of long type
                  const double& dparam, // Event parameter of double type
                  const string& sparam) // Event parameter of string type
  {

   if(id==CHARTEVENT_KEYDOWN)
     {
      switch(int(lparam))
        {
         case VK_LEFT: DrawSpreadChart(); break;
         case VK_RIGHT: DrawSpreadChart(); break;
         case VK_PRIOR: DrawSpreadChart(); break;
         case VK_NEXT:  DrawSpreadChart(); break;
         case VK_UP: DrawSpreadChart(); break;
         case VK_DOWN:  DrawSpreadChart(); break;
         default:         break;
        }

     }

   if(id==CHARTEVENT_CHART_CHANGE && (dChartMax!=WindowPriceMax(0) || dChartMin!=WindowPriceMin(0)))
      DrawSpreadChart();

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawSpreadChart()
  {

   int iWindowFirstVisibleBar=WindowFirstVisibleBar();
   int iWindowBarsPerChart=WindowBarsPerChart();

   if(iWindowBarsPerChart>iWindowFirstVisibleBar) iWindowBarsPerChart=iWindowFirstVisibleBar;
   int i=0,iSymbolSpreadShift=0;
   double dClose,dOpen,dHigh,dLow,dMaxMax=0.0,dMinMin=999999.0;
   double dFixedSpreadFactor=0.0;
   datetime dtCurrentBar=0;

   if(SymbolSpread=="") return;

   ArrayInitialize(SpreadCloseBuffer,0.0);
   ArrayInitialize(SpreadHighLowBuffer,0.0);
   ArrayInitialize(SpreadLowHighBuffer,0.0);
   ArrayInitialize(SpreadOpenBuffer,0.0);
   ArrayInitialize(SpreadUpBuffer,0.0);
   ArrayInitialize(SpreadDnBuffer,0.0);

   for(i=iWindowFirstVisibleBar;i>=iWindowFirstVisibleBar-iWindowBarsPerChart;i--)
     {

      dtCurrentBar=iTime(Symbol(),Period(),i);

      iSymbolSpreadShift=iBarShift(SymbolSpread,Period(),dtCurrentBar,true);

      if(iSymbolSpreadShift!=-1)
        {

         dClose= iClose(SymbolSpread,Period(),iSymbolSpreadShift);
         dHigh = iHigh(SymbolSpread,Period(),iSymbolSpreadShift);
         dLow=iLow(SymbolSpread,Period(),iSymbolSpreadShift);
         dOpen=iOpen(SymbolSpread,Period(),iSymbolSpreadShift);

         if((i==iWindowFirstVisibleBar || dFixedSpreadFactor==0.0) && dClose!=0.0)
           {
            dFixedSpreadFactor=iClose(Symbol(),Period(),i)/dClose;

           }

         if(iHigh(Symbol(),Period(),i)>dMaxMax) dMaxMax= iHigh(Symbol(),Period(),i);
         if(iLow(Symbol(),Period(),i)<dMinMin) dMinMin = iLow(Symbol(),Period(),i);

         dLow*=dFixedSpreadFactor;
         dHigh*=dFixedSpreadFactor;
         dClose*=dFixedSpreadFactor;
         dOpen *=dFixedSpreadFactor;


         SpreadLowHighBuffer[i] = dLow;
         SpreadHighLowBuffer[i] = dHigh;
         SpreadCloseBuffer[i]= dClose;
         SpreadOpenBuffer[i] = dOpen;

         if(dHigh>dMaxMax) dMaxMax= dHigh;
         if(dLow<dMinMin) dMinMin = dLow;
        }
     }

   double dScale=(dMaxMax-dMinMin)/dMinMin;

   dChartMax = dMaxMax*(1+dScale*0.05);
   dChartMin = dMinMin*(1-dScale*0.05);

   ChartSetInteger(0,CHART_SCALEFIX,true);
   ChartSetDouble(0,CHART_FIXED_MAX,dChartMax);
   ChartSetDouble(0,CHART_FIXED_MIN,dChartMin);

   for(i=iWindowFirstVisibleBar;i>=iWindowFirstVisibleBar-iWindowBarsPerChart;i--)
     {

      if(SpreadCloseBuffer[i]>=iClose(Symbol(),Period(),i))
         SpreadUpBuffer[i]=dChartMin;
      if(SpreadCloseBuffer[i]<iClose(Symbol(),Period(),i) && SpreadCloseBuffer[i]!=0.0)
         SpreadDnBuffer[i]=dChartMin;
     }

   if((SpreadUpBuffer[1]!=0 || SpreadDnBuffer[1]!=0) && 
      (SpreadUpBuffer[1]!=SpreadUpBuffer[2] && SpreadDnBuffer[1]!=SpreadDnBuffer[2])
      && dtLasttime!=Time[0])
     {
      string strSpreadAlert="";

      if(SpreadUpBuffer[1]>0.0) strSpreadAlert = ">";
      if(SpreadDnBuffer[1]>0.0) strSpreadAlert = "<";

      if(AlertPopup)
         Alert("Spread Alert - ",PeriodToString(Period())," ",SymbolSpread," ",strSpreadAlert," ",Symbol());

      if(Sound)
         PlaySound("alert.wav");

      if(EmailAlert)
         SendMail("Spread Alert - "+PeriodToString(Period())+" "+SymbolSpread+" "+strSpreadAlert+" "+Symbol(),
                  SymbolSpread+": "+DoubleToStr(iClose(SymbolSpread,Period(),1),MarketInfo(SymbolSpread,MODE_DIGITS))+
                  "\n"+Symbol()+": "+DoubleToStr(iClose(Symbol(),Period(),1),Digits)+
                  "\nServer Time: "+TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));

      dtLasttime=Time[0];
     }

   ChartRedraw();

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string PeriodToString(int imin)
  {

   string strprd;

   switch(imin)
     {

      case(1):
         strprd="M1";
         break;
      case(2):
         strprd="M2";
         break;
      case(3):
         strprd="M3";
         break;
      case(5):
         strprd="M5";
         break;
      case(15):
         strprd="M15";
         break;
      case(30):
         strprd="M30";
         break;
      case(60):
         strprd="H1";
         break;
      case(60*4):
         strprd="H4";
         break;
      case(60*24):
         strprd="D1";
         break;
      case(60*24*7):
         strprd="W1";
         break;
     }

   return (strprd);

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetLabel(string nm,string tx,int xd,int yd,string fn,int fs,color ct)
  {

   if(ObjectFind(nm)<0)
      ObjectCreate(nm,OBJ_LABEL,0,0,0);  //--- create the Label object

   ObjectSet(nm,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(nm,OBJPROP_XDISTANCE,xd);
   ObjectSet(nm,OBJPROP_YDISTANCE,yd);
   ObjectSet(nm,OBJPROP_COLOR,ct);
   ObjectSetText(nm,tx,fs,fn,ct);

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DisplaySpotPrice()
  {

   int x=50;
   int y=50;
   int fz=Fontsize;
//color cr;
   double dSymbolPrice=0.0,dSymbolSpreadPrice;
   string strTime="";

   string strpd=PeriodToString(Period());

   strTime=TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS);

   dSymbolPrice=Bid;

   int iSymbolLen=StringLen(Symbol());
   if(iSymbolLen<StringLen(SymbolSpread)) iSymbolLen=StringLen(SymbolSpread);

   SetLabel("Time",strpd+"  "+strTime,x,y,"Arial",fz-5,White);
   SetLabel("SymbolMain",Symbol(),x,y+(Fontsize+2)*1.2,"Arial",fz,White);
   SetLabel("QuoteMain",DoubleToStr(dSymbolPrice,Digits),x+iSymbolLen*fz,y+(fz+2)*1.2,"Arial Bold",fz,Lime);

   if(SymbolSpread!="")
     {
      SetLabel("SymbolSpread",SymbolSpread,x,y+(fz+2)*1.2*2,"Arial",fz,White);
      dSymbolSpreadPrice=iClose(SymbolSpread,Period(),0);
      SetLabel("QuoteSpread",DoubleToStr(dSymbolSpreadPrice,MarketInfo(SymbolSpread,MODE_DIGITS)),x+iSymbolLen*fz,y+(fz+2)*1.2*2,"Arial Bold",fz,ColorSpread);

      if(SpreadFactor!=0.0)
        {
         SetLabel("SpreadLabel","Spread",x,y+(fz+3)*1.2*3,"Arial",fz*0.9,White);
         SetLabel("SpreadValue",DoubleToStr(dSymbolPrice-dSymbolSpreadPrice*SpreadFactor,Digits),x+iSymbolLen*fz,y+(fz+3)*1.2*3,"Arial Bold",fz*0.9,MintCream);
        }
     }

  }
//+------------------------------------------------------------------+

Comments