Author: Copyright 2019, Roberto Jacobs (3rjfx) ~ By 3rjfx ~ Created: 2019/02/23
Price Data Components
Series array that contains open prices of each barSeries array that contains the highest prices of each barSeries array that contains the lowest prices of each barSeries array that contains close prices for each barSeries array that contains tick volumes of each bar Series array that contains open time of each bar
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emails
0 Views
0 Downloads
0 Favorites
OBVMTF
//+------------------------------------------------------------------+
//|                                                       OBVMTF.mq4 |
//|                           Copyright 2019, Roberto Jacobs (3rjfx) |
//|                              https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Roberto Jacobs (3rjfx) ~ By 3rjfx ~ Created: 2019/02/23"
#property link      "https://www.mql5.com/en/users/3rjfx"
#property description "Indicator OBVMTF base on the On Balance Volume indicator with Signal"
#property description "and Alert for MetaTrader 4 and options to display signal on the chart."
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
//--
#property indicator_color1 clrNONE
#property indicator_color2 clrNONE
//--
enum YN
 {
   No,
   Yes
 };
//--
enum corner
 {  
   NotShow=-1,     // Not Show Arrow
   topchart=0,     // On Top Chart
   bottomchart=1   // On Bottom Chart
 };
//--
//--
input ENUM_APPLIED_PRICE obv_prc = PRICE_CLOSE; // OBV Applied Price
input corner                 cor = topchart;    // Arrow Move Position
input YN                  alerts = Yes;         // Display Alerts / Messages (Yes) or (No)
input YN              EmailAlert = No;          // Email Alert (Yes) or (No)
input YN              sendnotify = No;          // Send Notification (Yes) or (No)
input YN             displayinfo = Yes;         // Display Trade Info
input color            textcolor = clrSnow;     // Text Color
input color              ArrowUp = clrLime;     // Arrow Up Color
input color              ArrowDn = clrRed;      // Arrow Down Color
input color              NTArrow = clrYellow;   // Arrow No Signal
//---
//---- indicator buffers
double OBVMoveUp[];
double OBVMoveDn[];
//--
//--- spacing
int scaleX=35,scaleY=40,scaleYt=18,offsetX=250,offsetY=3,fontSize=7; // coordinate
int txttf,
    arrtf;
color arclr;
ENUM_BASE_CORNER bcor;
//--- arrays for various things
int OBVTF[]={1,5,15,30,60,240,1440,10080,43200};
int XOBV[10];
string periodStr[]={"M1","M5","M15","M30","H1","H4","D1","W1","MN","MOVE"}; // Text Timeframes
//--
double 
   pricepos;
datetime 
   cbartime;
int cur,prv;
int imnn,imnp;
int cmnt,pmnt;
int arr;
long CI;
static int fbar;
string posisi,
       sigpos,
       iname,
       msgText;
string frtext="obvwave";
//---------//
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
    IndicatorBuffers(2);
    //--
    SetIndexBuffer(0,OBVMoveUp);
    SetIndexBuffer(1,OBVMoveDn);
    //--
    SetIndexStyle(0,DRAW_NONE);
    SetIndexStyle(1,DRAW_NONE);
    //--
//----
    //-- name for DataWindow
    SetIndexLabel(0,"OBV_Up");
    SetIndexLabel(1,"OBV_Dn");
    //--
    SetIndexEmptyValue(0,0.0);
    SetIndexEmptyValue(1,0.0);
//---- indicator short name
    IndicatorDigits(_Digits);
    iname=WindowExpertName();
    IndicatorShortName(iname);
    CI=ChartID();
    arr=ArraySize(XOBV);
    //--
    if(cor>=0)
      {
        if(cor==topchart) {bcor=CORNER_LEFT_UPPER; txttf=45; arrtf=-20;}
        if(cor==bottomchart) {bcor=CORNER_LEFT_LOWER; txttf=45; arrtf=-12;}
      }
    else
     {
       string name;
       for(int i=ObjectsTotal()-1; i>=0; i--)
         {
           name=ObjectName(i);
           if(StringFind(name,frtext,0)>-1) ObjectDelete(0,name);
         }
     }
    //--
//---
   return(INIT_SUCCEEDED);
  }
