I've been recently intrigued with the thread called "Central Banks and Big Players". The basic strategy is to buy or sell in the direction of the first 2 pip movement in price at the London and New York open. The author of the thread uses a very small SL (2 pips) ,TP 140 and does very well with the strategy. The EA (see code below) developed for this strategy works nicely except for one thing. As is it will move your stop towards BE pip by pip (until BE is reached)as price moves in your favor. The problem I have is , even when EA has set my stop to BE, I still lose the commission I have to pay on the trade . Could someone adjust the code below(in bold print) the changes necessary to have the EA bring the stop to BE+ (x) number of pips to cover the commission cost. thank you//+------------------------------------------------------------------+
//| CBBP_EA_v2-0.mq4 |
//| Zen Leow |
//| |
//+------------------------------------------------------------------+
#property copyright "Zen Leow"
#property link ""
#include <stdlib.mqh>
#include <stderror.mqh>
#define PRIMARY_ORDER 1
#define SECONDARY_ORDER 2
extern int EA_MAGIC_NUM = 3947947;
extern bool IsECN = true;
extern bool CheckHourOfAttach = true;
extern string Session1 = "London Session";
extern int SessionOpenHour1 = 8;
extern string Session2 = "New York Session";
extern int SessionOpenHour2 = 13;
extern int GraceMinutes = 5;
extern bool Show_Comments = true;
extern double UserDefinedSpread = 0;
extern int Slippage = 3;
extern double Pip_Distance = 2;
extern int TakeProfit = 140;
extern int StopLoss = 5;
extern bool UseJumpingStop = false;
extern int TrailingStop = 0;
extern bool Add_Spread_To_StopLoss = false;
extern bool Use_Spread_Filtering = true;
extern double Spread_Filter = 1.0;
extern bool MoneyManagement = true;
extern double RiskPercent = 0.25;
extern bool UseEquity=false;
extern bool Use_BE=true;
extern double BreakEven_Pips=5.0;
extern double FixedLots = 0.1;
extern double MaxLots = 15.0;
extern double MinLots = 0.01;
extern int LotsDecimalAllowed = 2;
string msg = "";
double CustomSpread = 0;
int PipFactor = 1;
bool StartupStatusOK = true;
int the_StopLoss = 0;
bool TradeTheSession = true;
bool ProblemLogged = false;
int todayOfYear = 0;
bool SessionIsOn = false;
double theSessionOpenPrice;
string latestSession;
int currentSessionHour;
bool SessionOpenPriceWritten = false;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
int currentHour = TimeHour(TimeCurrent());
if ((currentHour == SessionOpenHour1 || currentHour == SessionOpenHour2) && CheckHourOfAttach)
{
Alert ("IMPT: You should not attach this EA during "+Session1+" Open hour or the "+Session2+" Open hour");
StartupStatusOK = false;
}
if (Period() > PERIOD_H1)
{
Alert("This EA can only be attached to Charts with timeframe LESS THAN 1 hour");
StartupStatusOK = false;
}
if (MinLots < MarketInfo(Symbol(),MODE_MINLOT))
{
Alert("Invalid MinLots: "+MinLots+" | Try: "+MarketInfo(Symbol(),MODE_MINLOT));
StartupStatusOK = false;
}
if (MaxLots > MarketInfo(Symbol(),MODE_MAXLOT))
{
Alert("Invalid MaxLots: "+MaxLots+" | Try: "+MarketInfo(Symbol(),MODE_MAXLOT));
StartupStatusOK = false;
}
if (SessionOpenHour1 < 0 || SessionOpenHour1 > 23)
{
Alert("Invalid Opening Hour given for "+Session1+": "+SessionOpenHour1);
StartupStatusOK = false;
}
if (SessionOpenHour2 < 0 || SessionOpenHour2 > 23)
{
Alert("Invalid Opening Hour given for "+Session2+": "+SessionOpenHour2);
StartupStatusOK = false;
}
if (MoneyManagement && (RiskPercent <= 0 || RiskPercent > 100))
{
Alert("Invalid RiskPercent given: "+RiskPercent+"%");
StartupStatusOK = false;
}
if (StartupStatusOK)
{
Alert("CBBP EA loaded on "+Symbol()+" with valid inputs");
}
WriteToLogFile("Start Of CBBP EA");
GetSpread();
todayOfYear = DayOfYear();
// Cater for fractional pips
if (Digits == 3 || Digits == 5)
{
PipFactor = 10;
}
Slippage = Slippage * PipFactor;
if (Show_Comments)
{
WriteComment();
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Trade Management logic functions |
//+------------------------------------------------------------------+
bool TradeNotPlacedYet()
{
int total = OrdersTotal();
if (total > 0)
{
for(int cnt=0;cnt<total;cnt++)
{
if(OrderSelect(cnt,SELECT_BY_POS))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
{
SessionIsOn = false;
return (false);
}
}
}
}
// in case trade has already opened and closed for this session
int histotal = OrdersHistoryTotal();
if (histotal > 0)
{
for(cnt=0;cnt<histotal;cnt++)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
{
datetime LatestSessionStart = iTime(NULL,PERIOD_H1,0);
datetime LatestSessionGrace = LatestSessionStart + (GraceMinutes * 60);
datetime CurrentOrderOpenTime = OrderOpenTime();
if (CurrentOrderOpenTime >= LatestSessionStart && CurrentOrderOpenTime <= LatestSessionGrace)
{
SessionIsOn = false;
return (false);
}
}
}
}
}
return (true);
}
bool Should_Buy(int SessionOpenIndex)
{
if (SessionOpenIndex == -1)
{
return (false);
}
theSessionOpenPrice = Open[SessionOpenIndex];
double theSessionCurrentPrice = Close[0];
if (theSessionCurrentPrice > theSessionOpenPrice)
{
double lookoutPrice = theSessionOpenPrice + (Pip_Distance * Point * PipFactor);
if (theSessionCurrentPrice >= lookoutPrice)
{
if (Spread_Still_In_Range())
{
return (true);
}
else
{
if (!ProblemLogged)
{
string logmsg = "The spread is "+DoubleToStr(CustomSpread,1)+" when price moved "+DoubleToStr(Pip_Distance,1)+" from this Session Open Price. No Trade for this session";
WriteToLogFile(logmsg);
ProblemLogged = true;
TradeTheSession = false;
}
}
}
}
return (false);
}
bool Should_Sell(int SessionOpenIndex)
{
if (SessionOpenIndex == -1)
{
return (false);
}
theSessionOpenPrice = Open[SessionOpenIndex];
double theSessionCurrentPrice = Close[0];
if (theSessionCurrentPrice < theSessionOpenPrice)
{
double lookoutPrice = theSessionOpenPrice - (Pip_Distance * Point * PipFactor);
if (theSessionCurrentPrice <= lookoutPrice)
{
if (Spread_Still_In_Range())
{
return (true);
}
else
{
if (!ProblemLogged)
{
string logmsg = "The spread is "+DoubleToStr(CustomSpread,1)+" when price moved "+DoubleToStr(Pip_Distance,1)+" from this Session Open Price. No Trade for this session";
WriteToLogFile(logmsg);
ProblemLogged = true;
TradeTheSession = false;
}
}
}
}
return (false);
}
double PositionSizeToOpen(int StopLossPips)
{
double PositionSize;
double riskDollars;
if (MoneyManagement && StopLossPips > 0)
{
if (UseEquity)
{
riskDollars = (AccountEquity()/100) * RiskPercent;
}
else
{
riskDollars = (AccountBalance()/100) * RiskPercent;
}
PositionSize = (riskDollars / StopLossPips) / (MarketInfo(Symbol(),MODE_TICKVALUE) * PipFactor);
}
if (MoneyManagement && StopLossPips <= 0)
{
if (UseEquity)
{
PositionSize = ((AccountEquity()/100) * RiskPercent) / (MarketInfo(Symbol(),MODE_LOTSIZE) / AccountLeverage());
}
else
{
PositionSize = ((AccountBalance()/100) * RiskPercent) / (MarketInfo(Symbol(),MODE_LOTSIZE) / AccountLeverage());
}
}
if (!MoneyManagement)
{
PositionSize = FixedLots;
}
if (PositionSize < MinLots)
{
PositionSize = MinLots;
}
if (PositionSize > MaxLots)
{
PositionSize = MaxLots;
}
PositionSize = NormalizeDouble(PositionSize,LotsDecimalAllowed);
return (PositionSize);
}
bool SendOrders (int BuyOrSell, double LotSize, double PriceToOpen, double Slippage, double SL_Price, double TP_Price, string comments, datetime ExpirationTime)
{
int ticket, errorType;
if (BuyOrSell == OP_BUY)
{
if (IsECN)
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,0,0,comments,EA_MAGIC_NUM,ExpirationTime,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("BUY order opened : ",OrderOpenPrice());
msg = ticket + ": Buy position opened at "+DoubleToStr(OrderOpenPrice(),Digits);
WriteToLogFile(msg);
if (OrderModify(ticket,OrderOpenPrice(),SL_Price,TP_Price,0))
{
Print("Stop Loss and Take Profit added");
msg = ticket + ": Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" added";
WriteToLogFile(msg);
}
else
{
errorType = GetLastError();
Print("ERROR adding Stop Loss and Take Profit - ",ErrorDescription(errorType));
msg = ticket + ":ERROR adding Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" - "+ErrorDescription(errorType);
WriteToLogFile(msg);
}
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening BUY order : ", ErrorDescription(errorType));
msg = "CANNOT open BUY position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
else
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("BUY order opened : ",OrderOpenPrice());
msg = ticket + ": Buy position opened. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening BUY order : ", ErrorDescription(errorType));
msg = "CANNOT open BUY position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
}
if (BuyOrSell == OP_SELL)
{
if (IsECN)
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Sell Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Red");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,0,0,comments,EA_MAGIC_NUM,ExpirationTime,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("SELL order opened : ",OrderOpenPrice());
msg = ticket + ": Sell position opened at "+DoubleToStr(OrderOpenPrice(),Digits);
WriteToLogFile(msg);
if (OrderModify(ticket,OrderOpenPrice(),SL_Price,TP_Price,0))
{
Print("Stop Loss and Take Profit added");
msg = ticket + ": Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" added";
WriteToLogFile(msg);
}
else
{
errorType = GetLastError();
Print("ERROR adding Stop Loss and Take Profit - ",ErrorDescription(errorType));
msg = ticket + ":ERROR adding Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" - "+ErrorDescription(errorType);
WriteToLogFile(msg);
}
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening SELL order : ", ErrorDescription(errorType));
msg = "CANNOT open SELL position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
else
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Sell Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Red");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("Sell order opened : ",OrderOpenPrice());
msg = ticket + ": Sell position opened. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening SELL order : ", ErrorDescription(errorType));
msg = "CANNOT open SELL position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
}
}
bool Spread_Still_In_Range()
{
if (Use_Spread_Filtering && CustomSpread > Spread_Filter)
{
return (false);
}
return (true);
}
void OpenBuyOrder()
{
RefreshRates();
double PriceToOpen, TakeProfitPrice, StopLossPrice, PositionSize;
PriceToOpen = Ask;
PriceToOpen = NormalizeDouble(PriceToOpen,Digits);
PositionSize = PositionSizeToOpen(the_StopLoss);
if (TakeProfit == 0)
{
TakeProfitPrice = 0;
}
else
{
TakeProfitPrice = PriceToOpen + (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
}
if (the_StopLoss == 0)
{
StopLossPrice = 0;
}
else
{
StopLossPrice = PriceToOpen - (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
}
if (PositionSize < MinLots)
{
PositionSize = MinLots;
}
if (PositionSize > MaxLots)
{
PositionSize = MaxLots;
}
PositionSize = NormalizeDouble(PositionSize,LotsDecimalAllowed);
string DateNow = TimeDay(TimeCurrent())+"-"+TimeMonth(TimeCurrent())+"-"+TimeYear(TimeCurrent());
SendOrders(OP_BUY, PositionSize, PriceToOpen, Slippage, StopLossPrice, TakeProfitPrice, "CBBP_"+DateNow, 0);
}
void OpenSellOrder()
{
RefreshRates();
double PriceToOpen, TakeProfitPrice, StopLossPrice, PositionSize;
PriceToOpen = Bid;
PriceToOpen = NormalizeDouble(PriceToOpen,Digits);
PositionSize = PositionSizeToOpen(the_StopLoss);
if (TakeProfit == 0)
{
TakeProfitPrice = 0;
}
else
{
TakeProfitPrice = PriceToOpen - (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
}
if (the_StopLoss == 0)
{
StopLossPrice = 0;
}
else
{
StopLossPrice = PriceToOpen + (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
}
if (PositionSize < MinLots)
{
PositionSize = MinLots;
}
if (PositionSize > MaxLots)
{
PositionSize = MaxLots;
}
PositionSize = NormalizeDouble(PositionSize,LotsDecimalAllowed);
string DateNow = TimeDay(TimeCurrent())+"-"+TimeMonth(TimeCurrent())+"-"+TimeYear(TimeCurrent());
SendOrders(OP_SELL, PositionSize, PriceToOpen, Slippage, StopLossPrice, TakeProfitPrice, DateNow, 0);
}
void ManageTrades()
{
double TrailLevel = PipFactor*Point*TrailingStop;
TrailLevel = NormalizeDouble(TrailLevel,Digits);
double BE_Level = PipFactor*Point*BreakEven_Pips;
BE_Level = NormalizeDouble(BE_Level,Digits);
double TakeProfitPrice, StopLossPrice;
string logmsg = "";
int ticket, errorType;
double closeNOWprice = 0;
int total = OrdersTotal();
if (total > 0)
{
// must go backwards
for(int cnt=total-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
{
if (OrderType() == OP_BUY)
{
// In case Stop Loss and TakeProfit was not added. Let's do something about it here...
if (OrderStopLoss() == 0 && the_StopLoss != 0)
{
ticket = OrderTicket();
// Close the trade immediately if price has already moved broken the stop loss level
if (OrderOpenPrice()-Bid >= PipFactor*Point*the_StopLoss)
{
closeNOWprice = NormalizeDouble(Bid,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Red))
{
Print("Emergency (Stop Loss) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Stop Loss) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Stop Loss) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Stop Loss) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
else
{
// try to place the Stop Loss and Take Profit level now
StopLossPrice = OrderOpenPrice() - (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
TakeProfitPrice = OrderOpenPrice() + (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
if (OrderModify(ticket,OrderOpenPrice(),StopLossPrice,TakeProfitPrice,0))
{
Print("Stop Loss and Take Profit of order: ",ticket," added successfully");
logmsg = ticket+": Stop Loss and Take Profit added successfully!";
WriteToLogFile(logmsg);
}
else
{
errorType = GetLastError();
Print("ERROR! Adding Stop Loss and Take Profit of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Adding Stop Loss and Take Profit of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Similar to the above except this tackles the takeprofit level breech scenario
if (OrderTakeProfit() == 0 && TakeProfit != 0)
{
// Close the trade immediately if price has already moved broken the stop loss level
if (Bid-OrderOpenPrice() >= PipFactor*Point*TakeProfit)
{
ticket = OrderTicket();
closeNOWprice = NormalizeDouble(Bid,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Blue))
{
Print("Emergency (Take Profit) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Take Profit) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Take Profit) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Take Profit) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Check for Breakeven.
if (Use_BE)
{
if(Bid-OrderStopLoss() > PipFactor*Point*BreakEven_Pips)
{
if (OrderStopLoss() < OrderOpenPrice())
{
StopLossPrice = Bid - BE_Level;
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
if (StopLossPrice > OrderOpenPrice())
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green))
{
logmsg = "Buy Order "+OrderTicket()+" SL reached breakeven level.";
WriteToLogFile(logmsg);
}
}
else
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green))
{
logmsg = "Buy Order "+OrderTicket()+" SL moving towards breakeven level.";
WriteToLogFile(logmsg);
}
}
}
}
}
// Check for Floating Stop
if (!UseJumpingStop && (TrailingStop != 0))
{
if((Bid-OrderOpenPrice()) > TrailLevel && ((Bid-OrderOpenPrice()) >= BE_Level || OrderStopLoss() >= OrderOpenPrice()))
{
if(OrderStopLoss() < Bid-TrailLevel)
{
StopLossPrice = NormalizeDouble(Bid-TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green);
}
}
}
// Check for Jumping Stop
if (UseJumpingStop && (TrailingStop != 0))
{
if((Bid-OrderStopLoss()>(TrailLevel*2)) && ((Bid-OrderOpenPrice()) >= BE_Level || OrderStopLoss() >= OrderOpenPrice()))
{
if ((OrderStopLoss()+TrailLevel) < OrderTakeProfit() || OrderTakeProfit() == 0) // Stop loss level cannot be higher than take profit level
{
StopLossPrice = NormalizeDouble(OrderStopLoss()+TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green);
}
}
}
}
if (OrderType() == OP_SELL)
{
// In case Stop Loss and TakeProfit was not added. Let's do something about it here...
if (OrderStopLoss() == 0 && the_StopLoss != 0)
{
ticket = OrderTicket();
// Close the trade immediately if price has already moved broken the stop loss level
if (Ask - OrderOpenPrice() >= PipFactor*Point*the_StopLoss)
{
closeNOWprice = NormalizeDouble(Ask,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Red))
{
Print("Emergency (Stop Loss) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Stop Loss) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Stop Loss) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Stop Loss) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
else
{
// try to place the Stop Loss and Take Profit level now
StopLossPrice = OrderOpenPrice() + (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
TakeProfitPrice = OrderOpenPrice() - (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
if (OrderModify(ticket,OrderOpenPrice(),StopLossPrice,TakeProfitPrice,0))
{
Print("Stop Loss and Take Profit of order: ",ticket," added successfully");
logmsg = ticket+": Stop Loss and Take Profit added successfully!";
WriteToLogFile(logmsg);
}
else
{
errorType = GetLastError();
Print("ERROR! Adding Stop Loss and Take Profit of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Adding Stop Loss and Take Profit of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Similar to the above except this tackles the takeprofit level breech scenario
if (OrderTakeProfit() == 0 && TakeProfit != 0)
{
// Close the trade immediately if price has already moved broken the stop loss level
if (OrderOpenPrice()-Ask >= PipFactor*Point*TakeProfit)
{
ticket = OrderTicket();
closeNOWprice = NormalizeDouble(Ask,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Blue))
{
Print("Emergency (Take Profit) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Take Profit) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Take Profit) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Take Profit) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Check for Breakeven
if (Use_BE)
{
if(OrderStopLoss()-Ask > PipFactor*Point*BreakEven_Pips)
{
if (OrderStopLoss() > OrderOpenPrice())
{
StopLossPrice = Ask + BE_Level;
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
if (StopLossPrice < OrderOpenPrice())
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green))
{
logmsg = "Sell Order "+OrderTicket()+" SL reached breakeven level.";
WriteToLogFile(logmsg);
}
}
else
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green))
{
logmsg = "Sell Order "+OrderTicket()+" SL moving towards breakeven level.";
WriteToLogFile(logmsg);
}
}
}
}
}
// Check for Floating Stop
if (!UseJumpingStop && (TrailingStop != 0))
{
if((OrderOpenPrice()-Ask) > TrailLevel && ((OrderOpenPrice()-Ask) >= BE_Level || OrderStopLoss() <= OrderOpenPrice()))
{
if(OrderStopLoss() > Ask+TrailLevel)
{
StopLossPrice = NormalizeDouble(Ask+TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Red);
}
}
}
// Check for Jumping Stop
if (UseJumpingStop && (TrailingStop != 0))
{
// only activate when position is in profit by stoploss amt.
if(((OrderStopLoss()-Ask)>(TrailLevel*2)) && ((OrderOpenPrice()-Ask) >= BE_Level || OrderStopLoss() <= OrderOpenPrice()))
{
if ((OrderStopLoss()-TrailLevel) > OrderTakeProfit() || OrderTakeProfit() == 0) // Stop loss level cannot be less than take profit level
{
StopLossPrice = NormalizeDouble(OrderStopLoss()-TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Red);
}
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Miscellaneous functions |
//+------------------------------------------------------------------+
void GetSpread()
{
if (UserDefinedSpread <= 0)
{
CustomSpread = (MarketInfo(Symbol(),MODE_SPREAD)) / PipFactor;
}
else
{
CustomSpread = UserDefinedSpread;
}
// Should we add the spread into the StopLoss?
the_StopLoss = StopLoss;
if (StopLoss > 0)
{
if (Add_Spread_To_StopLoss)
{
the_StopLoss = StopLoss + CustomSpread;
}
else
{
the_StopLoss = StopLoss;
}
}
}
void WriteComment()
{
msg = "";
int currentHour = TimeHour(Time[0]);
if (SessionOpenHour1 < SessionOpenHour2)
{
if (currentHour < SessionOpenHour2)
{
msg = "EA waiting for "+Session2+" Open";
}
if (currentHour < SessionOpenHour1 || currentHour > SessionOpenHour2)
{
msg = "EA waiting for "+Session1+" Open";
}
}
else
{
if (currentHour < SessionOpenHour1)
{
msg = "EA waiting for "+Session1+" Open";
}
if (currentHour < SessionOpenHour2 || currentHour > SessionOpenHour1)
{
msg = "EA waiting for "+Session2+" Open";
}
}
msg = msg + "\nCurrent Time: "+ currentHour +":"+TimeMinute(TimeCurrent());
if (PipFactor == 10)
{
msg = msg + "\nWorking with Fractional pips";
}
else
{
msg = msg + "\nWorking with Non-Fractional pips";
}
// double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) / PipFactor;
if (MoneyManagement && the_StopLoss > 0)
{
msg = msg + "\nUsing MoneyManagement Feature according to Stop loss";
}
msg = msg + "\nCurrent Spread: "+DoubleToStr(CustomSpread,1)+" pips";
if (Add_Spread_To_StopLoss && the_StopLoss != 0)
{
msg = msg + "\nSpread will be added to your Stop Loss";
}
else
{
msg = msg + "\nSpread will NOT be added to Stop Loss";
}
if (SessionIsOn)
{
msg = msg + "\n\nTime to trade "+latestSession+". Looking for entry...";
msg = msg + "\nSession Open Price: "+DoubleToStr(theSessionOpenPrice,Digits);
msg = msg + "\nCurrent Price: "+DoubleToStr(Close[0],Digits);
}
else
{
msg = msg + "\n"+latestSession+" trading window is closed.";
}
Comment(msg);
}
void WriteToLogFile(string input)
{
string filename = "CBBP-"+Symbol()+"-"+Day()+"-"+Month()+"-"+Year()+".log";
int handle = FileOpen(filename,FILE_READ|FILE_WRITE);
if (handle>1)
{
string prefix = Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds()+" => ";
FileSeek(handle, 0, SEEK_END); // go to end of file
FileWrite(handle, prefix+input);
FileClose(handle);
}
}
// This method is created to spawn a new file for a new day. The first line to be written sometimes don't get written.
// The dummy message used here can act as a buffer so that useful info don't get missed out.
void CreateNewLogFileIfNewDay()
{
if (todayOfYear != DayOfYear())
{
todayOfYear = DayOfYear();
WriteToLogFile("Dummy message");
}
}
bool TimeToTrade()
{
int currentHour = TimeHour(Time[0]);
int currentMinute = TimeMinute(TimeCurrent());
if ((currentHour == SessionOpenHour1 || currentHour == SessionOpenHour2) && currentMinute < GraceMinutes)
{
return (true);
}
return (false);
}
int GetSessionOpenCandle()
{
int SessionOpenCandleIndex = -1;
for (int i=0; i<=GraceMinutes+1; i++)
{
if (TimeHour(Time[i]) == currentSessionHour && TimeMinute(Time[i]) == 0)
{
SessionOpenCandleIndex = i;
break;
}
}
return (SessionOpenCandleIndex);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
if (!StartupStatusOK)
{
Comment("There were errors in your EA inputs. Please recheck them again.");
return (0);
}
CreateNewLogFileIfNewDay();
ManageTrades();
GetSpread();
if (TimeToTrade())
{
currentSessionHour = TimeHour(Time[0]);
if (currentSessionHour == SessionOpenHour1)
{
latestSession = Session1;
}
if (currentSessionHour == SessionOpenHour2)
{
latestSession = Session2;
}
if (TradeNotPlacedYet() && TradeTheSession)
{
int SessionOpenIndex = GetSessionOpenCandle();
SessionIsOn = true;
if (!SessionOpenPriceWritten)
{
string logmsg = latestSession+" open at "+DoubleToStr(Open[SessionOpenIndex],Digits);
Print(logmsg);
WriteToLogFile(logmsg);
SessionOpenPriceWritten = true;
}
if (Should_Buy(SessionOpenIndex) && TradeTheSession)
{
OpenBuyOrder();
TradeTheSession = false;
}
if (Should_Sell(SessionOpenIndex) && TradeTheSession)
{
OpenSellOrder();
TradeTheSession = false;
}
}
else
{
SessionIsOn = false;
}
}
else
{
SessionIsOn = false;
TradeTheSession = true;
ProblemLogged = false;
SessionOpenPriceWritten = false;
}
if (Show_Comments)
{
WriteComment();
}
//----
return(0);
//| CBBP_EA_v2-0.mq4 |
//| Zen Leow |
//| |
//+------------------------------------------------------------------+
#property copyright "Zen Leow"
#property link ""
#include <stdlib.mqh>
#include <stderror.mqh>
#define PRIMARY_ORDER 1
#define SECONDARY_ORDER 2
extern int EA_MAGIC_NUM = 3947947;
extern bool IsECN = true;
extern bool CheckHourOfAttach = true;
extern string Session1 = "London Session";
extern int SessionOpenHour1 = 8;
extern string Session2 = "New York Session";
extern int SessionOpenHour2 = 13;
extern int GraceMinutes = 5;
extern bool Show_Comments = true;
extern double UserDefinedSpread = 0;
extern int Slippage = 3;
extern double Pip_Distance = 2;
extern int TakeProfit = 140;
extern int StopLoss = 5;
extern bool UseJumpingStop = false;
extern int TrailingStop = 0;
extern bool Add_Spread_To_StopLoss = false;
extern bool Use_Spread_Filtering = true;
extern double Spread_Filter = 1.0;
extern bool MoneyManagement = true;
extern double RiskPercent = 0.25;
extern bool UseEquity=false;
extern bool Use_BE=true;
extern double BreakEven_Pips=5.0;
extern double FixedLots = 0.1;
extern double MaxLots = 15.0;
extern double MinLots = 0.01;
extern int LotsDecimalAllowed = 2;
string msg = "";
double CustomSpread = 0;
int PipFactor = 1;
bool StartupStatusOK = true;
int the_StopLoss = 0;
bool TradeTheSession = true;
bool ProblemLogged = false;
int todayOfYear = 0;
bool SessionIsOn = false;
double theSessionOpenPrice;
string latestSession;
int currentSessionHour;
bool SessionOpenPriceWritten = false;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
int currentHour = TimeHour(TimeCurrent());
if ((currentHour == SessionOpenHour1 || currentHour == SessionOpenHour2) && CheckHourOfAttach)
{
Alert ("IMPT: You should not attach this EA during "+Session1+" Open hour or the "+Session2+" Open hour");
StartupStatusOK = false;
}
if (Period() > PERIOD_H1)
{
Alert("This EA can only be attached to Charts with timeframe LESS THAN 1 hour");
StartupStatusOK = false;
}
if (MinLots < MarketInfo(Symbol(),MODE_MINLOT))
{
Alert("Invalid MinLots: "+MinLots+" | Try: "+MarketInfo(Symbol(),MODE_MINLOT));
StartupStatusOK = false;
}
if (MaxLots > MarketInfo(Symbol(),MODE_MAXLOT))
{
Alert("Invalid MaxLots: "+MaxLots+" | Try: "+MarketInfo(Symbol(),MODE_MAXLOT));
StartupStatusOK = false;
}
if (SessionOpenHour1 < 0 || SessionOpenHour1 > 23)
{
Alert("Invalid Opening Hour given for "+Session1+": "+SessionOpenHour1);
StartupStatusOK = false;
}
if (SessionOpenHour2 < 0 || SessionOpenHour2 > 23)
{
Alert("Invalid Opening Hour given for "+Session2+": "+SessionOpenHour2);
StartupStatusOK = false;
}
if (MoneyManagement && (RiskPercent <= 0 || RiskPercent > 100))
{
Alert("Invalid RiskPercent given: "+RiskPercent+"%");
StartupStatusOK = false;
}
if (StartupStatusOK)
{
Alert("CBBP EA loaded on "+Symbol()+" with valid inputs");
}
WriteToLogFile("Start Of CBBP EA");
GetSpread();
todayOfYear = DayOfYear();
// Cater for fractional pips
if (Digits == 3 || Digits == 5)
{
PipFactor = 10;
}
Slippage = Slippage * PipFactor;
if (Show_Comments)
{
WriteComment();
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Trade Management logic functions |
//+------------------------------------------------------------------+
bool TradeNotPlacedYet()
{
int total = OrdersTotal();
if (total > 0)
{
for(int cnt=0;cnt<total;cnt++)
{
if(OrderSelect(cnt,SELECT_BY_POS))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
{
SessionIsOn = false;
return (false);
}
}
}
}
// in case trade has already opened and closed for this session
int histotal = OrdersHistoryTotal();
if (histotal > 0)
{
for(cnt=0;cnt<histotal;cnt++)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
{
datetime LatestSessionStart = iTime(NULL,PERIOD_H1,0);
datetime LatestSessionGrace = LatestSessionStart + (GraceMinutes * 60);
datetime CurrentOrderOpenTime = OrderOpenTime();
if (CurrentOrderOpenTime >= LatestSessionStart && CurrentOrderOpenTime <= LatestSessionGrace)
{
SessionIsOn = false;
return (false);
}
}
}
}
}
return (true);
}
bool Should_Buy(int SessionOpenIndex)
{
if (SessionOpenIndex == -1)
{
return (false);
}
theSessionOpenPrice = Open[SessionOpenIndex];
double theSessionCurrentPrice = Close[0];
if (theSessionCurrentPrice > theSessionOpenPrice)
{
double lookoutPrice = theSessionOpenPrice + (Pip_Distance * Point * PipFactor);
if (theSessionCurrentPrice >= lookoutPrice)
{
if (Spread_Still_In_Range())
{
return (true);
}
else
{
if (!ProblemLogged)
{
string logmsg = "The spread is "+DoubleToStr(CustomSpread,1)+" when price moved "+DoubleToStr(Pip_Distance,1)+" from this Session Open Price. No Trade for this session";
WriteToLogFile(logmsg);
ProblemLogged = true;
TradeTheSession = false;
}
}
}
}
return (false);
}
bool Should_Sell(int SessionOpenIndex)
{
if (SessionOpenIndex == -1)
{
return (false);
}
theSessionOpenPrice = Open[SessionOpenIndex];
double theSessionCurrentPrice = Close[0];
if (theSessionCurrentPrice < theSessionOpenPrice)
{
double lookoutPrice = theSessionOpenPrice - (Pip_Distance * Point * PipFactor);
if (theSessionCurrentPrice <= lookoutPrice)
{
if (Spread_Still_In_Range())
{
return (true);
}
else
{
if (!ProblemLogged)
{
string logmsg = "The spread is "+DoubleToStr(CustomSpread,1)+" when price moved "+DoubleToStr(Pip_Distance,1)+" from this Session Open Price. No Trade for this session";
WriteToLogFile(logmsg);
ProblemLogged = true;
TradeTheSession = false;
}
}
}
}
return (false);
}
double PositionSizeToOpen(int StopLossPips)
{
double PositionSize;
double riskDollars;
if (MoneyManagement && StopLossPips > 0)
{
if (UseEquity)
{
riskDollars = (AccountEquity()/100) * RiskPercent;
}
else
{
riskDollars = (AccountBalance()/100) * RiskPercent;
}
PositionSize = (riskDollars / StopLossPips) / (MarketInfo(Symbol(),MODE_TICKVALUE) * PipFactor);
}
if (MoneyManagement && StopLossPips <= 0)
{
if (UseEquity)
{
PositionSize = ((AccountEquity()/100) * RiskPercent) / (MarketInfo(Symbol(),MODE_LOTSIZE) / AccountLeverage());
}
else
{
PositionSize = ((AccountBalance()/100) * RiskPercent) / (MarketInfo(Symbol(),MODE_LOTSIZE) / AccountLeverage());
}
}
if (!MoneyManagement)
{
PositionSize = FixedLots;
}
if (PositionSize < MinLots)
{
PositionSize = MinLots;
}
if (PositionSize > MaxLots)
{
PositionSize = MaxLots;
}
PositionSize = NormalizeDouble(PositionSize,LotsDecimalAllowed);
return (PositionSize);
}
bool SendOrders (int BuyOrSell, double LotSize, double PriceToOpen, double Slippage, double SL_Price, double TP_Price, string comments, datetime ExpirationTime)
{
int ticket, errorType;
if (BuyOrSell == OP_BUY)
{
if (IsECN)
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,0,0,comments,EA_MAGIC_NUM,ExpirationTime,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("BUY order opened : ",OrderOpenPrice());
msg = ticket + ": Buy position opened at "+DoubleToStr(OrderOpenPrice(),Digits);
WriteToLogFile(msg);
if (OrderModify(ticket,OrderOpenPrice(),SL_Price,TP_Price,0))
{
Print("Stop Loss and Take Profit added");
msg = ticket + ": Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" added";
WriteToLogFile(msg);
}
else
{
errorType = GetLastError();
Print("ERROR adding Stop Loss and Take Profit - ",ErrorDescription(errorType));
msg = ticket + ":ERROR adding Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" - "+ErrorDescription(errorType);
WriteToLogFile(msg);
}
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening BUY order : ", ErrorDescription(errorType));
msg = "CANNOT open BUY position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
else
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("BUY order opened : ",OrderOpenPrice());
msg = ticket + ": Buy position opened. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening BUY order : ", ErrorDescription(errorType));
msg = "CANNOT open BUY position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
}
if (BuyOrSell == OP_SELL)
{
if (IsECN)
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Sell Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Red");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,0,0,comments,EA_MAGIC_NUM,ExpirationTime,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("SELL order opened : ",OrderOpenPrice());
msg = ticket + ": Sell position opened at "+DoubleToStr(OrderOpenPrice(),Digits);
WriteToLogFile(msg);
if (OrderModify(ticket,OrderOpenPrice(),SL_Price,TP_Price,0))
{
Print("Stop Loss and Take Profit added");
msg = ticket + ": Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" added";
WriteToLogFile(msg);
}
else
{
errorType = GetLastError();
Print("ERROR adding Stop Loss and Take Profit - ",ErrorDescription(errorType));
msg = ticket + ":ERROR adding Stop Loss: "+DoubleToStr(SL_Price,Digits)+" and Take Profit "+DoubleToStr(TP_Price,Digits)+" - "+ErrorDescription(errorType);
WriteToLogFile(msg);
}
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening SELL order : ", ErrorDescription(errorType));
msg = "CANNOT open SELL position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
else
{
Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Sell Order: "+Symbol()+", "+BuyOrSell+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Red");
ticket=OrderSend(Symbol(),BuyOrSell,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
Print("Sell order opened : ",OrderOpenPrice());
msg = ticket + ": Sell position opened. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (true);
}
}
else
{
errorType = GetLastError();
Print("Error opening SELL order : ", ErrorDescription(errorType));
msg = "CANNOT open SELL position. "+ErrorDescription(errorType);
WriteToLogFile(msg);
return (false);
}
}
}
}
bool Spread_Still_In_Range()
{
if (Use_Spread_Filtering && CustomSpread > Spread_Filter)
{
return (false);
}
return (true);
}
void OpenBuyOrder()
{
RefreshRates();
double PriceToOpen, TakeProfitPrice, StopLossPrice, PositionSize;
PriceToOpen = Ask;
PriceToOpen = NormalizeDouble(PriceToOpen,Digits);
PositionSize = PositionSizeToOpen(the_StopLoss);
if (TakeProfit == 0)
{
TakeProfitPrice = 0;
}
else
{
TakeProfitPrice = PriceToOpen + (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
}
if (the_StopLoss == 0)
{
StopLossPrice = 0;
}
else
{
StopLossPrice = PriceToOpen - (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
}
if (PositionSize < MinLots)
{
PositionSize = MinLots;
}
if (PositionSize > MaxLots)
{
PositionSize = MaxLots;
}
PositionSize = NormalizeDouble(PositionSize,LotsDecimalAllowed);
string DateNow = TimeDay(TimeCurrent())+"-"+TimeMonth(TimeCurrent())+"-"+TimeYear(TimeCurrent());
SendOrders(OP_BUY, PositionSize, PriceToOpen, Slippage, StopLossPrice, TakeProfitPrice, "CBBP_"+DateNow, 0);
}
void OpenSellOrder()
{
RefreshRates();
double PriceToOpen, TakeProfitPrice, StopLossPrice, PositionSize;
PriceToOpen = Bid;
PriceToOpen = NormalizeDouble(PriceToOpen,Digits);
PositionSize = PositionSizeToOpen(the_StopLoss);
if (TakeProfit == 0)
{
TakeProfitPrice = 0;
}
else
{
TakeProfitPrice = PriceToOpen - (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
}
if (the_StopLoss == 0)
{
StopLossPrice = 0;
}
else
{
StopLossPrice = PriceToOpen + (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
}
if (PositionSize < MinLots)
{
PositionSize = MinLots;
}
if (PositionSize > MaxLots)
{
PositionSize = MaxLots;
}
PositionSize = NormalizeDouble(PositionSize,LotsDecimalAllowed);
string DateNow = TimeDay(TimeCurrent())+"-"+TimeMonth(TimeCurrent())+"-"+TimeYear(TimeCurrent());
SendOrders(OP_SELL, PositionSize, PriceToOpen, Slippage, StopLossPrice, TakeProfitPrice, DateNow, 0);
}
void ManageTrades()
{
double TrailLevel = PipFactor*Point*TrailingStop;
TrailLevel = NormalizeDouble(TrailLevel,Digits);
double BE_Level = PipFactor*Point*BreakEven_Pips;
BE_Level = NormalizeDouble(BE_Level,Digits);
double TakeProfitPrice, StopLossPrice;
string logmsg = "";
int ticket, errorType;
double closeNOWprice = 0;
int total = OrdersTotal();
if (total > 0)
{
// must go backwards
for(int cnt=total-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
{
if (OrderType() == OP_BUY)
{
// In case Stop Loss and TakeProfit was not added. Let's do something about it here...
if (OrderStopLoss() == 0 && the_StopLoss != 0)
{
ticket = OrderTicket();
// Close the trade immediately if price has already moved broken the stop loss level
if (OrderOpenPrice()-Bid >= PipFactor*Point*the_StopLoss)
{
closeNOWprice = NormalizeDouble(Bid,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Red))
{
Print("Emergency (Stop Loss) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Stop Loss) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Stop Loss) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Stop Loss) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
else
{
// try to place the Stop Loss and Take Profit level now
StopLossPrice = OrderOpenPrice() - (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
TakeProfitPrice = OrderOpenPrice() + (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
if (OrderModify(ticket,OrderOpenPrice(),StopLossPrice,TakeProfitPrice,0))
{
Print("Stop Loss and Take Profit of order: ",ticket," added successfully");
logmsg = ticket+": Stop Loss and Take Profit added successfully!";
WriteToLogFile(logmsg);
}
else
{
errorType = GetLastError();
Print("ERROR! Adding Stop Loss and Take Profit of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Adding Stop Loss and Take Profit of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Similar to the above except this tackles the takeprofit level breech scenario
if (OrderTakeProfit() == 0 && TakeProfit != 0)
{
// Close the trade immediately if price has already moved broken the stop loss level
if (Bid-OrderOpenPrice() >= PipFactor*Point*TakeProfit)
{
ticket = OrderTicket();
closeNOWprice = NormalizeDouble(Bid,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Blue))
{
Print("Emergency (Take Profit) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Take Profit) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Take Profit) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Take Profit) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Check for Breakeven.
if (Use_BE)
{
if(Bid-OrderStopLoss() > PipFactor*Point*BreakEven_Pips)
{
if (OrderStopLoss() < OrderOpenPrice())
{
StopLossPrice = Bid - BE_Level;
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
if (StopLossPrice > OrderOpenPrice())
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green))
{
logmsg = "Buy Order "+OrderTicket()+" SL reached breakeven level.";
WriteToLogFile(logmsg);
}
}
else
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green))
{
logmsg = "Buy Order "+OrderTicket()+" SL moving towards breakeven level.";
WriteToLogFile(logmsg);
}
}
}
}
}
// Check for Floating Stop
if (!UseJumpingStop && (TrailingStop != 0))
{
if((Bid-OrderOpenPrice()) > TrailLevel && ((Bid-OrderOpenPrice()) >= BE_Level || OrderStopLoss() >= OrderOpenPrice()))
{
if(OrderStopLoss() < Bid-TrailLevel)
{
StopLossPrice = NormalizeDouble(Bid-TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green);
}
}
}
// Check for Jumping Stop
if (UseJumpingStop && (TrailingStop != 0))
{
if((Bid-OrderStopLoss()>(TrailLevel*2)) && ((Bid-OrderOpenPrice()) >= BE_Level || OrderStopLoss() >= OrderOpenPrice()))
{
if ((OrderStopLoss()+TrailLevel) < OrderTakeProfit() || OrderTakeProfit() == 0) // Stop loss level cannot be higher than take profit level
{
StopLossPrice = NormalizeDouble(OrderStopLoss()+TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green);
}
}
}
}
if (OrderType() == OP_SELL)
{
// In case Stop Loss and TakeProfit was not added. Let's do something about it here...
if (OrderStopLoss() == 0 && the_StopLoss != 0)
{
ticket = OrderTicket();
// Close the trade immediately if price has already moved broken the stop loss level
if (Ask - OrderOpenPrice() >= PipFactor*Point*the_StopLoss)
{
closeNOWprice = NormalizeDouble(Ask,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Red))
{
Print("Emergency (Stop Loss) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Stop Loss) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Stop Loss) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Stop Loss) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
else
{
// try to place the Stop Loss and Take Profit level now
StopLossPrice = OrderOpenPrice() + (the_StopLoss * Point * PipFactor);
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
TakeProfitPrice = OrderOpenPrice() - (TakeProfit * Point * PipFactor);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
if (OrderModify(ticket,OrderOpenPrice(),StopLossPrice,TakeProfitPrice,0))
{
Print("Stop Loss and Take Profit of order: ",ticket," added successfully");
logmsg = ticket+": Stop Loss and Take Profit added successfully!";
WriteToLogFile(logmsg);
}
else
{
errorType = GetLastError();
Print("ERROR! Adding Stop Loss and Take Profit of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Adding Stop Loss and Take Profit of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Similar to the above except this tackles the takeprofit level breech scenario
if (OrderTakeProfit() == 0 && TakeProfit != 0)
{
// Close the trade immediately if price has already moved broken the stop loss level
if (OrderOpenPrice()-Ask >= PipFactor*Point*TakeProfit)
{
ticket = OrderTicket();
closeNOWprice = NormalizeDouble(Ask,Digits);
if (OrderClose(ticket,OrderLots(),closeNOWprice,Slippage,Blue))
{
Print("Emergency (Take Profit) closure of order: ",ticket," successful");
logmsg = ticket+": Emergency (Take Profit) closure successful!";
WriteToLogFile(logmsg);
continue;
}
else
{
errorType = GetLastError();
Print("ERROR! Emergency (Take Profit) closure of order: ",ticket," failed! - ",ErrorDescription(errorType));
logmsg = ticket + ":Emergency (Take Profit) closure of order: "+ticket+" failed! - "+ErrorDescription(errorType);
WriteToLogFile(logmsg);
}
}
}
// Check for Breakeven
if (Use_BE)
{
if(OrderStopLoss()-Ask > PipFactor*Point*BreakEven_Pips)
{
if (OrderStopLoss() > OrderOpenPrice())
{
StopLossPrice = Ask + BE_Level;
StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
if (StopLossPrice < OrderOpenPrice())
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green))
{
logmsg = "Sell Order "+OrderTicket()+" SL reached breakeven level.";
WriteToLogFile(logmsg);
}
}
else
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Green))
{
logmsg = "Sell Order "+OrderTicket()+" SL moving towards breakeven level.";
WriteToLogFile(logmsg);
}
}
}
}
}
// Check for Floating Stop
if (!UseJumpingStop && (TrailingStop != 0))
{
if((OrderOpenPrice()-Ask) > TrailLevel && ((OrderOpenPrice()-Ask) >= BE_Level || OrderStopLoss() <= OrderOpenPrice()))
{
if(OrderStopLoss() > Ask+TrailLevel)
{
StopLossPrice = NormalizeDouble(Ask+TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Red);
}
}
}
// Check for Jumping Stop
if (UseJumpingStop && (TrailingStop != 0))
{
// only activate when position is in profit by stoploss amt.
if(((OrderStopLoss()-Ask)>(TrailLevel*2)) && ((OrderOpenPrice()-Ask) >= BE_Level || OrderStopLoss() <= OrderOpenPrice()))
{
if ((OrderStopLoss()-TrailLevel) > OrderTakeProfit() || OrderTakeProfit() == 0) // Stop loss level cannot be less than take profit level
{
StopLossPrice = NormalizeDouble(OrderStopLoss()-TrailLevel,Digits);
OrderModify(OrderTicket(),OrderOpenPrice(),StopLossPrice,OrderTakeProfit(),0,Red);
}
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| Miscellaneous functions |
//+------------------------------------------------------------------+
void GetSpread()
{
if (UserDefinedSpread <= 0)
{
CustomSpread = (MarketInfo(Symbol(),MODE_SPREAD)) / PipFactor;
}
else
{
CustomSpread = UserDefinedSpread;
}
// Should we add the spread into the StopLoss?
the_StopLoss = StopLoss;
if (StopLoss > 0)
{
if (Add_Spread_To_StopLoss)
{
the_StopLoss = StopLoss + CustomSpread;
}
else
{
the_StopLoss = StopLoss;
}
}
}
void WriteComment()
{
msg = "";
int currentHour = TimeHour(Time[0]);
if (SessionOpenHour1 < SessionOpenHour2)
{
if (currentHour < SessionOpenHour2)
{
msg = "EA waiting for "+Session2+" Open";
}
if (currentHour < SessionOpenHour1 || currentHour > SessionOpenHour2)
{
msg = "EA waiting for "+Session1+" Open";
}
}
else
{
if (currentHour < SessionOpenHour1)
{
msg = "EA waiting for "+Session1+" Open";
}
if (currentHour < SessionOpenHour2 || currentHour > SessionOpenHour1)
{
msg = "EA waiting for "+Session2+" Open";
}
}
msg = msg + "\nCurrent Time: "+ currentHour +":"+TimeMinute(TimeCurrent());
if (PipFactor == 10)
{
msg = msg + "\nWorking with Fractional pips";
}
else
{
msg = msg + "\nWorking with Non-Fractional pips";
}
// double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) / PipFactor;
if (MoneyManagement && the_StopLoss > 0)
{
msg = msg + "\nUsing MoneyManagement Feature according to Stop loss";
}
msg = msg + "\nCurrent Spread: "+DoubleToStr(CustomSpread,1)+" pips";
if (Add_Spread_To_StopLoss && the_StopLoss != 0)
{
msg = msg + "\nSpread will be added to your Stop Loss";
}
else
{
msg = msg + "\nSpread will NOT be added to Stop Loss";
}
if (SessionIsOn)
{
msg = msg + "\n\nTime to trade "+latestSession+". Looking for entry...";
msg = msg + "\nSession Open Price: "+DoubleToStr(theSessionOpenPrice,Digits);
msg = msg + "\nCurrent Price: "+DoubleToStr(Close[0],Digits);
}
else
{
msg = msg + "\n"+latestSession+" trading window is closed.";
}
Comment(msg);
}
void WriteToLogFile(string input)
{
string filename = "CBBP-"+Symbol()+"-"+Day()+"-"+Month()+"-"+Year()+".log";
int handle = FileOpen(filename,FILE_READ|FILE_WRITE);
if (handle>1)
{
string prefix = Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds()+" => ";
FileSeek(handle, 0, SEEK_END); // go to end of file
FileWrite(handle, prefix+input);
FileClose(handle);
}
}
// This method is created to spawn a new file for a new day. The first line to be written sometimes don't get written.
// The dummy message used here can act as a buffer so that useful info don't get missed out.
void CreateNewLogFileIfNewDay()
{
if (todayOfYear != DayOfYear())
{
todayOfYear = DayOfYear();
WriteToLogFile("Dummy message");
}
}
bool TimeToTrade()
{
int currentHour = TimeHour(Time[0]);
int currentMinute = TimeMinute(TimeCurrent());
if ((currentHour == SessionOpenHour1 || currentHour == SessionOpenHour2) && currentMinute < GraceMinutes)
{
return (true);
}
return (false);
}
int GetSessionOpenCandle()
{
int SessionOpenCandleIndex = -1;
for (int i=0; i<=GraceMinutes+1; i++)
{
if (TimeHour(Time[i]) == currentSessionHour && TimeMinute(Time[i]) == 0)
{
SessionOpenCandleIndex = i;
break;
}
}
return (SessionOpenCandleIndex);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
if (!StartupStatusOK)
{
Comment("There were errors in your EA inputs. Please recheck them again.");
return (0);
}
CreateNewLogFileIfNewDay();
ManageTrades();
GetSpread();
if (TimeToTrade())
{
currentSessionHour = TimeHour(Time[0]);
if (currentSessionHour == SessionOpenHour1)
{
latestSession = Session1;
}
if (currentSessionHour == SessionOpenHour2)
{
latestSession = Session2;
}
if (TradeNotPlacedYet() && TradeTheSession)
{
int SessionOpenIndex = GetSessionOpenCandle();
SessionIsOn = true;
if (!SessionOpenPriceWritten)
{
string logmsg = latestSession+" open at "+DoubleToStr(Open[SessionOpenIndex],Digits);
Print(logmsg);
WriteToLogFile(logmsg);
SessionOpenPriceWritten = true;
}
if (Should_Buy(SessionOpenIndex) && TradeTheSession)
{
OpenBuyOrder();
TradeTheSession = false;
}
if (Should_Sell(SessionOpenIndex) && TradeTheSession)
{
OpenSellOrder();
TradeTheSession = false;
}
}
else
{
SessionIsOn = false;
}
}
else
{
SessionIsOn = false;
TradeTheSession = true;
ProblemLogged = false;
SessionOpenPriceWritten = false;
}
if (Show_Comments)
{
WriteComment();
}
//----
return(0);