标题: 求助!老师看看这个EA怎么回事?谢谢 [打印本页] 作者: tianyaruolin 时间: 2018-1-11 00:52 标题: 求助!老师看看这个EA怎么回事?谢谢 [attach]13465[/attach]
源码如下:
//+-------------------------------------------------------------------+
//| 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 "
[attach]13466[/attach]
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",
"
[attach]13466[/attach]
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);
*/
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)
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) )
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 (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 (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)
}//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
}//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)
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)
}//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;
}//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);
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);
//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
}//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)
//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;
//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.
///////////////////////////////////////////////////////////////////////////////////////////////
}//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
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)
if (OrderOpenPrice()-OrderTakeProfit()>(TP+1)*Point ||OrderOpenPrice()-OrderTakeProfit() ",ErrorDescription(GetLastError()));
}
}
}
}
}
//-------------------------------------------------------------------------
if (USE_ATR) HedgingLevel=iATR(NULL,PERIOD_D1,14,0)*PercentATR/100;
else HedgingLevel=HedgingLevel*Point;
//Check all manual order, if no it's countpart hedging order, then creat one
for (i=0;i0) Alert(Ticket,"的对冲单:",Tic," 生成 SELL STOP:",NormalizeDouble(OpenPrice-HedgingLevel,Digits)," ",Lots,"Lots");
}
if (Type==OP_SELL)
{
Tic=OrderSend(Symbol(),OP_BUYSTOP,Lots,NormalizeDouble(OpenPrice+HedgingLevel,Digits),0,0,0,"Hedging "+DoubleToStr(Ticket,0),Ticket,0,Red);
if( Tic>0) Alert(Ticket,"的对冲单:",Tic," 生成 BUY STOP:",NormalizeDouble(OpenPrice+HedgingLevel,Digits)," ",Lots,"Lots");
}
}
}
}
//Check all hedge order, if no it's countpart manual order, then delete the hedge Order
for (i=0;i1/*exclde type OP_BUY && OP_SELL */ ) OrderDelete(Ticket);//no it's countpart manual order exist, delete this hedge OrderClose
}
}
//v2.2 revise manul order TP=0 if Hedge order have created.
for (i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS)==false) continue;
if(Symbol()==OrderSymbol() && OrderMagicNumber()!=0 && OrderType()<2) //Actived HedgeOrder founded!
{
Ticket=OrderMagicNumber();
if( OrderSelect(Ticket,SELECT_BY_TICKET)==false) break;
if( OrderTakeProfit()!=0)
if(OrderModify(Ticket,OrderOpenPrice(),0,0,0,0)) Alert(Ticket,"对冲单已生成, 系统将止盈改为零,需要手动开锁!");
}
}