Hello forum, good day.
I'm an MQL5 newbie and I have started with the Step-By-Step Guide to writing an Expert Advisor in MQL5 for Beginners tutorial, but when I run the code I get a message about Invalid stops and an error 4756. I started to modify it but still continue to get the same errors. Could someone with more experience in MQL5 point me in the right direction or help me with a couple freelance classes/jobs in order to complete this EA please? Help will be much appreciated.
What I'm trying to do in my first EA is:
1. Check ADX indicator values when a new bar is created (right at 00:00 hours).
2. If +DI > -DI it should be Buy position, else, if +DI < -DI should be a Sell position.
3. Once determined if it is a Buy or Sell position:
3.1. If it is a Buy position and the previous bar is black (Bear), the order should be placed as a pending order (Buy Stop) with the Opening price of the previous bar; Stop Loss should be placed at the Lowest price from previous bar - 0.1 cents. If the previous bar is not black, then the order shuld not be placed.
3.2. If it is a Sell position and the previous bar is white (Bull), the order should be placed as a pending order (Sell Stop) with the Opening price of the previous bar; Stop Loss should be placed at the Highest price from previous bar + 0.1 cents. If the previous bar is not white, then the order will not be placed.
4. Stop Loss should be moved every day.
5. When the latest price of the product (ask/buy, or bid/sell) reaches Stop Loss, the position is closed.
For now I'm trying to do this with a Market order, but I need to do it with a Pending order. Here is the code I'm using:
//--- Input variables input double Lots = 0.1; // Lots to trade / Trade volume input int StopLoss = 1000; // Stop Loss should be in $ input int ADX_Period = 14; // ADX Period //--- Global Variables bool BuyOpened, SellOpened; // Variables to check for Opened positions int ADX_Handle; // Handle for our ADX indicator int SL; // To be used for Stop Loss value double ADX_Val[], // Dynamic arrays to hold the values of ADX, Plus_DI[], // +DI and Minus_DI[]; // -DI for each bar double p_Open, // Dynamic arrays to hold the opening, p_High, // highest, p_Low, // lowest p_Close; // and closing prices of each bar //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit () { //--- Get handle for ADX indicator ADX_Handle = iADX(NULL, 0, ADX_Period); //--- What if ADX_Handle returns invalid handle? if ( ADX_Handle < 0 ) { Alert("Error creating ADX_Handle for indicators - error: ", GetLastError(), "!"); } //--- Assign StopLoss value to SL variable SL = StopLoss; //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4 if ( _Digits == 5 || _Digits == 3 ) { SL *= 10; } //--- Check that everything is running correctly return(0); } // end OnInit() //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit (const int reason) { //--- Release our indicator handles IndicatorRelease(ADX_Handle); } // end OnDeinit() //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick () { /** * Check for new bars */ //--- Do we have enough bars to work with? if ( Bars(_Symbol, _Period) < 60 ) { Alert("We have less than 60 bars, EA will not exist!!"); return; } //--- We will use the static Old_Time variable to serve the bar time. //--- At each OnTick execution we will check the current bar time with the saved one. //--- If the bar time isn't equal to the saved time, it indicates that we have a new tick. static datetime Old_Time; datetime New_Time[1]; bool IsNewBar = false; //--- Copying the last bar time to the element New_Time[0] int copied = CopyTime(_Symbol, _Period, 0, 1, New_Time); if ( copied > 0 ) { // ok, the data has been copied successfully if ( Old_Time != New_Time[0] ) { // if old time isn't equal to new bar time IsNewBar = true; // if it isn't a first call, the new bar has appeared if ( MQL5InfoInteger(MQL5_DEBUGGING) ) { Print( "We have new bar here ", New_Time[0], " old time was ", Old_Time ); } Old_Time = New_Time[0]; } } else { Alert("Error in copying historical times data, error: ", GetLastError(), "!!"); ResetLastError(); return; } //--- EA should only check for new trade if we have a new bar if ( IsNewBar == false ) { return; } //--- Do we have enough bars to work with? int Mybars = Bars(_Symbol, _Period); if ( Mybars < 60 ) { // if total bars is less than 60 bars Alert("We have less than 60 bars, EA will now exist!!"); return; } //--- Define some MQL5 structures we will use for our trade MqlTradeRequest request; // To be used for sending our trade requests MqlTradeResult result; // To be used to get our trade results MqlRates rates[]; // To be used to store prices, volumes and spread of each bar ZeroMemory(request); // Initialization of request structure /** * Reverse the time series ... 3 2 1 0 */ //--- The rates array ArraySetAsSeries(rates, true); //--- The ADX values arrays ArraySetAsSeries(ADX_Val, true); //--- The ADX +DI values array ArraySetAsSeries(Plus_DI, true); //--- The ADX -DI values array ArraySetAsSeries(Minus_DI, true); //--- Copy the new values of our indicators to buffers (arrays) using the handle CopyBuffer(ADX_Handle, 0, 1, 3, ADX_Val); CopyBuffer(ADX_Handle, 1, 1, 3, Plus_DI); CopyBuffer(ADX_Handle, 2, 1, 3, Minus_DI); //--- Get the details of the last 3 bars int copied_rates = CopyRates(_Symbol, _Period, 0, 3, rates); // CopyOpen(_Symbol, Period(), 0, 3, p_Open); // CopyHigh(_Symbol, Period(), 0, 3, p_High); // CopyLow(_Symbol, Period(), 0, 3, p_Low); // CopyClose(_Symbol, Period(), 0, 3, p_Close); //--- Do we have positions opened already? BuyOpened = false; // Variable to hold the result of Buy opened position SellOpened = false; // Variable to hold the result of Sell opened position if ( PositionSelect(_Symbol) == true ) { // We have an opened position if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ) { BuyOpened = true; // It's a buy } else if ( PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL ) { SellOpened = true; // It's a sell } } //--- Current position information // bool open_position = PositionSelect(_Symbol); // long position_type = PositionGetInteger(POSITION_TYPE); // Copy the previous bar prices prior to the current bar, that is Bar 1 p_Open = rates[1].open; // Bar 1 opening price p_High = rates[1].high; // Bar 1 highest price p_Low = rates[1].low; // Bar 1 lowest price p_Close = rates[1].close; // Bar 1 closing price //--- Declare variables to hold our Buy and Sell conditions bool Buy_Condition = (Plus_DI[0] > Minus_DI[0]) && (p_Close < p_Open); // Buy condition bool Sell_Condition = (Plus_DI[0] < Minus_DI[0]) && (p_Close > p_Open); // Sell condition /** * Check for long/Buy, or a short/Sell */ if ( Buy_Condition ) { //--- Open Buy order //--- Any opened Buy position? if ( BuyOpened ) { Alert("We already have a Buy position!"); return; // Don't open a new buy position } ZeroMemory(request); ZeroMemory(result); request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_BUY; request.symbol = _Symbol; request.volume = Lots; request.price = NormalizeDouble(p_Open, _Digits); request.sl = NormalizeDouble(p_High - SL * _Point, _Digits); request.type_filling = ORDER_FILLING_FOK; request.deviation = 50; //--- Send Buy order int trade_order_1 = OrderSend(request, result); //--- Get the result code if ( result.retcode == TRADE_RETCODE_PLACED || result.retcode == TRADE_RETCODE_DONE ) { Alert("A buy order has been successfully placed with Ticket #", result.order, "!"); } else { Alert("The buy order request could not be completed - error: ", GetLastError(), "!"); ResetLastError(); return; } } else if ( Sell_Condition ) { //--- Open Sell order //--- Any opened Sell position? if ( SellOpened ) { Alert("We already have a Sell position !"); return; // Don't open a new Sell position } ZeroMemory(request); ZeroMemory(result); request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_SELL; request.symbol = _Symbol; request.volume = Lots; request.price = NormalizeDouble(p_Open, _Digits); request.sl = NormalizeDouble(p_Low + SL * _Point, _Digits); request.type_filling = ORDER_FILLING_FOK; request.deviation = 50; //--- Send Sell order int trade_order_2 = OrderSend(request, result); //--- Get the result code if ( result.retcode == TRADE_RETCODE_PLACED || result.retcode == TRADE_RETCODE_DONE ) { Alert("A sell order has been successfully placed with Ticket #", result.order, "!"); } else { Alert("The sell order request could not be completed - error: ", GetLastError(), "!"); ResetLastError(); return; } } } // end OnTick() //+------------------------------------------------------------------+
Regards and thank you in advance,
codeMolecules