----Matt's Order Reliable library code
bool O_R_CheckForHistory(int ticket) Cheers Matt, You are a star.
void O_R_Sleep(double mean_time, double max_time)
----Indicator readings----
void ReadIndicatorValues()
void GetPreviousCandleDirection()
void GetBB(int shift)
double GetRsi(int tf, int period, int ap, int shift)
double GetMa(int tf, int period, int FastMaShift, int method, int ap, int shift)
double CalculateVolatility(int period, int LookBack)
----Recovery----
void RecoveryModule()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)
void RecoveryCandlesticktrailingStop()
void LockInRecoveryProfit()
void AddReEntryLine(double price)
void CalculateReEntryLinePips() not included yet
void ReplaceReEntryLine()
void RecoveryCandlesticktrailingStop()
/*
extern string rec="----Recovery----";
extern bool UseRecovery=true;
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
*/
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;
//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;
string TradeDirection;
string PreviousCandleDirection;
//Moving average
double FastMaVal, SlowMaVal, PrevFastMaVal;
//Misc
string Gap, ScreenMessage;
int OldBars;
int OldCstBars;//For candlestick ts
string PipDescription=" pips";
bool ForceTradeClosure;
/*
//Recovery
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",
"Profit"};
int ExtShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int ExtVertShift=14;
double buy_price=0.0;
double sell_price=0.0;
*/
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, "Stop loss choice: ");
if (StopLoss > 0) ScreenMessage = StringConcatenate(ScreenMessage, "Stop loss: ", StopLoss, PipDescription, NL);
if (UseChannel) ScreenMessage = StringConcatenate(ScreenMessage, "Using the mid-point between fast and slow MA", NL);
if (UseMaRecross) ScreenMessage = StringConcatenate(ScreenMessage, "Closing trades on a MA cross in the opposite direction", NL);
if (HedgeNotStopLoss) ScreenMessage = StringConcatenate(ScreenMessage, "Hedging losing trades on a MA cross in the opposite direction. HedgeLotsMultiplier = ", HedgeLotsMultiplier, NL);
//extern bool HedgeNotStopLoss=true;
//extern int HedgeLotsMultiplier=2;
Gap="";
if (DisplayGapSize >0)
{
for (int cc=0; cc< DisplayGapSize; cc++)
{
Gap = StringConcatenate(Gap, " ");
}
}//if (DisplayGapSize >0)
if (TradeComment == "") TradeComment = " ";
//OldBars = Bars;
ReadIndicatorValues();//For initial display in case user has turned of constant re-display
DisplayUserFeedback();
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
Comment("");
//----
return(0);
}
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
{
//Reusable code that can be called by any of the stop loss manipulation routines except HiddenStopLoss().
//Checks to see if the market has hit the hidden sl and attempts to close the trade if so.
//Returns true if trade closure is successful, else returns false
//Check buy trade
if (type == OP_BUY)
{
double sl = NormalizeDouble(stop + (iPipsAboveVisual * Point), Digits);
if (Bid <= sl)
{
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Bid <= sl)
}//if (type = OP_BUY)
//Check buy trade
if (type == OP_SELL)
{
sl = NormalizeDouble(stop - (iPipsAboveVisual * Point), Digits);
if (Ask >= sl)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Ask >= sl)
}//if (type = OP_SELL)
}//End bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void BreakEvenStopLoss() // Move stop loss to breakeven
{
//Check hidden BE for trade closure
if (HideBreakEvenStop)
{
bool TradeClosed = CheckForHiddenStopLossHit(OrderType(), PipsAwayFromVisualBE, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideBreakEvenStop)
bool result;
if (OrderType()==OP_BUY)
{
if (Bid >= OrderOpenPrice () + (Point*BreakEvenPips) &&
OrderStopLoss()<OrderOpenPrice())
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
if (!result)
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//if !result && ShowManagementAlerts)
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
// bool PartCloseSuccess = PartCloseTradeFunction();
// if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}
}
if (OrderType()==OP_SELL)
{
if (Ask <= OrderOpenPrice() - (Point*BreakEvenPips) &&
(OrderStopLoss()>OrderOpenPrice()|| OrderStopLoss()==0))
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
if (!result && ShowManagementAlerts)
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//if !result && ShowManagementAlerts)
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
// {
// PartCloseSuccess = PartCloseTradeFunction();
// if (!PartCloseSuccess) SetAGlobalTicketVariable();
// }//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}
}
} // End BreakevenStopLoss sub
void JumpingStopLoss()
{
// Jump sl by pips and at intervals chosen by user .
// Also carry out partial closure if the user requires this
// Abort the routine if JumpAfterBreakevenOnly is set to true and be sl is not yet set
if (JumpAfterBreakevenOnly && OrderType()==OP_BUY)
{
if(OrderStopLoss()<OrderOpenPrice()) return(0);
}
if (OrderType()==OP_BUY)
{
//Check hidden js for trade closure
if (HideJumpingStop)
{
bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
// First check if sl needs setting to breakeven
if (sl==0 || sl<OrderOpenPrice())
{
if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
{
sl=OrderOpenPrice();
if (AddBEP==true) sl=sl+(BreakEvenProfit*Point); // If user wants to add a profit to the break even
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", Bid);
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
//bool PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
int err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), "Ticket ", OrderTicket(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
}//if (!result)
if (OrderType()==OP_SELL)
{
//Check hidden js for trade closure
if (HideJumpingStop)
{
TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualJS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
// First check if sl needs setting to breakeven
if (sl==0 || sl>OrderOpenPrice())
{
if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
{
sl = OrderOpenPrice();
if (AddBEP==true) sl=sl-(BreakEvenProfit*Point); // If user wants to add a profit to the break even
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
// PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
}//if (!result)
// Decrement sl by sl - JumpingStopPips.
// This will happen when market price <= (sl - JumpingStopPips)
if (Bid<= sl - ((JumpingStopPips*2)*Point) && sl<= OrderOpenPrice())
{
sl=sl-(JumpingStopPips*Point);
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
// PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
}//if (!result)
}// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())
}//if (OrderType()==OP_SELL)
} //End of JumpingStopLoss sub
void HiddenStopLoss()
{
//Called from ManageTrade if HideStopLossEnabled = true
//Should the order close because the stop has been passed?
//Buy trade
if (OrderType() == OP_BUY)
{
double sl = NormalizeDouble(OrderOpenPrice() - (HiddenStopLossPips * Point), Digits);
if (Bid <= sl)
{
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Bid <= sl)
}//if (OrderType() == OP_BUY)
//Sell trade
if (OrderType() == OP_SELL)
{
sl = NormalizeDouble(OrderOpenPrice() + (HiddenStopLossPips * Point), Digits);
if (Ask >= sl)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Ask >= sl)
}//if (OrderType() == OP_SELL)
}//End void HiddenStopLoss()
void HiddenTakeProfit()
{
//Called from ManageTrade if HideStopLossEnabled = true
//Should the order close because the stop has been passed?
//Buy trade
if (OrderType() == OP_BUY)
{
double tp = NormalizeDouble(OrderOpenPrice() + (HiddenTakeProfitPips * Point), Digits);
if (Bid >= tp)
{
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Ask >= tp)
}//if (OrderType() == OP_BUY)
//Sell trade
if (OrderType() == OP_SELL)
{
tp = NormalizeDouble(OrderOpenPrice() - (HiddenTakeProfitPips * Point), Digits);
if (Ask <= tp)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Bid <= tp)
}//if (OrderType() == OP_SELL)
if (TrailAfterBreakevenOnly && OrderType()==OP_SELL)
{
if(OrderStopLoss()>OrderOpenPrice()) return(0);
}
bool result;
double sl=OrderStopLoss(); //Stop loss
double BuyStop=0, SellStop=0;
if (OrderType()==OP_BUY)
{
if (HideTrailingStop)
{
bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualTS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
{
if (OrderStopLoss() == 0) sl = OrderOpenPrice();
if (Bid > sl + (TrailingStopPips*Point))
{
sl= Bid - (TrailingStopPips*Point);
// Exit routine if user has chosen StopTrailAtPipsProfit and
// sl is past the profit Point already
if (StopTrailAtPipsProfit && sl>= OrderOpenPrice() + (StopTrailPips*Point)) return;
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
}//if (result)
else
{
int err=GetLastError();
Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
}//else
if (OrderType()==OP_SELL)
{
if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
{
if (HideTrailingStop)
{
TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualTS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
if (OrderStopLoss() == 0) sl = OrderOpenPrice();
if (Ask < sl - (TrailingStopPips*Point))
{
sl= Ask + (TrailingStopPips*Point);
// Exit routine if user has chosen StopTrailAtPipsProfit and
// sl is past the profit Point already
if (StopTrailAtPipsProfit && sl<= OrderOpenPrice() - (StopTrailPips*Point)) return;
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
}//if (result)
else
{
err=GetLastError();
Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
}//else
if (modify)
{
result = OrderModify(OrderTicket(), OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
if (!result)
{
err = GetLastError();
if (err != 130) OldBars = 0;//Retry the modify at the next tick unless the error is invalid stops
}//if (!result)
}//if (modify)
}//End void CandlestickTrailingStop()
void ModifyFastMaStopLoss()
{
//Called from start() if there is an open trade.
//Modifies the trade's stop loss if the fast ma has moved in the trade's direction
if (!OrderSelect(TicketNo, SELECT_BY_TICKET) || OrderCloseTime() > 0) return;//In case order has closed
double stop = NormalizeDouble(FastMaVal, Digits);
void GetPreviousCandleDirection()
{
//Reads the direction of the previous candle
PreviousCandleDirection = none;
if (Close[1] > Open[1] ) PreviousCandleDirection = up;
if (Close[1] < Open[1] ) PreviousCandleDirection = down;
}//End void GetPreviousCandleDirection()
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);
//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);
//Swap filter
if (OpenTrades == 0) TradeDirectionBySwap();
//Max distance from fast ma
if (MathAbs(FastMaVal - Bid) > MaxDistanceFromFastMa * Point) 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);
//This idea from Pippo
if (UseRecovery)
{
if (RecoveryInProgress)
{
if (OpenTrades == 2)
{
SendLots = Lot * 2;
if (Use1.1.3.3Recovery) SendLots = Lot * 3;
}//if (OpenTrades == 2)
if (OpenTrades == 3)
{
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)
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;
/*
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 FastMaShift, int method, int ap, int shift)
{
return(iMA(NULL, tf, period, FastMaShift, method, ap, shift) );
}//End double GetMa(int tf, int period, int FastMaShift, int method, int ap, int shift)
TradeDirection = none;
//Fast ma is above slow ma and is rising
if (FastMaVal > SlowMaVal && FastMaVal > PrevFastMaVal) TradeDirection = buy;
//Fast ma is below slow ma and is falling
if (FastMaVal < SlowMaVal && FastMaVal < PrevFastMaVal) TradeDirection = sell;
// adjust for past-end-of-day cases
// eg in AUS, USDJPY trades 09-17 and 22-06
// so, the above check failed, check if it is because of this condition
if (!ok2Trade && hour < 12)
{
hour += 24;
ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);
// so, if the trading hours are 11pm - 6am and the time is between midnight to 11am, (say, 5am)
// the above code will result in comparing 5+24 to see if it is between 23 (11pm) and 30(6+24), which it is...
}
// check for end of day by looking at *both* end-hours
//=============================================================================
// O_R_CheckForHistory()
//
// This function is to work around a very annoying and dangerous bug in MT4:
// immediately after you send a trade, the trade may NOT show up in the
// order history, even though it exists according to ticket number.
// As a result, EA's which count history to check for trade entries
// may give many multiple entries, possibly blowing your account!
//
// This function will take a ticket number and loop until
// it is seen in the history.
//
// RETURN VALUE:
// TRUE if successful, FALSE otherwise
//
//
// FEATURES:
// * Re-trying under some error conditions, sleeping a random
// time defined by an exponential probability distribution.
//
// * Displays various error messages on the log for debugging.
//
// ORIGINAL AUTHOR AND DATE:
// Matt Kennel, 2010
//
//=============================================================================
bool O_R_CheckForHistory(int ticket)
{
//My thanks to Matt for this code. He also has the undying gratitude of all users of my trading robots
int lastTicket = OrderTicket();
int cnt = 0;
int err = GetLastError(); // so we clear the global variable.
err = 0;
bool exit_loop = false;
bool success=false;
while (!exit_loop) {
/* loop through open trades */
int total=OrdersTotal();
for(int c = 0; c < total; c++) {
if(OrderSelect(c,SELECT_BY_POS,MODE_TRADES) == true) {
if (OrderTicket() == ticket) {
success = true;
exit_loop = true;
}
}
}
if (cnt > 3) {
/* look through history too, as order may have opened and closed immediately */
total=OrdersHistoryTotal();
for(c = 0; c < total; c++) {
if(OrderSelect(c,SELECT_BY_POS,MODE_HISTORY) == true) {
if (OrderTicket() == ticket) {
success = true;
exit_loop = true;
}
}
}
}
cnt = cnt+1;
if (cnt > 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 < 10) {
ms=10;
}
Sleep(ms);
}//End void O_R_Sleep(double mean_time, double max_time)
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;
int index = StringFind(OrderSymbol(), c1);
if (index > -1)
{
c1open++;
}//if (index > -1)
index = StringFind(OrderSymbol(), c2);
if (index > -1)
{
c2open++;
}//if (index > -1)
//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.
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; i<ExtSymbolsTotal; i++)
{
if (ExtSymbols[i] != Symbol() ) continue;
if(ExtSymbolsSummaries[i][DEALS]<=0) continue;
line++;
//---- add line
if(line>ExtLines)
{
int y_dist=ExtVertShift*(line+1)+1;
ExtLines++;
}//if(line>ExtLines)
//---- set line
//color price_colour;//Steve mod
int digits=MarketInfo(ExtSymbols[i],MODE_DIGITS);
double buy_lots=ExtSymbolsSummaries[i][BUY_LOTS];
double sell_lots=ExtSymbolsSummaries[i][SELL_LOTS];
if(buy_lots!=0) buy_price=NormalizeDouble(ExtSymbolsSummaries[i][BUY_PRICE]/buy_lots, Digits);
if(sell_lots!=0) sell_price=NormalizeDouble(ExtSymbolsSummaries[i][SELL_PRICE]/sell_lots, Digits);
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);
//The most recent trade selected in CountOpenTrades will show the type of trades involved
if (SellOpen)
{
//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 (Bid <= 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 (Bid <= 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 (High[1] < target)
{
ObjectMove(breakevenlinename, 0, TimeCurrent(), High[1]);
}//if (High[1] < target)
OldRecoverTrailBars = Bars;
//return;
}//if (OldRecoverTrailBars != Bars)
//Has the market retraced to the recovery stop loss
target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
//Alert("Target = ", target);
if (Bid >= target)
{
ForceTradeClosure = true;
CloseAllTrades();
ObjectDelete(breakevenlinename);
return;
}//if (Bid >= target)
}//if (OrderType() == OP_SELL)
if (ForceTradeClosure)
{
CloseAllTrades();
return;
}//if (ForceTradeClosure)
if (HedgingInProgress)
{
CountOpenTrades();
if (BasketUpl >= 0)
{
CloseAllTrades();
return;
}//if (BasketUpl >= 0)
//Does the hedge trade need hedging? This function performs this task if necessary
if (HedgeTheHedge) HedgeTheHedgeTrade();
}//if (HedgingInProgress)
///////////////////////////////////////////////////////////////////////////////////////////////
//Find open trades.
CountOpenTrades();
if (OpenTrades == 1)
{
if (OrderProfit() > 0 && !HedgingInProgress) TradeManagementModule();
LookForTradeClosure();
}//if (TradeExists)
///////////////////////////////////////////////////////////////////////////////////////////////
/*
//Recovery
if (UseRecovery)
{
if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
//Replace accidentally deleted be line
if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
{
RecoveryModule();
}//if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
cservenak
16 Mar 2015, 18:50
//+-------------------------------------------------------------------+
//|Moving average trend-trading auto trading robot by Steve Hopwood.mq4 |
//| Copyright © 2009, Steve Hopwood |
//| http://www.hopwood3.freeserve.co.uk |
//+-------------------------------------------------------------------+
#property copyright "Copyright © 2009, Steve Hopwood"
#property link "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define NL "\n"
#define up "Up"
#define down "Down"
#define none "None"
#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 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
/*
Matt Kennel has provided the code for bool O_R_CheckForHistory(int ticket). Cheers Matt, You are a star.
Code for adding debugging Sleep
int x = 0;
while (x == 0) Sleep(100);
FUNCTIONS LIST
int init()
int start()
----Trading----
void LookForTradingOpportunities()
bool IsTradingAllowed()
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
bool DoesTradeExist() Not used
void CountOpenTrades()
bool CloseTrade(int ticket)
void LookForTradeClosure()
bool CheckTradingTimes()
void CloseAllTrades()
void HedgeTrade()
void HedgeTheHedgeTrade()
----Balance/swap filters module----
void TradeDirectionBySwap()
bool IsThisPairTradable()
bool BalancedPair(int type)
----Matt's Order Reliable library code
bool O_R_CheckForHistory(int ticket) Cheers Matt, You are a star.
void O_R_Sleep(double mean_time, double max_time)
----Indicator readings----
void ReadIndicatorValues()
void GetPreviousCandleDirection()
void GetBB(int shift)
double GetRsi(int tf, int period, int ap, int shift)
double GetMa(int tf, int period, int FastMaShift, int method, int ap, int shift)
double CalculateVolatility(int period, int LookBack)
----Recovery----
void RecoveryModule()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)
void RecoveryCandlesticktrailingStop()
void LockInRecoveryProfit()
void AddReEntryLine(double price)
void CalculateReEntryLinePips() not included yet
void ReplaceReEntryLine()
void RecoveryCandlesticktrailingStop()
----Trade management module----
void TradeManagementModule()
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void JumpingStopLoss()
void HiddenTakeProfit()
void HiddenStopLoss()
void TrailingStopLoss()
void ModifyFastMaStopLoss()
*/
extern string gen="----General inputs----";
extern double Lot=0.2;
extern bool StopTrading=false;
extern bool TradeLong=true;
extern bool TradeShort=true;
extern int MaxDistanceFromFastMa=25;
extern int TakeProfit=200;
extern int MagicNumber=0;
extern string TradeComment="";
extern bool CriminalIsECN=false;
extern double MaxSpread=120;
extern bool UseZeljko=true;
extern bool OnlyTradeCurrencyTwice=true;
extern string sti="----Stop loss choices----";
extern int StopLoss=0;
extern bool UseChannel=false;
extern bool UseMaRecross=false;
extern string hed="Hedging";
extern bool HedgeNotStopLoss=true;
extern double HedgeLotsMultiplier=2;
extern bool HedgeTheHedge = true;
extern double HedgeTheHedgeLotsMultiplier=2;
extern string fmai="----Moving averages----";
extern string fma="Fast MA";
extern int FastMaTF=0;//Time frame defaults to current chart
extern int FastMaPeriod=100;
extern int FastMaShift=0;//The MA Shift input
extern string fmame="Method: 0=sma; 1=ema; 2=smma; 3=lwma";
extern int FastMaMethod=0;
extern string fmaap="Applied price: 0=Close; 1=Open; 2=High";
extern string fmaap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int FastMaAppliedPrice=0;
extern string sma="Slow MA";
extern int SlowMaTF=0;//Time frame defaults to current chart
extern int SlowMaPeriod=200;
extern int SlowMaShift=0;//The MA Shift input
extern string smame="Method: 0=sma; 1=ema; 2=smma; 3=lwma";
extern int SlowMaMethod=0;
extern string smaap="Applie0 price: 0=Close; 1=Open; 2=High";
extern string smaap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int SlowMaAppliedPrice=0;
extern string masc="----Moving average slope candles----";
extern int MaCandlesLookback=5;
extern string amc="----Available Margin checks----";
extern string sco="Scoobs";
extern bool UseScoobsMarginCheck=false;
extern string fk="ForexKiwi";
extern bool UseForexKiwi=true;
extern int FkMinimumMarginPercent=1500;
/*
extern string rec="----Recovery----";
extern bool UseRecovery=true;
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
*/
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 pts="----Swap filter----";
extern bool CadPairsPositiveOnly=true;
extern bool AudPairsPositiveOnly=true;
extern bool NzdPairsPositiveOnly=true;
extern string tmm="----Trade management module----";
extern string BE="Break even settings";
extern bool BreakEven=false;
extern int BreakEvenPips=25;
extern int BreakEvenProfit=10;
extern bool HideBreakEvenStop=false;
extern int PipsAwayFromVisualBE=5;
extern string cts="----Candlestick trailing stop----";
extern bool UseCandlestickTrailingStop=false;
extern string JSL="Jumping stop loss settings";
extern bool JumpingStop=false;
extern int JumpingStopPips=100;
extern bool AddBEP=true;
extern bool JumpAfterBreakevenOnly=false;
extern bool HideJumpingStop=false;
extern int PipsAwayFromVisualJS=10;
extern string TSL="Trailing stop loss settings";
extern bool TrailingStop=false;
extern int TrailingStopPips=50;
extern bool HideTrailingStop=false;
extern int PipsAwayFromVisualTS=10;
extern bool TrailAfterBreakevenOnly=false;
extern bool StopTrailAtPipsProfit=false;
extern int StopTrailPips=0;
extern string hsl1="Hidden stop loss settings";
extern bool HideStopLossEnabled=false;
extern int HiddenStopLossPips=20;
extern string htp="Hidden take profit settings";
extern bool HideTakeProfitEnabled=false;
extern int HiddenTakeProfitPips=20;
extern string mis="----Odds and ends----";
extern bool ShowManagementAlerts=true;
extern int DisplayGapSize=30;
//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;
string TradeDirection;
string PreviousCandleDirection;
//Moving average
double FastMaVal, SlowMaVal, PrevFastMaVal;
//Hedging
bool HedgingInProgress;
double BasketUpl;
//Misc
string Gap, ScreenMessage;
int OldBars;
int OldCstBars;//For candlestick ts
string PipDescription=" pips";
bool ForceTradeClosure;
/*
//Recovery
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",
"Profit"};
int ExtShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int ExtVertShift=14;
double buy_price=0.0;
double sell_price=0.0;
*/
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);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, PipDescription, NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss choice: ");
if (StopLoss > 0) ScreenMessage = StringConcatenate(ScreenMessage, "Stop loss: ", StopLoss, PipDescription, NL);
if (UseChannel) ScreenMessage = StringConcatenate(ScreenMessage, "Using the mid-point between fast and slow MA", NL);
if (UseMaRecross) ScreenMessage = StringConcatenate(ScreenMessage, "Closing trades on a MA cross in the opposite direction", NL);
if (HedgeNotStopLoss) ScreenMessage = StringConcatenate(ScreenMessage, "Hedging losing trades on a MA cross in the opposite direction. HedgeLotsMultiplier = ", HedgeLotsMultiplier, NL);
//extern bool HedgeNotStopLoss=true;
//extern int HedgeLotsMultiplier=2;
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MaxDistanceFromFastMa: ", MaxDistanceFromFastMa, 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, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MaxSpread = ", MaxSpread, ": Spread: ", MarketInfo(Symbol(), MODE_SPREAD), NL );
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Long swap = ", MarketInfo(Symbol(), MODE_SWAPLONG), ": Short swap = ", MarketInfo(Symbol(), MODE_SWAPSHORT), NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, 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
ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Fast moving average: ", DoubleToStr(FastMaVal, Digits), NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Slow moving average: ", DoubleToStr(SlowMaVal, Digits), NL);
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade direction: ", TradeDirection, 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);
if (AddBEP) ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit, PipDescription);
if (JumpAfterBreakevenOnly) ScreenMessage = StringConcatenate(ScreenMessage, ": JumpAfterBreakevenOnly = true");
ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
}//if (JumpingStop)
if (TrailingStop)
{
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trailing stop is set to ", TrailingStopPips, PipDescription);
if (TrailAfterBreakevenOnly) ScreenMessage = StringConcatenate(ScreenMessage, ": TrailAfterBreakevenOnly = true");
ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
}//if (TrailingStop)
if (HideStopLossEnabled)
{
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden stop loss enabled at ", HiddenStopLossPips, PipDescription, NL);
}//if (HideStopLossEnabled)
if (HideTakeProfitEnabled)
{
ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden take profit enabled at ", HiddenTakeProfitPips, PipDescription, NL);
}//if (HideTakeProfitEnabled)
//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);
Comment(ScreenMessage);
}//void DisplayUserFeedback()
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//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;
MaxDistanceFromFastMa*= multiplier;
BreakEvenPips*= multiplier;
BreakEvenProfit*= multiplier;
PipsAwayFromVisualBE*= multiplier;
JumpingStopPips*= multiplier;
PipsAwayFromVisualJS*= multiplier;
TrailingStopPips*= multiplier;
PipsAwayFromVisualTS*= multiplier;
StopTrailPips*= multiplier;
HiddenStopLossPips*= multiplier;
HiddenTakeProfitPips*= multiplier;
Gap="";
if (DisplayGapSize >0)
{
for (int cc=0; cc< DisplayGapSize; cc++)
{
Gap = StringConcatenate(Gap, " ");
}
}//if (DisplayGapSize >0)
if (TradeComment == "") TradeComment = " ";
//OldBars = Bars;
ReadIndicatorValues();//For initial display in case user has turned of constant re-display
DisplayUserFeedback();
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
Comment("");
//----
return(0);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//TRADE MANAGEMENT MODULE
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
{
//Reusable code that can be called by any of the stop loss manipulation routines except HiddenStopLoss().
//Checks to see if the market has hit the hidden sl and attempts to close the trade if so.
//Returns true if trade closure is successful, else returns false
//Check buy trade
if (type == OP_BUY)
{
double sl = NormalizeDouble(stop + (iPipsAboveVisual * Point), Digits);
if (Bid <= sl)
{
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Bid <= sl)
}//if (type = OP_BUY)
//Check buy trade
if (type == OP_SELL)
{
sl = NormalizeDouble(stop - (iPipsAboveVisual * Point), Digits);
if (Ask >= sl)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Ask >= sl)
}//if (type = OP_SELL)
}//End bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void BreakEvenStopLoss() // Move stop loss to breakeven
{
//Check hidden BE for trade closure
if (HideBreakEvenStop)
{
bool TradeClosed = CheckForHiddenStopLossHit(OrderType(), PipsAwayFromVisualBE, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideBreakEvenStop)
bool result;
if (OrderType()==OP_BUY)
{
if (Bid >= OrderOpenPrice () + (Point*BreakEvenPips) &&
OrderStopLoss()<OrderOpenPrice())
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
if (!result)
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//if !result && ShowManagementAlerts)
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
// bool PartCloseSuccess = PartCloseTradeFunction();
// if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}
}
if (OrderType()==OP_SELL)
{
if (Ask <= OrderOpenPrice() - (Point*BreakEvenPips) &&
(OrderStopLoss()>OrderOpenPrice()|| OrderStopLoss()==0))
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
if (!result && ShowManagementAlerts)
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//if !result && ShowManagementAlerts)
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
// {
// PartCloseSuccess = PartCloseTradeFunction();
// if (!PartCloseSuccess) SetAGlobalTicketVariable();
// }//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}
}
} // End BreakevenStopLoss sub
void JumpingStopLoss()
{
// Jump sl by pips and at intervals chosen by user .
// Also carry out partial closure if the user requires this
// Abort the routine if JumpAfterBreakevenOnly is set to true and be sl is not yet set
if (JumpAfterBreakevenOnly && OrderType()==OP_BUY)
{
if(OrderStopLoss()<OrderOpenPrice()) return(0);
}
if (JumpAfterBreakevenOnly && OrderType()==OP_SELL)
{
if(OrderStopLoss()>OrderOpenPrice() || OrderStopLoss() == 0 ) return(0);
}
double sl=OrderStopLoss(); //Stop loss
if (OrderType()==OP_BUY)
{
//Check hidden js for trade closure
if (HideJumpingStop)
{
bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
// First check if sl needs setting to breakeven
if (sl==0 || sl<OrderOpenPrice())
{
if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
{
sl=OrderOpenPrice();
if (AddBEP==true) sl=sl+(BreakEvenProfit*Point); // If user wants to add a profit to the break even
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", Bid);
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
//bool PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
int err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), "Ticket ", OrderTicket(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
}//if (!result)
return(0);
}//if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
} //close if (sl==0 || sl<OrderOpenPrice()
// Increment sl by sl + JumpingStopPips.
// This will happen when market price >= (sl + JumpingStopPips)
if (Bid>= sl + ((JumpingStopPips*2)*Point) && sl>= OrderOpenPrice())
{
sl=sl+(JumpingStopPips*Point);
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
//PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
}//if (!result)
}// if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())
}//if (OrderType()==OP_BUY)
if (OrderType()==OP_SELL)
{
//Check hidden js for trade closure
if (HideJumpingStop)
{
TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualJS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
// First check if sl needs setting to breakeven
if (sl==0 || sl>OrderOpenPrice())
{
if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
{
sl = OrderOpenPrice();
if (AddBEP==true) sl=sl-(BreakEvenProfit*Point); // If user wants to add a profit to the break even
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
// PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
}//if (!result)
return(0);
}//if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
} // if (sl==0 || sl>OrderOpenPrice()
// Decrement sl by sl - JumpingStopPips.
// This will happen when market price <= (sl - JumpingStopPips)
if (Bid<= sl - ((JumpingStopPips*2)*Point) && sl<= OrderOpenPrice())
{
sl=sl-(JumpingStopPips*Point);
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
//if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
//{
// PartCloseSuccess = PartCloseTradeFunction();
//if (!PartCloseSuccess) SetAGlobalTicketVariable();
//}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
}//if (result)
if (!result)
{
err=GetLastError();
if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
Print(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
}//if (!result)
}// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())
}//if (OrderType()==OP_SELL)
} //End of JumpingStopLoss sub
void HiddenStopLoss()
{
//Called from ManageTrade if HideStopLossEnabled = true
//Should the order close because the stop has been passed?
//Buy trade
if (OrderType() == OP_BUY)
{
double sl = NormalizeDouble(OrderOpenPrice() - (HiddenStopLossPips * Point), Digits);
if (Bid <= sl)
{
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Bid <= sl)
}//if (OrderType() == OP_BUY)
//Sell trade
if (OrderType() == OP_SELL)
{
sl = NormalizeDouble(OrderOpenPrice() + (HiddenStopLossPips * Point), Digits);
if (Ask >= sl)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Ask >= sl)
}//if (OrderType() == OP_SELL)
}//End void HiddenStopLoss()
void HiddenTakeProfit()
{
//Called from ManageTrade if HideStopLossEnabled = true
//Should the order close because the stop has been passed?
//Buy trade
if (OrderType() == OP_BUY)
{
double tp = NormalizeDouble(OrderOpenPrice() + (HiddenTakeProfitPips * Point), Digits);
if (Bid >= tp)
{
while(IsTradeContextBusy()) Sleep(100);
bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
int err=GetLastError();
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Ask >= tp)
}//if (OrderType() == OP_BUY)
//Sell trade
if (OrderType() == OP_SELL)
{
tp = NormalizeDouble(OrderOpenPrice() - (HiddenTakeProfitPips * Point), Digits);
if (Ask <= tp)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
if (result)
{
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());
}//if (result)
else
{
err=GetLastError();
if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
}//else
}//if (Bid <= tp)
}//if (OrderType() == OP_SELL)
}//End void HiddenTakeProfit()
void TrailingStopLoss()
{
if (TrailAfterBreakevenOnly && OrderType()==OP_BUY)
{
if(OrderStopLoss()<OrderOpenPrice()) return(0);
}
if (TrailAfterBreakevenOnly && OrderType()==OP_SELL)
{
if(OrderStopLoss()>OrderOpenPrice()) return(0);
}
bool result;
double sl=OrderStopLoss(); //Stop loss
double BuyStop=0, SellStop=0;
if (OrderType()==OP_BUY)
{
if (HideTrailingStop)
{
bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualTS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
{
if (OrderStopLoss() == 0) sl = OrderOpenPrice();
if (Bid > sl + (TrailingStopPips*Point))
{
sl= Bid - (TrailingStopPips*Point);
// Exit routine if user has chosen StopTrailAtPipsProfit and
// sl is past the profit Point already
if (StopTrailAtPipsProfit && sl>= OrderOpenPrice() + (StopTrailPips*Point)) return;
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
}//if (result)
else
{
int err=GetLastError();
Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
}//else
}//if (Bid > sl + (TrailingStopPips*Point))
}//if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
}//if (OrderType()==OP_BUY)
if (OrderType()==OP_SELL)
{
if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
{
if (HideTrailingStop)
{
TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualTS, OrderStopLoss() );
if (TradeClosed) return;//Trade has closed, so nothing else to do
}//if (HideJumpingStop)
if (OrderStopLoss() == 0) sl = OrderOpenPrice();
if (Ask < sl - (TrailingStopPips*Point))
{
sl= Ask + (TrailingStopPips*Point);
// Exit routine if user has chosen StopTrailAtPipsProfit and
// sl is past the profit Point already
if (StopTrailAtPipsProfit && sl<= OrderOpenPrice() - (StopTrailPips*Point)) return;
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result)
{
Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
}//if (result)
else
{
err=GetLastError();
Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
}//else
}//if (Ask < sl - (TrailingStopPips*Point))
}//if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
}//if (OrderType()==OP_SELL)
} // End of TrailingStopLoss sub
void CandlestickTrailingStop()
{
//Trails the stop at the hi/lo of the previous candle.
//Only tries to do this once per bar, so an invalid stop error will only be generated once.
if (OldCstBars == Bars) return;
OldCstBars = Bars;
bool result = false, modify = false;
int err;
double stop;
if (OrderType() == OP_BUY)
{
if (Low[1] > OrderStopLoss() && OrderProfit() >= 0)
{
stop = NormalizeDouble(Low[1], Digits);
modify = true;
}//if (Close[1] > OrderStopLoss() && OrderProfit() >= 0)
}//if (OrderType == OP_BUY)
if (OrderType() == OP_SELL)
{
if ( (High[1] < OrderStopLoss() || OrderStopLoss() == 0) && OrderProfit() >= 0)
{
stop = NormalizeDouble(High[1], Digits);
modify = true;
}//if (Close[1] > OrderStopLoss() && OrderProfit() >= 0)
}//if (OrderType() == OP_SELL)
if (modify)
{
result = OrderModify(OrderTicket(), OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
if (!result)
{
err = GetLastError();
if (err != 130) OldBars = 0;//Retry the modify at the next tick unless the error is invalid stops
}//if (!result)
}//if (modify)
}//End void CandlestickTrailingStop()
void ModifyFastMaStopLoss()
{
//Called from start() if there is an open trade.
//Modifies the trade's stop loss if the fast ma has moved in the trade's direction
if (!OrderSelect(TicketNo, SELECT_BY_TICKET) || OrderCloseTime() > 0) return;//In case order has closed
double stop = NormalizeDouble(FastMaVal, Digits);
if (OrderType() == OP_BUY && FastMaVal > OrderStopLoss() && FastMaVal >= OrderOpenPrice() ) OrderModify(TicketNo, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
if (OrderType() == OP_SELL && FastMaVal < OrderStopLoss() && FastMaVal <= OrderOpenPrice() ) OrderModify(TicketNo, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
}//void ModifyFastMaStopLoss()
void TradeManagementModule()
{
// Call the working subroutines one by one.
//Candlestick trailing stop
if (UseCandlestickTrailingStop) CandlestickTrailingStop();
// Hidden stop loss
if (HideStopLossEnabled) HiddenStopLoss();
// Hidden take profit
if (HideTakeProfitEnabled) HiddenTakeProfit();
// 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)
{
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);
if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, MagicNumber, expiry, col);
//Is a 2 stage criminal
if (CriminalIsECN)
{
bool result;
int err;
ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, MagicNumber, expiry, col);
if (ticket > 0)
{
if (take > 0 && stop > 0)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
if (!result)
{
err=GetLastError();
Print(Symbol(), " SL/TP order modify failed with error(",err,"): ",ErrorDescription(err));
}//if (!result)
}//if (take > 0 && stop > 0)
if (take != 0 && stop == 0)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
if (!result)
{
err=GetLastError();
Print(Symbol(), " SL order modify failed with error(",err,"): ",ErrorDescription(err));
}//if (!result)
}//if (take == 0 && stop != 0)
if (take == 0 && stop != 0)
{
while(IsTradeContextBusy()) Sleep(100);
result = OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
if (!result)
{
err=GetLastError();
Print(Symbol(), " SL order modify failed with error(",err,"): ",ErrorDescription(err));
}//if (!result)
}//if (take == 0 && stop != 0)
}//if (ticket > 0)
}//if (CriminalIsECN)
//Error trapping for both
if (ticket < 0)
{
string stype;
if (type == OP_BUY) stype = "OP_BUY";
if (type == OP_SELL) stype = "OP_SELL";
if (type == OP_BUYLIMIT) stype = "OP_BUYLIMIT";
if (type == OP_SELLLIMIT) stype = "OP_SELLLIMIT";
if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
err=GetLastError();
Alert(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
Print(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
return(false);
}//if (ticket < 0)
TicketNo = ticket;
//Make sure the trade has appeared in the platform's history to avoid duplicate trades
O_R_CheckForHistory(ticket);
//Got this far, so trade send succeeded
return(true);
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
/*
bool DoesTradeExist()
{
TicketNo = -1;
if (OrdersTotal() == 0) return(false);
for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
{
if (!OrderSelect(cc,SELECT_BY_POS)) continue;
if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )
{
TicketNo = OrderTicket();
return(true);
}//if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )
}//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
return(false);
}//End bool DoesTradeExist()
*/
void GetPreviousCandleDirection()
{
//Reads the direction of the previous candle
PreviousCandleDirection = none;
if (Close[1] > Open[1] ) PreviousCandleDirection = up;
if (Close[1] < Open[1] ) PreviousCandleDirection = down;
}//End void GetPreviousCandleDirection()
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);
//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);
//Swap filter
if (OpenTrades == 0) TradeDirectionBySwap();
//Max distance from fast ma
if (MathAbs(FastMaVal - Bid) > MaxDistanceFromFastMa * Point) 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);
//This idea from Pippo
if (UseRecovery)
{
if (RecoveryInProgress)
{
if (OpenTrades == 2)
{
SendLots = Lot * 2;
if (Use1.1.3.3Recovery) SendLots = Lot * 3;
}//if (OpenTrades == 2)
if (OpenTrades == 3)
{
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)
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;
GetPreviousCandleDirection();
if (UseChannel) stop = NormalizeDouble((FastMaVal + SlowMaVal) / 2, Digits);
//Long
//if (TradeDirection == buy && PreviousCandleDirection == up && Bid >= FastMaVal && FastMaVal > PrevFastMaVal)
if (TradeDirection == buy && PreviousCandleDirection == up && Bid >= FastMaVal)
{
if (!TradeLong) return;
//Balanced pair trade filter. Only apply to pre-recovery trades.
//Will remove the comments when I add Recovery
//if (OpenTrades + 1 < Start_Recovery_at_trades || !UseRecovery)
//{
if (UseZeljko && !BalancedPair(OP_BUY) ) return;
//}//if (OpenTrades + 1 < Start_Recovery_at_trades)
if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
if (StopLoss > 0) stop = NormalizeDouble(Ask - (StopLoss * Point), Digits);
type = OP_BUY;
price = Ask;
SendTrade = true;
}//if (TradeDirection == buy && PreviousCandleDirection == up)
//Short
//if (TradeDirection == sell && PreviousCandleDirection == down && Bid <= FastMaVal && FastMaVal < PrevFastMaVal)
if (TradeDirection == sell && PreviousCandleDirection == down && Bid <= FastMaVal)
{
if (!TradeShort) return;
//Balanced pair trade filter. Only apply to pre-recovery trades
//Will remove the comments when I add Recovery
//if (OpenTrades + 1 < Start_Recovery_at_trades || !UseRecovery)
//{
if (UseZeljko && !BalancedPair(OP_SELL) ) return;
//}//if (OpenTrades + 1 < Start_Recovery_at_trades)
if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
if (StopLoss > 0) stop = NormalizeDouble(Bid + (StopLoss * Point), Digits);
type = OP_SELL;
price = Bid;
SendTrade = true;
}//if (Ask < 0)
if (SendTrade)
{
bool result = SendSingleTrade(type, TradeComment, SendLots, price, stop, take);
}//if (SendTrade)
//Actions when trade send succeeds
if (SendTrade && result)
{
}//if (result)
//Actions when trade send fails
if (SendTrade && !result)
{
OldBars = 0;
}//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)
{
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 FastMaShift, int method, int ap, int shift)
{
return(iMA(NULL, tf, period, FastMaShift, method, ap, shift) );
}//End double GetMa(int tf, int period, int FastMaShift, int method, int ap, int shift)
void ReadIndicatorValues()
{
//Read MA's and calculate trade direction.
FastMaVal = GetMa(FastMaTF, FastMaPeriod, FastMaShift, FastMaMethod, FastMaAppliedPrice, 0);
SlowMaVal = GetMa(SlowMaTF, SlowMaPeriod, SlowMaShift, SlowMaMethod, SlowMaAppliedPrice, 0);
PrevFastMaVal = GetMa(FastMaTF, FastMaPeriod, FastMaShift, FastMaMethod, FastMaAppliedPrice, MaCandlesLookback);
TradeDirection = none;
//Fast ma is above slow ma and is rising
if (FastMaVal > SlowMaVal && FastMaVal > PrevFastMaVal) TradeDirection = buy;
//Fast ma is below slow ma and is falling
if (FastMaVal < SlowMaVal && FastMaVal < PrevFastMaVal) TradeDirection = sell;
}//void ReadIndicatorValues()
//End Indicator module
////////////////////////////////////////////////////////////////////////////////////////////////
void HedgeTrade()
{
//Hedges a losing trade following a MA recross
//First, remove any tp from the losing trade
OrderModify(TicketNo, OrderOpenPrice(), 0, 0, OrderExpiration(), CLR_NONE);
double SendLots = OrderLots() * HedgeLotsMultiplier;
double type, price;
//Original trade is a buy
RefreshRates();
if (OrderType() == OP_BUY)
{
type = OP_SELL;
price = Bid;
}//if (OrderType() == OP_BUY)
//Original trade is a sell
RefreshRates();
if (OrderType() == OP_SELL)
{
type = OP_BUY;
price = Ask;
}//if (OrderType() == OP_SELL)
bool result = SendSingleTrade(type, TradeComment, SendLots, price, 0, 0);
//Actions when trade send succeeds
if (result)
{
HedgingInProgress = true;
BuyOpen = true;
SellOpen = true;
OpenTrades++;
}//if (!result)
//Actions when trade send fails
if (!result)
{
OldBars = 0;
}//if (!result)
}//void HedgeTrade()
void LookForTradeClosure()
{
//Deal with losing trades
if (!OrderSelect(TicketNo, SELECT_BY_TICKET) ) return;
if (OrderSelect(TicketNo, SELECT_BY_TICKET) && OrderCloseTime() > 0) return;
bool CloseTrade;
if (OrderType() == OP_BUY && TradeDirection == sell)
{
//MA recross
if (UseMaRecross) CloseTrade = true;
//Hedging
if (HedgeNotStopLoss && OpenTrades < 2) HedgeTrade();
}//if (OrderType() == OP_BUY && TradeDirection == sell)
if (OrderType() == OP_SELL && TradeDirection == buy)
{
//MA recross
if (UseMaRecross) CloseTrade = true;
//Hedging
if (HedgeNotStopLoss && OpenTrades < 2) HedgeTrade();
}//if (OrderType() == OP_SELL && TradeDirection == buy)
if (CloseTrade)
{
bool result = CloseTrade(TicketNo);
//Actions when trade send succeeds
if (result)
{
}//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 (OrderSymbol() == Symbol() )
{
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;
}//if (OrderSymbol() == Symbol() )
}//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
}//End void CloseAllTrades()
bool CheckTradingTimes()
{
int hour = TimeHour(TimeLocal() );
if (end_hourm < start_hourm)
{
end_hourm += 24;
}
if (end_houre < start_houre)
{
end_houre += 24;
}
bool ok2Trade = true;
ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);
// adjust for past-end-of-day cases
// eg in AUS, USDJPY trades 09-17 and 22-06
// so, the above check failed, check if it is because of this condition
if (!ok2Trade && hour < 12)
{
hour += 24;
ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);
// so, if the trading hours are 11pm - 6am and the time is between midnight to 11am, (say, 5am)
// the above code will result in comparing 5+24 to see if it is between 23 (11pm) and 30(6+24), which it is...
}
// check for end of day by looking at *both* end-hours
if (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;
BasketUpl = 0;
HedgingInProgress = false;
if (OrdersTotal() == 0) return;
for (int cc = 0; cc <= OrdersTotal(); cc++)
{
if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
OpenTrades++;
TicketNo = OrderTicket();
if (OrderType() == OP_BUY) BuyOpen = true;
if (OrderType() == OP_SELL) SellOpen = true;
BasketUpl+= (OrderProfit() + OrderSwap() + OrderCommission() );
}//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
}//for (int cc = 0; cc < OrdersTotal() - 1; cc++)
if (BuyOpen && SellOpen)
{
HedgingInProgress = true;
}//if (BuyOpen && SellOpen)
}//End void CountOpenTrades();
//=============================================================================
// O_R_CheckForHistory()
//
// This function is to work around a very annoying and dangerous bug in MT4:
// immediately after you send a trade, the trade may NOT show up in the
// order history, even though it exists according to ticket number.
// As a result, EA's which count history to check for trade entries
// may give many multiple entries, possibly blowing your account!
//
// This function will take a ticket number and loop until
// it is seen in the history.
//
// RETURN VALUE:
// TRUE if successful, FALSE otherwise
//
//
// FEATURES:
// * Re-trying under some error conditions, sleeping a random
// time defined by an exponential probability distribution.
//
// * Displays various error messages on the log for debugging.
//
// ORIGINAL AUTHOR AND DATE:
// Matt Kennel, 2010
//
//=============================================================================
bool O_R_CheckForHistory(int ticket)
{
//My thanks to Matt for this code. He also has the undying gratitude of all users of my trading robots
int lastTicket = OrderTicket();
int cnt = 0;
int err = GetLastError(); // so we clear the global variable.
err = 0;
bool exit_loop = false;
bool success=false;
while (!exit_loop) {
/* loop through open trades */
int total=OrdersTotal();
for(int c = 0; c < total; c++) {
if(OrderSelect(c,SELECT_BY_POS,MODE_TRADES) == true) {
if (OrderTicket() == ticket) {
success = true;
exit_loop = true;
}
}
}
if (cnt > 3) {
/* look through history too, as order may have opened and closed immediately */
total=OrdersHistoryTotal();
for(c = 0; c < total; c++) {
if(OrderSelect(c,SELECT_BY_POS,MODE_HISTORY) == true) {
if (OrderTicket() == ticket) {
success = true;
exit_loop = true;
}
}
}
}
cnt = cnt+1;
if (cnt > 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 < 10) {
ms=10;
}
Sleep(ms);
}//End void O_R_Sleep(double mean_time, double max_time)
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Balance/swap filters module
void TradeDirectionBySwap()
{
//Sets TradeLong & TradeShort according to the positive/negative swap it attracts
double LongSwap = MarketInfo(Symbol(), MODE_SWAPLONG);
double ShortSwap = MarketInfo(Symbol(), MODE_SWAPSHORT);
if (CadPairsPositiveOnly)
{
if (StringSubstr(Symbol(), 0, 3) == "CAD" || StringSubstr(Symbol(), 0, 3) == "cad" || StringSubstr(Symbol(), 3, 3) == "CAD" || StringSubstr(Symbol(), 3, 3) == "cad" )
{
if (LongSwap > 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;
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 (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; i<ExtSymbolsTotal; i++)
{
if (ExtSymbols[i] != Symbol() ) continue;
if(ExtSymbolsSummaries[i][DEALS]<=0) continue;
line++;
//---- add line
if(line>ExtLines)
{
int y_dist=ExtVertShift*(line+1)+1;
ExtLines++;
}//if(line>ExtLines)
//---- set line
//color price_colour;//Steve mod
int digits=MarketInfo(ExtSymbols[i],MODE_DIGITS);
double buy_lots=ExtSymbolsSummaries[i][BUY_LOTS];
double sell_lots=ExtSymbolsSummaries[i][SELL_LOTS];
if(buy_lots!=0) buy_price=NormalizeDouble(ExtSymbolsSummaries[i][BUY_PRICE]/buy_lots, Digits);
if(sell_lots!=0) sell_price=NormalizeDouble(ExtSymbolsSummaries[i][SELL_PRICE]/sell_lots, Digits);
}//for(i=0; i<ExtSymbolsTotal; i++)
}//if(total>0)
}//End void CheckRecoveryTakeProfit()
int Analyze()
{
double profit;
int i,index,type,total=OrdersTotal();
//----
for(i=0; i<total; i++)
{
if(!OrderSelect(i,SELECT_BY_POS)) continue;
type=OrderType();
if(type!=OP_BUY && type!=OP_SELL) continue;
index=SymbolsIndex(OrderSymbol());
if(index<0 || index>=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; i<ExtSymbolsTotal; i++)
{
if(ExtSymbolsSummaries[i][DEALS]>0) total++;
}
//----
return(total);
}//int Analyze()
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int SymbolsIndex(string SymbolName)
{
bool found=false;
//----
for(int i=0; i<ExtSymbolsTotal; i++)
{
if(SymbolName==ExtSymbols[i])
{
found=true;
break;
}
}
//----
if(found) return(i);
if(ExtSymbolsTotal>=SYMBOLS_MAX) return(-1);
//----
i=ExtSymbolsTotal;
ExtSymbolsTotal++;
ExtSymbols[i]=SymbolName;
ExtSymbolsSummaries[i][DEALS]=0;
ExtSymbolsSummaries[i][BUY_LOTS]=0;
ExtSymbolsSummaries[i][BUY_PRICE]=0;
ExtSymbolsSummaries[i][SELL_LOTS]=0;
ExtSymbolsSummaries[i][SELL_PRICE]=0;
ExtSymbolsSummaries[i][NET_LOTS]=0;
ExtSymbolsSummaries[i][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.
//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 <= target)
{
ForceTradeClosure = true;
CloseAllTrades();
ObjectDelete(breakevenlinename);
return;
}//if (Ask <= target)
}//if (OrderType() == OP_BUY)
//The most recent trade selected in CountOpenTrades will show the type of trades involved
if (SellOpen)
{
//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 (Bid <= 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 (Bid <= 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 (High[1] < target)
{
ObjectMove(breakevenlinename, 0, TimeCurrent(), High[1]);
}//if (High[1] < target)
OldRecoverTrailBars = Bars;
//return;
}//if (OldRecoverTrailBars != Bars)
//Has the market retraced to the recovery stop loss
target = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
//Alert("Target = ", target);
if (Bid >= target)
{
ForceTradeClosure = true;
CloseAllTrades();
ObjectDelete(breakevenlinename);
return;
}//if (Bid >= target)
}//if (OrderType() == OP_SELL)
}//End void RecoveryCandlesticktrailingStop()
//End Recovery module
///////////////////////////////////////////////////////////////////////////////////////////////////////
*/
void HedgeTheHedgeTrade()
{
//Hedges a hedge trade if the ma's have recrossed. Called from start() if HedgingInProgress is set
//Find the latest trade
for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
{
if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
if (OrderType() == OP_BUY && TradeDirection == sell) HedgeTrade();
if (OrderType() == OP_SELL && TradeDirection == buy) HedgeTrade();
return;
}//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
}//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
}//End void HedgeTheHedgeTrade()
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
static bool TradeExists;
if (OrdersTotal() == 0)
{
TicketNo = -1;
ForceTradeClosure = false;
}//if (OrdersTotal() == 0)
if (ForceTradeClosure)
{
CloseAllTrades();
return;
}//if (ForceTradeClosure)
if (HedgingInProgress)
{
CountOpenTrades();
if (BasketUpl >= 0)
{
CloseAllTrades();
return;
}//if (BasketUpl >= 0)
//Does the hedge trade need hedging? This function performs this task if necessary
if (HedgeTheHedge) HedgeTheHedgeTrade();
}//if (HedgingInProgress)
///////////////////////////////////////////////////////////////////////////////////////////////
//Find open trades.
CountOpenTrades();
if (OpenTrades == 1)
{
if (OrderProfit() > 0 && !HedgingInProgress) TradeManagementModule();
LookForTradeClosure();
}//if (TradeExists)
///////////////////////////////////////////////////////////////////////////////////////////////
/*
//Recovery
if (UseRecovery)
{
if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
//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)
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//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 < start_hourm)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Available margin filters
if (UseScoobsMarginCheck && OpenTrades > 0)
{
if(AccountMargin() > (AccountFreeMargin()/100) && TicketNo == -1)
{
Comment(Gap + "There is insufficient margin to allow trading. You might want to turn off the UseScoobsMarginCheck input.");
return;
}//if(AccountMargin() > (AccountFreeMargin()/100))
}//if (UseScoobsMarginCheck)
if (UseForexKiwi && AccountMargin() > 0)
{
double ml = NormalizeDouble(AccountEquity() / AccountMargin() * 100, 2);
if (ml < FkMinimumMarginPercent && TicketNo == -1)
{
Comment(Gap + "There is insufficient margin percent to allow trading. " + DoubleToStr(ml, 2) + "%");
return;
}//if (ml < FkMinimumMarginPercent)
}//if (UseForexKiwi && AccountMargin() > 0)
///////////////////////////////////////////////////////////////////////////////////////////////
//Trading
if (OldBars != Bars)
{
OldBars = Bars;
ReadIndicatorValues();
if (TicketNo > -1 && StopLoss == 0 && OrderProfit() > 0 && UseChannel)
{
ModifyFastMaStopLoss();
}//if (TicketNo > -1)
if (TicketNo == -1 && !StopTrading)
{
LookForTradingOpportunities();
}//if (TicketNo == -1)
}//if (OldBars != Bars)
///////////////////////////////////////////////////////////////////////////////////////////////
DisplayUserFeedback();
//----
return(0);
}
//+------------------------------------------------------------------+
i'd like to convert this code.
@cservenak