Untitled
unknown
c_cpp
3 years ago
66 kB
9
Indexable
//+------------------------------------------------------------------+ //| pmhouse_ZR_v7p4 | //| A. Sweeney | //+------------------------------------------------------------------+ #property copyright "Click here for the latest version" #property description "Coded by: A Sweeney - Updated: pcei" #property link "https://oneglancetrader.com/download" #property strict // inputs, RSI OB/OS levels, RSI period, RSI timeframes // if ob/os = false and ob/os[+1] = true take the trade //+------------------------------------------------------------------+ //| Includes and object initialization | //+------------------------------------------------------------------+ enum EA_Setting {Manual, RSI_MTF}; // enum Trade_Volume {Fixed_Lot, Fixed_P enum CLOSE_PENDING_TYPE { CLOSE_BUY_LIMIT, CLOSE_SELL_LIMIT, CLOSE_BUY_STOP, CLOSE_SELL_STOP, CLOSE_ALL_PENDING }; //+------------------------------------------------------------------+ //| Input variables | //+------------------------------------------------------------------+ sinput string UtilitySettings; // ** UTILITY SETTINGS ** input bool Push_Notifications = true; input bool WriteSpreadHistory = false; input string SpreadFileName_csv = "spreadHistory.csv"; sinput string RecoverySettings; // ** ZONE RECOVERY SETTINGS ** input int HeSoPoint = 100000; //GU:100000; BTC:100; JPY-XAU:1000 input int SlippageOpenOrder = 3; extern int RecoveryZoneSize = 200; // Recovery Zone Size (points) extern int TakeProfit = 200; // Take Profit (points) input int MaxTrades = 0; // Max Trades (0 for unlimited) input bool SetMaxLoss = false; // Max Loss after Max Trades reached? input double MaxLoss = 0; // Max Loss after Max Trades (0 for unlimted) in deposit currency. input bool UseRecoveryTakeProfit = true; // Use a Recovery Take Profit input int RecoveryTakeProfit = 30; // Recovery Take Profit (points). extern double PendingPrice = 0; // Price for pending orders //sinput string ATRHeader; // ** ATR Dynamic Zone Sizing ** bool UseATR = false; // Use ATR? int ATRPeriod = 14; // ATR Period double ATRZoneFraction = 0.2; // Fraction of ATR to use as Recovery Zone double ATRTPFraction = 0.3; // Fraction or ATR to use for TP sizes double ATRRecoveryZone = 0.15; // Fraction of ATR to use for recovery TP. sinput string MoneyManagement; // ** MONEY MANAGEMENT SETTINGS ** input double RiskPercent = 0; // Account % Initial Lot Size (set to 0 if not used) input double InitialLotSize = 0.01; // Initial Lot Size (if % not used) input double LotMultiplier = 2; // Multiplier for Lots input double LotAdditions = 0; sinput string CustomLotSizing; // ** CUSTOM LOT SIZES ** input double CustomLotSize1 = 0; input double CustomLotSize2 = 0; input double CustomLotSize3 = 0; input double CustomLotSize4 = 0; input double CustomLotSize5 = 0; input double CustomLotSize6 = 0; input double CustomLotSize7 = 0; input double CustomLotSize8 = 0; input double CustomLotSize9 = 0; input double CustomLotSize10 = 0; //sinput string TimerSettings; // ** TIMER SETTINGS ** bool UseTimer = false; // Use a Trade Timer? int StartHour = 0; // Start Hour int StartMinute = 0; // Start Minute int EndHour = 0; // End Hour int EndMinute = 0; // End Minute bool UseLocalTime = false; // Use local time? //sinput string TradeSettings; // ** EA SETTINGS ** EA_Setting EA_Mode= Manual; int RSIPeriod = 14; // RSI Period double OverboughtLevel = 70; //Over-bought level double OversoldLevel = 30; // Over-sold level bool UseM1Timeframe = true; // Use M1 Timeframe? bool UseM5Timeframe = true; // Use M5 Timeframe? bool UseM15Timeframe = true; // Use M15 Timeframe? bool UseM30Timeframe = true; // Use M30 Timeframe? bool UseH1Timeframe = true; // Use H1 Timeframe? bool UseH4Timeframe = true; // Use H4 Timeframe? bool UseDailyTimeframe = true; // Use Daily Timeframe? bool UseWeeklyTimeframe = false; // Use Weekly Timeframe? bool UseMonthlyTimeframe = false; // Use Monthly Timeframe? sinput string Visuals; // ** VISUALS ** input color profitLineColor = clrLightSeaGreen; input int Panel_X = 120; // Panel X coordinate. input int Panel_Y = 40; // Panel Y coordinate. input color Panel_Color = clrBlack; // Panel background colour. input color Panel_Lable_Color = clrWhite; // Panel lable text color. sinput string BacktestingSettings; // ** OTHER SETTINGS ** input int MagicNumber = 030589; // Magic Number input int Slippage = 100; // Slippage Max (Points). bool TradeOnBarOpen = true; // Trade on New Bar? int speed = 500; // Back tester speed double TestCommission = 7; // Back tester simulated commission //+------------------------------------------------------------------+ //| Global variable and indicators | //+------------------------------------------------------------------+ #define EA_NAME "pmhouse_ZR_v7p4" #define SELL_BUTTON "Sell Button" #define BUY_BUTTON "Buy Button" #define PENDING_EDIT "Pending Edit" #define CLOSE_ALL_BUTTON "Close All Button" #define TP_EDIT "TP Edit" #define ZONE_EDIT "Zone Edit" string gTradingPanelObjects[100]; #define PROFIT_LINE "Profit Line" datetime gLastTime; int gInitialTicket; double gBuyOpenPrice; double gSellOpenPrice; double gBuyTakeProfit; double gSellTakeProfit; double gLotSize; double gInitialLotSize; double gInitialProfitTarget; bool gRecoveryInitiated; int gBuyStopTicket = 0; int gSellStopTicket = 0; int gBuyTicket = 0; int gSellTicket = 0; double gCustomLotSizes[10]; double UsePip; double UseSlippage; double gCurrentDirection; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { gRecoveryInitiated = false; gCurrentDirection = 0; // Set magic number UsePip = PipPoint(Symbol()); UseSlippage = GetSlippage(Symbol(), Slippage); gLastTime = 0; gCustomLotSizes[0] = CustomLotSize1; gCustomLotSizes[1] = CustomLotSize2; gCustomLotSizes[2] = CustomLotSize3; gCustomLotSizes[3] = CustomLotSize4; gCustomLotSizes[4] = CustomLotSize5; gCustomLotSizes[5] = CustomLotSize6; gCustomLotSizes[6] = CustomLotSize7; gCustomLotSizes[7] = CustomLotSize8; gCustomLotSizes[8] = CustomLotSize9; gCustomLotSizes[9] = CustomLotSize10; CreateTradingPanel(); Print("INIT SUCCESFUL, Recovery Initiated: ", gRecoveryInitiated, " Current Dirn: ", gCurrentDirection, " Magic No: ", MagicNumber, " Slippage: ", Slippage); if(OrdersTotal() > 0) FindOpenOrders(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert Shutdown function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { switch(reason) { case 0: { DeleteTradePanel(); Print("EA De-Initialised, removed by EA"); break; } case 1: { DeleteTradePanel(); Print("EA De-Initialised, removed by user"); break; } case 2: { DeleteTradePanel(); Print("EA De-Initialised, EA recompiled"); break; } case 3: { DeleteTradePanel(); Print("EA De-Initialised, Symbol changed"); break; } case 4: { DeleteTradePanel(); Print("EA De-Initialised, chart closed by user."); break; } case 5: { Print("EA De-Initialised, input parameters changed."); break; } case 6: { Print("EA De-Initialised, account changed"); break; } case 7: { DeleteTradePanel(); Print("EA De-Initialised, A new template has been applied."); break; } case 8: { DeleteTradePanel(); Print("EA De-Initialised, EA failed to initialize."); break; } case 9: { DeleteTradePanel(); Print("EA De-Initialised, Terminal closed by user."); break; } } } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { //Write spread history to a specific file: if(WriteSpreadHistory == true) { int countAlert = 0; if(countAlert < 1) { Alert("Writing the spread to file..."); countAlert++; } saveSpread(SpreadFileName_csv); } if(IsVisualMode() == true) { int Waitloop = 0; while(Waitloop < speed) { Waitloop++; } } // Check timer bool tradeEnabled = true; if(UseTimer == true) { tradeEnabled = CheckDailyTimer(); } // Check for bar open bool newBar = true; int barShift = 0; // check if a new bar has been opened if(TradeOnBarOpen == true) { newBar = false; datetime time[]; bool firstRun = false; CopyTime(_Symbol,PERIOD_CURRENT,0,2,time); if(gLastTime == 0) firstRun = true; if(time[0] > gLastTime) { if(firstRun == false) newBar = true; gLastTime = time[0]; } barShift = 1; } // Money management // set lot size to initial lot size for doubling later gInitialLotSize = CheckVolume(_Symbol, InitialLotSize); // check the input value for lot initial lot size and set to initial if(RiskPercent != 0) { int StopLoss = TakeProfit; if(UseATR == true) { double atr = iATR(_Symbol, PERIOD_D1, ATRPeriod, 1); StopLoss = (int)round((atr*ATRTPFraction)/_Point); // set the stop loss a fraction of atr in points } gInitialLotSize = GetTradeSize(_Symbol,InitialLotSize,RiskPercent,StopLoss); } // Check entries on new bar if(newBar == true && tradeEnabled == true) // check for new bar and whether timer allows to open { switch(EA_Mode) { case RSI_MTF: { int direction = Is_RSI_OBOS_on_MTF(barShift + 1); int nowFalse = Is_RSI_OBOS_on_MTF(barShift); if(direction == 1 && nowFalse == 0) { Print("Buy signal generated."); if(gCurrentDirection == 0) { TakeTrade(direction); Print("Buy signal generated."); } else { Print("Buy signal not used as EA in trade on ", _Symbol); } } else if(direction == -1 && nowFalse == 0) { if(gCurrentDirection == 0) { TakeTrade(direction); Print("Sell signal generated."); } else { Print("Sell signal not used as EA in trade on ", _Symbol); } } } } } if(gCurrentDirection != 0) { // on every tick work out the average price // count the number of buy and sell orders int positions = 0; double averagePrice = 0; double currentProfit = 0; double positionSize = 0; double netLotSize = 0; double totalCommision = 0; double totalSpreadCosts = 0; double point_value = _Point*MarketInfo(_Symbol, MODE_TICKVALUE)/MarketInfo(_Symbol, MODE_TICKSIZE); for(int counter = 0; counter <= OrdersTotal() - 1; counter++) { if(OrderSelect(counter, SELECT_BY_POS)) { if(OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()) { positions += 1; currentProfit += OrderProfit(); if(OrderType() == OP_BUY) { positionSize += (OrderOpenPrice()*OrderLots()); netLotSize += OrderLots(); totalSpreadCosts += (OrderLots()*MarketInfo(_Symbol, MODE_SPREAD)*point_value); totalCommision += OrderCommission(); } else if(OrderType() == OP_SELL) { positionSize -= (OrderOpenPrice()*OrderLots()); netLotSize -= OrderLots(); totalSpreadCosts += (OrderLots()*MarketInfo(_Symbol, MODE_SPREAD)*point_value); totalCommision += OrderCommission(); } } } } // if the current profits are greater than the desired recovery profit and costs close the trades double volume; if(CustomLotSize1 != 0) volume = CustomLotSize1; else volume = gInitialLotSize; double profitTarget = (RecoveryTakeProfit + minRecoveryZone())*point_value*volume; if(UseATR == true) { double atr = iATR(_Symbol, PERIOD_D1, ATRPeriod, 1); profitTarget = (ATRRecoveryZone*atr*point_value*volume)/_Point; } // simulate commission for backtesting double tradeCosts = 0; if(IsTesting()) { tradeCosts = totalSpreadCosts+(MathAbs(netLotSize)*TestCommission); } else { tradeCosts = totalSpreadCosts+totalCommision; // spread and commision } double tp = RecoveryTakeProfit + minRecoveryZone(); if(UseRecoveryTakeProfit == false || gRecoveryInitiated == false) { profitTarget = (TakeProfit + minRecoveryZone())*point_value*volume; // initial profit is equal to planned rz over tp, in $$ } if(currentProfit >= (profitTarget +tradeCosts)) { CloseOrdersAndReset(); Print("Orders closed, profit target of: ", DoubleToStr(profitTarget, 2), "$ exceeded at: ", DoubleToStr(currentProfit, 2), "$, Costs(", DoubleToStr(tradeCosts, 2), "$)"); } if(netLotSize != 0) { averagePrice = NormalizeDouble(positionSize/netLotSize, _Digits); Comment(StringConcatenate("Average Price: ", DoubleToStr(averagePrice, _Digits), ", Profit Target: $", DoubleToStr(profitTarget, 2), " + Trade Costs: $", DoubleToStr(tradeCosts, 2), ", Running Profit: $", DoubleToStr(currentProfit, 2), ", MinRZS: ", IntegerToString(minRecoveryZone()))); } if(positions >= MaxTrades && MaxTrades != 0 && currentProfit < -MaxLoss && SetMaxLoss == true) { CloseOrdersAndReset(); Print("Orders closed, max trades reached and max loss of: -$", MaxLoss, " by $", currentProfit); } // set the take profit line price double temp_profitPrice = 0; if(gCurrentDirection == 1 && netLotSize != 0) { tp = (profitTarget + tradeCosts - currentProfit)*_Point/(point_value*netLotSize); double profitPrice = NormalizeDouble(Bid + tp, _Digits); temp_profitPrice = profitPrice; if(!ObjectSetDouble(0, PROFIT_LINE, OBJPROP_PRICE, profitPrice)) Print("Could not set line"); } else if(gCurrentDirection == -1 && netLotSize != 0) { tp = (profitTarget + tradeCosts - currentProfit)*_Point/(point_value*netLotSize); double profitPrice = NormalizeDouble(Ask + tp, _Digits); temp_profitPrice = profitPrice; if(!ObjectSetDouble(0, PROFIT_LINE, OBJPROP_PRICE, profitPrice)) Print("Could not set line"); } SymbolProfitAtSpecificPrice(temp_profitPrice); // check if the current direction is buy and the bid price (sell stop has opened) is below the recovery line if(gCurrentDirection == 1) { double price = MarketInfo(Symbol(), MODE_ASK); if(OrderSelect(gSellStopTicket, SELECT_BY_TICKET)) { if(OrderType() == OP_SELL) // if the sell stop has opened { Print("Recovery Sell Stop has been opened, initiating recovery..."); gSellTicket = gSellStopTicket; // make the stop a sell ticket gSellStopTicket = 0; // reset the sell stop ticket // increase the lot size gLotSize = GetTradeVolume(positions+1); if(MaxTrades == 0 || positions < MaxTrades) // check we've not exceeded the max trades { // open a buy stop order at double the running lot size gBuyStopTicket = OpenPendingOrder(Symbol(), OP_BUYSTOP, gLotSize, gBuyOpenPrice, 0, 0, StringConcatenate("Recovery Buy Stop opened."), 0, clrTurquoise); // create an opposite buy stop gRecoveryInitiated = true; // signal that we are in recovery mode } // change the current direction to sell gCurrentDirection = -1; } } else { static int counterAlert1 = 0; if(counterAlert1 < 1) { string message = "Warning - EA could not find the recovery Sell Stop for " + Symbol(); sendNotification(AccountName() + " - " + Symbol() + " cannot open the SELL STOP order"); Alert(message); Print(message); counterAlert1++; } } } // check if the current direction is sell and the ask price (sell stop has opened) is below the recovery line if(gCurrentDirection == -1) { double price = MarketInfo(Symbol(), MODE_BID); if(OrderSelect(gBuyStopTicket, SELECT_BY_TICKET)) { if(OrderType() == OP_BUY) // if the buy stop has opened { Print("Recovery Buy Stop has been opene, initiating recovery..."); gBuyTicket = gBuyStopTicket; // set the buy ticket to the stop gBuyStopTicket = 0; // reset the buy ticket // increase the lot size gLotSize = GetTradeVolume(positions+1); if(MaxTrades == 0 || positions < MaxTrades) // check we've not exceeded the max trades { // open a sell stop order at double the running lot size gSellStopTicket = OpenPendingOrder(Symbol(), OP_SELLSTOP, gLotSize, gSellOpenPrice, 0, 0, StringConcatenate("Recovery Sell Stop opened."), 0, clrPink); // create an opposite sell stop gRecoveryInitiated = true; // signal we're in recovery mode } // change the current direction to sell gCurrentDirection = 1; } } else { static int counterAlert2 = 0 ; if(counterAlert2 < 1) { string message = "Warning - EA could not find the recovery Buy Stop" + Symbol(); sendNotification(AccountName() + " - " + Symbol() + " cannot open the BUY STOP order"); Alert(message); Print(message); counterAlert2++; } } } } else { Comment("No OGT Zone Recovery Trades Active"); } } // Initial trade taking algorithm //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void TakeTrade(int direction) { double tp = 0; double rz = 0; // if the user has selected to use the ATR to size zones if(UseATR == true) { double atr = iATR(_Symbol, PERIOD_D1, ATRPeriod, 1); tp = atr*ATRTPFraction; rz = atr*ATRZoneFraction; //TakeProfit = tp; //RecoveryZoneSize = rz; } else if(UseATR == false) { if(RecoveryZoneSize < minRecoveryZone()) { rz = 5*(RecoveryZoneSize + minRecoveryZone())*_Point; } else { rz = RecoveryZoneSize*_Point; } if(TakeProfit < minRecoveryZone()) { tp = 5*(TakeProfit + minRecoveryZone())*_Point; } else { tp = TakeProfit*_Point; } } if(CustomLotSize1 != 0) gLotSize = CustomLotSize1; else gLotSize = gInitialLotSize; double price = 0; if(direction == 1) { gBuyTicket = OpenMarketOrder(Symbol(), OP_BUY, gLotSize, "Initial Buy Order", clrGreen); if(OrderSelect(gBuyTicket, SELECT_BY_TICKET)) { gBuyOpenPrice = OrderOpenPrice(); gSellOpenPrice = NormalizeDouble((gBuyOpenPrice - rz), _Digits); gBuyTakeProfit = NormalizeDouble((gBuyOpenPrice + tp), _Digits); gSellTakeProfit = NormalizeDouble((gBuyOpenPrice - (tp + rz)), _Digits); // ModifyStopsByPrice(gBuyTicket, gSellTakeProfit, gBuyTakeProfit); //open a recovery stop order in the opposite direction gLotSize = GetTradeVolume(2); gSellStopTicket = OpenPendingOrder(Symbol(), OP_SELLSTOP, gLotSize, gSellOpenPrice, 0, 0, "Initial Recovery Sell Stop)", 0, clrPink); gCurrentDirection = direction; price = gBuyOpenPrice; } } // Sell Trade else if(direction == -1) { gSellTicket = OpenMarketOrder(Symbol(), OP_SELL, gLotSize, "Initial Sell Order", clrRed); if(OrderSelect(gSellTicket, SELECT_BY_TICKET)) { gSellOpenPrice = OrderOpenPrice(); gBuyOpenPrice = NormalizeDouble((gSellOpenPrice + rz), _Digits); gSellTakeProfit = NormalizeDouble((gSellOpenPrice - tp), _Digits); gBuyTakeProfit = NormalizeDouble((gSellOpenPrice + (tp + rz)), _Digits); // ModifyStopsByPrice(gSellTicket, gBuyTakeProfit, gSellTakeProfit); //open a recovery stop order in the opposite direction gLotSize = GetTradeVolume(2); gBuyStopTicket = OpenPendingOrder(Symbol(), OP_BUYSTOP, gLotSize, gBuyOpenPrice, 0, 0, "Initial Recovery Buy Stop)", 0, clrTurquoise); gCurrentDirection = direction; price = gSellOpenPrice; } } CreateProfitLine(direction, price, tp); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PlaceTrade(int pType) { double tp = 0; double rz = 0; // if the user has selected to use the ATR to size zones if(UseATR == true) { double atr = iATR(_Symbol, PERIOD_D1, ATRPeriod, 1); tp = atr*ATRTPFraction; rz = atr*ATRZoneFraction; //TakeProfit = tp; //RecoveryZoneSize = rz; } else if(UseATR == false) { if(RecoveryZoneSize < minRecoveryZone()) { rz = 5*(RecoveryZoneSize + minRecoveryZone())*_Point; } else { rz = RecoveryZoneSize*_Point; } if(TakeProfit < minRecoveryZone()) { tp = 5*(TakeProfit + minRecoveryZone())*_Point; } else { tp = TakeProfit*_Point; } } if(CustomLotSize1 != 0) gLotSize = CustomLotSize1; else gLotSize = gInitialLotSize; if(pType == OP_BUYLIMIT) { gBuyStopTicket = OpenPendingOrder(Symbol(), OP_BUYLIMIT, gLotSize, PendingPrice, 0, 0, "Buy Limit Order", 0, 0); gBuyOpenPrice = PendingPrice; gSellOpenPrice = NormalizeDouble((gBuyOpenPrice - rz), _Digits); gCurrentDirection = -1; } else if(pType == OP_BUYSTOP) { gBuyStopTicket = OpenPendingOrder(Symbol(), OP_BUYSTOP, gLotSize, PendingPrice, 0, 0, "Buy Stop Order", 0, 0); gBuyOpenPrice = PendingPrice; gSellOpenPrice = NormalizeDouble((gBuyOpenPrice - rz), _Digits); gCurrentDirection = -1; } else if(pType == OP_SELLLIMIT) { gSellOpenPrice = PendingPrice; gBuyOpenPrice = NormalizeDouble((gSellOpenPrice + rz), _Digits); gSellStopTicket = OpenPendingOrder(Symbol(), OP_SELLLIMIT, gLotSize, PendingPrice, 0, 0, "Sell Limit Order", 0, 0); gCurrentDirection = 1; } else if(pType == OP_SELLSTOP) { gSellOpenPrice = PendingPrice; gBuyOpenPrice = NormalizeDouble((gSellOpenPrice + rz), _Digits); gSellStopTicket = OpenPendingOrder(Symbol(), OP_SELLSTOP, gLotSize, PendingPrice, 0, 0, "Sell Stop Order", 0, 0); gCurrentDirection = 1; } CreateProfitLine(gCurrentDirection, PendingPrice, 0); } // RSI Entry Function //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int Is_RSI_OBOS_on_MTF(int shift) { int direction = 0; // check if the MTF is showing oversold, buy signal double rsi = iRSI(_Symbol, PERIOD_M1, RSIPeriod, PRICE_CLOSE, shift); if((UseM1Timeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_M5, RSIPeriod, PRICE_CLOSE, shift); if(UseM5Timeframe == false || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_M15, RSIPeriod, PRICE_CLOSE, shift); if((UseM15Timeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_M30, RSIPeriod, PRICE_CLOSE, shift); if((UseM30Timeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_H1, RSIPeriod, PRICE_CLOSE, shift); if((UseH1Timeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_H4, RSIPeriod, PRICE_CLOSE, shift); if((UseH4Timeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_D1, RSIPeriod, PRICE_CLOSE, shift); if((UseDailyTimeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_W1, RSIPeriod, PRICE_CLOSE, shift); if((UseWeeklyTimeframe == false) || (rsi < OversoldLevel)) { rsi = iRSI(_Symbol, PERIOD_MN1, RSIPeriod, PRICE_CLOSE, shift); if((UseMonthlyTimeframe == false) || (rsi < OversoldLevel)) { direction = 1; return direction; } } } } } } } } } // check if the MTF is showing overbought, sell signal rsi = iRSI(_Symbol, PERIOD_M1, RSIPeriod, PRICE_CLOSE, shift); if((UseM1Timeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_M5, RSIPeriod, PRICE_CLOSE, shift); if(UseM5Timeframe == false || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_M15, RSIPeriod, PRICE_CLOSE, shift); if((UseM15Timeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_M30, RSIPeriod, PRICE_CLOSE, shift); if((UseM30Timeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_H1, RSIPeriod, PRICE_CLOSE, shift); if((UseH1Timeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_H4, RSIPeriod, PRICE_CLOSE, shift); if((UseH4Timeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_D1, RSIPeriod, PRICE_CLOSE, shift); if((UseDailyTimeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_W1, RSIPeriod, PRICE_CLOSE, shift); if((UseWeeklyTimeframe == false) || (rsi > OverboughtLevel)) { rsi = iRSI(_Symbol, PERIOD_MN1, RSIPeriod, PRICE_CLOSE, shift); if((UseMonthlyTimeframe == false) || (rsi > OverboughtLevel)) { direction = -1; return direction; } } } } } } } } } return direction; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseOrdersAndReset() { CloseAllMarketOrders(); DeletePendingOrders(CLOSE_ALL_PENDING); gLotSize = gInitialLotSize; gCurrentDirection = 0; gBuyStopTicket = 0; gSellStopTicket = 0; gBuyTicket = 0; gSellTicket = 0; gRecoveryInitiated = false; DeleteProfitLine(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CreateProfitLine(double pDirection, double pPrice, double pPoints) { double price = 0; if(pDirection == 1) { price = NormalizeDouble(pPrice + pPoints, _Digits); } else if(pDirection == -1) { price = NormalizeDouble(pPrice - pPoints, _Digits); } ObjectCreate(0, PROFIT_LINE, OBJ_HLINE, 0,0,price); ObjectSetInteger(0, PROFIT_LINE, OBJPROP_COLOR, profitLineColor); ObjectSetInteger(0, PROFIT_LINE, OBJPROP_STYLE, STYLE_DASH); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DeleteProfitLine() { ObjectDelete(0, PROFIT_LINE); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CreateTradingPanel() { // create the button to start the trade off long buttonWidth = 50; long buttonHeight = 25; long panelX = Panel_X; long panelY = Panel_Y; long boxMargin = 10; long lableX = panelX+boxMargin+5; long lableY = panelY+boxMargin+10; long lableHeight = 40; long buttonX = panelX+boxMargin+20; long buttonY = panelY+lableHeight+boxMargin; long panelWidth = boxMargin+buttonWidth+boxMargin+buttonWidth+boxMargin +40; long panelHeight = boxMargin+lableHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin; double pending = NormalizeDouble(PendingPrice, MarketInfo(Symbol(), MODE_DIGITS)); string buttonBox = "ButtonBox"; ObjectCreate(0, buttonBox, OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0,buttonBox,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0, buttonBox, OBJPROP_XSIZE, panelWidth); ObjectSetInteger(0, buttonBox, OBJPROP_YSIZE, panelHeight); ObjectSetInteger(0, buttonBox, OBJPROP_XDISTANCE, panelX); ObjectSetInteger(0, buttonBox, OBJPROP_YDISTANCE, panelY); ObjectSetInteger(0, buttonBox, OBJPROP_BGCOLOR, Panel_Color); ObjectSetInteger(0,buttonBox,OBJPROP_BORDER_TYPE,BORDER_RAISED); ObjectSetInteger(0,buttonBox,OBJPROP_COLOR,clrGray); ObjectSetInteger(0,buttonBox,OBJPROP_SELECTABLE,false); ObjectSetInteger(0,buttonBox,OBJPROP_HIDDEN,false); ObjectSetInteger(0,buttonBox,OBJPROP_ZORDER,0); gTradingPanelObjects[0] = buttonBox; string panelLabel = "Trading Panel Label"; ObjectCreate(0, panelLabel, OBJ_LABEL, 0,0,0); ObjectSetString(0, panelLabel, OBJPROP_TEXT, EA_NAME); ObjectSetInteger(0, panelLabel, OBJPROP_XDISTANCE, lableX); ObjectSetInteger(0, panelLabel, OBJPROP_YDISTANCE, lableY); ObjectSetInteger(0, panelLabel, OBJPROP_COLOR, Panel_Lable_Color); ObjectSetInteger(0, panelLabel, OBJPROP_FONTSIZE, 9); gTradingPanelObjects[1] = panelLabel; string sellButtonName = SELL_BUTTON; ObjectCreate(0, sellButtonName, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, sellButtonName, OBJPROP_XSIZE, buttonWidth); ObjectSetInteger(0, sellButtonName, OBJPROP_YSIZE, buttonHeight); ObjectSetInteger(0, sellButtonName, OBJPROP_XDISTANCE, buttonX); ObjectSetInteger(0, sellButtonName, OBJPROP_YDISTANCE, buttonY); ObjectSetInteger(0, sellButtonName, OBJPROP_COLOR, Panel_Lable_Color); ObjectSetInteger(0, sellButtonName, OBJPROP_BGCOLOR, clrRed); ObjectSetString(0, sellButtonName, OBJPROP_TEXT, "Sell"); gTradingPanelObjects[2] = SELL_BUTTON; string buyButtonName = BUY_BUTTON; ObjectCreate(0, buyButtonName, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, buyButtonName, OBJPROP_XSIZE, buttonWidth); ObjectSetInteger(0, buyButtonName, OBJPROP_YSIZE, buttonHeight); ObjectSetInteger(0, buyButtonName, OBJPROP_XDISTANCE, (buttonX+buttonWidth+boxMargin)); ObjectSetInteger(0, buyButtonName, OBJPROP_YDISTANCE, buttonY); ObjectSetInteger(0, buyButtonName, OBJPROP_COLOR, Panel_Lable_Color); ObjectSetInteger(0, buyButtonName, OBJPROP_BGCOLOR, clrGreen); ObjectSetString(0, buyButtonName, OBJPROP_TEXT, "Buy"); gTradingPanelObjects[3] = BUY_BUTTON; ObjectCreate(0, CLOSE_ALL_BUTTON, OBJ_BUTTON, 0, 0, 0); ObjectSetInteger(0, CLOSE_ALL_BUTTON, OBJPROP_XSIZE, buttonWidth+boxMargin+buttonWidth); ObjectSetInteger(0, CLOSE_ALL_BUTTON, OBJPROP_YSIZE, buttonHeight); ObjectSetInteger(0, CLOSE_ALL_BUTTON, OBJPROP_XDISTANCE, (buttonX)); ObjectSetInteger(0, CLOSE_ALL_BUTTON, OBJPROP_YDISTANCE, buttonY+buttonHeight+boxMargin); ObjectSetInteger(0, CLOSE_ALL_BUTTON, OBJPROP_COLOR, Panel_Lable_Color); ObjectSetInteger(0, CLOSE_ALL_BUTTON, OBJPROP_BGCOLOR, clrGray); ObjectSetString(0, CLOSE_ALL_BUTTON, OBJPROP_TEXT, "Close All Orders"); gTradingPanelObjects[4] = CLOSE_ALL_BUTTON; string TPLabel = "TP Label"; ObjectCreate(0, TPLabel, OBJ_LABEL, 0, 0, 0); ObjectSetString(0, TPLabel, OBJPROP_TEXT, "TP: "); ObjectSetInteger(0, TPLabel, OBJPROP_XDISTANCE, buttonX); ObjectSetInteger(0, TPLabel, OBJPROP_YDISTANCE, 5+buttonY+buttonHeight+boxMargin+buttonHeight+boxMargin); ObjectSetInteger(0, TPLabel, OBJPROP_COLOR, Panel_Lable_Color); gTradingPanelObjects[5] = TPLabel; string zoneLable = "Zone Lable"; ObjectCreate(0, zoneLable, OBJ_LABEL, 0, 0, 0); ObjectSetString(0, zoneLable, OBJPROP_TEXT, "Zone: "); ObjectSetInteger(0, zoneLable, OBJPROP_XDISTANCE, buttonX); ObjectSetInteger(0, zoneLable, OBJPROP_YDISTANCE, 5+ buttonY+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin); ObjectSetInteger(0, zoneLable, OBJPROP_COLOR, Panel_Lable_Color); gTradingPanelObjects[6] = zoneLable; ObjectCreate(0, TP_EDIT, OBJ_EDIT, 0, 0, 0); ObjectSetInteger(0, TP_EDIT, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, TP_EDIT, OBJPROP_XDISTANCE, buttonX+buttonWidth+boxMargin); ObjectSetInteger(0, TP_EDIT, OBJPROP_YDISTANCE, buttonY+buttonHeight+boxMargin+buttonHeight+boxMargin); ObjectSetInteger(0, TP_EDIT, OBJPROP_XSIZE, buttonWidth); ObjectSetInteger(0, TP_EDIT, OBJPROP_YSIZE, buttonHeight); ObjectSetInteger(0, TP_EDIT, OBJPROP_COLOR, clrBlack); ObjectSetInteger(0, TP_EDIT, OBJPROP_BGCOLOR, clrWhite); ObjectSetString(0, TP_EDIT, OBJPROP_TEXT, IntegerToString(TakeProfit)); ObjectSetInteger(0,TP_EDIT,OBJPROP_ALIGN,ALIGN_CENTER); gTradingPanelObjects[7] = TP_EDIT; ObjectCreate(0, ZONE_EDIT, OBJ_EDIT, 0, 0, 0); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_XDISTANCE, buttonX+buttonWidth+boxMargin); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_YDISTANCE, buttonY+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_XSIZE, buttonWidth); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_YSIZE, buttonHeight); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_COLOR, clrBlack); ObjectSetInteger(0, ZONE_EDIT, OBJPROP_BGCOLOR, clrWhite); ObjectSetString(0, ZONE_EDIT, OBJPROP_TEXT, IntegerToString(RecoveryZoneSize)); ObjectSetInteger(0,ZONE_EDIT,OBJPROP_ALIGN,ALIGN_CENTER); gTradingPanelObjects[8] = ZONE_EDIT; ObjectCreate(0, PENDING_EDIT, OBJ_EDIT, 0, 0, 0); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_XDISTANCE, buttonX+buttonWidth+boxMargin); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_YDISTANCE, buttonY+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_XSIZE, buttonWidth); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_YSIZE, buttonHeight); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_COLOR, clrBlack); ObjectSetInteger(0, PENDING_EDIT, OBJPROP_BGCOLOR, clrWhite); ObjectSetString(0, PENDING_EDIT, OBJPROP_TEXT, IntegerToString(pending)); ObjectSetInteger(0,PENDING_EDIT,OBJPROP_ALIGN,ALIGN_CENTER); gTradingPanelObjects[9] = PENDING_EDIT; string pendingLabel = "Pending Label"; ObjectCreate(0, pendingLabel, OBJ_LABEL, 0, 0, 0); ObjectSetString(0, pendingLabel, OBJPROP_TEXT, "Price: "); ObjectSetInteger(0, pendingLabel, OBJPROP_XDISTANCE, buttonX); ObjectSetInteger(0, pendingLabel, OBJPROP_YDISTANCE, 5+ buttonY+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin+buttonHeight+boxMargin); ObjectSetInteger(0, pendingLabel, OBJPROP_COLOR, Panel_Lable_Color); gTradingPanelObjects[10] = pendingLabel; } // Panel action buttons void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam) { if(sparam == SELL_BUTTON && gCurrentDirection == 0) { if(gCurrentDirection == 0 && PendingPrice == 0) TakeTrade((int)-1); else if(PendingPrice > Bid) PlaceTrade(OP_SELLLIMIT); else if(PendingPrice < Bid) PlaceTrade(OP_SELLSTOP); } else if(sparam == BUY_BUTTON && gCurrentDirection == 0) { if(gCurrentDirection == 0 && PendingPrice == 0) TakeTrade((int)1); else if(PendingPrice > Ask) PlaceTrade(OP_BUYSTOP); else if(PendingPrice < Ask) PlaceTrade(OP_BUYLIMIT); } else if(sparam == CLOSE_ALL_BUTTON) { CloseOrdersAndReset(); Print("Close all pressed."); } else if(id == CHARTEVENT_OBJECT_ENDEDIT && sparam == TP_EDIT) { string takeProfitString = ObjectGetString(0, TP_EDIT, OBJPROP_TEXT); TakeProfit = StringToPips(takeProfitString); } else if(id == CHARTEVENT_OBJECT_ENDEDIT && sparam == ZONE_EDIT) { string zoneString = ObjectGetString(0, ZONE_EDIT, OBJPROP_TEXT); RecoveryZoneSize = StringToPips(zoneString); } else if(id == CHARTEVENT_OBJECT_ENDEDIT && sparam == PENDING_EDIT) { string pendingString = ObjectGetString(0, PENDING_EDIT, OBJPROP_TEXT); PendingPrice = NormalizeDouble(StringToDouble(pendingString), _Digits); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DeleteTradePanel() { for(int count = 0; count <= ArraySize(gTradingPanelObjects)-1; count++) { if(ArraySize(gTradingPanelObjects) > 0) { string objectName = gTradingPanelObjects[count]; ObjectDelete(0, objectName); } } } // USEFUL FUNCTIONS // Pip Point Function double PipPoint(string Currency) { double CalcPoint = 0; double CalcDigits = MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 2 || CalcDigits == 3) CalcPoint = 0.01; else if(CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001; else if(CalcDigits == 0) CalcPoint = 0; else if(CalcDigits == 1) CalcPoint = 0.1; return(CalcPoint); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetSlippage(string Currency, int SlippagePips) { double CalcSlippage = SlippagePips; int CalcDigits = (int)MarketInfo(Currency,MODE_DIGITS); if(CalcDigits == 0 || CalcDigits == 1 || CalcDigits == 2 || CalcDigits == 4) CalcSlippage = SlippagePips; else if(CalcDigits == 3 || CalcDigits == 5) CalcSlippage = SlippagePips; return(CalcSlippage); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetPoints(int Pips) { int CalcPoint = Pips; double CalcDigits = MarketInfo(Symbol(),MODE_DIGITS); if(CalcDigits == 0 || CalcDigits == 1 || CalcDigits == 2 || CalcDigits == 4) CalcPoint = Pips; return(CalcPoint); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int StringToPips(string text) { int pips = (int) StringToInteger(text); if(pips <= 0) { Alert("Invalid pips from string: ", pips); sendNotification(AccountName() + " - " + Symbol() + " Invalid pips from string: " + IntegerToString(pips)); } return pips; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseAllMarketOrders() { int retryCount = 0; for(int Counter = 0; Counter <= OrdersTotal()-1; Counter++) { if(OrderSelect(Counter,SELECT_BY_POS)) { if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol && (OrderType() == OP_BUY || OrderType() == OP_SELL)) { // Close Order int CloseTicket = OrderTicket(); double CloseLots = OrderLots(); while(IsTradeContextBusy()) Sleep(10); RefreshRates(); double ClosePrice = MarketInfo(_Symbol,MODE_BID); if(OrderType() == OP_SELL) ClosePrice = MarketInfo(_Symbol, MODE_ASK); bool Closed = OrderClose(CloseTicket,CloseLots,ClosePrice,Slippage,Red); // Error Handling if(Closed == false) { int ErrorCode = GetLastError(); string ErrAlert = StringConcatenate("Close All Market Orders - Error ",ErrorCode,"."); Alert(ErrAlert); sendNotification(AccountName() + " - " + Symbol() + " - " + ErrAlert); Print(ErrAlert); } else Counter--; } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetTradeVolume(int pTradeNo) { double lots = 0; double volume = 0; if(CustomLotSize1 == 0) { lots = (gLotSize*LotMultiplier)+LotAdditions; //increase the lot size } else if(CustomLotSize1 != 0) { if(pTradeNo > 10) { Alert("No of trades exceeds custom lot size inputs (10)"); sendNotification(AccountName() + " - " + Symbol() + " - " + "No of trades exceeds custom lot size inputs (10)"); return -1; } else { lots = gCustomLotSizes[pTradeNo-1]; } } volume = CheckVolume(_Symbol, lots); return volume; } // Verify and adjust trade volume double CheckVolume(string pSymbol,double pVolume) { double minVolume = SymbolInfoDouble(pSymbol,SYMBOL_VOLUME_MIN); double maxVolume = SymbolInfoDouble(pSymbol,SYMBOL_VOLUME_MAX); double stepVolume = SymbolInfoDouble(pSymbol,SYMBOL_VOLUME_STEP); double tradeSize; if(pVolume < minVolume) { Alert("Sent volume is smaller than the minimum volume for this symbol: ", _Symbol, ", min: ", DoubleToString(minVolume), ", sent: ", DoubleToString(pVolume)); sendNotification(AccountName() + " - " + Symbol() + " - " + "Sent volume is smaller than the minimum volume: " + DoubleToString(minVolume) + " sent: " + DoubleToString(pVolume)); tradeSize = minVolume; } else if(pVolume > maxVolume) { Alert("Sent volume is larger than the maximum volume for this symbol: ", _Symbol, ", max: ", DoubleToString(maxVolume), ", sent: ", DoubleToString(pVolume)); sendNotification(AccountName() + " - " + Symbol() + " - " + "Sent volume is larger than the maximum volume: " + DoubleToString(maxVolume) + " sent: " + DoubleToString(pVolume)); tradeSize = maxVolume; } else tradeSize = MathRound(pVolume / stepVolume) * stepVolume; if(stepVolume >= 0.1) tradeSize = NormalizeDouble(tradeSize,1); else tradeSize = NormalizeDouble(tradeSize,2); return(tradeSize); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool DeletePendingOrders(CLOSE_PENDING_TYPE pDeleteType) { bool error = false; bool deleteOrder = false; // Loop through open order pool from oldest to newest for(int order = 0; order <= OrdersTotal() - 1; order++) { // Select order bool result = OrderSelect(order,SELECT_BY_POS); int orderType = OrderType(); int orderMagicNumber = OrderMagicNumber(); int orderTicket = OrderTicket(); double orderVolume = OrderLots(); // Determine if order type matches pCloseType if((pDeleteType == CLOSE_ALL_PENDING && orderType != OP_BUY && orderType != OP_SELL) || (pDeleteType == CLOSE_BUY_LIMIT && orderType == OP_BUYLIMIT) || (pDeleteType == CLOSE_SELL_LIMIT && orderType == OP_SELLLIMIT) || (pDeleteType == CLOSE_BUY_STOP && orderType == OP_BUYSTOP) || (pDeleteType == CLOSE_SELL_STOP && orderType == OP_SELLSTOP)) { deleteOrder = true; } else deleteOrder = false; // Close order if pCloseType and magic number match currently selected order if(deleteOrder == true && orderMagicNumber == MagicNumber) { result = OrderDelete(orderTicket); if(result == false) { Print("Delete multiple orders, failed to delete order: ", orderTicket); error = true; } else order--; } } return(error); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OpenPendingOrder(string pSymbol,int pType,double pVolume,double pPrice,double pStop,double pProfit,string pComment,datetime pExpiration,color pArrow) { int retryCount = 0; int ticket = 0; int errorCode = 0; int max_attempts = 5; string orderType; string errDesc; // Order retry loop while(retryCount <= max_attempts) { while(IsTradeContextBusy()) Sleep(10); while(true) { if(pType == OP_SELLSTOP) { if((MarketInfo(Symbol(),MODE_BID) > pPrice) && ((MarketInfo(Symbol(),MODE_BID) - pPrice)*HeSoPoint > (MarketInfo(Symbol(), MODE_STOPLEVEL)+SlippageOpenOrder))) { ticket = OrderSend(pSymbol, pType, pVolume, pPrice, Slippage, pStop, pProfit, pComment, MagicNumber, pExpiration, pArrow); break; } } else if(pType == OP_BUYSTOP) { if((MarketInfo(Symbol(),MODE_ASK) < pPrice) && ((pPrice - MarketInfo(Symbol(),MODE_ASK))*HeSoPoint > (MarketInfo(Symbol(), MODE_STOPLEVEL)+SlippageOpenOrder))) { ticket = OrderSend(pSymbol, pType, pVolume, pPrice, Slippage, pStop, pProfit, pComment, MagicNumber, pExpiration, pArrow); break; } } else if(pType == OP_BUYLIMIT) { ticket = OrderSend(pSymbol, pType, pVolume, pPrice, Slippage, pStop, pProfit, pComment, MagicNumber, pExpiration, pArrow); break; } else if(pType == OP_SELLLIMIT) { ticket = OrderSend(pSymbol, pType, pVolume, pPrice, Slippage, pStop, pProfit, pComment, MagicNumber, pExpiration, pArrow); break; } } // Error handling if(ticket == -1) { errorCode = GetLastError(); bool checkError = RetryOnError(errorCode); // Unrecoverable error if(checkError == false) { Alert("Open ",orderType," order: Error ",errorCode,"."); sendNotification(AccountName() + " - " + Symbol() + " - " + "Open " + orderType + " order: Error " + IntegerToString(errorCode)); Print("Symbol: ",pSymbol,", Volume: ",pVolume,", Price: ",pPrice,", SL: ",pStop,", TP: ",pProfit,", Expiration: ",pExpiration); break; } // Retry on error else { Print("Server error detected, retrying..."); Sleep(3000); retryCount++; } } // Order successful else { Comment(orderType," order #",ticket," opened on ",_Symbol); Print(orderType," order #",ticket," opened on ",_Symbol); break; } } // Failed after retry if(retryCount > max_attempts) { Alert("Open ",orderType," order: Max retries exceeded. Error ",errorCode," - ",errDesc); sendNotification(AccountName() + " - " + Symbol() + " - " + "Open " + orderType + " order: Max retries exceeded. Error " + IntegerToString(errorCode) + " - " + errDesc); //Print("Symbol: ",pSymbol,", Volume: ",pVolume,", Price: ",pPrice,", SL: ",pStop,", TP: ",pProfit,", Expiration: ",pExpiration); } return(ticket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool RetryOnError(int pErrorCode) { // Retry on these error codes switch(pErrorCode) { case ERR_BROKER_BUSY: case ERR_COMMON_ERROR: case ERR_NO_ERROR: case ERR_NO_CONNECTION: case ERR_NO_RESULT: case ERR_SERVER_BUSY: case ERR_NOT_ENOUGH_RIGHTS: case ERR_MALFUNCTIONAL_TRADE: case ERR_TRADE_CONTEXT_BUSY: case ERR_TRADE_TIMEOUT: case ERR_REQUOTE: case ERR_TOO_MANY_REQUESTS: case ERR_OFF_QUOTES: case ERR_PRICE_CHANGED: case ERR_TOO_FREQUENT_REQUESTS: return(true); } return(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OpenMarketOrder(string pSymbol, int pType, double pVolume, string pComment, color pArrow) { int retryCount = 0; int ticket = 0; int errorCode = 0; int max_attempts = 5; int wait_time = 3000; double orderPrice = 0; string orderType; string errDesc; // Order retry loop while(retryCount <= max_attempts) { while(IsTradeContextBusy()) Sleep(10); // Get current bid/ask price if(pType == OP_BUY) orderPrice = MarketInfo(pSymbol,MODE_ASK); else if(pType == OP_SELL) orderPrice = MarketInfo(pSymbol,MODE_BID); // Place market order ticket = OrderSend(pSymbol,pType,pVolume,orderPrice,Slippage,0,0,pComment,MagicNumber,0,pArrow); // Error handling if(ticket == -1) { errorCode = GetLastError(); bool checkError = RetryOnError(errorCode); // Unrecoverable error if(checkError == false) { Alert("Open ",orderType," order: Error ",errorCode,"."); sendNotification(AccountName() + " - " + Symbol() + " - " + "Open " + orderType + " order: Error " + IntegerToString(errorCode)); Print("Symbol: ",pSymbol,", Volume: ",pVolume,", Price: ",orderPrice); break; } // Retry on error else { Print("Server error detected, retrying..."); Sleep(wait_time); retryCount++; } } // Order successful else { Comment(orderType," order #",ticket," opened on ",pSymbol); Print(orderType," order #",ticket," opened on ",pSymbol); break; } } // Failed after retry if(retryCount > max_attempts) { Alert("Open ",orderType," order: Max retries exceeded. Error ",errorCode," - ",errDesc); sendNotification(AccountName() + " - " + Symbol() + " - " + "Open " + orderType + " order: Max retries exceeded. Error " + IntegerToString(errorCode) + " - " + errDesc); Print("Symbol: ",pSymbol,", Volume: ",pVolume,", Price: ",orderPrice); } return(ticket); } // Return trade size based on risk per trade of stop loss in points double GetTradeSize(string pSymbol, double pFixedVol, double pPercent, int pStopPoints) { double tradeSize; if(pPercent > 0 && pStopPoints > 0) { if(pPercent > 10) pPercent = 10; double margin = AccountInfoDouble(ACCOUNT_BALANCE) * (pPercent / 100); double tickSize = SymbolInfoDouble(pSymbol,SYMBOL_TRADE_TICK_VALUE); tradeSize = (margin / pStopPoints) / tickSize; tradeSize = CheckVolume(pSymbol,tradeSize); return(tradeSize); } else { tradeSize = pFixedVol; tradeSize = CheckVolume(pSymbol,tradeSize); return(tradeSize); } } // Create datetime value datetime CreateDateTime(int pHour = 0, int pMinute = 0) { MqlDateTime timeStruct; TimeToStruct(TimeCurrent(),timeStruct); timeStruct.hour = pHour; timeStruct.min = pMinute; datetime useTime = StructToTime(timeStruct); return(useTime); } // Check timer bool CheckDailyTimer() { datetime TimeStart = CreateDateTime(StartHour, StartMinute); datetime TimeEnd = CreateDateTime(EndHour, EndMinute); datetime currentTime; if(UseLocalTime == true) currentTime = TimeLocal(); else currentTime = TimeCurrent(); // check if the timer goes over midnight if(TimeEnd <= TimeStart) { TimeStart -= 86400; if(currentTime > TimeEnd) { TimeStart += 86400; TimeEnd += 86400; } } bool timerOn = false; if(currentTime >= TimeStart && currentTime < TimeEnd) { timerOn = true; } return(timerOn); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void FindOpenOrders() { double largest_lots = 0; int ticket = -1; int open_orders = 0; int stopTicket = 0; for(int Counter = 0; Counter <= OrdersTotal()-1; Counter++) { if(OrderSelect(Counter,SELECT_BY_POS)) { if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol && (OrderType() == OP_BUY || OrderType() == OP_SELL)) { open_orders++; if(OrderLots() > largest_lots) { ticket = OrderTicket(); largest_lots = OrderLots(); } } if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol && OrderType() == OP_BUYSTOP) { gBuyStopTicket = OrderTicket(); stopTicket = gBuyStopTicket; } else if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol && OrderType() == OP_SELLSTOP) { gSellStopTicket = OrderTicket(); stopTicket = gSellStopTicket; } } } if(ticket > 0) { if(OrderSelect(ticket, SELECT_BY_TICKET)) { int type = OrderType(); if(type == OP_BUY) { gCurrentDirection = 1; gBuyTicket = ticket; } else if(type == OP_SELL) { gCurrentDirection = -1; gSellTicket = ticket; } if(open_orders > 1) gRecoveryInitiated = true; } Print("Check for orders complete, resuming recovery direction of trade: ", ticket, " with recovery stop: ", stopTicket, " in place. ", open_orders, " orders already opened."); } else { Print("Check for orders complete, none currently open."); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int minRecoveryZone() { int minRZS_point = 0; minRZS_point = (int)(MarketInfo(Symbol(), MODE_SPREAD) + MarketInfo(Symbol(), MODE_STOPLEVEL)); return minRZS_point; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void saveSpread(string filename) { static double firstSpread = MarketInfo(Symbol(),MODE_SPREAD); if(MarketInfo(Symbol(),MODE_SPREAD) != firstSpread) { int filehandle=FileOpen(filename,FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI); FileSeek(filehandle, 0, SEEK_END); FileWrite(filehandle,TimeCurrent(),Symbol(), EnumToString(ENUM_TIMEFRAMES(_Period)), MarketInfo(Symbol(), MODE_SPREAD)); FileClose(filehandle); firstSpread = MarketInfo(Symbol(),MODE_SPREAD); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void sendNotification(string notiMess) { if(Push_Notifications) SendNotification(notiMess); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PrintText(string object, string text, int x, int y, color colorText) { ObjectCreate(object, OBJ_LABEL, 0, 0, 0); ObjectSetText(object, text, 9, "Verdana", colorText); ObjectSet(object, OBJPROP_CORNER, CORNER_RIGHT_LOWER); ObjectSet(object, OBJPROP_XDISTANCE, x); ObjectSet(object, OBJPROP_YDISTANCE, y); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SymbolProfitAtSpecificPrice(double SpecificPrice) { //Alert(SpecificPrice); double point_value = Point()*MarketInfo(Symbol(), MODE_TICKVALUE)/MarketInfo(Symbol(), MODE_TICKSIZE); double currentProfit = 0; double totalCommision = 0; double totalSpreadCosts = 0; double tradeCosts = 0; double profitTarget = 0; double stoplossTarget = 0; double totalprofit = 0 ; for(int i=OrdersTotal()-1; i>=0; i--) { double temp_profitTarget_buy = 0 ; double temp_stoplossTarget_sell = 0 ; double temp_profitTarget_sell = 0 ; double temp_stoplossTarget_buy = 0; if(OrderSelect(i,SELECT_BY_POS)) { if(OrderSymbol() == Symbol()) { if(OrderType() == OP_BUY && SpecificPrice > OrderOpenPrice()) { double tp_target = MathAbs(SpecificPrice - OrderOpenPrice())/Point; temp_profitTarget_buy = NormalizeDouble(tp_target*point_value*OrderLots(),2); } if(OrderType() == OP_SELL && SpecificPrice < OrderOpenPrice()) { double tp_target = MathAbs(SpecificPrice - OrderOpenPrice())/Point; temp_profitTarget_sell = NormalizeDouble(tp_target*point_value*OrderLots(),2); } if(OrderType() == OP_BUY && SpecificPrice <= OrderOpenPrice()) { double sl_target = MathAbs(OrderOpenPrice() - SpecificPrice)/Point; temp_stoplossTarget_buy = NormalizeDouble(sl_target*point_value*OrderLots(),2); } if(OrderType() == OP_SELL && SpecificPrice >= OrderOpenPrice()) { double sl_target = MathAbs(SpecificPrice - OrderOpenPrice())/Point; temp_stoplossTarget_sell = NormalizeDouble(sl_target*point_value*OrderLots(),2); } currentProfit += OrderProfit(); totalSpreadCosts += (OrderLots()*MarketInfo(Symbol(), MODE_SPREAD)*point_value); totalCommision += OrderCommission(); } profitTarget += (temp_profitTarget_buy + temp_profitTarget_sell); stoplossTarget += (temp_stoplossTarget_buy + temp_stoplossTarget_sell); } } tradeCosts = totalCommision; //+totalSpreadCosts currentProfit = currentProfit + tradeCosts; totalprofit = profitTarget - stoplossTarget + tradeCosts; //PrintText("profitTarget", "Profit at " + NormalizeDouble(SpecificPrice, MarketInfo(Symbol(), MODE_DIGITS)) + " : " + DoubleToString(profitTarget,2) + "$", 20, 100, Blue); //PrintText("stoplossTarget", "Stoploss at " + NormalizeDouble(SpecificPrice, MarketInfo(Symbol(), MODE_DIGITS)) + " : " + DoubleToString(stoplossTarget,2) + "$", 20, 120, Red); PrintText("currentProfit", "Current Profit: " + DoubleToString(currentProfit,2) + "$", 20, 40, Blue); PrintText("totalprofit", "Total profit at profit line: " + DoubleToString(totalprofit,2) + "$", 20, 20, Green); // return totalprofit; } //+------------------------------------------------------------------+
Editor is loading...