比特币通信协议 - 币圈消息

比特币通信协议篇11、二、TURN简介。在典型的情况下,TURN客户端连接到内网中,并且通过一个或者多个NAT到 详细

求助!老师看看这个EA怎么回事?谢谢

  [复制链接]
407 13
tianyaruolin 发表于 2018-1-11 00:52:56 | 只看该作者 |阅读模式 打印 上一主题 下一主题

源码如下:
//+-------------------------------------------------------------------+
//|                                                        Bbands_EA  |
//|                           Copyright ?2011, Steve Hopwood - LHDT  |
//+-------------------------------------------------------------------+
/*
V1.0046  - Fixed a bug when lauching the EA for the first time (EA took position directly, sometimes too late)
         - Removed the trigger on lower timeframe (V1.0045)
         - Changed default settings to reduce DD and stay in profits :
            - ECN to false
            - AllowMultipleTrendTrade to false
            - BreakEvenPips to 10pips
            - BreakEvenProfit to 3
            - JumpingStop to true
            - JumpingStopPips to 10pips
V1.0045  - Added trigger on lower TF when all conditions are met
V1.0044  - First version ! Hiaaa !
*/
#property copyright "Copyright ?2011, Steve Hopwood, LhDT"
#property link      "http://www.hopwood3.freeserve.co.uk"
#include
#include
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "None"
#define  both "Both"
#define  buy "Buy"
#define  sell "Sell"
#define  ranging "Ranging"
#define  confused "Confused, and so cannot trade"
#define  trending "Trending"
#define  opentrade "There is a trade open"
#define  stopped "Trading is stopped"
#define  red "Red"
#define  blue "Blue"
//Pending trade price line
#define  pendingpriceline &quot

ending price line"
//Hidden sl and tp lines. If UseStealth enabled, the bot will close trades on a touch/break of these lines.
//Each line is named with its appropriate prefix and the ticket number of the relevant trade
#define  TpPrefix "Tp"
#define  SlPrefix "Sl"
//Caterpillar
#define  buyline "Buy line"
#define  sellline "Sell line"
//Defined constants from hanover. Thanks David
#define AUD 0
#define CAD 1
#define CHF 2
#define EUR 3
#define GBP 4
#define JPY 5
#define NZD 6
#define USD 7
#define M1  0
#define M5  1
#define M15 2
#define M30 3
#define H1  4
#define H4  5
#define D1  6
#define W1  7
#define MN  8
extern string  Symp1 = "----Bbands Inputs----";
extern bool    ARS                        = true;
extern int     BarCheck                   = 1;
extern bool    TakeScreenShot             = true;
bool           Open_candleClose           = true;
bool           Close_candleClose          = true;
extern bool    AllowMultipleTrendTrade    = false;
extern string  exc = "----Bbands Values----";
extern int     Length               = 20;
extern int     Deviation            = 0;
extern double  MoneyRisk       = 1.0;
extern string  gen="----General inputs----";
extern double  Lot=0.01;
extern bool    StopTrading=false;
extern bool    TradeLong=true;
extern bool    TradeShort=true;
extern int     TakeProfit=0;
extern int     StopLoss=0;
extern int     MagicNumber=2872811;
extern string  TradeComment="Bbands EA";
extern bool    CriminalIsECN=false;
extern double  MaxSpread=120;
//Hidden tp/sl inputs.
extern string  hts="----Stealth stop loss and take profit inputs----";
extern int     HiddenPips=10;//Added to the 'hard' sl and tp and used for closure calculations
extern string  bf="----Trading balance filters----";
extern bool    UseZeljko=false;
extern bool    OnlyTradeCurrencyTwice=false;
extern string  bbi="----Bollinger Band inputs----";
extern int     BbPeriod=25;
extern int     BbDeviation=2;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         BbUpper, BbMiddle, BbLower, BbExtent;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  rsiin="----Rsi inputs----";
extern int     RsiTf=1440;
extern int     RsiPeriod=20;
extern string  rsap="Applied price: 0=Close; 1=Open; 2=High";
extern string  rsap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int     RsiAppliedPrice=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         RsiVal;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  mai="----Moving average----";
extern int     MaTF=0;//Time frame defaults to current chart
extern int     MaPeriod=50;
extern int     MaShift=0;//The MA Shift input
extern string  mame="Method: 0=sma; 1=ema; 2=smma;  3=lwma";
extern int     MaMethod=1;
extern string  maap="Applied price: 0=Close; 1=Open; 2=High";
extern string  maap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int     MaAppliedPrice=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         MaVal;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  vs="----Volatility inputs----";
extern int     LookBackDays=20;
extern int     LowVolatility=100;
extern int     MediumVolatility=150;
extern int     HighVolatility=200;
extern int     PsychoticallyDeranged=250;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         Volatility;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  cat="----Caterpillar trend trade entry and TS----";
extern bool    UseCaterpillar=false;
extern int     MaxTrades=5;
extern int     MinPipsBetweenCandles=5;//Min distance between trade open prices
extern int     CatTimeFrame=60;//Trading/updating tf can be independent of current chart
extern color   BuyLineColour=Green;
extern color   SellLineColour=Red;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int            OldCatBars;
int            OnePip=1;//For adding to sl, candle close etc
bool           CandleTraded;//Only one trade per candle
string         CsGvName;
int            OldH1Bars;//For orphan gv removal
bool           TradeOpen;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  tdm="----Trend detection module----";
extern bool    RisingTrend=false;
extern bool    FallingTrend=false;
extern bool    UseTrendDetection=true;
//RSI. >55 is trending up.  slow, trend is up & vice versa
extern string  tmas="Two MA - 'slowkey'";
extern bool    UseSlowkey=false;
extern int     FastMaTdTF=0;//Time frame defaults to current chart
extern int     FastMaTdPeriod=100;
extern int     FastMaTdShift=0;//The MA Shift input
extern string  tmame="Method: 0=sma; 1=ema; 2=smma;  3=lwma";
extern int     FastMaTdMethod=0;
extern string  tmaap="Applied price: 0=Close; 1=Open; 2=High";
extern string  tmaap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int     FastMaTdAppliedPrice=0;
extern int     SlowMaTdTF=0;//Time frame defaults to current chart
extern int     SlowMaTdPeriod=200;
extern int     SlowMaTdShift=0;
extern int     SlowMaTdMethod=0;
extern int     SlowMaTdAppliedPrice=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         FastTrendMaVal, SlowTrendMaVal;//2 MA trend
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Single, much longer term MA. Rising MA the trend is up and vice-versa
extern string  aal="----All averages inputs----";
extern bool    UseAA=false;
extern int     TimeFrame    =  1440;
extern int     Price        =  0;
extern int     MA_Period    = 50;
extern int     MA_Shift     =  0;
extern int     MA_Method    =  0;
extern int     CandleShift  =  0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         AaVal, AaUp, AaDown;//Buffers 0 (val) 1 (up) and 3 (down)
string         AaDirection;
bool           CloseOnOppositeSignal;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  hm="----Hanover module----";
extern bool    UseHanover=false;
extern string  ctf="Time frames";
//extern string  TimeFrames="M1,M5,M15,M30,H1,H4,D1,W1,MN";
extern string  TimeFrames="D1";
extern int     SlopeConfirmationCandles=0;
extern int     StrongThreshold=0;
extern int     WeakThreshold=0;
extern string  hof="Hanover output file";
extern string  OutputFile            = "Output---Recent Strength.CSV";
extern int     NumPoints=15;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Arrays etc
string         InputString;//All purpose string to pass to CleanUpInputString() to remove unwanted leading/trailing stuff
int            NoOfTimeFrames;//The number for timeframes inputted into the TimeFrames input
string         Tf[];//Holds the time frames inputted into the TimeFrames input
string         StrongWeak[];//Holds the pair that represents the strongest and weakest in each time frame
string         StrongestCcy[], WeakestCcy[];//Go on, take a guess
double         StrongVal[], PrevStrongVal[], WeakVal[], PrevWeakVal[];//Another guess?
string         ConstructedPair[];//Holds the pairs made out of the currencies
string         Ccy1, Ccy2;//First and second currency in the pair
//Variables copied from the Strength Alerts indi. int LoadRSvalues() came from this
int      dig, tmf, h, i, j, k;
string alrt[11];
double   RSvalue[8,9,99];   // [currency,timeframe,datapoint#]
                            // currency: 0=AUD, 1=CAD, 2=CHF, 3=EUR, 4=GBP, 5=JPY, 6=NZD, 7=USD
                            // timeframe: 0=M1, 1=M5, 2=M15, 3=M30, 4=H1, 5=H4, 6=D1, 7=W1, 8=MN
                        
