The EA in this thread was made from Earnforex's template for mt4 EAs. Entered the parameters and everything but the bot takes no trades and runs no errors but for warnings all about "Possible loss of data value due to type conversion. The EA is to enter a buy or sell when the 30-minute candle crosses and closes above or below my customer indicator while volume is more than a specific give-threshold and the colour of the indicator is green or red after the close of the candle. Also,take the order at the beginning of the next candle or the close of the current candle( all the same thing). Tp is the highest high or lowest low in the previous 54 bars max and sl is the lowest low or highest high in the previous 25 bars max. 3 orders per entry. this is the idea of the code and it happens every day when manually backtested. the mql4 code is below
MQL4:
/* EvaluateEntry : Buy when price above vwap and volume>1240 and vwap is lime green, Sell when price below vwap and volume>1240 and vwap is red EvaluateExit /tp: exit buy when price reaches previous highest high in 54 bars, exit sell when price reaches previous lowest low in 54 bars StopLoss : exit buy when price reaches previous lowest low in 25 bars, exit sell when price reaches previous highest high in 25 bars ExecuteTrailingStop : To insert your trailing stop rules */ //-PROPERTIES-// //Properties help the software look better when you load it in MT4 //Provide more information and details //This is what you see in the About tab when you load an Indicator or an Expert Advisor #property version "1.00" #property strict #property copyright "The_Generalist" #property description "The Lord hand Automated EA" #property description " " #property description "works using the custom indicator vwap+(1) " #property description "WARNING : You use this software at your own risk." #property description "The creator of these plugins cannot be held responsible for any damage or loss." #property description " " //You can add an icon for when the EA loads on chart but it's not necessary //The commented line below is an example of icon, icon must be in the MQL4/Files folder and have a ico extension #property icon "\\Files\\EF-Icon-64x64px.ico" //-INCLUDES-// //Include allows to import code from another file //In the following instance the file has to be placed in the MQL4/Include Folder #include <MQLTA ErrorHandling.mqh> //-COMMENTS-// //This is a single line comment and I do it placing // at the start of the comment, this text is ignored when compiling /* This is a multi line comment it starts with /* and it finishes with the * and / like below */ //-ENUMERATIVE VARIABLES-// //Enumerative variables are useful to associate numerical values to easy to remember strings //It is similar to constants but also helps if the variable is set from the input page of the EA //The text after the // is what you see in the input paramenters when the EA loads //It is good practice to place all the enumberative at the start //Enumerative for the hour of the day enum ENUM_HOUR{ h00=00, //00:00 h01=01, //01:00 h02=02, //02:00 h03=03, //03:00 h04=04, //04:00 h05=05, //05:00 h06=06, //06:00 h07=07, //07:00 h08=08, //08:00 h09=09, //09:00 h10=10, //10:00 h11=11, //11:00 h12=12, //12:00 h13=13, //13:00 h14=14, //14:00 h15=15, //15:00 h16=16, //16:00 h17=17, //17:00 h18=18, //18:00 h19=19, //19:00 h20=20, //20:00 h21=21, //21:00 h22=22, //22:00 h23=23, //23:00 }; //Enumerative for the entry signal value enum ENUM_SIGNAL_ENTRY{ SIGNAL_ENTRY_NEUTRAL=0, //SIGNAL ENTRY NEUTRAL SIGNAL_ENTRY_BUY=1, //SIGNAL ENTRY BUY SIGNAL_ENTRY_SELL=-1, //SIGNAL ENTRY SELL }; //Enumerative for the exit signal value enum ENUM_SIGNAL_EXIT{ SIGNAL_EXIT_NEUTRAL=0, //SIGNAL EXIT NEUTRAL SIGNAL_EXIT_BUY=1, //SIGNAL EXIT BUY SIGNAL_EXIT_SELL=-1, //SIGNAL EXIT SELL SIGNAL_EXIT_ALL=2, //SIGNAL EXIT ALL }; //Enumerative for the allowed trading direction enum ENUM_TRADING_ALLOW_DIRECTION{ TRADING_ALLOW_BOTH=0, //ALLOW BOTH BUY AND SELL TRADING_ALLOW_BUY=1, //ALLOW BUY ONLY TRADING_ALLOW_SELL=-1, //ALLOW SELL ONLY }; //Enumerative for the base used for risk calculation enum ENUM_RISK_BASE{ RISK_BASE_EQUITY=1, //EQUITY RISK_BASE_BALANCE=2, //BALANCE RISK_BASE_FREEMARGIN=3, //FREE MARGIN }; //Enumerative for the default risk size enum ENUM_RISK_DEFAULT_SIZE{ RISK_DEFAULT_FIXED=1, //FIXED SIZE RISK_DEFAULT_AUTO=2, //AUTOMATIC SIZE BASED ON RISK }; //Enumerative for the Stop Loss mode enum ENUM_MODE_SL{ SL_FIXED=0, //FIXED STOP LOSS SL_AUTO=1, //AUTOMATIC STOP LOSS }; //Enumerative for the Take Profit Mode enum ENUM_MODE_TP{ TP_FIXED=0, //FIXED TAKE PROFIT TP_AUTO=1, //AUTOMATIC TAKE PROFIT }; //Enumerative for the stop loss calculation enum ENUM_MODE_SL_BY{ SL_BY_POINTS=0, //STOP LOSS PASSED IN POINTS SL_BY_PRICE=1, //STOP LOSS PASSED BY PRICE }; //-INPUT PARAMETERS-// //The input parameters are the ones that can be set by the user when launching the EA //If you place a comment following the input variable this will be shown as description of the field //This is where you should include the input parameters for your entry and exit signals input string Comment_strategy="=========="; //Entry And Exit Settings //Add in this section the parameters for the indicators used in your entry and exit input int MAValueInput = 35; // Default MA period as an input input color IndicatorColorInput = clrNONE; // Default color as an input int MAValue; // Actual MA period to be used in the strategy color IndicatorColor; // Actual color to be used in the strategy //General input parameters input string Comment_0="=========="; //Risk Management Settings input ENUM_RISK_DEFAULT_SIZE RiskDefaultSize=RISK_DEFAULT_AUTO; //Position Size Mode input double DefaultLotSize=1; //Position Size (if fixed or if no stop loss defined) input ENUM_RISK_BASE RiskBase=RISK_BASE_BALANCE; //Risk Base input int MaxRiskPerTrade=2; //Percentage To Risk Each Trade input double MinLotSize=0.01; //Minimum Position Size Allowed input double MaxLotSize=100; //Maximum Position Size Allowed input string Comment_1="=========="; //Trading Hours Settings input bool UseTradingHours=false; //Limit Trading Hours input ENUM_HOUR TradingHourStart=h07; //Trading Start Hour (Broker Server Hour) input ENUM_HOUR TradingHourEnd=h19; //Trading End Hour (Broker Server Hour) input string Comment_2="=========="; //Stop Loss And Take Profit Settings input ENUM_MODE_SL StopLossMode=SL_FIXED; //Stop Loss Mode input int DefaultStopLoss=0; //Default Stop Loss In Points (0=No Stop Loss) input int MinStopLoss=0; //Minimum Allowed Stop Loss In Points input int MaxStopLoss=5000; //Maximum Allowed Stop Loss In Points input ENUM_MODE_TP TakeProfitMode=TP_FIXED; //Take Profit Mode input int DefaultTakeProfit=0; //Default Take Profit In Points (0=No Take Profit) input int MinTakeProfit=0; //Minimum Allowed Take Profit In Points input int MaxTakeProfit=5000; //Maximum Allowed Take Profit In Points input string Comment_3="=========="; //Trailing Stop Settings input bool UseTrailingStop=false; //Use Trailing Stop input string Comment_4="=========="; //Additional Settings input int MagicNumber=0; //Magic Number For The Orders Opened By This EA input string OrderNote=""; //Comment For The Orders Opened By This EA input int Slippage=5; //Slippage in points input int MaxSpread=100; //Maximum Allowed Spread To Trade In Points //-GLOBAL VARIABLES-// //The variables included in this section are global, hence they can be used in any part of the code //It is useful to add a comment to remember what is the variable for bool IsPreChecksOk=false; //Indicates if the pre checks are satisfied bool IsNewCandle=false; //Indicates if this is a new candle formed bool IsSpreadOK=false; //Indicates if the spread is low enough to trade bool IsOperatingHours=false; //Indicates if it is possible to trade at the current time (server time) bool IsTradedThisBar=false; //Indicates if an order was already executed in the current candle double TickValue=0; //Value of a tick in account currency at 1 lot double LotSize=0; //Lot size for the position int OrderOpRetry=10; //Number of attempts to retry the order submission int TotalOpenOrders=0; //Number of total open orders int TotalOpenBuy=0; //Number of total open buy orders int TotalOpenSell=0; //Number of total open sell orders int StopLossBy=SL_BY_POINTS; //How the stop loss is passed for the lot size calculation ENUM_SIGNAL_ENTRY SignalEntry=SIGNAL_ENTRY_NEUTRAL; //Entry signal variable ENUM_SIGNAL_EXIT SignalExit=SIGNAL_EXIT_NEUTRAL; //Exit signal variable //-NATIVE MT4 EXPERT ADVISOR RUNNING FUNCTIONS-// //OnInit is executed once, when the EA is loaded //OnInit is also executed if the time frame or symbol for the chart is changed int OnInit(){ //It is useful to set a function to check the integrity of the initial parameters and call it as first thing CheckPreChecks(); //If the initial pre checks have something wrong, stop the program if(!IsPreChecksOk){ OnDeinit(INIT_FAILED); return(INIT_FAILED); } // Get the VWAP value and color using iCustom // Assign the values from inputs or iCustom as needed // if (MAValueInput > 0) { // MAValue = MAValueInput; // } // if (IndicatorColorInput != clrNONE) { // IndicatorColor = IndicatorColorInput; // } //Function to initialize the values of the global variables InitializeVariables(); //If everything is ok the function returns successfully and the control is passed to a timer or the OnTike function return(INIT_SUCCEEDED); } //The OnDeinit function is called just before terminating the program void OnDeinit(const int reason){ //You can include in this function something you want done when the EA closes //For example clean the chart form graphical objects, write a report to a file or some kind of alert } //The OnTick function is triggered every time MT4 receives a price change for the symbol in the chart void OnTick(){ //Re-initialize the values of the global variables at every run InitializeVariables(); //ScanOrders scans all the open orders and collect statistics, if an error occurs it skips to the next price change if(!ScanOrders()) return; //CheckNewBar checks if the price change happened at the start of a new bar CheckNewBar(); //CheckOperationHours checks if the current time is in the operating hours CheckOperationHours(); //CheckSpread checks if the spread is above the maximum spread allowed CheckSpread(); //CheckTradedThisBar checks if there was already a trade executed in the current candle CheckTradedThisBar(); //EvaluateExit contains the code to decide if there is an exit signal EvaluateExit(); //ExecuteExit executes the exit in case there is an exit signal ExecuteExit(); //Scan orders again in case some where closed, if an error occurs it skips to the next price change if(!ScanOrders()) return; //Execute Trailing Stop ExecuteTrailingStop(); //EvaluateEntry contains the code to decide if there is an entry signal EvaluateEntry(); //ExecuteEntry executes the entry in case there is an entry signal ExecuteEntry(); } //-CUSTOM EA FUNCTIONS-// //Perform integrity checks when the EA is loaded void CheckPreChecks(){ IsPreChecksOk=true; //Check if Live Trading is enabled in MT4 if(!IsTradeAllowed()){ IsPreChecksOk=false; Print("Live Trading is not enabled, please enable it in MT4 and chart settings"); return; } //Check if the default stop loss you are setting in above the minimum and below the maximum if(DefaultStopLoss<MinStopLoss || DefaultStopLoss>MaxStopLoss){ IsPreChecksOk=false; Print("Default Stop Loss must be between Minimum and Maximum Stop Loss Allowed"); return; } //Check if the default take profit you are setting in above the minimum and below the maximum if(DefaultTakeProfit<MinTakeProfit || DefaultTakeProfit>MaxTakeProfit){ IsPreChecksOk=false; Print("Default Take Profit must be between Minimum and Maximum Take Profit Allowed"); return; } //Check if the Lot Size is between the minimum and maximum if(DefaultLotSize<MinLotSize || DefaultLotSize>MaxLotSize){ IsPreChecksOk=false; Print("Default Lot Size must be between Minimum and Maximum Lot Size Allowed"); return; } //Slippage must be >= 0 if(Slippage<0){ IsPreChecksOk=false; Print("Slippage must be a positive value"); return; } //MaxSpread must be >= 0 if(MaxSpread<0){ IsPreChecksOk=false; Print("Maximum Spread must be a positive value"); return; } //MaxRiskPerTrade is a % between 0 and 100 if(MaxRiskPerTrade<0 || MaxRiskPerTrade>100){ IsPreChecksOk=false; Print("Maximum Risk Per Trade must be a percentage between 0 and 100"); return; } } //Initialize variables void InitializeVariables(){ IsNewCandle=false; IsTradedThisBar=false; IsOperatingHours=false; IsSpreadOK=false; LotSize=DefaultLotSize; TickValue=0; TotalOpenBuy=0; TotalOpenSell=0; TotalOpenOrders=0; SignalEntry=SIGNAL_ENTRY_NEUTRAL; SignalExit=SIGNAL_EXIT_NEUTRAL; } //Evaluate if there is an entry signal void EvaluateEntry(){ SignalEntry=SIGNAL_ENTRY_NEUTRAL; if(!IsSpreadOK) return; //If the spread is too high don't give an entry signal //if(UseTradingHours && !IsOperatingHours) return; //If you are using trading hours and it's not a trading hour don't give an entry signal //if(!IsNewCandle) return; //If you want to provide a signal only if it's a new candle opening //if(IsTradedThisBar) return; //If you don't want to execute multiple trades in the same bar //if(TotalOpenOrders>0) return; //If there are already open orders and you don't want to open more // Define variables for your indicators and conditions //Defining the data needed for the entry evaluation: volume + vwap MAValue = iCustom(NULL, 30, "Vwap+(1)", 0, 1); // VWAP value IndicatorColor = iCustom(NULL, 30, "Vwap+(1)", 0, 1); // VWAP color double VwapCurr = iCustom(NULL, 30, "Vwap+(1)", 0, 1); ; //MvwapA Current is the vwap value in the last closed candle (1) double VWAPColorCurr = iCustom(Symbol(), PERIOD_CURRENT, "Vwap+(1)", 0, 1); //vwap Current color is the color value in the last closed candle (1) int VolumeThreshold = 1230; long CurrentVolume = iVolume(Symbol(), PERIOD_CURRENT, 1); //volume Current is the volume value in the last closed candle (1) //This is where you should insert your Entry Signal for BUY orders //Include a condition to open a buy order, the condition will have to set SignalEntry=SIGNAL_ENTRY_BUY if (IndicatorColor == LimeGreen && iClose(Symbol(),PERIOD_CURRENT,1) > VwapCurr && CurrentVolume > VolumeThreshold ){ for(int i = 0; i < 3; i++) { SignalEntry=SIGNAL_ENTRY_BUY; }} //This is where you should insert your Entry Signal for SELL orders //Include a condition to open a sell order, the condition will have to set SignalEntry=SIGNAL_ENTRY_SELL if (IndicatorColor == Red && iClose(Symbol(),PERIOD_CURRENT,1) < VwapCurr && CurrentVolume > VolumeThreshold ){ for(int i = 0; i < 3; i++) { SignalEntry=SIGNAL_ENTRY_SELL; }} } //Execute entry if there is an entry signal void ExecuteEntry(){ //If there is no entry signal no point to continue, exit the function if(SignalEntry==SIGNAL_ENTRY_NEUTRAL) return; int Operation; double OpenPrice=0; double StopLossPrice=0; double TakeProfitPrice=0; //If there is a Buy entry signal if(SignalEntry==SIGNAL_ENTRY_BUY){ RefreshRates(); //Get latest rates Operation=OP_BUY; //Set the operation to BUY OpenPrice=Ask; //Set the open price to Ask price //If the Stop Loss is fixed and the default stop loss is set if(StopLossMode==SL_FIXED && DefaultStopLoss>0){ StopLossPrice=OpenPrice-DefaultStopLoss*Point; } //If the Stop Loss is automatic if(StopLossMode==SL_AUTO){ //Set the Stop Loss to the custom stop loss price StopLossPrice=StopLossPriceCalculate(OP_BUY); } //If the Take Profix price is fixed and defined if(TakeProfitMode==TP_FIXED && DefaultTakeProfit>0){ TakeProfitPrice=OpenPrice+DefaultTakeProfit*Point; } //If the Take Profit is automatic if(TakeProfitMode==TP_AUTO){ //Set the Take Profit to the custom take profit price TakeProfitPrice=TakeProfitCalculate(OP_BUY); } //Normalize the digits for the float numbers OpenPrice=NormalizeDouble(OpenPrice,Digits()); StopLossPrice=NormalizeDouble(StopLossPrice,Digits()); TakeProfitPrice=NormalizeDouble(TakeProfitPrice,Digits()); //Submit the order SendOrder(Operation,Symbol(),OpenPrice,StopLossPrice,TakeProfitPrice); } if(SignalEntry==SIGNAL_ENTRY_SELL){ RefreshRates(); //Get latest rates Operation=OP_SELL; //Set the operation to SELL OpenPrice=Bid; //Set the open price to Ask price //If the Stop Loss is fixed and the default stop loss is set if(StopLossMode==SL_FIXED && DefaultStopLoss>0){ StopLossPrice=OpenPrice+DefaultStopLoss*Point(); } //If the Stop Loss is automatic if(StopLossMode==SL_AUTO){ //Set the Stop Loss to the custom stop loss price StopLossPrice=StopLossPriceCalculate(OP_SELL); } //If the Take Profix price is fixed and defined if(TakeProfitMode==TP_FIXED && DefaultTakeProfit>0){ TakeProfitPrice=OpenPrice-DefaultTakeProfit*Point(); } //If the Take Profit is automatic if(TakeProfitMode==TP_AUTO){ //Set the Take Profit to the custom take profit price TakeProfitPrice=TakeProfitCalculate(OP_SELL); } //Normalize the digits for the float numbers OpenPrice=NormalizeDouble(OpenPrice,Digits()); StopLossPrice=NormalizeDouble(StopLossPrice,Digits()); TakeProfitPrice=NormalizeDouble(TakeProfitPrice,Digits()); //Submit the order SendOrder(Operation,Symbol(),OpenPrice,StopLossPrice,TakeProfitPrice); } } //Evaluate if there is an exit signal void EvaluateExit(){ SignalExit=SIGNAL_EXIT_NEUTRAL; MAValue = iCustom(NULL, 30, "Vwap+(1)", 0, 1); // VWAP value IndicatorColor = iCustom(NULL, 30, "Vwap+(1)", 0, 1); // VWAP color //Defining the data needed for the entry evaluation: vwap + volume +color double VwapCurr= iCustom(NULL, 30, "Vwap+(1)", 0, 1); ; //MvwapA Current is the vwap value in the last closed candle (1) double VWAPColorCurr = iCustom(Symbol(), PERIOD_CURRENT, "Vwap+(1)", 0, 1); //vwap Current color is the color value in the last closed candle (1) int VolumeThreshold = 1230; long CurrentVolume = iVolume(Symbol(), PERIOD_CURRENT, 1); //This is where you should include your exit signal for BUY orders //If you want, include a condition to close the open buy orders, condition will have to set SignalExit=SIGNAL_EXIT_BUY then return //Close Buy if Price closes below MA or RSI closes in overbought area //double BuyHigh = iHigh(NULL, 30, iHighest(NULL, 30, MODE_HIGH, 54, 1)){SignalExit=SIGNAL_EXIT_BUY}; // TakeProfit = BuyHigh; // Calculate BuyHigh in a separate statement int highestBar = iHighest(NULL, 30, MODE_HIGH, 54, 1); if (highestBar >= 0) { SignalExit = SIGNAL_EXIT_BUY; } //This is where you should include your exit signal for SELL orders //If you want, include a condition to close the open sell orders, condition will have to set SignalExit=SIGNAL_EXIT_SELL then return // Calculate TP based on lowest low within specified bars //double SellLow = iLow(NULL, 30, iLowest(NULL, 30, MODE_LOW, 54, 1)){SignalExit=SIGNAL_EXIT_SELL}; // TakeProfit = SellLow; // Calculate SellLow in a separate statement int lowestBar = iLowest(NULL, 30, MODE_LOW, 54, 1); if (lowestBar >= 0) {SignalExit = SIGNAL_EXIT_SELL; } //This is where you should include your exit signal for ALL orders //If you want, include a condition to close all the open orders, condition will have to set SignalExit=SIGNAL_EXIT_ALL then return } //Execute exit if there is an exit signal void ExecuteExit(){ //If there is no Exit Signal no point to continue the routine if(SignalExit==SIGNAL_EXIT_NEUTRAL) return; //If there is an exit signal for all orders if(SignalExit==SIGNAL_EXIT_ALL){ //Close all orders CloseAll(OP_ALL); } //If there is an exit signal for BUY order if(SignalExit==SIGNAL_EXIT_BUY){ //Close all BUY orders CloseAll(OP_BUY); } //If there is an exit signal for SELL orders if(SignalExit==SIGNAL_EXIT_SELL){ //Close all SELL orders CloseAll(OP_SELL); } } //Execute Trailing Stop to limit losses and lock in profits void ExecuteTrailingStop(){ //If the option is off then exit if(!UseTrailingStop) return; //If there are no open orders no point to continue the code if(TotalOpenOrders==0) return; //if(!IsNewCandle) return; //If you only want to do the stop trailing once at the beginning of a new candle //Scan all the orders to see if some needs a stop loss update for(int i=0;i<OrdersTotal();i++) { //If there is a problem reading the order print the error, exit the function and return false if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false){ int Error=GetLastError(); string ErrorText=GetLastErrorText(Error); Print("ERROR - Unable to select the order - ",Error," - ",ErrorText); return; } //If the order is not for the instrument on chart we can ignore it if(OrderSymbol()!=Symbol()) continue; //If the order has Magic Number different from the Magic Number of the EA then we can ignore it if(OrderMagicNumber()!=MagicNumber) continue; //Define current values RefreshRates(); double SLPrice=NormalizeDouble(OrderStopLoss(),Digits()); //Current Stop Loss price for the order double TPPrice=NormalizeDouble(OrderTakeProfit(),Digits()); //Current Take Profit price for the order double Spread=MarketInfo(Symbol(),MODE_SPREAD)*Point(); //Current Spread for the instrument double StopLevel=MarketInfo(Symbol(),MODE_STOPLEVEL)*Point(); //Minimum distance between current price and stop loss //If it is a buy order then trail stop for buy orders if(OrderType()==OP_BUY){ //Include code to trail the stop for buy orders double NewSLPrice=0; //This is where you should include the code to assign a new value to the STOP LOSS double NewTPPrice=TPPrice; //Normalize the price before the submission NewSLPrice=NormalizeDouble(NewSLPrice,Digits()); //If there is no new stop loss set then skip to next order if(NewSLPrice==0) continue; //If the new stop loss price is lower than the previous then skip to next order, we only move the stop closer to the price and not further away if(NewSLPrice<=SLPrice) continue; //If the distance between the current price and the new stop loss is not enough then skip to next order //This allows to avoid error 130 when trying to update the order if(Bid-NewSLPrice<StopLevel) continue; //Submit the update ModifyOrder(OrderTicket(),OrderOpenPrice(),NewSLPrice,NewTPPrice); } //If it is a sell order then trail stop for sell orders if(OrderType()==OP_SELL){ //Include code to trail the stop for sell orders double NewSLPrice=0; //This is where you should include the code to assign a new value to the STOP LOSS double NewTPPrice=TPPrice; //Normalize the price before the submission NewSLPrice=NormalizeDouble(NewSLPrice,Digits()); //If there is no new stop loss set then skip to next order if(NewSLPrice==0) continue; //If the new stop loss price is higher than the previous then skip to next order, we only move the stop closer to the price and not further away if(NewSLPrice>=SLPrice) continue; //If the distance between the current price and the new stop loss is not enough then skip to next order //This allows to avoid error 130 when trying to update the order if(NewSLPrice-Ask<StopLevel) continue; //Submit the update ModifyOrder(OrderTicket(),OrderOpenPrice(),NewSLPrice,NewTPPrice); } } return; } //Check and return if the spread is not too high void CheckSpread(){ //Get the current spread in points, the (int) transforms the double coming from MarketInfo into an integer to avoid a warning when compiling int SpreadCurr=(int)MarketInfo(Symbol(),MODE_SPREAD); if(SpreadCurr<=MaxSpread){ IsSpreadOK=true; } else{ IsSpreadOK=false; } } //Check and return if it is operation hours or not void CheckOperationHours(){ //If we are not using operating hours then IsOperatingHours is true and I skip the other checks if(!UseTradingHours){ IsOperatingHours=true; return; } //Check if the current hour is between the allowed hours of operations, if so IsOperatingHours is set true if(TradingHourStart==TradingHourEnd && Hour()==TradingHourStart) IsOperatingHours=true; if(TradingHourStart<TradingHourEnd && Hour()>=TradingHourStart && Hour()<=TradingHourEnd) IsOperatingHours=true; if(TradingHourStart>TradingHourEnd && ((Hour()>=TradingHourStart && Hour()<=23) || (Hour()<=TradingHourEnd && Hour()>=0))) IsOperatingHours=true; } //Check if it is a new bar datetime NewBarTime=TimeCurrent(); void CheckNewBar(){ //NewBarTime contains the open time of the last bar known //if that open time is the same as the current bar then we are still in the current bar, otherwise we are in a new bar if(NewBarTime==iTime(Symbol(),PERIOD_CURRENT,0)) IsNewCandle=false; else{ NewBarTime=iTime(Symbol(),PERIOD_CURRENT,0); IsNewCandle=true; } } //Check if there was already an order open this bar datetime LastBarTraded; void CheckTradedThisBar(){ //LastBarTraded contains the open time the last trade //if that open time is in the same bar as the current then IsTradedThisBar is true if(iBarShift(Symbol(),PERIOD_CURRENT,LastBarTraded)==0) IsTradedThisBar=true; else IsTradedThisBar=false; } // Lot Size Calculator void LotSizeCalculate(double SL = 0, double MaxRiskPerTradeLocal = 2.0) { // If the position size is dynamic if(RiskDefaultSize == RISK_DEFAULT_AUTO){ // If the stop loss is not zero then calculate the lot size if(SL != 0){ double RiskBaseAmount = 0; // TickValue is the value of the individual price increment for 1 lot of the instrument, expressed in the account currency TickValue = MarketInfo(Symbol(), MODE_TICKVALUE); // Define the base for the risk calculation depending on the parameter chosen if(RiskBase == RISK_BASE_BALANCE) RiskBaseAmount = AccountBalance(); if(RiskBase == RISK_BASE_EQUITY) RiskBaseAmount = AccountEquity(); if(RiskBase == RISK_BASE_FREEMARGIN) RiskBaseAmount = AccountFreeMargin(); // Calculate the Position Size based on account balance and risk percentage LotSize = (CalculateLotSize(RiskBaseAmount, MaxRiskPerTrade) * MaxRiskPerTrade / 100) / (SL * TickValue); } // If the stop loss is zero then the lot size is the default one if(SL == 0){ LotSize = DefaultLotSize; } } // Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size LotSize = MathFloor(LotSize / MarketInfo(Symbol(), MODE_LOTSTEP)) * MarketInfo(Symbol(), MODE_LOTSTEP); // Limit the lot size in case it is greater than the maximum allowed by the user if (LotSize > MaxLotSize) LotSize = MaxLotSize; // Limit the lot size in case it is greater than the maximum allowed by the broker if (LotSize > MarketInfo(Symbol(), MODE_MAXLOT)) LotSize = MarketInfo(Symbol(), MODE_MAXLOT); // If the lot size is too small then set it to 0 and don't trade if (LotSize < MinLotSize || LotSize < MarketInfo(Symbol(), MODE_MINLOT)) LotSize = 0; } // Function to calculate lot size based on account balance and risk percentage double CalculateLotSize(double balance, double riskPercentage) { if (balance < 5000) return (balance * riskPercentage) / 100; if (balance < 10000) return (balance * riskPercentage) / 100; if (balance < 25000) return (balance * riskPercentage) / 100; if (balance < 50000) return (balance * riskPercentage) / 100; if (balance < 100000) return (balance * riskPercentage) / 100; if (balance >= 100000) return (balance * riskPercentage) / 100; return 1; } //Stop Loss Price Calculation if dynamic double StopLossPriceCalculate(int Command=-1){ double StopLossPrice=0; //Include a value for the stop loss, ideally coming from an indicator return StopLossPrice; } //Take Profit Price Calculation if dynamic double TakeProfitCalculate(int Command=-1){ double TakeProfitPrice=0; //Include a value for the take profit, ideally coming from an indicator return TakeProfitPrice; } //Send Order Function adjusted to handle errors and retry multiple times void SendOrder(int Command, string Instrument, double OpenPrice, double SLPrice, double TPPrice, datetime Expiration=0){ //Retry a number of times in case the submission fails for(int i=1; i<=OrderOpRetry; i++){ //Set the color for the open arrow for the order color OpenColor=clrBlueViolet; if(Command==OP_BUY){ OpenColor=clrChartreuse; } if(Command==OP_SELL){ OpenColor=clrDarkTurquoise; } //Calculate the position size, if the lot size is zero then exit the function double SLPoints=0; //If the Stop Loss price is set then find the points of distance between open price and stop loss price, and round it if(SLPrice>0) SLPoints=MathCeil(MathAbs(OpenPrice-SLPrice)/Point()); //Call the function to calculate the position size LotSizeCalculate(SLPoints); //If the position size is zero then exit and don't submit any orderInit if(LotSize==0) return; //Submit the order int res=OrderSend(Instrument,Command,LotSize,OpenPrice,Slippage,NormalizeDouble(SLPrice,Digits()),NormalizeDouble(TPPrice,Digits()),OrderNote,MagicNumber,Expiration,OpenColor); //If the submission is successful print it in the log and exit the function if(res!=-1){ Print("TRADE - OPEN SUCCESS - Order ",res," submitted: Command ",Command," Volume ",LotSize," Open ",OpenPrice," Stop ",SLPrice," Take ",TPPrice," Expiration ",Expiration); break; } //If the submission failed print the error else{ Print("TRADE - OPEN FAILED - Order ",res," submitted: Command ",Command," Volume ",LotSize," Open ",OpenPrice," Stop ",SLPrice," Take ",TPPrice," Expiration ",Expiration); int Error=GetLastError(); string ErrorText=GetLastErrorText(Error); Print("ERROR - NEW - error sending order, return error: ",Error," - ",ErrorText); } } return; } //Modify Order Function adjusted to handle errors and retry multiple times void ModifyOrder(int Ticket, double OpenPrice, double SLPrice, double TPPrice){ //Try to select the order by ticket number and print the error if failed if(OrderSelect(Ticket,SELECT_BY_TICKET)==false){ int Error=GetLastError(); string ErrorText=GetLastErrorText(Error); Print("ERROR - SELECT TICKET - error selecting order ",Ticket," return error: ",Error); return; } //Normalize the digits for stop loss and take profit price SLPrice=NormalizeDouble(SLPrice,Digits()); TPPrice=NormalizeDouble(TPPrice,Digits()); //Try to submit the changes multiple times for(int i=1; i<=OrderOpRetry; i++){ //Submit the change bool res=OrderModify(Ticket,OpenPrice,SLPrice,TPPrice,0,Blue); //If the change is successful print the result and exit the function if(res){ Print("TRADE - UPDATE SUCCESS - Order ",Ticket," new stop loss ",SLPrice," new take profit ",TPPrice); break; } //If the change failed print the error with additional information to troubleshoot else{ int Error=GetLastError(); string ErrorText=GetLastErrorText(Error); Print("ERROR - UPDATE FAILED - error modifying order ",Ticket," return error: ",Error," Open=",OpenPrice, " Old SL=",OrderStopLoss()," Old TP=",OrderTakeProfit(), " New SL=",SLPrice," New TP=",TPPrice," Bid=",MarketInfo(OrderSymbol(),MODE_BID)," Ask=",MarketInfo(OrderSymbol(),MODE_ASK)); Print("ERROR - ",ErrorText); } } return; } //Close Single Order Function adjusted to handle errors and retry multiple times void CloseOrder(int Ticket, double Lots, double CurrentPrice){ //Try to close the order by ticket number multiple times in case of failure for(int i=1; i<=OrderOpRetry; i++){ //Send the close command bool res=OrderClose(Ticket,Lots,CurrentPrice,Slippage,Red); //If the close was successful print the resul and exit the function if(res){ Print("TRADE - CLOSE SUCCESS - Order ",Ticket," closed at price ",CurrentPrice); break; } //If the close failed print the error else{ int Error=GetLastError(); string ErrorText=GetLastErrorText(Error); Print("ERROR - CLOSE FAILED - error closing order ",Ticket," return error: ",Error," - ",ErrorText); } } return; } //Close All Orders of a specified type const int OP_ALL=-1; //Constant to define the additional OP_ALL command which is the reference to all type of orders void CloseAll(int Command){ //If the command is OP_ALL then run the CloseAll function for both BUY and SELL orders if(Command==OP_ALL){ CloseAll(OP_BUY); CloseAll(OP_SELL); return; } double ClosePrice=0; //Scan all the orders to close them individually //NOTE that the for loop scans from the last to the first, this is because when we close orders the list of orders is updated //hence the for loop would skip orders if we scan from first to last for(int i=OrdersTotal()-1; i>=0; i--) { //First select the order individually to get its details, if the selection fails print the error and exit the function if( OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false ) { Print("ERROR - Unable to select the order - ",GetLastError()); break; } //Check if the order is for the current symbol and was opened by the EA and is the type to be closed if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()==Command) { //Define the close price RefreshRates(); if(Command==OP_BUY) ClosePrice=Bid; if(Command==OP_SELL) ClosePrice=Ask; //Get the position size and the order identifier (ticket) double Lots=OrderLots(); int Ticket=OrderTicket(); //Close the individual order CloseOrder(Ticket,Lots,ClosePrice); } } } //Scan all orders to find the ones submitted by the EA //NOTE This function is defined as bool because we want to return true if it is successful and false if it fails bool ScanOrders(){ //Scan all the orders, retrieving some of the details for(int i=0;i<OrdersTotal();i++) { //If there is a problem reading the order print the error, exit the function and return false if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false){ int Error=GetLastError(); string ErrorText=GetLastErrorText(Error); Print("ERROR - Unable to select the order - ",Error," - ",ErrorText); return false; } //If the order is not for the instrument on chart we can ignore it if(OrderSymbol()!=Symbol()) continue; //If the order has Magic Number different from the Magic Number of the EA then we can ignore it if(OrderMagicNumber()!=MagicNumber) continue; //If it is a buy order then increment the total count of buy orders if(OrderType()==OP_BUY) TotalOpenBuy++; //If it is a sell order then increment the total count of sell orders if(OrderType()==OP_SELL) TotalOpenSell++; //Increment the total orders count TotalOpenOrders++; //Find what is the open time of the most recent trade and assign it to LastBarTraded //this is necessary to check if we already traded in the current candle if(OrderOpenTime()>LastBarTraded || LastBarTraded==0) LastBarTraded=OrderOpenTime(); }return true; } [ATTACH type="full"]25011[/ATTACH]