spreadchart

spreadchart
Price Data Components
Series array that contains close prices for each barSeries array that contains the highest prices of each barSeries array that contains the lowest prices of each barSeries array that contains open prices of each bar
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt plays sound alertsIt sends emails
0 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