源码如下:
//+-------------------------------------------------------------------+
//| 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 "
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",
"
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.如何加上警报?
非常感谢!!
|