MQL MT5 - Code

Discussion in 'Automated Trading' started by Spectre2007, Apr 28, 2017.

  1. Here is some MQL code for anyone that is interested in experimenting with the demo AMP MT5 accounts.



    //+------------------------------------------------------------------+
    //| line in sand.mq5 |
    //| Copyright 2017, MetaQuotes Software Corp. |
    //| https://www.mql5.com |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2017, MetaQuotes Software Corp."
    #property link "https://www.mql5.com"
    #property version "1.00"
    #include <Trade/Trade.mqh>
    CTrade Trade;
    #define MAGIC 1234501
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    enum strategy_mode
    {
    mode1,//high low mode
    mode2//ATR STD
    };
    input string Sample_StartTime = "2:30";
    input string Sample_EndTime = "2:45";
    input int Initial_Numshares =1;
    input int NumShares_Step =1;
    input int Max_Shares =1;
    input double Day_Profit_Target= 200;
    input strategy_mode mode_s=mode2; //Strategy mode
    input color colorA = clrRed;
    input color colorB = clrGreen;
    input color colorC = clrViolet;
    input int up_shift=75;//upperpartline: pricels + X tick
    input int down_shift=75;//lowerpartline: pricels - X tick
    input ENUM_ORDER_TYPE_FILLING OrderFillingType=ORDER_FILLING_RETURN;
    input string comatr="===[ATR Settings]===";//~
    input double atr_hit=0.8;//ATR value to hit
    input int atr_ma_period=80; // averaging period ATR
    input string comstd="===[StdDev Settings]===";//~
    input double std_hit=1.6;//STD value to hit
    input int std_ma_period=80; // averaging period
    input int std_ma_shift=0; // horizontal shift
    input ENUM_MA_METHOD std_ma_method=MODE_SMA; // smoothing type
    input ENUM_APPLIED_PRICE std_applied_price=PRICE_CLOSE; // type of price or handle
    double last_bid,tmp_lot;
    double iATRBuffer[1],iStdDevBuffer[1];
    int ATRhandle,STDhandle;
    double PriceLS;
    bool cross_down_line_up,cross_down_line_down,cross_up_line_up,cross_up_line_down;
    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //---
    cross_down_line_up=false;cross_down_line_down=false;cross_up_line_up=false;cross_up_line_down=false;
    last_bid= SymbolInfoDouble(Symbol(),SYMBOL_BID);
    tmp_lot = Initial_Numshares;
    PriceLS=0;
    Trade.SetTypeFilling(OrderFillingType);
    Trade.SetExpertMagicNumber(MAGIC);
    if(mode_s==mode2)
    {
    ATRhandle=iATR(_Symbol,0,atr_ma_period);
    if(ATRhandle==INVALID_HANDLE)
    {
    //--- tell about the failure and output the error code
    PrintFormat("Failed to create handle of the iATR indicator for the symbol %s/%s, error code %d",
    GetLastError());
    //--- the indicator is stopped early
    return(INIT_FAILED);
    }
    STDhandle=iStdDev(_Symbol,0,std_ma_period,std_ma_shift,std_ma_method,std_applied_price);
    if(STDhandle==INVALID_HANDLE)
    {
    //--- tell about the failure and output the error code
    PrintFormat("Failed to create handle of the iStdDev indicator for the symbol %s/%s, error code %d",
    GetLastError());
    //--- the indicator is stopped early
    return(INIT_FAILED);
    }
    }
    //---
    return(INIT_SUCCEEDED);
    }
    //+------------------------------------------------------------------+
    //| Expert deinitialization function |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    //---
    ObjectsDeleteAll(0,"hline_",0,OBJ_HLINE);
    ObjectsDeleteAll(0,"text_",0,OBJ_LABEL);
    }
    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    //---
    if(PositionsTotal()==0 && tmp_lot!=Initial_Numshares)
    {
    PriceLS =0;
    tmp_lot = Initial_Numshares;
    }
    if(mode_s==mode1 && PriceLS==0)
    {
    int _start= iBarShift(Symbol(),Period(),cur_time(Sample_StartTime));
    int _stop = iBarShift(Symbol(),Period(),cur_time(Sample_EndTime));
    double _low=iLow(iLowest(_start-_stop+1,_stop));
    double _high=iHigh(iHighest(_start-_stop+1,_stop));
    PriceLS=(_high+_low)/2;
    }
    if(mode_s==mode2 && PriceLS==0)
    {
    CopyBuffer(ATRhandle,0,0,1,iATRBuffer);
    double _atr=iATRBuffer[0];
    CopyBuffer(STDhandle,0,0,1,iStdDevBuffer);
    double _std=iStdDevBuffer[0];
    if(_atr>atr_hit && _std>std_hit)
    {
    PriceLS=iClose(1);
    draw_hline("mid",PriceLS,colorC);
    }
    }
    double price_up_line=PriceLS+up_shift*Point();
    double price_down_line=PriceLS -down_shift*Point();
    if(PriceLS!=0)
    {
    draw_hline("up_price",price_up_line,colorC);
    draw_hline("down_price",price_down_line,colorC);
    }
    if(tmp_lot>Max_Shares)
    {
    PriceLS =0;
    tmp_lot = Initial_Numshares;
    return;
    }
    double _bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
    if(last_bid<price_down_line && _bid>price_down_line)
    {
    cross_down_line_up=true;cross_down_line_down=false;
    }
    if(last_bid>price_down_line && _bid<price_down_line)
    {
    cross_down_line_up=false;cross_down_line_down=true;
    }
    if(last_bid<price_up_line && _bid>price_up_line)
    {
    cross_up_line_up=true;cross_up_line_down=false;
    }
    if(last_bid>price_up_line && _bid<price_up_line)
    {
    cross_up_line_up=false;cross_up_line_down=true;
    }
    if(cross_down_line_up && cross_up_line_up)
    {
    cross_down_line_up=false;cross_down_line_down=false;cross_up_line_up=false;cross_up_line_down=false;
    double quantity=NormalizeDouble(tmp_lot,2);
    double Tickdistance=Day_Profit_Target*SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/quantity;
    double line_value=Tickdistance+SymbolInfoDouble(Symbol(),SYMBOL_ASK);
    double sl_line_value=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-Tickdistance;
    Trade.Buy(quantity,NULL,0,sl_line_value,line_value,"");
    Print("buy");
    tmp_lot+=NumShares_Step;
    draw_hline("tp",line_value,colorB,STYLE_SOLID,2);
    draw_hline("sl",sl_line_value,colorA,STYLE_SOLID,2);
    LabelCreate(0,0,20,20,0,"Current Position : "+DoubleToString(SymbolInfoDouble(Symbol(),SYMBOL_ASK),int(SymbolInfoInteger(Symbol(),SYMBOL_DIGITS)))+" Profit Target Price : "+DoubleToString(line_value,int(SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))));
    Print(Trade.ResultRetcodeDescription());
    }
    if(cross_down_line_down && cross_up_line_down)
    {
    cross_down_line_up=false;cross_down_line_down=false;cross_up_line_up=false;cross_up_line_down=false;
    double quantity=NormalizeDouble(tmp_lot,2);
    double Tickdistance=Day_Profit_Target*SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/quantity;
    double line_value=SymbolInfoDouble(Symbol(),SYMBOL_BID) -Tickdistance;
    double sl_line_value=Tickdistance+SymbolInfoDouble(Symbol(),SYMBOL_BID);
    Trade.Sell(quantity,NULL,0,sl_line_value,line_value,"");
    Print("sell");
    tmp_lot+=NumShares_Step;
    draw_hline("tp",line_value,colorB,STYLE_SOLID,2);
    draw_hline("sl",sl_line_value,colorA,STYLE_SOLID,2);
    LabelCreate(0,0,20,20,0,"Current Position : "+DoubleToString(SymbolInfoDouble(Symbol(),SYMBOL_BID),int(SymbolInfoInteger(Symbol(),SYMBOL_DIGITS)))+" Profit Target Price : "+DoubleToString(line_value,int(SymbolInfoInteger(Symbol(),SYMBOL_DIGITS))));
    Print(Trade.ResultRetcodeDescription());
    }
    last_bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
    }
    //+------------------------------------------------------------------+
    void draw_hline(string _name,double _price,color clr=clrRed,ENUM_LINE_STYLE style=STYLE_SOLID,int width=1)
    {
    long chart_ID=ChartID();
    string name="hline_"+_name;
    //--- create a horizontal line
    ObjectCreate(chart_ID,name,OBJ_HLINE,0,0,_price);
    ObjectSetDouble(chart_ID,name,OBJPROP_PRICE,_price);
    //--- set line color
    ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
    //--- set line display style
    ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
    //--- set line width
    ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
    }
    //+------------------------------------------------------------------+
    double iHigh(int index)
    {
    if(index < 0) return(-1);
    double Arr[];
    if(CopyHigh(_Symbol,_Period,index,1,Arr)>0)
    return(Arr[0]);
    else return(-1);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    int iHighest(int count=WHOLE_ARRAY,
    int start=0)
    {
    if(start<0) return(-1);
    if(count<=0) count=Bars(_Symbol,_Period);
    double High[];
    ArraySetAsSeries(High,true);
    CopyHigh(_Symbol,_Period,start,count,High);
    return(ArrayMaximum(High,0,count)+start);
    return(0);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    //+------------------------------------------------------------------+
    double iLow(int index)
    {
    if(index < 0) return(-1);
    double Arr[];
    if(CopyLow(Symbol(),Period(),index,1,Arr)>0)
    return(Arr[0]);
    else return(-1);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    int iLowest(int count=WHOLE_ARRAY,
    int start=0)
    {
    if(start<0) return(-1);
    if(count<=0) count=Bars(_Symbol,_Period);
    double Low[];
    ArraySetAsSeries(Low,true);
    CopyLow(_Symbol,_Period,start,count,Low);
    return(ArrayMinimum(Low,0,count)+start);
    //---
    return(0);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    int iBarShift(string symbol,ENUM_TIMEFRAMES timeframe,datetime time,bool exact=false)
    {
    datetime LastBar;
    if(!SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE,LastBar))
    {
    //-- Sometimes SeriesInfoInteger with SERIES_LASTBAR_DATE return an error,
    //-- so we try an other method
    datetime opentimelastbar[1];
    if(CopyTime(symbol,timeframe,0,1,opentimelastbar)==1)
    LastBar=opentimelastbar[0];
    else
    return(-1);
    }
    //--- if time > LastBar we always return 0
    if(time>LastBar)
    return(0);
    //---
    int shift=Bars(symbol,timeframe,time,LastBar);
    datetime checkcandle[1];
    //-- If time requested doesn't match opening time of a candle,
    //-- we need a correction of shift value
    if(CopyTime(symbol,timeframe,time,1,checkcandle)==1)
    {
    if(checkcandle[0]==time)
    return(shift-1);
    else if(exact && time>checkcandle[0]+PeriodSeconds(timeframe))
    return(-1);
    else
    return(shift);
    /*
    Can be replaced by the following statement for more concision
    return(checkcandle[0]==time ? shift-1 : (exact && time>checkcandle[0]+PeriodSeconds(timeframe) ? -1 : shift));
    */
    }
    return(-1);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    datetime cur_time(string _time)
    {
    return(StringToTime(TimeToString(TimeTradeServer(),TIME_DATE)+" "+_time+":00"));
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    double iHighD()
    {
    double Arr[];
    if(CopyHigh(_Symbol,PERIOD_D1,1,1,Arr)>0)
    return(Arr[0]);
    else return(-1);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    double iLowD()
    {
    double Arr[];
    if(CopyLow(Symbol(),PERIOD_D1,1,1,Arr)>0)
    return(Arr[0]);
    else return(-1);
    }
    //+------------------------------------------------------------------+
    void LabelCreate(const long chart_ID=0, // chart's ID
    const int sub_window=0, // subwindow index
    const int x=0, // X coordinate
    const int y=0, // Y coordinate
    const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring
    const string text="Label", // text
    const string font="Arial", // font
    const int font_size=20, // font size
    const color clr=clrWhite) // priority for mouse click
    {
    //--- reset the error value
    string name="text_profit";
    ObjectCreate(chart_ID,name,OBJ_LABEL,0,0,0);
    //--- set label coordinates
    ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
    ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
    //--- set the chart's corner, relative to which point coordinates are defined
    ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
    //--- set the text
    ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
    //--- set text font
    ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
    //--- set font size
    ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
    //--- set color
    ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
    }
    //+------------------------------------------------------------------+
    //| |
    //+------------------------------------------------------------------+
    double iClose(int nShift)
    {
    double timeseries[1];
    if(CopyClose(_Symbol,0,nShift,1,timeseries)==1) return(timeseries[0]);
    else return(-1.0);
    }
    //+------------------------------------------------------------------+
     
  2. Cool, thanks for sharing. Nice to see, instead of the usual ET thread.
     
  3. --MT5 amp demo accounts, use the local server time location on the charts, so when developing strategies that are scheduled news dependent, you need to put in the appropriate time inputs.

    --USA AMP accounts lets you try out the demo using futures.(ESM7)

    --Profit targets are number of ticks.

    --Above code has two modes, a time mode where two time points are used to generate a line that's split into the upper line and lower line. The upper and lower line try to break granularity logic, where a 'cross' up or down is defined of the 'thicker' line. So for ESM7, if your put 75 for each field. It takes the price 2378.00 and +- .75 to generate 2378.75 and 2377.25.

    -ATR/STD criteria, a line is generated when ATR and STD exceed set criteria, and logic is similar to 'cross'.