Formation Logo
Brijon Concept of Threes
MQ4 API
 

Brijon_Concept_of_Threes_auto_trading_robot_by_Steve_Hopwood.mq4

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