string   ccy[8] = {"AUD","CAD","CHF","EUR","GBP","JPY","NZD","USD"};
string   tf[9]  = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
string   arr[11];
int      ReadBars;//Bot reads the output file when this != Bars   
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  amc="----Available Margin checks----";
extern string  sco="Scoobs";
extern bool    UseScoobsMarginCheck=false;
extern string  fk="ForexKiwi";
extern bool    UseForexKiwi=false;
extern int     FkMinimumMarginPercent=1500;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool           EnoughMargin;
string         MarginMessage;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  rec="----Recovery----";
extern bool    UseRecovery=false;
extern int     Start_Recovery_at_trades=2;  //DC
extern bool    Use1.1.3.3Recovery=false;
extern bool    Use1.1.2.4Recovery=false;
extern bool    Use1.2.6Recovery=true;//Pippo's idea
extern int     ReEntryLinePips=50;
extern color   ReEntryLineColour=Turquoise;
extern color   BreakEvenLineColour=Blue;
extern int     RecoveryBreakEvenProfitPips=20;
extern bool    UseRecoveryTradeProfitLockin=false;
extern string  rts="Recovery trailing stop";
extern bool    UseRecoveryTrailingStop=true;
extern int     RecoveryTrailingStopAt=10;
extern color   RecoveryStopLossLineColour=Red;
bool    UseHardRecoveryStop=false;//Doesn't work but is part of the code and I cannot be bothered to remove it
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define  breakevenlinename "Break even line"
#define  reentrylinename "Re entry line"
//From iExposure for Recovery BE calcs
#define        SYMBOLS_MAX 1024
#define        DEALS          0
#define        BUY_LOTS       1
#define        BUY_PRICE      2
#define        SELL_LOTS      3
#define        SELL_PRICE     4
#define        NET_LOTS       5
#define        PROFIT         6
int            OldRecoverTrailBars;
bool           RecoveryInProgress, TpMoved;
int            RecoveryLockProfitsAt=50;
int            RecoveryLockInPips=10;
string         ExtSymbols[SYMBOLS_MAX];
int            ExtSymbolsTotal=0;
double         ExtSymbolsSummaries[SYMBOLS_MAX][7];
int            ExtLines=-1;
string         ExtCols[8]={"Symbol",
                   "Deals",
                   "Buy lots",
                   "Buy price",
                   "Sell lots",
                   "Sell price",
                   "Net lots",
                   &quot

rofit"};
int            ExtShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int            ExtVertShift=14;
double         buy_price=0.0;
double         sell_price=0.0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  tt="----Trading hours----";
extern string  Trade_Hours= "Set Morning & Evening Hours";
extern string  Trade_Hoursi= "Use 24 hour, local time clock";
extern string  Trade_Hours_M= "Morning Hours 0-12";
extern  int    start_hourm = 0;
extern  int    end_hourm = 12;
extern string  Trade_Hours_E= "Evening Hours 12-24";
extern  int    start_houre = 12;
extern  int    end_houre = 24;
extern string  spt="----Specific time inputs----";
extern double  StartTime=12.15;
extern string  pts="----Swap filter----";
extern bool    CadPairsPositiveOnly=true;
extern bool    AudPairsPositiveOnly=true;
extern bool    NzdPairsPositiveOnly=true;
extern string  tmm="----Trade management module----";
//Breakeven has to be enabled for JS and TS to work.
extern string  BE="Break even settings";
extern bool    BreakEven=true;
extern int     BreakEvenPips=10;
extern int     BreakEvenProfit=3;
extern string  cts="----Candlestick trailing stop----";
extern bool    UseCandlestickTrailingStop=false;
extern int     CstTimeFrame=0;//Defaults to current chart
extern int     CstTrailCandles=1;//Defaults to previous candle
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int            OldCstBars;//For candlestick ts
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern string  JSL="Jumping stop loss settings";
extern bool    JumpingStop=true;
extern int     JumpingStopPips=10;
extern string  TSL="Trailing stop loss settings";
extern bool    TrailingStop=false;
extern int     TrailingStopPips=20;
extern string  mis="----Odds and ends----";
extern bool    ShowManagementAlerts=true;
extern int     DisplayGapSize=30;
// Bbands vars
double         MA,SefcCheck,fisher_blue, fisher_red, Ci_red, Ci_blue, SMA8_previous, SMA8_current, SMA13_previous, SMA13_current,BBValue,BBValueRed,BBValueBlue,BBValue_prev, trendLineValue,CurrentPrice,macd ;
int            AccEquity, Ci_last, last_cross, hTF, lTF;
string         Sentiment,Sentiment5m, TrendLine,TrendLine5m, Emotion,Emotion5m, ShaffDirection, fisher_check, hma, Ci, SMA_Cross, lastTradeType, sar, BBands, BBands_lower;
string         TriggerTrend, TrendDetectionMethod; // used to trigger a trade
bool           PriceHit;
//Matt's O-R stuff
int           O_R_Setting_max_retries  = 10;
double        O_R_Setting_sleep_time   = 4.0; /* seconds */
double        O_R_Setting_sleep_max   = 15.0; /* seconds */
//Trading variables
int            TicketNo, OpenTrades;
bool           CanTradeThisPair;//Will be false when this pair fails the currency can only trade twice filter, or the balanced trade filter
bool           BuyOpen, SellOpen;
int            RetryCount = 10;//Will make this number of attempts to get around the trade context busy error.
//Pending price inputs. Keeps things hidden from the crims
bool           PendingBuy, PendingSell;
double         PendingPrice, PendingStop, PendingTake;
datetime       PendingTime;
double         PendingCandleRange;
double         PendingRecreationCancelPips = 2;
//Hidden stops variables
double         HiddenStopLoss, HiddenTakeProfit;
//Date/Time
datetime       ConvertedStartTime;
//Trend detection
string         trend;
//Misc
string         Gap, ScreenMessage;
int            OldBars;
string         PipDescription=" pips";
bool           ForceTradeClosure;
void DisplayUserFeedback()
{
   
   if (IsTesting() && !IsVisualMode()) return;
   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), NL );
   /*
   //Code for time to bar-end display from Candle Time by Nick Bilak
   double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);
   */
      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   if (TradeLong) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking long trades", NL);
   if (TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking short trades", NL);
   if (!TradeLong && !TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Both TradeLong and TradeShort are set to false", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, " (Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), ")", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, PipDescription,  NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss: ", StopLoss, PipDescription,  NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = false", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MaxSpread = ", MaxSpread/10, ": Spread = ", MarketInfo(Symbol(), MODE_SPREAD)/10, NL, NL );
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
   if (start_hourm == 0 && end_hourm == 12 && start_houre && end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
   else
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_hourm: ", DoubleToStr(start_hourm, 2),
                      ": end_hourm: ", DoubleToStr(end_hourm, 2), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_houre: ", DoubleToStr(start_houre, 2),
                      ": end_houre: ", DoubleToStr(end_houre, 2), NL);
                     
   }//else
   
   if (StartTime > 0)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Start time: ", TimeToStr(ConvertedStartTime, TIME_MINUTES), NL);
   }//if (StartTime > 0)
   
   //Trend
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   if (UseTrendDetection)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trend is ", trend, NL);
      //Rsi
      if (UseRsiTrendDetection)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trend Rsi ", TrendRsiVal, NL);
      }//if (UseRsiTrendDetection)
      
      //slowkey 2 moving average
      if (UseSlowkey)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Fast MA ", FastTrendMaVal, ":  Slow MA ", SlowTrendMaVal,  NL);
      }//if (UseSlowkey)
      
      //Single moving average
      if (UseAA)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "AA (TF:"+TimeFrame+") value ", AaVal, ": AA direction: ", AaDirection, NL);
      }//if (UseAA)
      
      //NB V10
      if (UseNanningBobForTrend)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Fast MA ", FastNbTrendMaVal, ":  Slow MA ", SlowNbTrendMaVal,  NL);      
      }//if (UseNanningBobForTrend)
   
      if (UseNanningBobForTrigger)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "NB trade trigger direction: ", TradeTriggerDirection, NL);
      }//if (UseNanningBobForTrigger)
      
      
      
   }//if (UseTrendDetection)
   
      //ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   
   if (UseHanover)
   {
      string now, then;         
      for (int cc = 0; cc  0)
         {
            double prevstrength1 = ReadStrength(Ccy1, Tf[cc], SlopeConfirmationCandles);
            now = StringConcatenate(": Shift ",SlopeConfirmationCandles, " = ", DoubleToStr(prevstrength1, 2));
            double prevstrength2 = ReadStrength(Ccy2, Tf[cc], SlopeConfirmationCandles);
            then = StringConcatenate(": Shift ", SlopeConfirmationCandles, " = ", DoubleToStr(prevstrength2, 2));
         }//if (SlopeCandles[cc] > 0)
      
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TF ", Tf[cc],
                                           ": ", Ccy1, ": Now = ", DoubleToStr(strength1, 2),
                                           now,
                                           ": ", Ccy2, ": Now = ", DoubleToStr(strength2, 2),
                                           then,
                                           NL);
      }//for (int cc = 0; cc  0 && WeakThreshold > 0)
      {
         bool tradeable = false;
         if (strength1 > StrongThreshold && strength2  StrongThreshold && strength2  StrongThreshold && strength1  StrongThreshold && strength2  0 && WeakThreshold > 0)
      
   }//if (UseHanover)
   /*
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Rsi: ", RsiVal, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Moving average: ", MaVal, NL);
   */
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   
   if (BreakEven)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Breakeven is set to ", BreakEvenPips, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   }//if (BreakEven)
   if (UseCandlestickTrailingStop)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using candlestick trailing stop", NL);      
   }//if (UseCandlestickTrailingStop)
   
   if (JumpingStop)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Jumping stop is set to ", JumpingStopPips, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
   }//if (JumpingStop)
   
   if (TrailingStop)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trailing stop is set to ", TrailingStopPips, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
   }//if (TrailingStop)
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Upper line: ", DoubleToStr(BbUpper, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Middle line: ", DoubleToStr(BbMiddle, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
   
   if (MarginMessage != "") ScreenMessage = StringConcatenate(ScreenMessage,NL, Gap, MarginMessage, NL);
   // Symhonie Messages
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "----------------------------------", NL);
   if(ARS) {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "ARS Ratio System: ON. Next ARS Lot : ", Lot, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Account Equity : ", AccEquity + " " + AccountCurrency(), NL);
   } else {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "ARS Ratio System: OFF. Manual Lot : ", Lot, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Account Equity : ", AccEquity + " " + AccountCurrency(), NL);
   }
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "----------------------------------", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BBands Color ("+Period()+")    : ", BBands, NL);
   if(AllowMultipleTrendTrade){
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MultipleTrade : ON" , NL);
    } else {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MultipleTrade : OFF" , NL);
    }
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "----------------------------------", NL);
   
   if(SellOpen || BuyOpen) {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TRADE IN PROGRESS ..." , NL);
   } else {
      if(AllowMultipleTrendTrade){
       ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LOOKING FOR GOOD ENTRY ... (Multipletrade is ON)" , NL);
      } else {
       if(lastTradeType=="SELL") ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LOOKING FOR -BUY- TRADE (last trade was a " + lastTradeType + ")", NL);
       if(lastTradeType=="BUY") ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LOOKING FOR -SELL- TRADE (last trade was a " + lastTradeType + ")", NL);
       if(!lastTradeType=="BUY" && !lastTradeType=="SELL") ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LOOKING FOR GOOD ENTRY ... (Multipletrade is OFF)" , NL);
      }
   }
   
   Comment(ScreenMessage);
}//void DisplayUserFeedback()
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   // get current TF and higher/lower  TF
   if(Period()==1) { hTF = 5; lTF = 0; }
   if(Period()==5) { hTF = 30; lTF = 1; }
   if(Period()==15) { hTF = 60; lTF = 5; }
   if(Period()==30) { hTF = 240; lTF = 15; }
   if(Period()==60) { hTF = 240; lTF = 30; }
   if(Period()==240) { hTF = 1440; lTF = 60; }
   if(Period()==1440) { hTF = 10080; lTF = 240; }
   if(Period()==10080) { hTF = 43200; lTF = 1440; }
   //Adapt to x digit criminals
   int multiplier;
   if(Digits == 2 || Digits == 4) multiplier = 1;
   if(Digits == 3 || Digits == 5) multiplier = 10;
   if(Digits == 6) multiplier = 100;   
   if(Digits == 7) multiplier = 1000;   
   
   if (multiplier > 1) PipDescription = " points";
   
   TakeProfit*= multiplier;
   StopLoss*= multiplier;
   HiddenPips*= multiplier;
   
   BreakEvenPips*= multiplier;
   BreakEvenProfit*= multiplier;
   JumpingStopPips*= multiplier;
   TrailingStopPips*= multiplier;
   
   MinPipsBetweenCandles*= multiplier;//Caterpillar
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc0)
   
   //Reset CriminIsECN if crim is IBFX and the punter does not know or, like me, keeps on forgetting
   string name = TerminalCompany();
   int ispart = StringFind(name, "IBFX", 0);
   if (ispart  -1) CriminalIsECN = true;   
   
   //Set up the arrays
   if (UseHanover)
   {
      SetUpArrays();
      Ccy1 = StringSubstr(Symbol(), 0, 3);
      Ccy2 = StringSubstr(Symbol(), 3, 3);
      ReadBars = iBars(NULL, PERIOD_M1);//Don't need it again when start() triggers
      ReadHanover();
   }//if (UseHanover)
   
   if (TradeComment == "") TradeComment = " ";
   ConvertedStartTime = hhmm_to_time(StartTime);
   OldBars = Bars;
   ReadIndicatorValues();//For initial display in case user has turned of constant re-display
   if (UseTrendDetection) TrendDetectionModule();
   DisplayUserFeedback();
   
   //Call sq's show trades indi
   //iCustom(NULL, 0, "SQ_showTrades",Magic, 0,0);
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//TRADE MANAGEMENT MODULE
void ReportError()
{
   //All purpose sl mod error reporter. Called when a sl mod fails
   
   int err=GetLastError();
      
   Alert(OrderTicket()," stop loss modification failed with error(",err,"): ",ErrorDescription(err));
   Print(OrderTicket()," stop loss modification failed with error(",err,"): ",ErrorDescription(err));      
}//void ReportError()
void BreakEvenStopLoss() // Move stop loss to breakeven
{
   double NewStop;
   bool result;
   bool modify=false;
   string LineName = SlPrefix + DoubleToStr(OrderTicket(), 0);
   double sl = ObjectGet(LineName, OBJPROP_PRICE1);
   
   if (OrderType()==OP_BUY)
   {
      if (sl >= OrderOpenPrice() ) return;
      if (Bid >= OrderOpenPrice () + (Point*BreakEvenPips))         
      {
         //Calculate the new stop
         NewStop = NormalizeDouble(OrderOpenPrice()+(BreakEvenProfit*Point), Digits);
         if (HiddenPips > 0)
         {
            if (ObjectFind(LineName) == -1)
            {
               ObjectCreate(LineName, OBJ_HLINE, 0, TimeCurrent(), 0);
               ObjectSet(LineName, OBJPROP_COLOR, Red);
               ObjectSet(LineName, OBJPROP_WIDTH, 1);
               ObjectSet(LineName, OBJPROP_STYLE, STYLE_DOT);
            }//if (ObjectFind(LineName == -1) )
         
            ObjectMove(LineName, 0, TimeCurrent(), NewStop);         
         }//if (HiddenPips > 0)
         modify = true;   
      }//if (Bid >= OrderOpenPrice () + (Point*BreakEvenPips) &&
   }//if (OrderType()==OP_BUY)                           
   
   if (OrderType()==OP_SELL)
   {
     if (sl  0) return;
     if (Ask  0)
         {
            if (ObjectFind(LineName) == -1)
            {
               ObjectCreate(LineName, OBJ_HLINE, 0, TimeCurrent(), 0);
               ObjectSet(LineName, OBJPROP_COLOR, Red);
               ObjectSet(LineName, OBJPROP_WIDTH, 1);
               ObjectSet(LineName, OBJPROP_STYLE, STYLE_DOT);
            }//if (ObjectFind(LineName == -1) )
         
            ObjectMove(LineName, 0, Time[0], NewStop);
         }//if (HiddenPips > 0)         
         modify = true;   
     }//if (Ask OrderOpenPrice()|| OrderStopLoss()==0))     
   }//if (OrderType()==OP_SELL)
   //Move 'hard' stop loss whether hidden or not. Don't want to risk losing a breakeven through disconnect.
   if (modify && HiddenStopLoss > 0)
   {
      while (IsTradeContextBusy() ) Sleep(100);
      result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);      
      if (!result) ReportError();
   }//if (modify)
   
} // End BreakevenStopLoss sub
void JumpingStopLoss()
{
   // Jump sl by pips and at intervals chosen by user .
   if (OrderProfit() = (sl + JumpingStopPips)
      if (Bid>= sl + ((JumpingStopPips*2)*Point) )
      {
         NewStop = NormalizeDouble(sl + (JumpingStopPips * Point), Digits);
         if (HiddenPips > 0) ObjectMove(LineName, 0, Time[0], NewStop);
         modify = true;   
      }// if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())      
   }//if (OrderType()==OP_BUY)
   
   if (OrderType()==OP_SELL)
   {
      if (sl > OrderOpenPrice() ) return;//Not at breakeven yet
      // Decrement sl by sl - JumpingStopPips.
      // This will happen when market price  0) ObjectMove(LineName, 0, Time[0], NewStop);
         modify = true;   
      }// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())         
   }//if (OrderType()==OP_SELL)
   //Move 'hard' stop loss whether hidden or not. Don't want to risk losing a breakeven through disconnect.
   if (modify && HiddenStopLoss > 0)
   {
      while (IsTradeContextBusy() ) Sleep(100);
      result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);      
      if (!result) ReportError();
   }//if (modify)
} //End of JumpingStopLoss sub
void TrailingStopLoss()
{
   
   if (OrderProfit() = (sl + JumpingStopPips)
      if (Bid>= sl + (TrailingStopPips * Point) )
      {
         NewStop = NormalizeDouble(sl + (TrailingStopPips * Point), Digits);
         if (HiddenPips > 0) ObjectMove(LineName, 0, Time[0], NewStop);
         modify = true;   
      }// if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())      
   }//if (OrderType()==OP_BUY)
   
   if (OrderType()==OP_SELL)
   {
      if (sl > OrderOpenPrice() ) return;//Not at breakeven yet
      // Decrement sl by sl - TrailingStopPips.
      // This will happen when market price  0) ObjectMove(LineName, 0, Time[0], NewStop);
         modify = true;   
      }// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())         
   }//if (OrderType()==OP_SELL)
   //Move 'hard' stop loss whether hidden or not. Don't want to risk losing a breakeven through disconnect.
   if (modify && HiddenStopLoss > 0)
   {
      while (IsTradeContextBusy() ) Sleep(100);
      result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);      
      if (!result) ReportError();
   }//if (modify)
      
} // End of TrailingStopLoss sub
void CandlestickTrailingStop()
{
   
   //Trails the stop at the hi/lo of the previous candle shifted by the user choice.
   //Only tries to do this once per bar, so an invalid stop error will only be generated once. I could code for
   //a too-close sl, but cannot be arsed. Coders, sort this out for yourselves.
   
   if (OldCstBars == Bars) return;
   OldCstBars = Bars;
   if (OrderProfit()  sl)
      {
         NewStop = NormalizeDouble(Low[1], Digits);
         if (HiddenPips > 0) ObjectMove(LineName, 0, Time[0], NewStop);
         modify = true;   
      }//if (iLow(NULL, CstTimeFrame, CstTrailCandles) > sl)
   }//if (OrderType == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (iHigh(NULL, CstTimeFrame, CstTrailCandles)  0) ObjectMove(LineName, 0, Time[0], NewStop);
         modify = true;   
      }//if (iHigh(NULL, CstTimeFrame, CstTrailCandles)  0)
   {
      while (IsTradeContextBusy() ) Sleep(100);
      result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);      
      if (!result) ReportError();
   }//if (modify)
}//End void CandlestickTrailingStop()
void TradeManagementModule()
{
   // Call the working subroutines one by one.
   //Candlestick trailing stop
   if (UseCandlestickTrailingStop) CandlestickTrailingStop();
   // Breakeven
   if(BreakEven) BreakEvenStopLoss();
   // JumpingStop
   if(JumpingStop) JumpingStopLoss();
   //TrailingStop
   if(TrailingStop) TrailingStopLoss();
}//void TradeManagementModule()
//END TRADE MANAGEMENT MODULE
////////////////////////////////////////////////////////////////////////////////////////////////
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
{
   //pah (Paul) contributed the code to get around the trade context busy error. Many thanks, Paul.
   
   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);
   //RetryCount is declared as 10 in the Trading variables section at the top of this file
   for (int cc = 0; cc  -1)
         {
            ModifyOrder(ticket, stop, take);
         }//if (ticket > 0)}
      }//if (CriminalIsECN)
      
      if (ticket > -1) break;//Exit the trade send loop
      if (cc == RetryCount - 1) return(false);
   
      //Error trapping for both
      if (ticket  0 && stop > 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           if (OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE)) return;           
        }//if (take > 0 && stop > 0)
   
        if (take != 0 && stop == 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           if (OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE)) return;
        }//if (take == 0 && stop != 0)
        if (take == 0 && stop != 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           if (OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE)) return;
        }//if (take == 0 && stop != 0)
   }//for (int cc = 0; cc = 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
      {
         TicketNo = OrderTicket();
         //Replace missing tp and sl lines
         if (HiddenPips > 0) ReplaceMissingSlTpLines();
         return(true);         
      }//if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   return(false);
}//End bool DoesTradeExist()
bool IsTradingAllowed()
{
   //Returns false if any of the filters should cancel trading, else returns true to allow trading
   
      
   //Maximum spread
   if (MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread) return(false);


   //Swap filter
   if (OpenTrades == 0) TradeDirectionBySwap();
   //An individual currency can only be traded twice, so check for this
   CanTradeThisPair = true;
   if (OnlyTradeCurrencyTwice && OpenTrades == 0)
   {
      IsThisPairTradable();      
   }//if (OnlyTradeCurrencyTwice)
   if (!CanTradeThisPair) return(false);
   
   
   
   
   return(true);
}//End bool IsTradingAllowed()
void LookForTradingOpportunities()
{
   RefreshRates();
   double take, stop, price;
   int type;
   bool SendTrade;
   double SendLots = Lot;
   //Using Recovery
   double target = ObjectGet(reentrylinename, OBJPROP_PRICE1);
   if (UseRecovery)
   {
      if (RecoveryInProgress)
      {
         if (OpenTrades == 2)
         {
            if (Use1.1.2.4Recovery) SendLots = Lot * 2;         
            if (Use1.1.3.3Recovery) SendLots = Lot * 3;         
         }//if (OpenTrades == 2)
      
         if (OpenTrades == 3)
         {
            if (Use1.1.2.4Recovery) SendLots = Lot * 4;
            if (Use1.1.3.3Recovery) SendLots = Lot * 3;
         }//if (OpenTrades == 3)
      
         if (OpenTrades == 4) return;//No further trading is possible
      
      
      }//if (RecoveryInProgress)
      
      //This idea from Pippo   
      if (Use1.2.6Recovery && OpenTrades + 1 >= Start_Recovery_at_trades)
      {
         if (OpenTrades == Start_Recovery_at_trades - 1) SendLots = Lot * 2;
         if (OpenTrades == Start_Recovery_at_trades) SendLots = Lot * 6;
         if (OpenTrades == Start_Recovery_at_trades + 1) return;      
      }//if (Use1.2.6Recovery)
   
   }//if (UseRecovery)
   //Check filters
   if (!IsTradingAllowed() ) return;
   //Trend
   string Ttrend = trend;//Temp trend string
   if (!UseTrendDetection) Ttrend = up;//Set up a dummy if the user is not using the trend stuff
   
   //Long
   if (TriggerTrend == buy && Ttrend == up)//Replace with whatever conditional is appropriate
   {
      if (!TradeLong) return;
   
      //Hanover RS
      if (UseHanover && !HanoverFilter(OP_BUY) ) return(false);
   
      if (UseNanningBobForTrigger && TradeTriggerDirection == down) return;
      //Balanced pair trade filter. Only apply to pre-recovery trades.
      //Will remove the comments when I add Recovery
      //if (OpenTrades + 1  0)
      {
         take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         HiddenTakeProfit = take;
         if (HiddenPips > 0) take = NormalizeDouble(take + (HiddenPips * Point), Digits);
      }//if (TakeProfit > 0)
      
      if (StopLoss > 0)
      {
         stop = NormalizeDouble(Ask - (StopLoss * Point), Digits);
         HiddenStopLoss = stop;
         if (HiddenPips > 0) stop = NormalizeDouble(stop - (HiddenPips * Point), Digits);
      }//if (StopLoss > 0)
      
      type = OP_BUY;
      price = Ask;
      SendTrade = true;
   }//if (Ask > 1000000)
   
   if (!UseTrendDetection) Ttrend = down;//Set up a dummy if the user is not using the trend stuff
   
   //Short
   if (TriggerTrend == sell && Ttrend == down)//Replace with whatever conditional is appropriate
   {
      if (!TradeShort) return;
      //Hanover RS
      if (UseHanover && !HanoverFilter(OP_SELL) ) return(false);
      if (UseNanningBobForTrigger && TradeTriggerDirection == up) return;
      //Balanced pair trade filter. Only apply to pre-recovery trades
      //Will remove the comments when I add Recovery
      //if (OpenTrades + 1  0)
      {
         take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         HiddenTakeProfit = take;
         if (HiddenPips > 0) take = NormalizeDouble(take - (HiddenPips * Point), Digits);
      }//if (TakeProfit > 0)
      
      if (StopLoss > 0)
      {
         stop = NormalizeDouble(Bid + (StopLoss * Point), Digits);
         HiddenStopLoss = stop;
         if (HiddenPips > 0) stop = NormalizeDouble(stop + (HiddenPips * Point), Digits);
      }//if (StopLoss > 0)
      
      type = OP_SELL;
      price = Bid;
      SendTrade = true;      
   }//if (Ask  0) ReplaceMissingSlTpLines();
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
   
   }//if (!result)
   
   
}//void LookForTradingOpportunities()
bool CloseTrade(int ticket)
{   
   while(IsTradeContextBusy()) Sleep(100);
   bool result = OrderClose(ticket, OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
   //Actions when trade send succeeds
   if (result)
   {
      if(TakeScreenShot==true) { WindowScreenShot("bbands_ea/"+Symbol()+"_"+TicketNo+"_OUT_"+Hour()+"-"+Minute()+"_"+TradeComment+".gif",1680,1050);  }
      return(true);
   }//if (result)
   
   //Actions when trade send fails
   if (!result)
   {
      return(false);
   }//if (!result)
   
}//End bool CloseTrade(ticket)
////////////////////////////////////////////////////////////////////////////////////////////////
//Indicator module
/*
void GetBB(int shift)
{
   //Reads BB figures into BbUpper, BbMiddle, BbLower
   
   
   BbUpper = iBands(NULL, 0, BbPeriod, BbDeviation, 0, PRICE_OPEN, MODE_UPPER, shift);
   BbLower = iBands(NULL, 0, BbPeriod, BbDeviation, 0, PRICE_OPEN, MODE_LOWER, shift);
   BbMiddle = iBands(NULL, 0, BbPeriod, BbDeviation, 0, PRICE_OPEN, MODE_MAIN, shift);
   
   BbExtent = BbUpper - BbLower;
   
}//void GetBb(int shift)
*/
double GetRsi(int tf, int period, int ap, int shift)
{
   return(iRSI(NULL, tf, period, ap, shift) );
}//End double GetRsi(int tf, int period, int ap, int shift)
double GetMa(int tf, int period, int mashift, int method, int ap, int shift)
{
   return(iMA(NULL, tf, period, mashift, method, ap, shift) );
}//End double GetMa(int tf, int period, int mashift, int method, int ap, int shift)
/*
double CalculateVolatility(int period, int LookBack)
{
   //Calculates the volatility of a pair based on an average of their movement over LookBack periods
   
   double pips;
   for (int cc = 1; cc BBValue ) && SellOpen)
   {
        //Alert("CLOSED "+Symbol()+" (Sell) TRADE TICKET : " + TicketNo);
        CloseTrade(TicketNo);
        TriggerTrend=NULL;
        //ReadIndicatorValues();
   }
   if ((BBands==red || MA[B]= CurrentPrice) PriceHit=true;
   } else {
      BBValue = BBValueRed;
      //CurrentPrice = Bid;
      //if(BBValue = CurrentPrice) PriceHit=true;
   } else {
      BBValue_prev = BBValueRed;
      //CurrentPrice = Bid;
      //if(BBValue  BBValue && PriceHit==true && (Open[1]Close[0])&& !SellOpen && lastTradeType!="SELL" ) { TriggerTrend = sell;lastTradeType= "SELL";}  
   
}//void ReadIndicatorValues()
//End Indicator module
////////////////////////////////////////////////////////////////////////////////////////////////
void LookForTradeClosure()
{
   //Close the trade if the new candle opens inside the bands
   
   if (!OrderSelect(TicketNo, SELECT_BY_TICKET) ) return;
   if (OrderSelect(TicketNo, SELECT_BY_TICKET) && OrderCloseTime() > 0) return;
   
   bool CloseTrade;
   
   string LineName = TpPrefix + DoubleToStr(TicketNo, 0);
   //Work with the lines on the chart that represent the hidden tp/sl
   double take = ObjectGet(LineName, OBJPROP_PRICE1);
   LineName = SlPrefix + DoubleToStr(TicketNo, 0);
   double stop = ObjectGet(LineName, OBJPROP_PRICE1);
   
   if (OrderType() == OP_BUY)
   {
      //TP
      if (Bid >= take && take > 0) CloseTrade = true;
      //SL
      if (Bid  0) CloseTrade = true;
   }//if (OrderType() == OP_BUY)
   
   
   if (OrderType() == OP_SELL)
   {
      //TP
      if (Bid  0) CloseTrade = true;
      //SL
      if (Bid >= stop && stop > 0) CloseTrade = true;
   }//if (OrderType() == OP_SELL)
   
   if (CloseTrade)
   {
      bool result = CloseTrade(TicketNo);
      //Actions when trade send succeeds
      if (result)
      {
         DeletePendingPriceLines();
      }//if (result)
   
      //Actions when trade send fails
      if (!result)
      {
   
      }//if (!result)
   
   }//if (CloseTrade)
   
   
}//void LookForTradeClosure()
void CloseAllTrades()
{
   ForceTradeClosure= false;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderMagicNumber() != MagicNumber) continue;
      if (OrderSymbol() != Symbol() ) continue;
      while(IsTradeContextBusy()) Sleep(100);
      if (OrderType() == OP_BUY || OrderType() == OP_SELL) bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
      if (result) cc++;
      if (!result) ForceTradeClosure= true;
      
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
}//End void CloseAllTrades()
bool CheckTradingTimes()
{
   int hour = TimeHour(TimeLocal() );
   
   if (end_hourm = start_hourm && hour = start_houre && hour = start_hourm && hour = start_houre && hour = MathMax(end_hourm, end_houre))
   {      
      ok2Trade = false;
   }//if (hour >= MathMax(end_hourm, end_houre))
   return(ok2Trade);
}//bool CheckTradingTimes()
void CountOpenTrades()
{
   OpenTrades = 0;
   TicketNo = -1;
   BuyOpen = false;
   SellOpen = false;
   if (OrdersTotal() == 0) return;
   
   for (int cc = 0; cc  0) ReplaceMissingSlTpLines();
         //Check for possible trade closure
         LookForTradeClosure();
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
   }//for (int cc = 0; cc  3) {
         /* look through history too, as order may have opened and closed immediately */
         total=OrdersHistoryTotal();
         for(c = 0; c  O_R_Setting_max_retries) {
         exit_loop = true;
      }
      if (!(success || exit_loop)) {
         Print("Did not find #"+ticket+" in history, sleeping, then doing retry #"+cnt);
         O_R_Sleep(O_R_Setting_sleep_time, O_R_Setting_sleep_max);
      }
   }
   // Select back the prior ticket num in case caller was using it.
   if (lastTicket >= 0) {
      OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
   }
   if (!success) {
      Print("Never found #"+ticket+" in history! crap!");
   }
   return(success);
}//End bool O_R_CheckForHistory(int ticket)
//=============================================================================
//                              O_R_Sleep()
//
//  This sleeps a random amount of time defined by an exponential
//  probability distribution. The mean time, in Seconds is given
//  in 'mean_time'.
//  This returns immediately if we are backtesting
//  and does not sleep.
//
//=============================================================================
void O_R_Sleep(double mean_time, double max_time)
{
   if (IsTesting()) {
      return;   // return immediately if backtesting.
   }
   double p = (MathRand()+1) / 32768.0;
   double t = -MathLog(p)*mean_time;
   t = MathMin(t,max_time);
   int ms = t*1000;
   if (ms  0) TradeLong = true;
         else TradeLong = false;
         if (ShortSwap > 0) TradeShort = true;
         else TradeShort = false;         
      }//if (StringSubstr(Symbol(), 0, 3) == "CAD" || StringSubstr(Symbol(), 0, 3) == "cad" )      
   }//if (CadPairsPositiveOnly)
   
   if (AudPairsPositiveOnly)
   {
      if (StringSubstr(Symbol(), 0, 3) == "AUD" || StringSubstr(Symbol(), 0, 3) == "aud" || StringSubstr(Symbol(), 3, 3) == "AUD" || StringSubstr(Symbol(), 3, 3) == "aud" )      
      {
         if (LongSwap > 0) TradeLong = true;
         else TradeLong = false;
         if (ShortSwap > 0) TradeShort = true;
         else TradeShort = false;         
      }//if (StringSubstr(Symbol(), 0, 3) == "AUD" || StringSubstr(Symbol(), 0, 3) == "aud" || StringSubstr(Symbol(), 3, 3) == "AUD" || StringSubstr(Symbol(), 3, 3) == "aud" )      
   }//if (AudPairsPositiveOnly)
   
   
   if (NzdPairsPositiveOnly)
   {
      if (StringSubstr(Symbol(), 0, 3) == "NZD" || StringSubstr(Symbol(), 0, 3) == "nzd" || StringSubstr(Symbol(), 3, 3) == "NZD" || StringSubstr(Symbol(), 3, 3) == "nzd" )      
      {
         if (LongSwap > 0) TradeLong = true;
         else TradeLong = false;
         if (ShortSwap > 0) TradeShort = true;
         else TradeShort = false;         
      }//if (StringSubstr(Symbol(), 0, 3) == "AUD" || StringSubstr(Symbol(), 0, 3) == "aud" || StringSubstr(Symbol(), 3, 3) == "AUD" || StringSubstr(Symbol(), 3, 3) == "aud" )      
   }//if (AudPairsPositiveOnly)
   
   
}//void TradeDirectionBySwap()
bool IsThisPairTradable()
{
   //Checks to see if either of the currencies in the pair is already being traded twice.
   //If not, then return true to show that the pair can be traded, else return false
   
   string c1 = StringSubstr(Symbol(), 0, 3);//First currency in the pair
   string c2 = StringSubstr(Symbol(), 3, 3);//Second currency in the pair
   int c1open = 0, c2open = 0;
   CanTradeThisPair = true;
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() != Symbol() ) continue;
      if (OrderMagicNumber() != MagicNumber) continue;
      int index = StringFind(OrderSymbol(), c1);
      if (index > -1)
      {
         c1open++;         
      }//if (index > -1)
   
      index = StringFind(OrderSymbol(), c2);
      if (index > -1)
      {
         c2open++;         
      }//if (index > -1)
   
      if (c1open == 1 && c2open == 1)
      {
         CanTradeThisPair = false;
         return(false);   
      }//if (c1open == 1 && c2open == 1)
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   //Got this far, so ok to trade
   return(true);
   
}//End bool IsThisPairTradable()
bool BalancedPair(int type)
{
   //Only allow an individual currency to trade if it is a balanced trade
   //e.g. UJ Buy open, so only allow Sell xxxJPY.
   //The passed parameter is the proposed trade, so an existing one must balance that
   //This code courtesy of Zeljko (zkucera) who has my grateful appreciation.
   
   string BuyCcy1, SellCcy1, BuyCcy2, SellCcy2;
   if (type == OP_BUY || type == OP_BUYSTOP)
   {
      BuyCcy1 = StringSubstr(Symbol(), 0, 3);
      SellCcy1 = StringSubstr(Symbol(), 3, 3);
   }//if (type == OP_BUY || type == OP_BUYSTOP)
   else
   {
      BuyCcy1 = StringSubstr(Symbol(), 3, 3);
      SellCcy1 = StringSubstr(Symbol(), 0, 3);
   }//else
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS)) continue;
      if (OrderSymbol() == Symbol()) continue;
      if (OrderMagicNumber() != MagicNumber) continue;      
      if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP)
      {
         BuyCcy2 = StringSubstr(OrderSymbol(), 0, 3);
         SellCcy2 = StringSubstr(OrderSymbol(), 3, 3);
      }//if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP)
      else
      {
         BuyCcy2 = StringSubstr(OrderSymbol(), 3, 3);
         SellCcy2 = StringSubstr(OrderSymbol(), 0, 3);
      }//else
      if (BuyCcy1 == BuyCcy2 || SellCcy1 == SellCcy2) return(false);
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   //Got this far, so it is ok to send the trade
   return(true);
}//End bool BalancedPair(int type)
//End Balance/swap filters module
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Recovery module
void RecoveryModule()
{
   
   //Draw a breakeven line if there is not one in place already.
   //The bot will adjust the tp's during the CountOpenTrades function.
   if (ObjectFind(breakevenlinename) > -1) return;
   
   //Do not need a breakeven line if Recovery is already at be
   //if (ObjectFind(breakevenlinename) > -1) return;
   
   
   buy_price = 0;
   sell_price = 0;
   CheckRecoveryTakeProfit();
   double recovery_profit;
   if (buy_price > 0)
   {
      recovery_profit = buy_price;
      recovery_profit = NormalizeDouble(buy_price + (RecoveryBreakEvenProfitPips * Point), Digits);
   }//if (buy_price > 0)
   
   if (sell_price > 0)
   {
      recovery_profit = sell_price;
      recovery_profit = NormalizeDouble(sell_price - (RecoveryBreakEvenProfitPips * Point), Digits);
   }//if (sell_price > 0)
   ObjectCreate(breakevenlinename,OBJ_HLINE,0,TimeCurrent(), recovery_profit );
   ObjectSet(breakevenlinename,OBJPROP_COLOR,BreakEvenLineColour);
   ObjectSet(breakevenlinename,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(breakevenlinename,OBJPROP_WIDTH,2);
   
}//End void RecoveryModule()
void CheckRecoveryTakeProfit()
{
   //This is adapted from the NB iExposure indicator. I do not understand how it works.
   //There will be redundant code, so anybody wishing to clear it up is most welcome to do so.
   
   ExtLines = 0;
   int    i,col,line;
   ArrayInitialize(ExtSymbolsSummaries,0.0);
   int total=Analyze();
   if(total>0)
   {
      line=0;
      for(i=0; iExtLines)
         {
            int y_dist=ExtVertShift*(line+1)+1;
            /*for(col=0; colExtLines)
         //---- set line
         //color  price_colour;//Steve mod
         int    digits=MarketInfo(ExtSymbols,MODE_DIGITS);
         double buy_lots=ExtSymbolsSummaries[BUY_LOTS];
         double sell_lots=ExtSymbolsSummaries[SELL_LOTS];
         if(buy_lots!=0)  buy_price=NormalizeDouble(ExtSymbolsSummaries[BUY_PRICE]/buy_lots, Digits);
         if(sell_lots!=0) sell_price=NormalizeDouble(ExtSymbolsSummaries[SELL_PRICE]/sell_lots, Digits);
         
      }//for(i=0; i0)
}//End void CheckRecoveryTakeProfit()
int Analyze()
{
   double profit;
   int    i,index,type,total=OrdersTotal();
//----
   for(i=0; i=SYMBOLS_MAX) continue;
      //----
      ExtSymbolsSummaries[index][DEALS]++;
      profit=OrderProfit()+OrderCommission()+OrderSwap();
      ExtSymbolsSummaries[index][PROFIT]+=profit;
      if(type==OP_BUY)
        {
         ExtSymbolsSummaries[index][BUY_LOTS]+=OrderLots();
         ExtSymbolsSummaries[index][BUY_PRICE]+=OrderOpenPrice()*OrderLots();
        }
      else
        {
         ExtSymbolsSummaries[index][SELL_LOTS]+=OrderLots();
         ExtSymbolsSummaries[index][SELL_PRICE]+=OrderOpenPrice()*OrderLots();
        }
     }
//----
   total=0;
   for(i=0; i0) total++;
     }
//----
   return(total);
}//int Analyze()
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SymbolsIndex(string SymbolName)
{
   bool found=false;
//----
   for(int i=0; i=SYMBOLS_MAX) return(-1);
//----
   i=ExtSymbolsTotal;
   ExtSymbolsTotal++;
   ExtSymbols=SymbolName;
   ExtSymbolsSummaries[DEALS]=0;
   ExtSymbolsSummaries[BUY_LOTS]=0;
   ExtSymbolsSummaries[BUY_PRICE]=0;
   ExtSymbolsSummaries[SELL_LOTS]=0;
   ExtSymbolsSummaries[SELL_PRICE]=0;
   ExtSymbolsSummaries[NET_LOTS]=0;
   ExtSymbolsSummaries[PROFIT]=0;
//----
   return(i);
}//End int SymbolsIndex(string SymbolName)
void AddReEntryLine(double price)
{
   if (ObjectFind(reentrylinename) > -1) ObjectDelete(reentrylinename);   
   
   
   if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
   {
      int err=GetLastError();      
      Alert("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
      Print("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
      return(0);
   }//if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
   
   ObjectSet(reentrylinename,OBJPROP_COLOR,ReEntryLineColour);
   ObjectSet(reentrylinename,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(reentrylinename,OBJPROP_WIDTH,2);     
}//void AddReEntryLine(int type, double price)
void ReplaceReEntryLine()
{
   //Find the most recent trade in the sequence and replace the missing re-entry line
   
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {      
      if (OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) )
      {
         if (OrderSymbol() == Symbol())
         {            
            if (OrderType() == OP_BUY) AddReEntryLine(NormalizeDouble(OrderOpenPrice() - (ReEntryLinePips * Point), Digits) );
            if (OrderType() == OP_SELL) AddReEntryLine(NormalizeDouble(OrderOpenPrice() + (ReEntryLinePips * Point), Digits) );
            return;
         }//if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)      
         
      }//if (OrderSelect(cc, SELECT_BY_POS) )
      
   }//for (cc = OpenTrades; cc >= 0; cc--)
}//void ReplaceReEntryLine()
void RecoveryCandlesticktrailingStop()
{
   //Called from start()
   //This function will only be called if Recovery is in progress.
   
/*
    * no tp in Recovery trades, just the breakeven line on the chart
    * at be +10, the breakeven line becomes the stop loss line
    * code a candlestick trail for the stop loss line
    * close the Recovery basket when the market retraces to the stop loss line
*/
   
   //Find the trade type. Function leaves an open trade selected   
   
   double target, stop;
   
   RefreshRates();
         
   if (BuyOpen)
   {
      //Should breakeven line be replaced by trailing stop line.
      //Irrelevant if be line has been deleted
      if (ObjectFind(breakevenlinename) > -1)
      {
         target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
         if (Ask >= target + (RecoveryTrailingStopAt * Point) )
         {
            ObjectDelete(breakevenlinename);
            ObjectCreate(breakevenlinename, 1,0,TimeCurrent(),target);
            ObjectSet(breakevenlinename,OBJPROP_COLOR,RecoveryStopLossLineColour);
            ObjectSet(breakevenlinename,OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet(breakevenlinename,OBJPROP_WIDTH,2);     
            //return;
         }//if (Ask >= target + (RecoveryTrailingStopAt * Point) )
      }//if (ObjectFind(breakevenlinename) > -1)
      
      //Abort the function if be line is wrong colour
      if (ObjectGet(breakevenlinename, OBJPROP_COLOR) != RecoveryStopLossLineColour) return;
  
      //Move the stop at each new candle
      if (OldRecoverTrailBars != Bars)
      {
         target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
         
         if (Low[1] > target)
         {
            ObjectMove(breakevenlinename, 0, TimeCurrent(), Low[1]);            
         }//if (Low[1] > target)
         OldRecoverTrailBars = Bars;
         //return;
      }//if (OldRecoverTrailBars != Bars)
      
      //Has the market retraced to the recovery stop loss
      target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
      
      if (Ask  -1)
      {
         target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
         if (Bid  -1)
      
      
      //Abort the function if be line is wrong colour
      if (ObjectGet(breakevenlinename, OBJPROP_COLOR) != RecoveryStopLossLineColour) return;
      
      
      
      //Move the stop at each new candle
      if (OldRecoverTrailBars != Bars)
      {
         target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
         if (High[1] = target)
      {
         ForceTradeClosure = true;
         CloseAllTrades();
         ObjectDelete(breakevenlinename);
         return;
      }//if (Bid >= target)
   }//if (OrderType() == OP_SELL)
   
   
}//End void RecoveryCandlesticktrailingStop()
//End Recovery module
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Trend detection module
void TrendDetectionModule()
{
   static int OldNbBars;
   //Define the trend according to the user's choices.
   //Only called if UseTrendDetection is set to true
   trend = ranging;//Default
   
   //Rsi. This one is scooby-doo's suggestion and is based on a 20 period D1 Rsi.
   if (UseRsiTrendDetection)
   {
      TrendRsiVal = GetRsi(RsiTdTf, RsiTdPeriod, RsiTdAppliedPrice, 0);
      if (TrendRsiVal > 55) trend = up;
      if (TrendRsiVal  Fast MA - trend is up and vice versa
   if (UseSlowkey)
   {
      FastTrendMaVal = GetMa(FastMaTdTF, FastMaTdPeriod, FastMaTdShift, FastMaTdMethod, FastMaTdAppliedPrice, 0);   
      SlowTrendMaVal = GetMa(SlowMaTdTF, SlowMaTdPeriod, SlowMaTdShift, SlowMaTdMethod, SlowMaTdAppliedPrice, 0);
      if (FastTrendMaVal > SlowTrendMaVal) trend = up;
      if (FastTrendMaVal  FastNbTrendMaVal && iHigh(NULL, PERIOD_D1, 0) > SlowNbTrendMaVal
         && iLow(NULL, PERIOD_D1, 0) > FastNbTrendMaVal && iLow(NULL, PERIOD_D1, 0) > SlowNbTrendMaVal)
         {
            if (UseNanningBobForTrend) trend = up;
            if (UseNanningBobForTrigger) TradeTriggerDirection = up;
         }//if (iHigh(NULL, PERIOD_D1, 0) > FastNbTrendMaVal && iHigh(NULL, PERIOD_D1, 0) > SlowNbTrendMaVal
         
      //Detect downtrend
      if (iHigh(NULL, PERIOD_D1, 0)  iClose(NULL, TrendConfirmationCandleTF, 1) ) TrendConfirmationCandleDir = down;
      if (iOpen(NULL, TrendConfirmationCandleTF, 1)  -1 && OrderTakeProfit() > 0)
   {
      if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT)
      {
         HiddenTakeProfit = NormalizeDouble(OrderTakeProfit() - (HiddenPips * Point), Digits);
      }//if (OrderType() == OP_BUY)
      
      if (OrderType() == OP_SELL)
      {
         HiddenTakeProfit = NormalizeDouble(OrderTakeProfit() + (HiddenPips * Point), Digits);
      }//if (OrderType() == OP_BUY)      
   }//if (TicketNo > -1 && OrderTakeProfit() > 0)
   
   if (HiddenTakeProfit > 0 && ObjectFind(LineName) == -1)
   {
      ObjectDelete(LineName);
      ObjectCreate(LineName, OBJ_HLINE, 0, TimeCurrent(), HiddenTakeProfit);
      ObjectSet(LineName, OBJPROP_COLOR, Green);
      ObjectSet(LineName, OBJPROP_WIDTH, 1);
      ObjectSet(LineName, OBJPROP_STYLE, STYLE_DOT);
   }//if (HiddenTakeProfit > 0)
   
   
   LineName = SlPrefix + DoubleToStr(TicketNo, 0);//TicketNo is set by the calling function - either CountOpenTrades or DoesTradeExist
   HiddenStopLoss = 0;
   if (TicketNo > -1 && OrderStopLoss() > 0)
   {
      if (OrderType() == OP_BUY)
      {
         HiddenStopLoss = NormalizeDouble(OrderStopLoss() + (HiddenPips * Point), Digits);
      }//if (OrderType() == OP_BUY)
      
      if (OrderType() == OP_SELL || OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT)
      {
         HiddenStopLoss = NormalizeDouble(OrderStopLoss() - (HiddenPips * Point), Digits);
      }//if (OrderType() == OP_BUY)      
   }//if (TicketNo > -1 && OrderStopLoss() > 0)
   
   if (HiddenStopLoss > 0 && ObjectFind(LineName) == -1)
   {
      ObjectDelete(LineName);
      ObjectCreate(LineName, OBJ_HLINE, 0, TimeCurrent(), HiddenStopLoss);
      ObjectSet(LineName, OBJPROP_COLOR, Red);
      ObjectSet(LineName, OBJPROP_WIDTH, 1);
      ObjectSet(LineName, OBJPROP_STYLE, STYLE_DOT);
   }//if (HiddenStopLoss > 0)
   
   
}//End void DrawPendingPriceLines()
void DeletePendingPriceLines()
{
   
   //ObjectDelete(pendingpriceline);
   string LineName = TpPrefix + DoubleToStr(TicketNo, 0);
   ObjectDelete(LineName);
   LineName = SlPrefix + DoubleToStr(TicketNo, 0);
   ObjectDelete(LineName);
   
}//End void DeletePendingPriceLines()
void ReplaceMissingSlTpLines()
{
   if (OrderTakeProfit() > 0 || OrderStopLoss() > 0) DrawPendingPriceLines();
}//End void ReplaceMissingSlTpLines()
void DeleteOrphanTpSlLines()
{
   if (ObjectsTotal() == 0) return;
   
   for (int cc = ObjectsTotal() - 1; cc >= 0; cc--)
   {
      string name = ObjectName(cc);
      
      if ((StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) && ObjectType(name) == OBJ_HLINE)
      {
         int tn = StrToDouble(StringSubstr(name, 2));
         if (tn > 0)
         {
            if (!OrderSelect(tn, SELECT_BY_TICKET, MODE_TRADES) || OrderCloseTime() > 0)
            {
               ObjectDelete(name);
               cc++;
            }//if (!OrderSelect(tn, SELECT_BY_TICKET, MODE_TRADES) || OrderCloseTime() > 0)
            
         }//if (tn > 0)
         
         
      }//if (StringSubstr(name, 0, 1) == TpPrefix)
      
   }//for (int cc = ObjectsTotal() - 1; cc >= 0; cc--)
   
   
}//End void DeleteOrphanTpSlLines()
//END Pending trade price lines module
///////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Caterpillar module
void DeleteOrphanGlobals()
{
   //Remove those globals left behind after a trade closes
   for (int cc = GlobalVariablesTotal() - 1; cc >= 0; cc--)
   {
      CsGvName = GlobalVariableName(cc);
      int tn = StrToDouble(CsGvName);
      if (tn > 0)
      {
         if (!OrderSelect(tn, SELECT_BY_TICKET) || OrderCloseTime() > 0)
         {
            GlobalVariableDel(CsGvName);
            cc++;            
         }//if (!OrderSelect(tn, SELECT_BY_TICKET) || OrderCloseTime() > 0)
      }//if (tn > 0)
      
   }//for (int cc = GlobalVariablesTotal() - 1; cc >= 0; cc--)
   
}//End void DeleteOrphanGlobals()
void MoveCaterpillarStopToBreakeven()
{
   //OpenTrades - 1 trade needs to have its stop moved to be at the opening of a new trade
   
   //Select OpenTrades - 1
   int found = 0;
   for (int cc = 0; cc  OrderOpenPrice() ) modify = true;
   
   if (modify)
   {
      int tries = 0;
      bool result = false;
      while (!result)
      {
         result = OrderModify(OrderTicket(), OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
         if (!result)
         {
            tries++;
            if (tries == 1) Alert(OrderTicket(), " stop loss move to BE failed");
            if (tries == 100)
            {
               result = true;//Give up
               Alert(OrderTicket(), " Caterpillar failed to move the sl to breakeven after 100 attempts.");
            }//if (tries == 100)            
         }//if (!result)
      }//while (!result)      
   }//if (modify)
   
   
}//End void MoveCaterpillarStopToBreakeven()
void CaterpillarTrailingStop(int TradesToCheck)
{
   //Move trade stops 1 candle to the right when there is a new hi or lo, depending on the trade type
   //Also deletes redundant gv's
   
   if (GlobalVariablesTotal() == 0) return;//Shouldn't happen, but you never know
   
   int found, shift, ctime;
   bool result;
   double stop;
   int MaxTradesTicketNo = -1;//This will hold the ticket number of the final trade in the sequence, but which is checked first
   
   
   //Cycle through the Golbal Variables list to look for those with an integer as their name
   for (int cc = GlobalVariablesTotal() - 1; cc >= 0; cc--)
   {
      CsGvName = GlobalVariableName(cc);
      int tn = StrToDouble(CsGvName);
      if (tn > 0)
      {
         //Delete the gv if the trade has closed
         if (!OrderSelect(tn, SELECT_BY_TICKET) || OrderCloseTime() > 0)
         {
            GlobalVariableDel(CsGvName);
            cc++;
            continue;
         }//if (!OrderSelect(tn, SELECT_BY_TICKET) || OrderCloseTime() > 0)
         
         //The trade is still open, so check for ownership
         if (OrderSymbol() != Symbol() ) continue;
         if (OrderMagicNumber() != MagicNumber ) continue;
      
         
         //Got this far, so Cat owns the trade and the stop needs moving.
         //Store the ticket number of the most recent trade in the sequence,for BE stop stuff further down
         if (MaxTradesTicketNo == -1) MaxTradesTicketNo = OrderTicket();
         //Calculate the shift back from current candle to the candle open time of the previous cts move
         shift = 0;
         ctime = GlobalVariableGet(CsGvName);
         while (Time[shift] > ctime && shift  ctime)
         //Point to the next candls
         shift--;
         //This is an attempt to stop the final trade in the sequence having its stop moved too early, because
         //this can result in it being stopped out as soon as it is opened
         if (shift  0)
            {
               while (IsTradeContextBusy() ) Sleep(100);
               result = OrderModify(tn, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
               GlobalVariableSet(CsGvName, Time[shift]);
            }//if (OrderStopLoss()  stop && stop > 0)
            {
               while (IsTradeContextBusy() ) Sleep(100);
               result = OrderModify(tn, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
               GlobalVariableSet(CsGvName, Time[shift]);
            }//if (OrderStopLoss() > stop)
         }//if (OrderType() == OP_SELL)
         
         found++;
         if (found >= TradesToCheck) break;//All finished
      }//if (tn > -1)
   }//for (int cc = GlobalVariablesTotal() - 1; cc >= 0; cc--)
   
   //Attempt to move the stop of the final trade to BE asap, if OpenTrades has reached the max allowed.   
   if (OpenTrades == MaxTrades)
   {
      if (OrderSelect(MaxTradesTicketNo, SELECT_BY_TICKET) && OrderCloseTime() == 0)
      {
         stop = OrderOpenPrice();
         bool modify = false;
         if (OrderType() == OP_BUY && OrderStopLoss()  OrderOpenPrice() )
         {
            modify = true;
         }//if (OrderType() == OP_SELL && OrderStopLoss() > OrderOpenPrice() )
         
         if (modify)
         {
            result = OrderModify(MaxTradesTicketNo, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
         }//if (modify)
         
      
      }//if (OrderSelect(MaxTradesTicketNo, SELECT_BY_TICKET) && OrderCloseTime() == 0)
      
   }//if (OpenTrades == MaxTrades)
}//void CaterpillarTrailingStop()
void LookForCatTradingOpportunities()
{
   RefreshRates();
   double take, stop, price;
   int type;
   bool SendTrade;
   double spread = MarketInfo(Symbol(), MODE_SPREAD) * Point;
   //Ensure a minimum gap in between trades
   double pipsgap = (OnePip * Point);
   if (OpenTrades > 0) pipsgap*= MinPipsBetweenCandles;
   
   double SendLots = Lot;
   //Check filters
   if (!IsTradingAllowed() ) return;
   
   RefreshRates();
   //Long
   double target;
   if (TradeLong)
   {      
      target = ObjectGet(buyline, OBJPROP_PRICE1);
      if (Bid > target)
      {
         //if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         //stop = NormalizeDouble(Low[1] - spread - (OnePip * Point), Digits);
         //stop = NormalizeDouble(iLow(NULL, CatTimeFrame, 1) - spread - (OnePip * Point), Digits);
         type = OP_BUY;
         price = Ask;
         SendTrade = true;
      }//if (Bid > target) return;
         
   }//if (TradeLong)
   
   
   //Short
   if (TradeShort)
   {
      target = ObjectGet(sellline, OBJPROP_PRICE1);
      if (Bid  1) MoveCaterpillarStopToBreakeven();//Move the stop of the previously opened trade to be
      if (OpenTrades > 2) CaterpillarTrailingStop(OpenTrades - 1);//All trades from OpenTrades - 2 should move their stops 1 candle to the right
      
      
      //Redraw the trade line
      pipsgap = (OnePip * Point);
      if (OpenTrades > 0) pipsgap*= MinPipsBetweenCandles;
      
      if (type == OP_BUY)
      {
         ObjectDelete(buyline);
         target = NormalizeDouble(price + pipsgap + spread, Digits);
         ObjectCreate(buyline,OBJ_HLINE,0,TimeCurrent(), target);
         ObjectSet(buyline,OBJPROP_COLOR,BuyLineColour);
         ObjectSet(buyline,OBJPROP_STYLE,STYLE_SOLID);  
      }//if (type == OP_BUY)
      
      if (type == OP_SELL)
      {
         ObjectDelete(sellline);
         target = NormalizeDouble(price - pipsgap - spread, Digits);
         ObjectCreate(sellline,OBJ_HLINE,0,TimeCurrent(), target);
         ObjectSet(sellline,OBJPROP_COLOR,SellLineColour);
         ObjectSet(sellline,OBJPROP_STYLE,STYLE_SOLID);         
      }//if (type == OP_SELL)
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
      
   }//if (!result)
   
   
}//void LookForCatTradingOpportunities()
void StartCaterpillar()
{
   //This function is the equivalent of start() in the independent Caterpillar EA. Please read BB's user guide
   //for details of how Cat works.
   
   static bool OldTradeOpen;
   static int OldH1Bars;
   //Delete orphan Caterpillar gv's
   if (OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      OldH1Bars = iBars(NULL, PERIOD_H1);
      if (GlobalVariablesTotal() > 0) DeleteOrphanGlobals();
   }//if (OldH1Bars != iBars(NULL, PERIOD_H1) )
   
   
   //Trading
   if (OpenTrades  0) pipsgap*= MinPipsBetweenCandles;
      double target;
      target = ObjectGet(buyline, OBJPROP_PRICE1);
      //if (TradeLong && NormalizeDouble(High[1] + pipsgap, Digits) > target)
      if (trend == up && TradeLong && NormalizeDouble(iHigh(NULL, CatTimeFrame, 1) + pipsgap, Digits) > target)
      {
         ObjectDelete(buyline);
         //target = NormalizeDouble(High[1] + pipsgap, Digits);
         target = NormalizeDouble(iHigh(NULL, CatTimeFrame, 1) + pipsgap, Digits);
         ObjectCreate(buyline,OBJ_HLINE,0,TimeCurrent(), target);
         ObjectSet(buyline,OBJPROP_COLOR,BuyLineColour);
         ObjectSet(buyline,OBJPROP_STYLE,STYLE_SOLID);               
         if (OpenTrades > 1) CaterpillarTrailingStop(OpenTrades);
      }//if (TradeLong)
   
      target = ObjectGet(sellline, OBJPROP_PRICE1);
      if (trend == down && TradeShort && NormalizeDouble(iLow(NULL, CatTimeFrame, 1) - pipsgap, Digits)  1) CaterpillarTrailingStop(OpenTrades);
      }//if (TradeShort && ObjectFind(sellline) == -1)
   }//if (OldCatBars != iBars(NULL, CatTimeFrame))
   
   ///////////////////////////////////////////////////////////////////////////////////////////////      
}//End void StartCaterpillar()
//END Caterp[illar module
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
datetime hhmm_to_time(double hhmm)
{
  return (StrToTime(DoubleToStr(MathFloor(hhmm),0)+":"+DoubleToStr((hhmm-MathFloor(hhmm))*100,0)) );
}//End datetime hhmm_to_time(double hhmm)
////////////////////////////////////////////////////////////////////////////////////////////////
//Hanover module
void SetUpArrays()
{
   //Sets up all the arrays required by this program
   int cc;
   int Index = 0;//For searching InputString
   int LastIndex = 0;//Points the the most recent Index
   
   //TimeFrames
   InputString = TimeFrames;
   CleanUpInputString();
   TimeFrames = InputString;
   NoOfTimeFrames = CalculateParamsPassed();
   string NewArray2 = ArrayResize(Tf, NoOfTimeFrames);
   
   Index = 0;//For searching InputString
   LastIndex = 0;//Points the the most recent Index
   for (cc = 0; cc  -1)
      {
         Tf[cc] = StringSubstr(InputString, LastIndex,Index-LastIndex);
         Tf[cc] = StringTrimLeft(Tf[cc]);
         Tf[cc] = StringTrimRight(Tf[cc]);
         LastIndex = Index+1;
      }//if (Index > -1)      
   }//for (cc = 0; cc  -1)
   {
      Index = StringFind(InputString, ",",LastIndex);
      if (Index > -1)
      {
         NoOfParams++;
         LastIndex = Index+1;            
      }//if (Index > -1)
   }//while(int cc > -1)
      
  return(NoOfParams);
}//int CalculateParamsPassed()
//+------------------------------------------------------------------+
string StringRight(string str, int n=1)
//+------------------------------------------------------------------+
// Returns the rightmost N characters of STR, if N is positive
// Usage:    string x=StringRight("ABCDEFG",2)  returns x = "FG"
//
// Returns all but the leftmost N characters of STR, if N is negative
// Usage:    string x=StringRight("ABCDEFG",-2)  returns x = "CDEFG"
{
  if (n > 0)  return(StringSubstr(str,StringLen(str)-n,n));
  if (n =0)  
      outstr = outstr + StringSubstr(upper,t1,1);
    else
      outstr = outstr + StringSubstr(str,i,1);
  }
  return(outstr);
}  
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
string StringTrim(string str)
//+------------------------------------------------------------------+
// Removes all spaces (leading, traing embedded) from a string
// Usage:    string x=StringUpper("The Quick Brown Fox")  returns x = "TheQuickBrownFox"
{
  string outstr = "";
  for(int i=0; i= StringLen(str)-1)   break;
    z1 = z2;
  }
  return(StringFindCount(str,delim));
}
//+------------------------------------------------------------------+
int ArrayLookupString(string str, string a[])   {
//+------------------------------------------------------------------+
for (int i=0; i= "0" && s = 0)  dp++;
      if (dp > 0)
        num = num + StrToInteger(s) / MathPow(10,dp);
      else
        num = num * 10 + StrToInteger(s);
    }
  }
  return(num*sgn);
}
int LoadRSvalues()  
{
  //This code courtesy of hanover. Many thanks David. You are a star.
  
  //Ccy[] holds the individual currency symbol
  //Tf[] holds the time frames
  //God knows where we go from here
  
  // Initialize array......
  for (i=0; i=99)   continue;                                    // max of 99 data points only
           for (i=0; i StrongVal[j])
            {
               StrongestCcy[j] = ccy;
               StrongVal[j] = RSvalue[i, DatapointTf, 0];
               PrevStrongVal[j] = RSvalue[i, DatapointTf, SlopeConfirmationCandles];
            }//if (RSvalue[i, j, k] > StrongVal[cc])
            
            //Find the seakest datapoint on the current currency and timeframe
            if (RSvalue[i, DatapointTf, 0]  StrongVal[cc])            
         }//for (k = 0; k  0)
      {
         double prevstrength1 = ReadStrength(Ccy1, Tf[cc], SlopeConfirmationCandles);
         double prevstrength2 = ReadStrength(Ccy2, Tf[cc], SlopeConfirmationCandles);   
      }//if (SlopeCandles[cc] > 0)   
     
      //EA is looking to buy.
      if (type == OP_BUY)
      {
         //First currency must be the strongest
         if (strength1  0 && prevstrength1 >= prevstrength2) return(false);
         
         //Threshold. First currency must be above StrongThreshold. Second currency must be below WeakThreshopld
         if (StrongThreshold > 0 && WeakThreshold > 0)
         {
            if (strength1  WeakThreshold) return(false);
         }//if (StrongThreshold > 0 && WeakThreshold > 0)
         
      }//if (type == OP_BUY)
      
      //EA is looking to sell, so first currency must be the weakest
      if (type == OP_SELL && strength1 >= strength2) return(false);
      
      //EA is looking to sell.
      if (type == OP_SELL)
      {
         //First currency must be the weakest
         if (strength1 >= strength2) return(false);
         //Slope must be falling
         if (SlopeConfirmationCandles > 0 && prevstrength1  0 && WeakThreshold > 0)
         {
            if (strength1 > WeakThreshold || strength2  0 && WeakThreshold > 0)
      }//if (type == OP_BUY)
      
      
         
         
         
   }//for (int cc = 0; cc  0) TradeManagementModule();
      LookForTradeClosure();
   }//if (TradeExists)
   ///////////////////////////////////////////////////////////////////////////////////////////////
   
   //Recovery
   if (UseRecovery)
   {
      if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
      
      /*
      I have moved this to SendSingleTrade.
      if (RecoveryInProgress)
      {
         if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
         RecoveryModule();
      }//if (RecoveryInProgress)
      */
      
      //Replace accidentally deleted be line
      if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
      {
         RecoveryModule();      
      }//if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
      
      //Recovery trailing sl
      if (RecoveryInProgress && UseRecoveryTrailingStop)
      {
         RecoveryCandlesticktrailingStop();     
      }//if (RecoveryInProgress && UseRecoveryTrailingStop)
      
      
   }//if (UseRecovery)
   //Replace deleted reentry line
   if (RecoveryInProgress && ObjectFind(reentrylinename) == -1)
   {
      ReplaceReEntryLine();
   }//if (RecoveryInProgress && ObjectFind(reentrylinename) == -1)
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////////////////
   
   //Post trade closure Sleep
   if (!TradeExists && ThereWasATradeOpen)
   {
      ThereWasATradeOpen = false;
      Sleep(1000);//1 second: 1000 * 60 = 1 minute: 1000 * 60 * 60 = 1 hour
   }//if (!TradeExists && ThereWasATradeOpen)
   

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading times
   bool TradeTimeOk = CheckTradingTimes();
   if (!TradeTimeOk)
   {
      Comment("Outside trading hours\nstart_hourm-end_hourm: ", start_hourm, "-",end_hourm, "\nstart_houre-end_houre: ", start_houre, "-",end_houre);
      return;
   }//if (hour  0)
   {
      if(AccountMargin() > (AccountFreeMargin()/100))
      {
         MarginMessage = "There is insufficient margin to allow trading. You might want to turn off the UseScoobsMarginCheck input.";
         DisplayUserFeedback();
         return;
      }//if(AccountMargin() > (AccountFreeMargin()/100))
      
   }//if (UseScoobsMarginCheck)
   if (UseForexKiwi && AccountMargin() > 0)
   {
      
      double ml = NormalizeDouble(AccountEquity() / AccountMargin() * 100, 2);
      if (ml  0)
   ///////////////////////////////////////////////////////////////////////////////////////////////         
   //Trading
   if (UseCaterpillar && !StopTrading) StartCaterpillar();
      
   if (TicketNo == -1 && !StopTrading)
   {
      //Trend detection      
      if (UseTrendDetection) TrendDetectionModule();
      if (!UseTrendDetection && RisingTrend) trend = up;
      if (!UseTrendDetection && FallingTrend) trend = down;
      
   
      LookForTradingOpportunities();
   }//if (TicketNo == -1)
   ///////////////////////////////////////////////////////////////////////////////////////////////      
   DisplayUserFeedback();
   
//----
   return(0);
}
//+------------------------------------------------------------------+
求教几个问题:
1.这个EA开仓时间是否有限制?
2.这个EA每次开仓几手?
3.如何加上警报?
非常感谢!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
收藏
收藏0
转播
转播
分享
分享
分享
淘帖0

精彩评论13

跳转到指定楼层
沙发
mqlbcg 发表于 2018-1-11 01:27:09 | 只看该作者
赚了金币再说
板凳
 楼主| tianyaruolin 发表于 2018-1-11 03:00:32 | 只看该作者
自顶希望老师看到
地板
億秒 发表于 2018-1-11 03:14:06 | 只看该作者
这么长的EA,建议牛版收费吧!



5#
 楼主| tianyaruolin 发表于 2018-1-11 03:24:20 | 只看该作者
呵呵,虽然长,但是问题简单啊。。
6#
 楼主| tianyaruolin 发表于 2018-1-11 03:50:17 | 只看该作者
顶。。。。。。。。。。
7#
chunshuo 发表于 2018-1-11 04:45:19 | 只看该作者
指标这个太长了
8#
stjy 发表于 2018-1-11 05:11:37 | 只看该作者





好东西,谢谢分享哦

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
9#
ivan29 发表于 2018-1-11 06:50:46 | 只看该作者


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
10#
大巧若拙 发表于 2018-1-11 07:00:50 | 只看该作者
z赚点金币吧。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题
阅读排行更多+

Powered by 顺水鱼MT4外汇EA网! X3.2© 2001-2017 顺水MT4外汇EA公司.( 陕ICP备17014341号-1