ASP Logo
Evogen ASP
Firmware API
 

Brijon Concept of Threes auto trading robot by Steve Hopwood.mq4

00001 /*********************************************************************************
00002 
00003  Copyright 2011 Steve Hopwood
00004 
00005 *********************************************************************************/
00006 
00007 /** \file Brijon Concept of Threes auto trading robot by Steve Hopwood.mq4
00008      CAN Bus initialization and communication
00009 
00010      \author Steve Hopwood
00011      \version 33
00012      \date March 8 2011
00013 \defgroup THREES Brijon Concept of Threes
00014 */
00015 //+-------------------------------------------------------------------+
00016 //|  Brijon Concept of Threes auto trading robot by Steve Hopwood.mq4 |
00017 //|                                  Copyright © 2009, Steve Hopwood  |
00018 //|                              http://www.hopwood3.freeserve.co.uk  |
00019 //+-------------------------------------------------------------------+
00020 #property copyright "Copyright © 2009, Steve Hopwood"
00021 #property link      "http://www.hopwood3.freeserve.co.uk"
00022 #include <WinUser32.mqh>
00023 #include <stdlib.mqh>
00024 #define  NL    "\n"
00025 #define  up "Up"
00026 #define  down "Down"
00027 #define  buy "Buy"
00028 #define  sell "Sell"
00029 #define  none "None"
00030 #define  ranging "Ranging"
00031 #define  confused "Confused, and so cannot trade"
00032 #define  trending "Trending"
00033 #define  opentrade "There is a trade open"
00034 #define  stopped "Trading is stopped"
00035 #define  highline "High line"
00036 #define  lowline "Low line"
00037 #define  todayopenline "Today's open line"
00038 #define  yesterdaycloseline "Yesterday's close line"
00039 #define  squarehighline "Square high line"
00040 #define  squarelowline "Square low line"
00041 #define  reentrylinename "Re entry line"
00042 
00043 
00044 
00045 
00046 extern string  gen="----General inputs----";
00047 extern double  Lot=1;
00048 extern int     MagicNumber=0;
00049 extern string  TradeComment="";
00050 extern bool    CriminalIsECN=false;
00051 extern bool    SendAlertNotTrade=true;
00052 extern string  td="----Trading direction choices----";
00053 extern bool    TradeLong=true;
00054 extern bool    TradeShort=true;
00055 extern string  tc="----Trade closure----";
00056 extern int     ClosureTargetPips=3;
00057 extern string  tpi="----Take profit----";
00058 extern bool    UseCandleLength=false;
00059 extern int     TakeProfit=0;
00060 extern bool    UseSquareForTakeProfit=false;
00061 extern string  sli="----Stop loss----";
00062 extern bool    UseStopLoss = false;
00063 extern string  slii="Leave at 0 to use candle length";
00064 extern int     StopLoss=0;
00065 extern bool    UseSquareForStopLoss=false;
00066 /*
00067 extern string  rsiin="----Rsi trade direction determination inputs----";
00068 extern int     RsiTf=1440;
00069 extern int     RsiPeriod=20;
00070 extern string  rsap="Applied price: 0=Close; 1=Open; 2=High";
00071 extern string  rsap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
00072 extern int     RsiAppliedPrice=0;
00073 */
00074 extern string  tdm="----Automatic Trade direction----";
00075 extern bool    UseD1Close=false;
00076 extern bool    UseW1Close=false;
00077 extern bool    UseSquareFilter=true;
00078 extern bool    UseVolume=true;
00079 //extern  int    VolumeTimeFrame=0;
00080 extern int     VolumeTickCountPeriod=60;
00081 extern int     MinTicksDifference=20;
00082 extern int     TicksCountBeforeTrading=200;
00083 extern string  ls="LSMA";
00084 extern bool    UseLSMA=false;
00085 extern int     LSMA_Period_Fast=21;
00086 extern int     LSMA_Period_Slow=336;
00087 extern string  vs="----Volatility inputs----";
00088 extern int     LookBackDays=2;
00089 //extern int     LowVolatility=50;
00090 //extern int     MediumVolatility=100;
00091 //extern int     HighVolatility=150;
00092 //extern int     PsychoticallyDeranged=200;
00093 extern string  rec="----Recovery----";
00094 extern int     ReEntryLinePips=0;
00095 extern color   ReEntryLineColour=Turquoise;
00096 extern string  tt="----Trading hours----";
00097 extern string  Trade_Hours= "Set Morning & Evening Hours";
00098 extern string  Trade_Hoursi= "Use 24 hour, local time clock";
00099 extern string  Trade_Hours_M= "Morning Hours 0-12";
00100 extern  int    start_hourm = 0;
00101 extern  int    end_hourm = 12;
00102 extern string  Trade_Hours_E= "Evening Hours 12-24";
00103 extern  int    start_houre = 12;
00104 extern  int    end_houre = 24;
00105 extern string  bl="----Bosun lines----";
00106 extern string  bl1="D1 1440: W1 10080: MN1 40320";
00107 extern int     BlTimeFrame=10080;
00108 extern int     AllowablePipsFrom_S_R=20;
00109 extern string  sq="----Square----";
00110 extern int     SquareTimeFrame=240;
00111 extern bool    SendSquareTouchAlert=false;
00112 extern string  tmm="----Trade management module----";
00113 extern string  BE="Break even settings";
00114 extern bool    BreakEven=false;
00115 extern int     BreakEvenPips=20;
00116 extern int     BreakEvenProfit=5;
00117 extern bool    HideBreakEvenStop=false;
00118 extern int     PipsAwayFromVisualBE=5;
00119 extern string  JSL="Jumping stop loss settings";
00120 extern bool    JumpingStop=false;
00121 extern int     JumpingStopPips=30;
00122 extern bool    AddBEP=false;
00123 extern bool    JumpAfterBreakevenOnly=false;
00124 extern bool    HideJumpingStop=false;
00125 extern int     PipsAwayFromVisualJS=10;
00126 extern string  TSL="Trailing stop loss settings";
00127 extern bool    TrailingStop=false;
00128 extern int     TrailingStopPips=50;
00129 extern bool    HideTrailingStop=false;
00130 extern int     PipsAwayFromVisualTS=10;
00131 extern bool    TrailAfterBreakevenOnly=false;
00132 extern bool    StopTrailAtPipsProfit=false;
00133 extern int     StopTrailPips=0;
00134 extern bool    UsePercentageOfSquare=true;
00135 extern double  SquarePercentToUse=50;
00136 extern string  hsl1="Hidden stop loss settings";
00137 extern bool    HideStopLossEnabled=false;
00138 extern int     HiddenStopLossPips=20;
00139 extern string  htp="Hidden take profit settings";
00140 extern bool    HideTakeProfitEnabled=false;
00141 extern int     HiddenTakeProfitPips=20;
00142 extern string  mis="----Odds and ends----";
00143 extern bool    ShowManagementAlerts=true;
00144 extern int     DisplayGapSize=30;
00145 
00146 
00147 //Candle variables
00148 double         Phigh, Plow, Popen, Copen;//Previous hi-lo-open and current open
00149 double         Yclose;//Yesterday close price
00150 
00151 //Volumes
00152 int            UpTicks, DownTicks;
00153 
00154 //Square
00155 double         SquareHigh, SquareLow;
00156 
00157 //LSMA
00158 double         LsmaFastVal, LsmaSlowVal, PrevLsmaFastVal, PrevLsmaSlowVal;
00159 string         LsmaFastTradeDirection, LsmaSlowTradeDirection;
00160 //Bosun lines
00161 double         Bl[14];//13 levels inc pivot   
00162 string         BlDescription[] = {"Bosun Line S6", "Bosun Line S5", "Bosun Line S4", "Bosun Line S3", "Bosun Line S2", "Bosun Line S1", "Bosun Line Pivot",
00163                                   "Bosun Line R1", "Bosun Line R2", "Bosun Line R3", "Bosun Line R4", "Bosun Line R5", "Bosun Line R6"};
00164 double         NextResistance, NextSupport;
00165 
00166 //Trading variables
00167 int            TicketNo, OpenTrades;
00168 bool TradeExists;
00169 
00170 //Matt's O-R stuff
00171 int            O_R_Setting_max_retries  = 10;
00172 double        O_R_Setting_sleep_time    = 4.0; /* seconds */
00173 double        O_R_Setting_sleep_max     = 15.0; /* seconds */
00174 
00175 //Rsi
00176 double         RsiVal;
00177 string         tradedirection;
00178 
00179 //Moving average
00180 double         MaVal;
00181 
00182 
00183 //Misc
00184 string         Gap, ScreenMessage;
00185 int            OldBars, OldD1Bars, OldTickBars;
00186 string         PipDescription=" pips";
00187 bool           AlertSent;//For manual traders to make the bot only send one trade at a time
00188 bool           SquareAlertSent;//For manual traders to receive an Alert at a touch of the square
00189 double         Volatility;
00190 
00191 void DisplayUserFeedback()
00192 {
00193    
00194    if (IsTesting() && !IsVisualMode()) return;
00195 
00196    ScreenMessage = "";
00197    ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
00198    ScreenMessage = StringConcatenate(ScreenMessage, Gap, TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), NL );
00199    /*
00200    //Code for time to bar-end display from Candle Time by Nick Bilak
00201    double i;
00202    int m,s,k;
00203    m=Time[0]+Period()*60-CurTime();
00204    i=m/60.0;
00205    s=m%60;
00206    m=(m-m%60)/60;
00207    ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);
00208    */
00209       
00210    ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
00211    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, NL);
00212    if (TradeLong) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading long", NL);
00213    else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not trading long", NL);
00214    if (TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading short", NL);
00215    else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not trading short", NL);
00216    if (SendAlertNotTrade) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Sending alerts not trades", NL);
00217    if (TakeProfit > 0) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, PipDescription,  NL);
00218    if (UseCandleLength) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: Using candle length", NL);
00219    if (UseSquareForTakeProfit) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: Using the Square", NL);
00220    if (TakeProfit == 0 && !UseCandleLength) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: None", NL);
00221    if (ClosureTargetPips > 0)  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "ClosureTargetPips: ", ClosureTargetPips, NL);
00222    if (StopLoss > 0) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss: ", StopLoss, PipDescription,  NL);
00223    if (StopLoss == 0 && UseStopLoss) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using previous candle length to calculate stop loss ", NL);
00224    if (!UseStopLoss) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not sending a stop loss ", NL);
00225    if (UseSquareForStopLoss) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss: Using the Square", NL);
00226    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
00227    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
00228    if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
00229    else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = false", NL);
00230    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL, NL );
00231    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
00232    if (start_hourm == 0 && end_hourm == 12 && start_houre && end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
00233    else
00234    {
00235       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_hourm: ", DoubleToStr(start_hourm, 2), 
00236                       ": end_hourm: ", DoubleToStr(end_hourm, 2), NL);
00237       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_houre: ", DoubleToStr(start_houre, 2), 
00238                       ": end_houre: ", DoubleToStr(end_houre, 2), NL);
00239                       
00240    }//else
00241    
00242    //Trade direction
00243    ScreenMessage = StringConcatenate(ScreenMessage,NL, Gap, "Trade direction: Direction is ", tradedirection, NL);      
00244    //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Rsi: ", RsiVal, ": Trend is: ", tradedirection, NL);
00245    string dir = none;      
00246    //D1 close
00247    if (iClose(NULL, PERIOD_D1, 2) > iClose(NULL, PERIOD_D1, 1) ) dir = down;
00248    if (iClose(NULL, PERIOD_D1, 2) < iClose(NULL, PERIOD_D1, 1) ) dir = up;      
00249    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      D1 closes: 2 days ago ", 
00250                    DoubleToStr(iClose(NULL, PERIOD_D1, 2), Digits), " Yesterdayago ", DoubleToStr(iClose(NULL, PERIOD_D1, 1), Digits), 
00251                    ": Direction is ", dir);
00252    if (UseD1Close) 
00253    {
00254       ScreenMessage = StringConcatenate(ScreenMessage, ": Filter enabled", NL);
00255    }//if (UseD1Close) 
00256    else ScreenMessage = StringConcatenate(ScreenMessage, ": Filter disabled", NL);
00257    
00258    //W1 close
00259    dir = none;      
00260    if (iClose(NULL, PERIOD_W1, 2) > iClose(NULL, PERIOD_W1, 1) ) dir = down;
00261    if (iClose(NULL, PERIOD_W1, 2) < iClose(NULL, PERIOD_W1, 1) ) dir = up;      
00262    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      W1 closes: ", 
00263                    DoubleToStr(iClose(NULL, PERIOD_W1, 2), Digits), " ", DoubleToStr(iClose(NULL, PERIOD_W1, 1), Digits), 
00264                    ": Direction is ", dir);
00265    if (UseW1Close) 
00266    {
00267       ScreenMessage = StringConcatenate(ScreenMessage, ": Filter enabled", NL);
00268    }//if (UseW1Close) 
00269    else ScreenMessage = StringConcatenate(ScreenMessage, ": Filter disabled", NL);
00270    
00271    if (UseSquareFilter) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Using Square filter (", 
00272                    DoubleToStr(SquareHigh, Digits), " ", DoubleToStr(SquareLow, Digits), "}", NL);
00273    else  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      SquareOverridesClose is disabled ", NL);
00274    
00275    //Volume
00276    dir = none;
00277    if (UpTicks > DownTicks && UpTicks - DownTicks > MinTicksDifference) dir = up;
00278    if (DownTicks > UpTicks && DownTicks - UpTicks > MinTicksDifference) dir = down;
00279    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Buy ticks: ", UpTicks, ": Sell ticks: ", DownTicks, 
00280                    ": TicksCountBeforeTrading ", TicksCountBeforeTrading, 
00281                    ": MinTicksDifference ", MinTicksDifference,
00282                    ": Difference ", MathAbs(UpTicks - DownTicks), 
00283                    ": Direction ", dir);
00284    if (UseVolume) ScreenMessage = StringConcatenate(ScreenMessage, "      Using Volume filter", NL);
00285    else  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Volume filter is disabled ", NL);
00286    
00287    
00288    //LSMA
00289    if (UseLSMA)
00290    {
00291        ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Using LSMA filter", NL);
00292    }//if (UseLSMA)
00293    else  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LSMA filter is disabled ", NL);
00294    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Fast LSMA: ", LsmaFastTradeDirection, ":  ",
00295                    PrevLsmaFastVal, "  ", LsmaFastVal, NL);
00296    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Slow LSMA: ", LsmaSlowTradeDirection, ":  ",
00297                    PrevLsmaSlowVal, "  ", LsmaSlowVal, NL);
00298 
00299    
00300    
00301    ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
00302    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Bosun lines", NL);
00303    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Next resistance: ", DoubleToStr(NextResistance, Digits), NL);
00304    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Next support: ", DoubleToStr(NextSupport, Digits), NL);
00305    ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      AllowablePipsFrom_S_R: ", AllowablePipsFrom_S_R, NL);
00306    ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Volatility = ", Volatility, ":  ReEntryLinePips = ", ReEntryLinePips, NL);
00307    
00308 
00309    ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
00310    
00311    if (BreakEven)
00312    {
00313       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Breakeven is set to ", BreakEvenPips, PipDescription);
00314       ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit, PipDescription);
00315       ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL); 
00316    }//if (BreakEven)
00317 
00318    if (JumpingStop)
00319    {
00320       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Jumping stop is set to ", JumpingStopPips, PipDescription);
00321       if (AddBEP) ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit, PipDescription);
00322       if (JumpAfterBreakevenOnly) ScreenMessage = StringConcatenate(ScreenMessage, ": JumpAfterBreakevenOnly = true");
00323       ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
00324    }//if (JumpingStop)
00325    
00326 
00327    if (TrailingStop)
00328    {
00329       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trailing stop is set to ", TrailingStopPips, PipDescription);
00330       if (TrailAfterBreakevenOnly) ScreenMessage = StringConcatenate(ScreenMessage, ": TrailAfterBreakevenOnly = true");
00331       ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
00332    }//if (TrailingStop)
00333 
00334    if (HideStopLossEnabled)
00335    {
00336       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden stop loss enabled at ", HiddenStopLossPips, PipDescription, NL);
00337    }//if (HideStopLossEnabled)
00338    
00339    if (HideTakeProfitEnabled)
00340    {
00341       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden take profit enabled at ", HideTakeProfitEnabled, PipDescription, NL);
00342    }//if (HideTakeProfitEnabled)
00343 
00344    //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Upper line: ", DoubleToStr(BbUpper, Digits), NL);
00345    //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Middle line: ", DoubleToStr(BbMiddle, Digits), NL);
00346    //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
00347    //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
00348    
00349    if (TicketNo!=-1) {
00350       if (OrderSelect(TicketNo, SELECT_BY_TICKET)) {
00351         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Open Ticket: ", TicketNo, " upl= $", OrderProfit(), NL);
00352       }
00353    }
00354 
00355    Comment(ScreenMessage);
00356 
00357 
00358 }//void DisplayUserFeedback()
00359 
00360 
00361 //+------------------------------------------------------------------+
00362 //| expert initialization function                                   |
00363 //+------------------------------------------------------------------+
00364 int init()
00365 {
00366 //----
00367 
00368    //Adapt to x digit criminals
00369    int multiplier = Get_X_Digit_Multiplier();
00370    
00371    if (multiplier > 1) PipDescription = " points";
00372    
00373    TakeProfit*= multiplier;
00374    StopLoss*= multiplier;
00375    BreakEvenPips*= multiplier;
00376    BreakEvenProfit*= multiplier;
00377    PipsAwayFromVisualBE*= multiplier;
00378    JumpingStopPips*= multiplier;
00379    PipsAwayFromVisualJS*= multiplier;
00380    TrailingStopPips*= multiplier;
00381    PipsAwayFromVisualTS*= multiplier;
00382    StopTrailPips*= multiplier;
00383    HiddenStopLossPips*= multiplier;
00384    HiddenTakeProfitPips*= multiplier;
00385    AllowablePipsFrom_S_R*= multiplier;
00386    ClosureTargetPips*= multiplier;
00387    ReEntryLinePips*= multiplier;
00388    
00389 
00390    Gap="";
00391    if (DisplayGapSize >0)
00392    {
00393       for (int cc=0; cc< DisplayGapSize; cc++)
00394       {
00395          Gap = StringConcatenate(Gap, " ");
00396       }   
00397    }//if (DisplayGapSize >0)
00398    
00399 
00400    if (TradeComment == "") TradeComment = " ";
00401    DisplayUserFeedback();
00402    //OldBars = Bars;
00403    
00404 //----
00405    return(0);
00406 }
00407 //+------------------------------------------------------------------+
00408 //| expert deinitialization function                                 |
00409 //+------------------------------------------------------------------+
00410 int deinit()
00411 {
00412 //----
00413    Comment("");
00414    
00415    
00416    //ObjectsDeleteAll(0);
00417    
00418    for (int cc = ObjectsTotal(); cc >= 0; cc--)
00419    {
00420       if (ObjectType(ObjectName(cc)) == OBJ_TREND)
00421       {
00422          ObjectDelete(ObjectName(cc) );
00423          cc++;
00424       }//if (ObjectType(ObjectName(cc)) == OBJ_TREND)
00425       
00426    }//for (int cc = ObjectsTotal; cc >= 0; cc--)
00427    
00428    
00429 //----
00430    return(0);
00431 }
00432 
00433 int Get_X_Digit_Multiplier()
00434 {
00435    //Returns a multiplier to adapt pips inputs etc to x digit crims
00436    
00437    int mult;
00438    if(Digits == 2 || Digits == 4) mult = 1;
00439    if(Digits == 3 || Digits == 5) mult = 10;
00440    if(Digits == 6) mult = 100;   
00441    if(Digits == 7) mult = 1000;   
00442    
00443    return(mult);
00444 
00445 }//int Get_X_Digit_Multiplier()
00446 
00447 ////////////////////////////////////////////////////////////////////////////////////////////////
00448 //TRADE MANAGEMENT MODULE
00449 
00450 bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
00451 {
00452    //Reusable code that can be called by any of the stop loss manipulation routines except HiddenStopLoss().
00453    //Checks to see if the market has hit the hidden sl and attempts to close the trade if so. 
00454    //Returns true if trade closure is successful, else returns false
00455    
00456    //Check buy trade
00457    if (type == OP_BUY)
00458    {
00459       double sl = NormalizeDouble(stop + (iPipsAboveVisual * Point), Digits);
00460       if (Bid <= sl)
00461       {
00462          while(IsTradeContextBusy()) Sleep(100);
00463          bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
00464          if (result)
00465          {
00466             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
00467          }//if (result)
00468          else
00469          {
00470             int err=GetLastError();
00471             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00472             Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00473          }//else
00474       }//if (Bid <= sl)  
00475    }//if (type = OP_BUY)
00476    
00477    //Check buy trade
00478    if (type == OP_SELL)
00479    {
00480       sl = NormalizeDouble(stop - (iPipsAboveVisual * Point), Digits);
00481       if (Ask >= sl)
00482       {
00483          while(IsTradeContextBusy()) Sleep(100);
00484          result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
00485          if (result)
00486          {
00487             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
00488          }//if (result)
00489          else
00490          {
00491             err=GetLastError();
00492             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00493             Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00494          }//else
00495       }//if (Ask >= sl)  
00496    }//if (type = OP_SELL)
00497    
00498 
00499 }//End bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
00500 
00501 
00502 void BreakEvenStopLoss() // Move stop loss to breakeven
00503 {
00504 
00505    //Check hidden BE for trade closure
00506    if (HideBreakEvenStop)
00507    {
00508       bool TradeClosed = CheckForHiddenStopLossHit(OrderType(), PipsAwayFromVisualBE, OrderStopLoss() );
00509       if (TradeClosed) return;//Trade has closed, so nothing else to do
00510    }//if (HideBreakEvenStop)
00511 
00512 
00513    bool result;
00514 
00515    if (OrderType()==OP_BUY)
00516          {
00517             if (Bid >= OrderOpenPrice () + (Point*BreakEvenPips) && 
00518                 OrderStopLoss()<OrderOpenPrice())
00519             {
00520                while(IsTradeContextBusy()) Sleep(100);
00521                result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
00522                if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
00523                Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
00524                if (!result)
00525                {
00526                   int err=GetLastError();
00527                   if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00528                   Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00529                }//if !result && ShowManagementAlerts)      
00530                //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
00531                //{
00532                //   bool PartCloseSuccess = PartCloseTradeFunction();
00533                //   if (!PartCloseSuccess) SetAGlobalTicketVariable();
00534                //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
00535             }
00536        }                             
00537           
00538    if (OrderType()==OP_SELL)
00539          {
00540            if (Ask <= OrderOpenPrice() - (Point*BreakEvenPips) &&
00541               (OrderStopLoss()>OrderOpenPrice()|| OrderStopLoss()==0)) 
00542             {
00543                while(IsTradeContextBusy()) Sleep(100);
00544                result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
00545                if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
00546                Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
00547                if (!result && ShowManagementAlerts)
00548                {
00549                   err=GetLastError();
00550                   if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00551                   Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00552                }//if !result && ShowManagementAlerts)      
00553               //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
00554               // {
00555               //    PartCloseSuccess = PartCloseTradeFunction();
00556               //    if (!PartCloseSuccess) SetAGlobalTicketVariable();
00557               // }//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
00558             }    
00559          }
00560       
00561 
00562 } // End BreakevenStopLoss sub
00563 
00564 void JumpingStopLoss() 
00565 {
00566    // Jump sl by pips and at intervals chosen by user .
00567    // Also carry out partial closure if the user requires this
00568 
00569    // Abort the routine if JumpAfterBreakevenOnly is set to true and be sl is not yet set
00570    if (JumpAfterBreakevenOnly && OrderType()==OP_BUY)
00571    {
00572       if(OrderStopLoss()<OrderOpenPrice()) return(0);
00573    }
00574   
00575    if (JumpAfterBreakevenOnly && OrderType()==OP_SELL)
00576    {
00577       if(OrderStopLoss()>OrderOpenPrice() || OrderStopLoss() == 0 ) return(0);
00578    }
00579   
00580    double sl=OrderStopLoss(); //Stop loss
00581 
00582    if (OrderType()==OP_BUY)
00583    {
00584       //Check hidden js for trade closure
00585       if (HideJumpingStop)
00586       {
00587          bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
00588          if (TradeClosed) return;//Trade has closed, so nothing else to do
00589       }//if (HideJumpingStop)
00590       
00591       // First check if sl needs setting to breakeven
00592       if (sl==0 || sl<OrderOpenPrice())
00593       {
00594          if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
00595          {
00596             sl=OrderOpenPrice();
00597             if (AddBEP==true) sl=sl+(BreakEvenProfit*Point); // If user wants to add a profit to the break even
00598             while(IsTradeContextBusy()) Sleep(100);
00599             bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
00600             if (result)
00601             {
00602                if (ShowManagementAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
00603                Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", Bid);
00604                //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
00605                //{
00606                   //bool PartCloseSuccess = PartCloseTradeFunction();
00607                   //if (!PartCloseSuccess) SetAGlobalTicketVariable();
00608                //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
00609             }//if (result)
00610             if (!result)
00611             {
00612                int err=GetLastError();
00613                if (ShowManagementAlerts) Alert(OrderSymbol(), "Ticket ", OrderTicket(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
00614                Print(OrderSymbol(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
00615             }//if (!result)
00616              
00617             return(0);
00618          }//if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
00619       } //close if (sl==0 || sl<OrderOpenPrice()
00620 
00621   
00622       // Increment sl by sl + JumpingStopPips.
00623       // This will happen when market price >= (sl + JumpingStopPips)
00624       if (Bid>= sl + ((JumpingStopPips*2)*Point) && sl>= OrderOpenPrice())      
00625       {
00626          sl=sl+(JumpingStopPips*Point);
00627          while(IsTradeContextBusy()) Sleep(100);
00628          result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
00629          if (result)
00630          {
00631             if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
00632             Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
00633             //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
00634             //{
00635                //PartCloseSuccess = PartCloseTradeFunction();
00636                //if (!PartCloseSuccess) SetAGlobalTicketVariable();
00637             //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
00638          }//if (result)
00639          if (!result)
00640          {
00641             err=GetLastError();
00642             if (ShowManagementAlerts) Alert(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
00643             Print(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
00644          }//if (!result)
00645              
00646       }// if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())      
00647    }//if (OrderType()==OP_BUY)
00648    
00649    if (OrderType()==OP_SELL)
00650    {
00651       //Check hidden js for trade closure
00652       if (HideJumpingStop)
00653       {
00654          TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualJS, OrderStopLoss() );
00655          if (TradeClosed) return;//Trade has closed, so nothing else to do
00656       }//if (HideJumpingStop)
00657             
00658       // First check if sl needs setting to breakeven
00659       if (sl==0 || sl>OrderOpenPrice())
00660       {
00661          if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
00662          {
00663             sl = OrderOpenPrice();
00664             if (AddBEP==true) sl=sl-(BreakEvenProfit*Point); // If user wants to add a profit to the break even
00665             while(IsTradeContextBusy()) Sleep(100);
00666             result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
00667             if (result)
00668             {
00669                //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
00670                //{
00671                  // PartCloseSuccess = PartCloseTradeFunction();
00672                   //if (!PartCloseSuccess) SetAGlobalTicketVariable();
00673                //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
00674             }//if (result)
00675             if (!result)
00676             {
00677                err=GetLastError();
00678                if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
00679                Print(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
00680             }//if (!result)
00681              
00682             return(0);
00683          }//if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
00684       } // if (sl==0 || sl>OrderOpenPrice()
00685    
00686       // Decrement sl by sl - JumpingStopPips.
00687       // This will happen when market price <= (sl - JumpingStopPips)
00688       if (Bid<= sl - ((JumpingStopPips*2)*Point) && sl<= OrderOpenPrice())      
00689       {
00690          sl=sl-(JumpingStopPips*Point);
00691          while(IsTradeContextBusy()) Sleep(100);
00692          result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
00693          if (result)
00694          {
00695             if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
00696             Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
00697             //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
00698             //{
00699               // PartCloseSuccess = PartCloseTradeFunction();
00700                //if (!PartCloseSuccess) SetAGlobalTicketVariable();
00701             //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
00702          }//if (result)          
00703          if (!result)
00704          {
00705             err=GetLastError();
00706             if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
00707             Print(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
00708          }//if (!result)
00709 
00710       }// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())         
00711    }//if (OrderType()==OP_SELL)
00712 
00713 } //End of JumpingStopLoss sub
00714 
00715 void HiddenStopLoss()
00716 {
00717    //Called from ManageTrade if HideStopLossEnabled = true
00718 
00719 
00720    //Should the order close because the stop has been passed?
00721    //Buy trade
00722    if (OrderType() == OP_BUY)
00723    {
00724       double sl = NormalizeDouble(OrderOpenPrice() - (HiddenStopLossPips * Point), Digits);
00725       if (Bid <= sl)
00726       {
00727          while(IsTradeContextBusy()) Sleep(100);
00728          bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
00729          if (result)
00730          {
00731             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
00732          }//if (result)
00733          else
00734          {
00735             int err=GetLastError();
00736             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00737             Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00738          }//else
00739       }//if (Bid <= sl)      
00740    }//if (OrderType() == OP_BUY)
00741    
00742    //Sell trade
00743    if (OrderType() == OP_SELL)
00744    {
00745       sl = NormalizeDouble(OrderOpenPrice() + (HiddenStopLossPips * Point), Digits);
00746       if (Ask >= sl)
00747       {
00748          while(IsTradeContextBusy()) Sleep(100);
00749          result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
00750          if (result)
00751          {
00752             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
00753          }//if (result)
00754          else
00755          {
00756             err=GetLastError();
00757             if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00758             Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00759          }//else
00760       }//if (Ask >= sl)   
00761    }//if (OrderType() == OP_SELL)
00762    
00763 
00764 }//End void HiddenStopLoss()
00765 
00766 void HiddenTakeProfit()
00767 {
00768    //Called from ManageTrade if HideStopLossEnabled = true
00769 
00770 
00771    //Should the order close because the stop has been passed?
00772    //Buy trade
00773    if (OrderType() == OP_BUY)
00774    {
00775       double tp = NormalizeDouble(OrderOpenPrice() + (HiddenTakeProfitPips * Point), Digits);
00776       if (Bid >= tp)
00777       {
00778          while(IsTradeContextBusy()) Sleep(100);
00779          bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
00780          if (result)
00781          {
00782             if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
00783          }//if (result)
00784          else
00785          {
00786             int err=GetLastError();
00787             if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00788             Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00789          }//else
00790       }//if (Ask >= tp)      
00791    }//if (OrderType() == OP_BUY)
00792    
00793    //Sell trade
00794    if (OrderType() == OP_SELL)
00795    {
00796       tp = NormalizeDouble(OrderOpenPrice() - (HiddenTakeProfitPips * Point), Digits);
00797       if (Ask <= tp)
00798       {
00799          while(IsTradeContextBusy()) Sleep(100);
00800          result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
00801          if (result)
00802          {
00803             if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
00804          }//if (result)
00805          else
00806          {
00807             err=GetLastError();
00808             if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00809             Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
00810          }//else
00811       }//if (Bid <= tp)   
00812    }//if (OrderType() == OP_SELL)
00813    
00814 
00815 }//End void HiddenTakeProfit()
00816 
00817 void TrailingStopLoss()
00818 {
00819       if (TrailAfterBreakevenOnly && OrderType()==OP_BUY)
00820       {
00821          if(OrderStopLoss()<OrderOpenPrice()) return(0);
00822       }
00823      
00824       if (TrailAfterBreakevenOnly && OrderType()==OP_SELL)
00825       {
00826          if(OrderStopLoss()>OrderOpenPrice()) return(0);
00827       }
00828      
00829    
00830    
00831    bool result;
00832    double sl=OrderStopLoss(); //Stop loss
00833    double BuyStop=0, SellStop=0;
00834    
00835    if (OrderType()==OP_BUY) 
00836       {
00837          if (HideTrailingStop)
00838          {
00839             bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualTS, OrderStopLoss() );
00840             if (TradeClosed) return;//Trade has closed, so nothing else to do
00841          }//if (HideJumpingStop)
00842        
00843        if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
00844        {
00845            if (OrderStopLoss() == 0) sl = OrderOpenPrice();
00846            if (Bid > sl +  (TrailingStopPips*Point))
00847            {
00848               sl= Bid - (TrailingStopPips*Point);
00849               // Exit routine if user has chosen StopTrailAtPipsProfit and
00850               // sl is past the profit Point already
00851               if (StopTrailAtPipsProfit && sl>= OrderOpenPrice() + (StopTrailPips*Point)) return;
00852               while(IsTradeContextBusy()) Sleep(100);
00853               result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
00854                if (result)
00855                {
00856                   Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
00857                }//if (result) 
00858                else
00859                {
00860                   int err=GetLastError();
00861                   Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
00862                }//else
00863    
00864            }//if (Bid > sl +  (TrailingStopPips*Point))
00865        }//if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
00866       }//if (OrderType()==OP_BUY) 
00867 
00868       if (OrderType()==OP_SELL) 
00869       {
00870        if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
00871        {
00872              if (HideTrailingStop)
00873              {
00874                 TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualTS, OrderStopLoss() );
00875                 if (TradeClosed) return;//Trade has closed, so nothing else to do
00876              }//if (HideJumpingStop)
00877        
00878            if (OrderStopLoss() == 0) sl = OrderOpenPrice();
00879            if (Ask < sl -  (TrailingStopPips*Point))
00880            {
00881                  sl= Ask + (TrailingStopPips*Point);
00882                    // Exit routine if user has chosen StopTrailAtPipsProfit and
00883                 // sl is past the profit Point already
00884                 if (StopTrailAtPipsProfit && sl<= OrderOpenPrice() - (StopTrailPips*Point)) return;
00885                 while(IsTradeContextBusy()) Sleep(100);
00886                 result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
00887                   if (result)
00888                   {
00889                      Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
00890                   }//if (result)
00891                   else
00892                   {
00893                      err=GetLastError();
00894                      Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
00895                   }//else
00896     
00897            }//if (Ask < sl -  (TrailingStopPips*Point))
00898        }//if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
00899       }//if (OrderType()==OP_SELL) 
00900 
00901       
00902 } // End of TrailingStopLoss sub
00903 
00904 
00905 void TradeManagementModule()
00906 {
00907 
00908    // Call the working subroutines one by one. 
00909 
00910    // Hidden stop loss
00911    if (HideStopLossEnabled) HiddenStopLoss();
00912 
00913    // Hidden take profit
00914    if (HideTakeProfitEnabled) HiddenTakeProfit();
00915 
00916    // Breakeven
00917    if(BreakEven) BreakEvenStopLoss();
00918 
00919    // JumpingStop
00920    if(JumpingStop) JumpingStopLoss();
00921 
00922    //TrailingStop
00923    if(TrailingStop) TrailingStopLoss();
00924 
00925    
00926 
00927 }//void TradeManagementModule()
00928 //END TRADE MANAGEMENT MODULE
00929 ////////////////////////////////////////////////////////////////////////////////////////////////
00930 
00931 bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
00932 {
00933    
00934    if (IsTradeContextBusy() ) return;
00935    
00936    int slippage = 10;
00937    if (Digits == 3 || Digits == 5) slippage = 100;
00938    
00939    color col = Red;
00940    if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
00941    
00942    int expiry = 0;
00943    //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);
00944 
00945    if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, MagicNumber, expiry, col);
00946    
00947    
00948    //Is a 2 stage criminal
00949    if (CriminalIsECN)
00950    {
00951       bool result;
00952       int err;
00953       ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, MagicNumber, expiry, col);
00954       if (ticket > 0)
00955       {
00956        
00957        if (take > 0 && stop > 0)
00958         {
00959            while(IsTradeContextBusy()) Sleep(100);
00960            result = OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
00961            if (!result)
00962            {
00963                err=GetLastError();
00964                Print(Symbol(), " SL/TP  order modify failed with error(",err,"): ",ErrorDescription(err));               
00965            }//if (!result)        
00966         }//if (take > 0 && stop > 0)
00967       
00968        if (take != 0 && stop == 0)
00969         {
00970            while(IsTradeContextBusy()) Sleep(100);
00971            result = OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
00972            if (!result)
00973            {
00974                err=GetLastError();
00975                Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
00976            }//if (!result)        
00977         }//if (take == 0 && stop != 0)
00978 
00979         if (take == 0 && stop != 0)
00980         {
00981            while(IsTradeContextBusy()) Sleep(100);
00982            result = OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
00983            if (!result)
00984            {
00985                err=GetLastError();
00986                Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
00987            }//if (!result)        
00988         }//if (take == 0 && stop != 0)
00989 
00990       }//if (ticket > 0)
00991         
00992       
00993       
00994    }//if (CriminalIsECN)
00995    
00996    //Error trapping for both
00997    if (ticket < 0)
00998    {
00999       string stype;
01000       if (type == OP_BUY) stype = "OP_BUY";
01001       if (type == OP_SELL) stype = "OP_SELL";
01002       if (type == OP_BUYLIMIT) stype = "OP_BUYLIMIT";
01003       if (type == OP_SELLLIMIT) stype = "OP_SELLLIMIT";
01004       if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
01005       if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
01006       err=GetLastError();
01007       //Alert(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
01008       Print(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
01009       return(false);
01010    }//if (ticket < 0)  
01011    
01012    TicketNo = ticket;
01013    
01014    //Make sure the trade has appeared in the platform's history to avoid duplicate trades
01015    O_R_CheckForHistory(ticket); 
01016    //Got this far, so trade send succeeded
01017    return(true);
01018    
01019 }//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
01020 
01021 bool DoesTradeExist()
01022 {
01023    
01024    TicketNo = -1;
01025    
01026    if (OrdersTotal() == 0) return(false);
01027    
01028    
01029    for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
01030    {
01031       if (!OrderSelect(cc,SELECT_BY_POS)) continue;
01032       
01033       if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
01034       {
01035          TicketNo = OrderTicket();
01036          return(true);         
01037       }//if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
01038    }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
01039 
01040    return(false);
01041 
01042 }//End bool DoesTradeExist()
01043 
01044 
01045 void LookForTradingOpportunities()
01046 {
01047 
01048 
01049    /*
01050    //Look to send a new trade at the start of each new M1 candle
01051    static int M1Bars;   
01052    if (M1Bars == iBars(NULL, PERIOD_M1) ) return;
01053    M1Bars = iBars(NULL, PERIOD_M1);
01054    */
01055 
01056    RefreshRates();
01057    double take, stop, price;
01058    int type;
01059    bool SendTrade;
01060    double extent = High[1] - Low[1];
01061    string stype;
01062    double re_entryprice;
01063    
01064    
01065    //Cater for no tradedirection determination choice   
01066    //if (!UseD1Close && !UseW1Close) tradedirection = up;//Removed following logic from sq
01067    
01068    //Long 
01069    if (Ask > Phigh && tradedirection == up && TradeLong && Copen > Popen)
01070    //if (Ask > Phigh && iClose(NULL, PERIOD_M1, 1) > Phigh && tradedirection == up && TradeLong && Copen > Popen)
01071    //if (Open[0] > High[1])
01072    {
01073       if (UseCandleLength) take = NormalizeDouble(Ask + extent, Digits);
01074       if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
01075       if (UseSquareForTakeProfit) take = SquareHigh;
01076       if (take > 0)
01077       {
01078          if (take - Ask < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
01079       }//if (take > 0)
01080       
01081       stop = Plow;
01082       if (StopLoss > 0) stop = NormalizeDouble(Ask - (StopLoss * Point), Digits);
01083       if (UseSquareForStopLoss) stop = SquareLow;
01084       if (stop > 0)
01085       {
01086          if (Ask - stop < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
01087       }//if (stop > 0)
01088       if (!UseStopLoss) stop = 0;
01089       type = OP_BUY;
01090       price = Ask;
01091       SendTrade = true;
01092       stype = "Buy ";
01093       re_entryprice = NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits);
01094    }//if (Ask > Phigh)
01095    
01096    //Cater for no tradedirection determination choice   
01097    //if (!UseD1Close && !UseW1Close) tradedirection = down;//Removed following logic from sq
01098    
01099    //Short
01100    if (Bid < Plow && tradedirection == down && TradeShort && Copen < Popen)
01101    //if (Bid < Plow && iClose(NULL, PERIOD_M1, 1) < Plow && tradedirection == down && TradeShort && Copen < Popen)
01102    //if (Open[0] < Low[1])
01103    {
01104       if (UseCandleLength) take = NormalizeDouble(Bid - extent, Digits);      
01105       if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
01106       if (UseSquareForTakeProfit) take = SquareLow;
01107       if (take > 0)
01108       {
01109          if (Bid - take < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
01110       }//if (take > 0)
01111       
01112       stop = Phigh;
01113       if (StopLoss > 0) stop = NormalizeDouble(Bid + (StopLoss * Point), Digits);
01114       if (UseSquareForStopLoss) stop = SquareHigh;
01115       if (stop > 0)
01116       {
01117          if (stop - Bid < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
01118       }//if (stop > 0)
01119       if (!UseStopLoss) stop = 0;
01120       
01121       type = OP_SELL;
01122       price = Bid;
01123       SendTrade = true;      
01124       stype = "Sell ";
01125       re_entryprice = NormalizeDouble(Bid + (ReEntryLinePips * Point), Digits);
01126    }//if (Bid < Plow)
01127    
01128 
01129    if (SendTrade)
01130    {
01131       while(IsTradeContextBusy() ) Sleep(100);
01132       if (!SendAlertNotTrade) bool result = SendSingleTrade(type, TradeComment, Lot, price, stop, take);
01133       if (SendAlertNotTrade)
01134       {
01135          Alert("Brijon Threes ", Symbol(), " ", stype, "trade has triggered. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
01136          SendMail("Trade alert", Symbol() + " " + stype + " trade has triggered. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
01137          AlertSent=true;
01138       }//if (SendAlertNotTrade)
01139       
01140    }//if (SendTrade)
01141    
01142    //Actions when trade send succeeds
01143    if (SendTrade && result)
01144    {
01145       if (!SendAlertNotTrade) AddReEntryLine(re_entryprice);
01146    }//if (result)
01147    
01148    //Actions when trade send fails
01149    if (SendTrade && !result)
01150    {
01151       //M1Bars = 0;
01152    }//if (!result)
01153    
01154    
01155 
01156 }//void LookForTradingOpportunities()
01157 
01158 bool CloseTrade(int ticket)
01159 {   
01160    while(IsTradeContextBusy()) Sleep(100);
01161    bool result = OrderClose(ticket, OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
01162 
01163    //Actions when trade send succeeds
01164    if (result)
01165    {
01166       return(true);
01167    }//if (result)
01168    
01169    //Actions when trade send fails
01170    if (!result)
01171    {
01172       return(false);
01173    }//if (!result)
01174    
01175 
01176 }//End bool CloseTrade(ticket)
01177 
01178 ////////////////////////////////////////////////////////////////////////////////////////////////
01179 //Indicator module
01180 
01181 /*
01182 void GetVolume(int VolumeTimeFrame)
01183 {
01184 
01185    UpTicks=(iVolume(NULL, VolumeTimeFrame, 0) + (iClose(NULL, VolumeTimeFrame, 0)- iOpen(NULL, VolumeTimeFrame, 0))/Point)/2;
01186    DownTicks=iVolume(NULL, VolumeTimeFrame, 0) -UpTicks;
01187 
01188 }//void GetVolume(int VolumeTimeFrame)
01189 */
01190 
01191 //-------------------------------
01192 // UpdateBuffer(): 
01193 // update a "buffer" array with a new value;
01194 // shift the buffer one position at every new "bar" opening;
01195 // buffer[] therefore works like Indicators "Buffers" (or "Series"):
01196 // buffer[0] gives the buffer value for the CURRENT "bar";
01197 // buffer[3] gives the buffer value from 3 "bars" ago;
01198 void UpdateBuffer(double &buffer[], double &new_current_value, int buffer_timeframe, datetime &last_buffer_update)
01199 {
01200   buffer[0] = new_current_value;
01201   int bars_passed = MathMin((iTime(NULL,buffer_timeframe,0) - last_buffer_update)/60, ArraySize(buffer));
01202   if (bars_passed>0) // update Buffer at each new "bar"
01203   { // shift the Buffer from one position, and "push" 0 in current [0] position
01204     // shift the buffer "bars_passed" times;
01205     // missed "bars" will have 0 value
01206     for (int k=0; k<bars_passed; k++) {
01207       for (int i=ArraySize(buffer); i>0; i--) { buffer[i] = buffer[i-1]; /*string s=s+" "+DoubleToStr(buffer[i],0);*/ }
01208       buffer[0] = 0;
01209     }
01210     //Print(s);
01211     // update last_buffer_update time
01212     last_buffer_update = iTime(NULL,buffer_timeframe,0);
01213     new_current_value = 0; // start fresh on new current bar
01214   }
01215 }
01216 
01217 //-------------------------------
01218 
01219 #define TICKS_BUFFER_MAX_BARS  60 // max number of "bars" in the Ticks "Buffers"
01220 // M1 "buffers" of UpTicks and DownTicks
01221 double   UpTicksM1Buffer[TICKS_BUFFER_MAX_BARS], DownTicksM1Buffer[TICKS_BUFFER_MAX_BARS];
01222 datetime UpTicksM1Buffer_lastupdate=0, DownTicksM1Buffer_lastupdate=0;
01223 
01224 //-------------------------------
01225 void GetVolume()
01226 {
01227    /*
01228    This breathtaking code comes courtesy of squalou. Breathtaking. Cheers sq; you are a star.
01229    */
01230    
01231    //Keeps a count of up and down quotes
01232    
01233    static double OldBid;
01234    if (OldBid == 0) OldBid = Bid;
01235   double upValue = UpTicksM1Buffer[0];
01236   double downValue=DownTicksM1Buffer[0];
01237   if (Bid > OldBid) upValue++;
01238   if (Bid < OldBid) downValue++;
01239   OldBid = Bid;
01240    
01241   // make sure the M1 Ticks "buffers" can hold VolumeTickCountPeriod M1 "bars"
01242   if (ArraySize(UpTicksM1Buffer) < VolumeTickCountPeriod) ArrayResize(UpTicksM1Buffer,VolumeTickCountPeriod);
01243   if (ArraySize(DownTicksM1Buffer)<VolumeTickCountPeriod) ArrayResize(DownTicksM1Buffer,VolumeTickCountPeriod);
01244    
01245   // update M1 Ticks "Buffers"
01246   UpdateBuffer(UpTicksM1Buffer,   upValue,   PERIOD_M1, UpTicksM1Buffer_lastupdate);
01247   UpdateBuffer(DownTicksM1Buffer, downValue, PERIOD_M1, DownTicksM1Buffer_lastupdate);
01248    
01249   // cumulate M1 tick counts over the last VolumeTickCountPeriod "bars" into the UpTicks and DownTicks "current" counters
01250   // UpTicks and DownTicks will always contain the past VolumeTickCountPeriod M1 "bars" Ticks with a granularity of M1
01251   UpTicks = 0;
01252   DownTicks = 0;
01253   for (int i=0; i<VolumeTickCountPeriod; i++) {
01254     UpTicks   += UpTicksM1Buffer[i];
01255     DownTicks += DownTicksM1Buffer[i];
01256   }
01257 
01258 }//void GetVolume()
01259 
01260 double CalculateVolatility(int period, int LookBack)
01261 {
01262    //Calculates the volatility of a pair based on an average of their movement over LookBack periods
01263    
01264    double pips;
01265    for (int cc = 1; cc <= LookBack; cc++)
01266    {
01267       pips+= iHigh(NULL, period, cc) - iLow(NULL, period, cc);      
01268    }//for (int cc = 1; cc < LookBack; cc++)
01269    
01270    pips/= LookBack;//Average pips movement per day
01271    //Alert(pips);
01272 
01273    //Convert to pips
01274    int multiplier;
01275    if (Digits == 2) multiplier = 10;
01276    if (Digits == 3) multiplier = 100;
01277    if (Digits == 4) multiplier = 1000;
01278    if (Digits == 5) multiplier = 10000;
01279    
01280    pips*= multiplier;
01281    int rpips = pips;//Convert to a simple integer - all we need
01282    
01283    return(rpips);
01284    
01285 }//End double CalculateVolatility(int period, int LookBack)
01286 
01287 
01288 void ReadIndicatorValues()
01289 {
01290 
01291    //GetBB(0);
01292    
01293    /*
01294    //Rsi D1 tradedirection
01295    RsiVal = GetRsi(RsiTf, RsiPeriod, RsiAppliedPrice, 0);
01296    tradedirection = ranging;
01297    if (RsiVal > 55) tradedirection = up;
01298    if (RsiVal < 45) tradedirection = down;
01299    */
01300    
01301    //if (UseVolume) GetVolume(VolumeTimeFrame);
01302    GetTradeDirectionFromTrend(Period(), 0);
01303    
01304    
01305 }//void ReadIndicatorValues()
01306 
01307 
01308 //End Indicator module
01309 ////////////////////////////////////////////////////////////////////////////////////////////////
01310 
01311 void LookForTradeClosure()
01312 {
01313    //Close the trade if appropriate
01314    
01315    if (!OrderSelect(TicketNo, SELECT_BY_TICKET) ) return;
01316    
01317    
01318    
01319    bool CloseTrade;
01320    
01321    RefreshRates();
01322    if (OrderType() == OP_BUY)
01323    {
01324       if (Ask >= OrderOpenPrice() + (ClosureTargetPips * Point) ) CloseTrade = true;
01325    }//if (OrderType() == OP_BUY)
01326    
01327    
01328    if (OrderType() == OP_SELL)
01329    {
01330       if (Bid <= OrderOpenPrice() - (ClosureTargetPips * Point) ) CloseTrade = true;
01331    }//if (OrderType() == OP_SELL)
01332    
01333    if (CloseTrade)
01334    {
01335       bool result = CloseTrade(TicketNo);
01336       //Actions when trade send succeeds
01337       if (result)
01338       {
01339    
01340       }//if (result)
01341    
01342       //Actions when trade send fails
01343       if (!result)
01344       {
01345          //M1Bars = 0;
01346       }//if (!result)
01347    
01348 
01349    }//if (CloseTrade)
01350    
01351    
01352 }//void LookForTradeClosure()
01353 
01354 
01355 bool CheckTradingTimes()
01356 {
01357    int hour = TimeHour(TimeLocal() );
01358    
01359    if (end_hourm < start_hourm)
01360   {
01361     end_hourm += 24;
01362   }
01363   
01364 
01365   if (end_houre < start_houre)
01366   {
01367     end_houre += 24;
01368   }
01369   
01370   bool ok2Trade = true;
01371   
01372   ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);
01373 
01374   // adjust for past-end-of-day cases
01375   // eg in AUS, USDJPY trades 09-17 and 22-06
01376   // so, the above check failed, check if it is because of this condition
01377   if (!ok2Trade && hour < 12)
01378   {
01379     hour += 24;
01380     ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);    
01381     // so, if the trading hours are 11pm - 6am and the time is between  midnight to 11am, (say, 5am)
01382     // the above code will result in comparing 5+24 to see if it is between 23 (11pm) and 30(6+24), which it is...
01383   }
01384 
01385 
01386    // check for end of day by looking at *both* end-hours
01387 
01388    if (hour >= MathMax(end_hourm, end_houre))
01389    {      
01390       ok2Trade = false;
01391    }//if (hour >= MathMax(end_hourm, end_houre))
01392 
01393    return(ok2Trade);
01394 
01395 }//bool CheckTradingTimes()
01396 
01397 void DrawLine(string name, datetime time1, double val1, datetime time2, double val2, color col, int width, int style, int ray)
01398 {
01399    //Plots a trendline with the given parameters
01400    
01401    ObjectDelete(name);
01402    
01403    ObjectCreate(name, OBJ_TREND, 0, time1, val1, time2, val2);
01404    ObjectSet(name, OBJPROP_COLOR, col);
01405    ObjectSet(name, OBJPROP_WIDTH, width);
01406    ObjectSet(name, OBJPROP_STYLE, style);
01407    ObjectSet(name, OBJPROP_RAY, ray);
01408    
01409 
01410 }//
01411 
01412 void CalculateThreesLines()
01413 {
01414    //Draws the hi-lo of the previous candle, plus the open of current candle at an appropriate colour
01415 //double         Phigh, Plow, Popen, Copen;//Previous hi-lo-open and current open
01416 //#define  highline "High line"
01417 //#define  lowline "Low line"
01418 //#define  todayopenline "Open line"
01419    
01420    Phigh = High[1];
01421    Plow = Low[1];
01422    Popen = Open[1];
01423    Copen = Open[0];
01424    
01425    datetime time1, time2;
01426    time1 = Time[1];   
01427    time2 = time1 + ((Period() * 60) * 2);
01428    
01429    //Previous High
01430    DrawLine(highline, time1, Phigh, time2, Phigh, Blue, 2, STYLE_SOLID, false);
01431    
01432    //Previous Low
01433    DrawLine(lowline, time1, Plow, time2, Plow, Blue, 2, STYLE_SOLID, false);
01434    
01435 
01436    //Currenct candle Open
01437    color col = White;
01438    if (Copen > Popen) col = Gold;
01439    if (Copen < Popen) col = Red;
01440    DrawLine(todayopenline, time1, Copen, time2, Copen, col, 2, STYLE_SOLID, false);
01441       
01442 
01443    //Draw the previous D1 close line
01444    if (OldD1Bars != iBars(NULL, PERIOD_D1) )
01445    {
01446       Yclose = iClose(NULL, PERIOD_D1, 1);
01447       OldD1Bars = iBars(NULL, PERIOD_D1);
01448       DrawLine(yesterdaycloseline, time1, Yclose, time2, Yclose, Turquoise, 1, STYLE_DOT, true);
01449       Volatility = CalculateVolatility(PERIOD_D1, LookBackDays);
01450 
01451       CalculateReEntryLinePips();
01452 
01453    }//if (OldD1Bars != iBars(NULL, PERIOD_D1) )
01454    
01455 
01456 }//void CalculateThreesLines()
01457 
01458 void CalculateReEntryLinePips()
01459 {
01460 
01461    
01462    //Set up volatility level
01463    //ReEntryLinePips = 250;
01464    
01465    /*
01466    if (Volatility < LowVolatility) ReEntryLinePips = 50;
01467    if (Volatility >= LowVolatility && Volatility < MediumVolatility) ReEntryLinePips = 75;
01468    if (Volatility >= MediumVolatility && Volatility < HighVolatility) ReEntryLinePips = 100;
01469    if (Volatility >= HighVolatility && Volatility < PsychoticallyDeranged) ReEntryLinePips = 125;
01470    */
01471    
01472    //Adapt to x digit criminals
01473    double multiplier;
01474    if(Digits == 2 || Digits == 4) multiplier = 1;
01475    if(Digits == 3 || Digits == 5) multiplier = 10;
01476    if(Digits == 6) multiplier = 100;   
01477    if(Digits == 7) multiplier = 1000;   
01478    
01479    ReEntryLinePips = Volatility;
01480    //Volatility*= multiplier;
01481    ReEntryLinePips*= multiplier;
01482    
01483    
01484    
01485 }//End void CalculateReEntryLinePips()
01486 
01487 void ReplaceReEntryLine()
01488 {
01489 
01490    //Find the most recent trade in the sequence and replace the missing re-entry line
01491    
01492    for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
01493    {      
01494       if (OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) )
01495       {
01496          if (OrderSymbol() == Symbol())
01497          {            
01498             if (OrderType() == OP_BUY) AddReEntryLine(NormalizeDouble(OrderOpenPrice() - (ReEntryLinePips * Point), Digits) );
01499             if (OrderType() == OP_SELL) AddReEntryLine(NormalizeDouble(OrderOpenPrice() + (ReEntryLinePips * Point), Digits) );
01500             return;
01501          }//if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)      
01502          
01503       }//if (OrderSelect(cc, SELECT_BY_POS) )
01504       
01505    }//for (cc = OpenTrades; cc >= 0; cc--)
01506             
01507 
01508 
01509 }//void ReplaceReEntryLine()
01510 
01511 void GetTradeDirection()
01512 {
01513    tradedirection = none;
01514    //'Naked' threes
01515    if (!UseD1Close && !UseW1Close)
01516    {
01517       if (Bid > Yclose) tradedirection = up;
01518       if (Bid < Yclose) tradedirection = down;
01519    }//if (!UseD1Close && !UseW1Close)
01520    
01521    
01522    //D1 close prices only
01523    if (UseD1Close)
01524    {
01525       if (iClose(NULL, PERIOD_D1, 1) > iClose(NULL, PERIOD_D1, 2)) tradedirection = up;
01526       if (iClose(NULL, PERIOD_D1, 1) < iClose(NULL, PERIOD_D1, 2)) tradedirection = down;
01527    }//if (UseD1Close)
01528    
01529    //W1 close prices only
01530    if (UseW1Close && !UseD1Close) 
01531    {
01532       if (iClose(NULL, PERIOD_W1, 1) > iClose(NULL, PERIOD_W1, 2)) tradedirection = up;      
01533       if (iClose(NULL, PERIOD_W1, 1) < iClose(NULL, PERIOD_W1, 2)) tradedirection = down;
01534       
01535    }//if (UseW1Close && !UseD1Close) 
01536    
01537    
01538    //W1 and D1 close prices
01539    if (UseW1Close && UseD1Close) 
01540    {
01541       if (tradedirection == up)
01542       {
01543          if (iClose(NULL, PERIOD_W1, 1) > iClose(NULL, PERIOD_W1, 2) 
01544          && iClose(NULL, PERIOD_D1, 1) > iClose(NULL, PERIOD_D1, 2)) tradedirection = up;
01545       }//if (tradedirection == up)
01546    
01547       if (tradedirection == down)
01548       {
01549          if (iClose(NULL, PERIOD_W1, 1) < iClose(NULL, PERIOD_W1, 2) 
01550          && iClose(NULL, PERIOD_D1, 1) < iClose(NULL, PERIOD_D1, 2)) tradedirection = down;
01551       }//if (tradedirection == down)
01552    
01553    }//if (UseW1Close && UseD1Close) 
01554    
01555    //Square
01556    if (UseSquareFilter)
01557    {
01558       //Use Bid as this is the visible line
01559       if (Bid > SquareHigh && tradedirection == down) tradedirection = none;
01560       if (Bid < SquareLow && tradedirection == up) tradedirection = none;
01561       
01562    }//if (UseSquarteFilter)
01563    
01564 
01565    //Volumes
01566    if (UseVolume)
01567    { // ensure we have enough UpTicks or DownTicks in our favor (MinTicksDifference minimum)
01568       if (tradedirection == down && DownTicks - UpTicks < MinTicksDifference) tradedirection =  none;
01569       if (tradedirection == up && UpTicks - DownTicks < MinTicksDifference) tradedirection =  none;
01570    }//if (UseVolume)
01571    
01572    //LSMA
01573    if (UseLSMA)
01574    {
01575       if (tradedirection == down && (LsmaFastTradeDirection != down || LsmaSlowTradeDirection != down) ) tradedirection = none;
01576       if (tradedirection == up && (LsmaFastTradeDirection != up || LsmaSlowTradeDirection != up) ) tradedirection = none;
01577    }//if (UseLSMA)
01578    
01579    //Distance from next support/resistance
01580    if (AllowablePipsFrom_S_R > 0)
01581    {
01582       if (tradedirection == up)
01583       {
01584          if (NextResistance - Ask < (AllowablePipsFrom_S_R * Point) ) tradedirection = none;
01585       }//if {tradedirection == up}
01586       
01587       if (tradedirection == down)
01588       {
01589          if (Bid - NextSupport < (AllowablePipsFrom_S_R * Point) ) tradedirection = none;
01590       }//if (tradedirection == down)
01591       
01592       
01593    }//if (AllowablePipsFrom_S_R > 0)
01594    
01595    
01596 }//End void GetTradeDirection()
01597 
01598 void CalculateBosunLines()
01599 {
01600    //The calculations code for this comes from Bosun_Kines.mq4, coded by IgorAD and modified by Kris.
01601    //My thanks to both of these individuals.
01602    
01603    double close = iClose(NULL,BlTimeFrame,1);
01604   
01605    Bl[12] = close * 1.5000;
01606    Bl[11] = close * 1.2500;
01607    Bl[10] = close * 1.1250;
01608    Bl[9] = close * 1.0625;
01609    Bl[8] = close * 1.0312;
01610    Bl[7] = close * 1.0156;
01611    Bl[6] = close;
01612    Bl[5] = close * 0.9844;
01613    Bl[4] = close * 0.9688;
01614    Bl[3] = close * 0.9375;
01615    Bl[2] = close * 0.8750;
01616    Bl[1] = close * 0.7500;
01617    Bl[0] = close * 0.5000;
01618 
01619    //Draw the lines
01620    datetime time1, time2;
01621    time1 = Time[1] - (60*60 * 3);   
01622    time2 = time1 + ((Period() * 60) * 3);
01623    
01624    for (int cc = 0; cc <= 12; cc++)
01625    {
01626       string name = "Bosun line ";
01627       DrawLine(BlDescription[cc], time1, Bl[cc], time2, Bl[cc], Chartreuse, 2, STYLE_SOLID, false);
01628    }//for (int cc = 0; cc <= 12; cc++)
01629    
01630 
01631 }//End void CalculateBosunLines()
01632 
01633 void GetBosunPosition()
01634 {
01635 //double         NextResistance, NextSupport;
01636 
01637    RefreshRates();
01638    //Extremes - highly unlikely
01639    if (Bid < Bl[0])
01640    {
01641       NextResistance = Bl[0];
01642       NextSupport = 0;
01643       return;
01644    }//if (Bid < Bl[0])
01645    
01646    if (Bid > Bl[12])
01647    {
01648       NextResistance = 100000;
01649       NextSupport = Bl[12];
01650       return;
01651    }//if (Bid > Bl[12])
01652    
01653    for (int cc = 1; cc <= 11; cc++)
01654    {
01655       if (Bid >= Bl[cc] && Bid <= Bl[cc + 1] )
01656       {
01657          NextResistance = Bl[cc + 1];
01658          NextSupport = Bl[cc];
01659          return;
01660       }//if (Bid >= Bl[cc] && Bid <= Bl[cc + 1] )
01661       
01662    }//for (int cc = 1; cc <= 11; cc++)
01663    
01664 
01665 }//End void GetBosunPosition()
01666 
01667 void GetSquare()
01668 {
01669    /*
01670    The square is a yellow box that defines the highest and lowest of the previous 3 candles,
01671    with a user choice of time frame
01672    */
01673    int tf = SquareTimeFrame;
01674    int nBars = 3;
01675    int shift = 1;
01676    if (tf > PERIOD_H1) { // adjust to H1 bars to avoid the "broker-GMT-offset syndrom" on H4 bars or higher
01677      nBars *= tf/PERIOD_H1;
01678      shift *= tf/PERIOD_H1;
01679      tf = PERIOD_H1;
01680    }
01681    
01682    int highest = iHighest(NULL, tf, MODE_HIGH, nBars, shift);
01683    SquareHigh = iHigh(NULL, tf, highest);
01684    int lowest = iLowest(NULL, tf, MODE_LOW, nBars, shift);
01685    SquareLow = iLow(NULL, tf, lowest);
01686    
01687    //Draw the lines
01688    datetime time1, time2;
01689    time1 = iTime(NULL, tf, nBars+shift-1);
01690    time2 = Time[0];
01691    DrawLine(squarehighline, time1, SquareHigh, time2, SquareHigh, Yellow, 3, STYLE_SOLID, false);
01692    DrawLine(squarelowline, time1, SquareLow, time2, SquareLow, Yellow, 4, STYLE_SOLID, false);
01693 
01694 }//End void GetSquare()
01695 
01696 void SquareTouchTest()
01697 {
01698    //Sends al alert at a touch of the square
01699    
01700    if (Ask >= SquareHigh)
01701    {
01702       Alert("Brijon Threes ", Symbol(), " touch of the square High. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
01703       SendMail("Square touch alert",  Symbol() + " touch of the square High. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
01704       SquareAlertSent = true;
01705    }//if (Ask >= SquareHigh)
01706    
01707    if (Bid <= SquareLow)
01708    {
01709       Alert("Brijon Threes ", Symbol(), " touch of the square Low. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
01710       SendMail("Square touch alert",  Symbol() + " touch of the square Low. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
01711       SquareAlertSent = true;
01712    }//if (Ask >= SquareHigh)
01713    
01714 
01715 }//void SquareTouchTest()
01716 
01717 int GetMultiplier()
01718 {
01719    //Returns a multiplying factor to turn the result of price calculations into full pips
01720    int multiplier;
01721    if (Digits == 2) multiplier = 100;
01722    if (Digits == 3) multiplier = 1000;
01723    if (Digits == 4) multiplier = 10000;
01724    if (Digits == 5) multiplier = 100000;
01725    if (Digits == 6) multiplier = 1000000;//Not tested this one
01726    
01727    return(multiplier);
01728    
01729 
01730 }//End int GetMultiplier()
01731 
01732 //=============================================================================
01733 //                           O_R_CheckForHistory()
01734 //
01735 //  This function is to work around a very annoying and dangerous bug in MT4:
01736 //      immediately after you send a trade, the trade may NOT show up in the
01737 //      order history, even though it exists according to ticket number.
01738 //      As a result, EA's which count history to check for trade entries
01739 //      may give many multiple entries, possibly blowing your account!
01740 //
01741 //  This function will take a ticket number and loop until
01742 //  it is seen in the history.
01743 //
01744 //  RETURN VALUE:
01745 //     TRUE if successful, FALSE otherwise
01746 //
01747 //
01748 //  FEATURES:
01749 //     * Re-trying under some error conditions, sleeping a random
01750 //       time defined by an exponential probability distribution.
01751 //
01752 //     * Displays various error messages on the log for debugging.
01753 //
01754 //  ORIGINAL AUTHOR AND DATE:
01755 //     Matt Kennel, 2010
01756 //
01757 //=============================================================================
01758 bool O_R_CheckForHistory(int ticket)
01759 {
01760    //My thanks to Matt for this code. He also has the undying gratitude of all users of my trading robots
01761    
01762    int lastTicket = OrderTicket();
01763 
01764    int cnt = 0;
01765    int err = GetLastError(); // so we clear the global variable.
01766    err = 0;
01767    bool exit_loop = false;
01768    bool success=false;
01769 
01770    while (!exit_loop) {
01771       /* loop through open trades */
01772       int total=OrdersTotal();
01773       for(int c = 0; c < total; c++) {
01774          if(OrderSelect(c,SELECT_BY_POS,MODE_TRADES) == true) {
01775             if (OrderTicket() == ticket) {
01776                success = true;
01777                exit_loop = true;
01778             }
01779          }
01780       }
01781       if (cnt > 3) {
01782          /* look through history too, as order may have opened and closed immediately */
01783          total=OrdersHistoryTotal();
01784          for(c = 0; c < total; c++) {
01785             if(OrderSelect(c,SELECT_BY_POS,MODE_HISTORY) == true) {
01786                if (OrderTicket() == ticket) {
01787                   success = true;
01788                   exit_loop = true;
01789                }
01790             }
01791          }
01792       }
01793 
01794       cnt = cnt+1;
01795       if (cnt > O_R_Setting_max_retries) {
01796          //exit_loop = true;
01797          Alert(Symbol(), " Brijon ea might need restarting. It thinks there should be a trade in the playform's history that is not showing up.");
01798          cnt = 0;
01799       }
01800       if (!(success || exit_loop)) {
01801          Print("Did not find #"+ticket+" in history, sleeping, then doing retry #"+cnt);
01802          O_R_Sleep(O_R_Setting_sleep_time, O_R_Setting_sleep_max);
01803       }
01804    }
01805    // Select back the prior ticket num in case caller was using it.
01806    if (lastTicket >= 0) {
01807       OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
01808    }
01809    if (!success) {
01810       Print("Never found #"+ticket+" in history! crap!");
01811    }
01812    return(success);
01813 }//End bool O_R_CheckForHistory(int ticket)
01814 
01815 //=============================================================================
01816 //                              O_R_Sleep()
01817 //
01818 //  This sleeps a random amount of time defined by an exponential
01819 //  probability distribution. The mean time, in Seconds is given
01820 //  in 'mean_time'.
01821 //  This returns immediately if we are backtesting
01822 //  and does not sleep.
01823 //
01824 //=============================================================================
01825 void O_R_Sleep(double mean_time, double max_time)
01826 {
01827    if (IsTesting()) {
01828       return;   // return immediately if backtesting.
01829    }
01830 
01831    double p = (MathRand()+1) / 32768.0;
01832    double t = -MathLog(p)*mean_time;
01833    t = MathMin(t,max_time);
01834    int ms = t*1000;
01835    if (ms < 10) {
01836       ms=10;
01837    }
01838    Sleep(ms);
01839 }//End void O_R_Sleep(double mean_time, double max_time)
01840 
01841 double iLsma(int LSMA_Period,int shift)
01842 {
01843    //Code to calculate LSMA value. Copied from MrPip's work. Many thanks, MrPip
01844    
01845    double wt;
01846    
01847    double ma1=iMA(NULL,0,LSMA_Period,0,MODE_SMA ,PRICE_CLOSE,shift);
01848    double ma2=iMA(NULL,0,LSMA_Period,0,MODE_LWMA,PRICE_CLOSE,shift);
01849    wt = MathFloor((3.0*ma2-2.0*ma1)/Point) * Point;
01850    return(wt);
01851 }//double iLsma(int LSMAPeriod,int shift)  
01852 
01853 string GetTradeDirectionFromTrend(int tf, int shift)
01854 {
01855    //squalou coded this. Cheers, sq.
01856 
01857    LsmaFastTradeDirection = none;
01858    LsmaSlowTradeDirection = none;
01859    
01860    double lsma_cur, lsma_prev;
01861 
01862    
01863    //Fast lsma
01864    LsmaFastVal = iLsma(LSMA_Period_Fast, shift);
01865    PrevLsmaFastVal = iLsma(LSMA_Period_Fast, shift + 1);
01866    if (LsmaFastVal > PrevLsmaFastVal) LsmaFastTradeDirection = up;
01867    if (LsmaFastVal < PrevLsmaFastVal) LsmaFastTradeDirection = down;
01868    
01869    //Slow lsma
01870    LsmaSlowVal = iLsma(LSMA_Period_Slow, shift);
01871    PrevLsmaSlowVal = iLsma(LSMA_Period_Slow, shift + 1);
01872    if (LsmaSlowVal > PrevLsmaSlowVal) LsmaSlowTradeDirection = up;
01873    if (LsmaSlowVal < PrevLsmaSlowVal) LsmaSlowTradeDirection = down;
01874    
01875    
01876 }//End string GetTradeDirectionFromTrend()
01877 
01878 void AddReEntryLine(double price)
01879 {
01880       if (ObjectFind(reentrylinename) > -1) ObjectDelete(reentrylinename);   
01881       
01882       
01883       if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
01884       {
01885          int err=GetLastError();      
01886          Alert("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
01887          Print("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
01888          return(0);
01889 
01890       }//if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
01891       
01892       ObjectSet(reentrylinename,OBJPROP_COLOR,ReEntryLineColour);
01893       ObjectSet(reentrylinename,OBJPROP_STYLE,STYLE_SOLID);
01894       ObjectSet(reentrylinename,OBJPROP_WIDTH,2);     
01895 
01896 
01897 }//void AddReEntryLine(int type, double price)
01898 
01899 
01900 //+------------------------------------------------------------------+
01901 //| expert start function                                            |
01902 //+------------------------------------------------------------------+
01903 int start()
01904 {
01905 //----
01906 
01907    /*
01908    if (!IsDemo() && !SendAlertNotTrade)
01909    {
01910       Alert("Live trading with this EA is not allowed yet.");
01911       return;
01912    }//if (!IsDemo() )
01913    */
01914    
01915    GetVolume();
01916    
01917    static bool ThereWasATradeOpen;
01918    static bool Sleeping = true;
01919    
01920 
01921    //Define tradedirection
01922    ReadIndicatorValues();
01923    GetTradeDirection();
01924    //Get position of market in relation to Bosun lines
01925    GetBosunPosition();
01926    //Square
01927    static int LastSquareUpdate;
01928    if (LastSquareUpdate != iTime(NULL,Period(),0))
01929    {      
01930       GetSquare();
01931       LastSquareUpdate = iTime(NULL,Period(),0);
01932       SquareAlertSent=false;
01933       //Adjust trailing stop pips if necessary. Chaotic place to do this, but the code has to go somewhere
01934       if (UsePercentageOfSquare)
01935       {
01936          //Calculate percentage of square in pips
01937          int multiplier = GetMultiplier();
01938          double extent = (SquareHigh - SquareLow) * multiplier;
01939          TrailingStopPips = extent * (SquarePercentToUse / 100);
01940       }//if (UsePercentageOfSquare)
01941       
01942    }//if (LastSquareUpdate != iTime(NULL,Period(),0))
01943    
01944    //Send an alert at the touch of the square
01945    if (SendSquareTouchAlert && !SquareAlertSent) SquareTouchTest();
01946    
01947    if (Sleeping)
01948    {
01949       Comment("              Sleeping");
01950       if (OldBars != Bars)
01951       {
01952          Sleeping = false;
01953       }//if OldBars != Bars)
01954       else return;
01955    }//if (Sleeping)
01956    
01957    //ReadIndicatorValues();
01958    
01959    ///////////////////////////////////////////////////////////////////////////////////////////////
01960    //New candle
01961    if (OldBars != Bars)
01962    {
01963       CalculateThreesLines();//Draw hi-lo-open lines. Also D1 close bar
01964       CalculateBosunLines();
01965       AlertSent=false;//For manual traders
01966       OldBars = Bars;
01967    }//if (OldBars != Bars)
01968    
01969    
01970    ///////////////////////////////////////////////////////////////////////////////////////////////
01971 
01972 
01973    if (OrdersTotal() == 0)
01974    {
01975       TicketNo = -1;
01976    }//if (OrdersTotal() == 0)
01977 
01978    //ReadIndicatorValues();
01979 
01980    
01981       
01982    ///////////////////////////////////////////////////////////////////////////////////////////////
01983    //Find open trades
01984    TradeExists = DoesTradeExist();
01985    if (TradeExists )
01986    {
01987       ThereWasATradeOpen = true;         
01988       if (OrderProfit() > 0) TradeManagementModule();
01989       if (OrderProfit() > 0 && ClosureTargetPips > 0) LookForTradeClosure();
01990       //Replace deleted reentry line
01991       if (ObjectFind(reentrylinename) == -1 && TicketNo > -1)
01992       {
01993          ReplaceReEntryLine();
01994       }//if (ObjectFind(reentrylinename) == -1 && OpenTrades > 0)
01995 
01996    }//if (TradeExists)
01997 
01998    if (ObjectFind(reentrylinename) > -1 && !TradeExists) ObjectDelete(reentrylinename);
01999    
02000    //Post trade closure Sleep
02001    if (!TradeExists && ThereWasATradeOpen && !SendAlertNotTrade)
02002    {
02003       ThereWasATradeOpen = false;
02004       Comment("              A trade has closed. I am sleeping until the next candle opens.");
02005       Sleeping = true;
02006       OldBars = Bars;
02007       return;
02008    }//if (!TradeExists && ThereWasATradeOpen)
02009    
02010    ///////////////////////////////////////////////////////////////////////////////////////////////
02011    
02012    
02013  
02014     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
02015    //Trading times
02016    bool TradeTimeOk = CheckTradingTimes();
02017    if (!TradeTimeOk)
02018    {
02019       Comment("Outside trading hours\nstart_hourm-end_hourm: ", start_hourm, "-",end_hourm, "\nstart_houre-end_houre: ", start_houre, "-",end_houre);
02020       return;
02021    }//if (hour < start_hourm)
02022    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
02023 
02024    ///////////////////////////////////////////////////////////////////////////////////////////////         
02025    //Trading
02026    if (SendAlertNotTrade && AlertSent == true)
02027    {
02028       DisplayUserFeedback();
02029       return;
02030    }//if (SendAlertNotTrade && AlertSent == true)
02031    
02032    if (UseVolume && UpTicks + DownTicks < TicksCountBeforeTrading)
02033    {
02034       DisplayUserFeedback();
02035       return;
02036    }//if (UseVolume && UpTicks + DownTicks < TicksCountBeforeTrading)
02037    
02038    
02039    if (TicketNo == -1)
02040    {
02041       LookForTradingOpportunities();
02042    }//if (TicketNo == -1)
02043    ///////////////////////////////////////////////////////////////////////////////////////////////      
02044 
02045    DisplayUserFeedback();
02046    
02047 //----
02048    return(0);
02049 }
02050 //+------------------------------------------------------------------+
Make Controller Kit
 
ASP