//---------//
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
    Comment("");
    string name;
    for(int i=ObjectsTotal()-1; i>=0; i--)
      {
        name=ObjectName(i);
        if(StringFind(name,frtext,0)>-1) ObjectDelete(0,name);
      }
    //--
    GlobalVariablesDeleteAll();
//----
   return(0);
  }
//---------//
//+------------------------------------------------------------------+
//| 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[])
  {
//---
    ArraySetAsSeries(open,true);
    ArraySetAsSeries(high,true);
    ArraySetAsSeries(low,true);
    ArraySetAsSeries(close,true);
    ArraySetAsSeries(time,true);
    ArraySetAsSeries(volume,true);
    int trn=0,xbup=0,xbdn=0,i;
    cbartime=time[0];
    arclr=NTArrow;
    //--
    imnn=Minute();
    if(imnn!=imnp)
      {
        ResetLastError();
        RefreshRates();
        if(cor>=0)
          {
            for(int x=0; x<arr; x++)
              {
                CreateArrowLabel(CI,frtext+"_tfx_arrow_"+string(x),periodStr[x],"Bodoni MT Black",fontSize,textcolor,bcor,
                                 txttf+x*scaleX+offsetX,scaleY+offsetY+7,true); //"Georgia" "Bodoni MT Black" "Verdana" "Arial Black"
              }
          }
        //--
        for(i=0; i<arr-1; i++)
          {
            XOBV[i]=GetDirection(OBVTF[i]);
            if(cor>=0)
              {
                if(XOBV[i]>0) arclr=ArrowUp;
                if(XOBV[i]<0) arclr=ArrowDn;
                CreateArrowLabel(CI,frtext+"_win_arrow_"+string(i),CharToString(108),"Wingdings",14,arclr,bcor,
                                 txttf+i*scaleX+offsetX,arrtf+scaleY+offsetY+7,true);
              }
            if(i<6)
              {
                if(XOBV[i]>0) xbup++;
                if(XOBV[i]<0) xbdn++;
              }
          }
        if(i==9)
          {
            if(xbup>=4) 
              {
                trn=1;
                XOBV[i]=xbup; arclr=ArrowUp; OBVMoveUp[0]=GetPrice(_Period,trn); 
                pricepos=OBVMoveUp[0]; 
                cur=1;
                fbar=iBarShift(_Symbol,0,cbartime,false);
              }
            else
            if(xbdn>=4) 
              {
                trn=-1;
                XOBV[i]=xbdn; arclr=ArrowDn; OBVMoveDn[0]=GetPrice(_Period,trn); 
                pricepos=OBVMoveDn[0]; 
                cur=-1;
                fbar=iBarShift(_Symbol,0,cbartime,false);
              }
            else 
              {
                XOBV[i]=0; 
                arclr=NTArrow; 
                OBVMoveDn[0]=0.0; 
                OBVMoveUp[0]=0.0; 
                pricepos=close[0];
                cur=0;
                fbar=iBarShift(_Symbol,0,time[0],false);
              }
            //--
            if(cor>=0) CreateArrowLabel(CI,frtext+"_win_arrow_"+string(i),CharToString(108),"Wingdings",14,arclr,bcor,
                                        txttf+i*scaleX+offsetX+8,arrtf+scaleY+offsetY+7,true);
          }
        //--
        imnp=imnn;
      }
    //--   
    if(alerts==Yes||EmailAlert==Yes||sendnotify==Yes) Do_Alerts(cur,fbar);
    if(displayinfo==Yes) ChartComm();
    //--
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//---------//

// Getting the applied price index shift
double GetAppliedPrice(int xtf,int nIndex)
  {
//---
   double dPrice=0.0;
   //--
   switch(obv_prc)
     {
      case PRICE_OPEN:  dPrice=iOpen(_Symbol,xtf,nIndex);                                                                 break;
      case PRICE_HIGH:  dPrice=iHigh(_Symbol,xtf,nIndex);                                                                 break;
      case PRICE_LOW:   dPrice=iLow(_Symbol,xtf,nIndex);                                                                  break;
      case PRICE_CLOSE:  dPrice=iClose(_Symbol,xtf,nIndex);                                                               break;
      case PRICE_MEDIAN:  dPrice=(iHigh(_Symbol,xtf,nIndex)+iLow(_Symbol,xtf,nIndex))/2.0;                                break;
      case PRICE_TYPICAL:  dPrice=(iHigh(_Symbol,xtf,nIndex)+iLow(_Symbol,xtf,nIndex)+iClose(_Symbol,xtf,nIndex))/3.0;    break;
      case PRICE_WEIGHTED:  dPrice=(iHigh(_Symbol,xtf,nIndex)+iLow(_Symbol,xtf,nIndex)+2*iClose(_Symbol,xtf,nIndex))/4.0; break;
     }
   //--
   return(dPrice);
//---
  }
//---------//

// getting the price direction
int GetDirection(int xtf) 
  {
//---
    int ret=0,
        bar=4,
        i;
    RefreshRates();
    //--
    double OBV[];
    ArrayResize(OBV,bar);
    ArraySetAsSeries(OBV,true);
     OBV[bar-1]=(double)iVolume(_Symbol,xtf,bar-1);
    //--
    for(i=bar-2; i>=0; i--)
      {
        double dCurrentPrice=GetAppliedPrice(xtf,i);
        double dPreviousPrice=GetAppliedPrice(xtf,i+1);
        if(dCurrentPrice==dPreviousPrice)
           OBV[i]=OBV[i+1];
        else
          {
            if(dCurrentPrice<dPreviousPrice)
              OBV[i]=OBV[i+1]-(double)iVolume(_Symbol,xtf,i);  
            else
              OBV[i]=OBV[i+1]+(double)iVolume(_Symbol,xtf,i); 
         }
      }
    //--
    if(OBV[0]>OBV[1]) ret=1;
    if(OBV[0]<OBV[1]) ret=-1;
    //--
    return(ret);
//---
  }
//---------//

// getting the price position
double GetPrice(int xtf,int bb)
  {
//---
    int bar=(int)480/xtf < 9 ? 5 : (int)480/xtf;
    if(bar>100) bar=100;
    double ppos=0;
    double hih[],
           lol[];
    ArrayResize(hih,bar);
    ArrayResize(lol,bar);
    ArraySetAsSeries(hih,true);
    ArraySetAsSeries(lol,true);
    //--
    for(int x=bar-1; x>=0; x--)
      {
        hih[x]=iHigh(_Symbol,xtf,x);
        lol[x]=iLow(_Symbol,xtf,x);
      }
    if(bb>0) {ppos=iLow(_Symbol,xtf,ArrayMinimum(lol,bar,0)); cbartime=iTime(_Symbol,xtf,ArrayMinimum(lol,bar,0));}
    if(bb<0) {ppos=iHigh(_Symbol,xtf,ArrayMaximum(hih,bar,0)); cbartime=iTime(_Symbol,xtf,ArrayMaximum(hih,bar,0));}
    //--
    return(ppos);
//---
  }
//---------//

void Do_Alerts(int fcur,int fb)
  {
    //--
    cmnt=Minute();
    if(cmnt!=pmnt)
      {
        //--
        if(fcur==1)
          {
            msgText="On Balance Volume Up Start"+" at bars: "+string(fb);
            posisi="Bullish"; 
            sigpos="Open BUY Order";
          }
        else
        if(fcur==-1)
          {
            msgText="On Balance Volume Down Start"+" at bars: "+string(fb);
            posisi="Bearish"; 
            sigpos="Open SELL Order";
          }
        else
          {
            msgText="On Balance Volume Signal Not Found!";
            posisi="Not Found!"; 
            sigpos="Wait for Confirmation!";
          }
        //--
        if(fcur!=prv)
          {
            Print(iname,"--- "+_Symbol+" "+TF2Str(_Period)+": "+msgText+
                  "\n--- at: ",TimeToString(iTime(_Symbol,0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
            //--
            if(alerts==Yes)
              Alert(iname,"--- "+_Symbol+" "+TF2Str(_Period)+": "+msgText+
                    "--- at: ",TimeToString(iTime(_Symbol,0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
            //--
            if(EmailAlert==Yes) 
              SendMail(iname,"--- "+_Symbol+" "+TF2Str(_Period)+": "+msgText+
                               "\n--- at: "+TimeToString(iTime(_Symbol,0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
            //--
            if(sendnotify==Yes) 
              SendNotification(iname+"--- "+_Symbol+" "+TF2Str(_Period)+": "+msgText+
                               "\n--- at: "+TimeToString(iTime(_Symbol,0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);                
            //--
            prv=fcur;
            //pbartime=fbartime;
          }
        //--
        pmnt=cmnt;
      }
    //--
    return;
    //---
  }
//---------//

string TF2Str(int period)
  {
   switch(period)
     {
       //--
       case PERIOD_M1: return("M1");
       case PERIOD_M5: return("M5");
       case PERIOD_M15: return("M15");
       case PERIOD_M30: return("M30");
       case PERIOD_H1: return("H1");
       case PERIOD_H4: return("H4");
       case PERIOD_D1: return("D1");
       case PERIOD_W1: return("W1");
       case PERIOD_MN1: return("MN");
       //--
     }
   return(string(period));
  }  
//---------//

string AccountMode() // function: to known account trade mode
   {
//----
//--- Demo, Contest or Real account 
   ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
 //---
   string trade_mode;
   //--
   switch(account_type) 
     { 
      case  ACCOUNT_TRADE_MODE_DEMO: 
         trade_mode="Demo"; 
         break; 
      case  ACCOUNT_TRADE_MODE_CONTEST: 
         trade_mode="Contest"; 
         break; 
      default: 
         trade_mode="Real"; 
         break; 
     }
   //--
   return(trade_mode);
//----
   } //-end AccountMode()
//---------//

void ChartComm() // function: write comments on the chart
  {
//----
   //--
   Comment("\n     :: Server Date Time : ",(string)Year(),".",(string)Month(),".",(string)Day(), "   ",TimeToString(TimeCurrent(),TIME_SECONDS), 
      "\n     ------------------------------------------------------------", 
      "\n      :: Broker             :  ",TerminalCompany(), 
      "\n      :: Acc. Name       :  ",AccountName(), 
      "\n      :: Acc, Number    :  ",(string)AccountNumber(),
      "\n      :: Acc,TradeMode :  ",AccountMode(),
      "\n      :: Acc. Leverage   :  1 : ",(string)AccountLeverage(), 
      "\n      :: Acc. Balance     :  ",DoubleToString(AccountBalance(),2),
      "\n      :: Acc. Equity       :  ",DoubleToString(AccountEquity(),2), 
      "\n      --------------------------------------------",
      "\n      :: Indicator Name  :  ",iname,
      "\n      :: Currency Pair    :  ",_Symbol,
      "\n      :: Current Spread  :  ",IntegerToString(SymbolInfoInteger(_Symbol,SYMBOL_SPREAD),0),
      "\n      :: Signal Start       : at bar ",string(fbar),
      "\n      :: Price Start        :  ",DoubleToString(pricepos,_Digits), 
      "\n      :: Indicator Signal :  ",posisi,
      "\n      :: Suggested        :  ",sigpos);
   //---
   ChartRedraw();
   return;
//----
  } //-end ChartComm()  
//---------//

bool CreateArrowLabel(long   chart_id, 
                      string lable_name, 
                      string label_text,
                      string font_model,
                      int    font_size,
                      color  label_color,
                      int    chart_corner,
                      int    x_cor, 
                      int    y_cor,
                      bool   price_hidden)
  { 
//--- 
    //--
    ObjectDelete(chart_id,lable_name);
    //--
    if(!ObjectCreate(chart_id,lable_name,OBJ_LABEL,0,0,0,0,0)) 
      { 
        Print(__FUNCTION__, 
            ": failed to create \"Arrow Label\" sign! Error code = ",GetLastError());
        return(false); 
      } 
    //--
    ObjectSetString(chart_id,lable_name,OBJPROP_TEXT,label_text);
    ObjectSetString(chart_id,lable_name,OBJPROP_FONT,font_model); 
    ObjectSetInteger(chart_id,lable_name,OBJPROP_FONTSIZE,font_size);
    ObjectSetInteger(chart_id,lable_name,OBJPROP_COLOR,label_color);
    ObjectSetInteger(chart_id,lable_name,OBJPROP_CORNER,chart_corner);
    ObjectSetInteger(chart_id,lable_name,OBJPROP_XDISTANCE,x_cor);
    ObjectSetInteger(chart_id,lable_name,OBJPROP_YDISTANCE,y_cor);
    ObjectSetInteger(chart_id,lable_name,OBJPROP_HIDDEN,price_hidden);
    //--- successful execution 
    return(true);
    //--
  }
//---------//  
//+------------------------------------------------------------------+

Comments