stevehopwoodforex.com
https://www.stevehopwoodforex.com/phpBB3/
Print view

HELP WITH ERROR 4107
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=2914
Page 1 of 18
Author:  fx800 [ Mon Aug 05, 2013 5:41 pm ]
Post subject:  HELP WITH ERROR 4107

Firstly, my congratulations to Steve and Shelley for a very formidable ea, the Bob and Shelley again.

I tried to modify the ea to enter by a pending order rather than buyopen/sellopen in order to avoid a premature entry like the one shown below.

I am getting error 4107. Tried goggling for help without any success.

Would appreciate any help from the brilliant coders in Steve's forum.

Thanks in advance.

peter
Author:  phil_trade [ Mon Aug 05, 2013 5:57 pm ]
Post subject:  Re: HELP WITH ERROR 4107

OrderSend Error 4107 (Backtesting)

January 24, 2011 (Last updated on September 22, 2011)


OrderSend Error 4107 is a so-called MQL4 run-time error that is similar to OrderSend Error 129 but, unlike the latter, appears only during backtesting of the Empty4 expert advisors, not during their live or demo run. The error is called ERR_INVALID_PRICE_PARAM (Invalid price) in the Empty4 documentation; it has no counterpart in MT5. There are two main reasons for this 4107 error to appear:
•Negative values in price, stoploss or takeprofit parameters of the OrderSend() function. Just make sure you pass the valid price parameters to this function, they surely shouldn’t be negative.
•Unnormalized doubles in price, stoploss or takeprofit parameters of the OrderSend() function. If your Forex broker uses 4 digits after the dot in quotes and you are trying to use 5 digits in your orders, then you’ll be getting error 4107 during backtesting. The best solution here is to always normalize all the price doubles using the standard Empty4 function before passing them to OrderSend():

OpenPrice = NormalizeDouble(OpenPrice, Digits);
StopLossPrice = NormalizeDouble(StopLossPrice, Digits);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice, Digits);
OrderSend(Symbol(), OP_BUY, 1, OpenPrice, StopLossPrice, TakeProfitPrice, ...);
Author:  fx800 [ Mon Aug 05, 2013 6:15 pm ]
Post subject:  Re: HELP WITH ERROR 4107

phil_trade wrote:OrderSend Error 4107 (Backtesting)

January 24, 2011 (Last updated on September 22, 2011)


OrderSend Error 4107 is a so-called MQL4 run-time error that is similar to OrderSend Error 129 but, unlike the latter, appears only during backtesting of the Empty4 expert advisors, not during their live or demo run. The error is called ERR_INVALID_PRICE_PARAM (Invalid price) in the Empty4 documentation; it has no counterpart in MT5. There are two main reasons for this 4107 error to appear:
•Negative values in price, stoploss or takeprofit parameters of the OrderSend() function. Just make sure you pass the valid price parameters to this function, they surely shouldn’t be negative.
•Unnormalized doubles in price, stoploss or takeprofit parameters of the OrderSend() function. If your Forex broker uses 4 digits after the dot in quotes and you are trying to use 5 digits in your orders, then you’ll be getting error 4107 during backtesting. The best solution here is to always normalize all the price doubles using the standard Empty4 function before passing them to OrderSend():

OpenPrice = NormalizeDouble(OpenPrice, Digits);
StopLossPrice = NormalizeDouble(StopLossPrice, Digits);
TakeProfitPrice = NormalizeDouble(TakeProfitPrice, Digits);
OrderSend(Symbol(), OP_BUY, 1, OpenPrice, StopLossPrice, TakeProfitPrice, ...);
Many thanks, Phil Trade. I have applied NormalizeDouble to takeprofit and stoploss and wait to see if it fixes the problem.

peter
Author:  phil_trade [ Mon Aug 05, 2013 6:36 pm ]
Post subject:  Re: HELP WITH ERROR 4107

Unfortunately, the error 4107 persists during demo despite applying NormalizeDouble to price, takeprofit and stoploss.
add a Print to see all prices ( Price/SL/TP and Bid) in journal so you can understand.
Author:  phil_trade [ Mon Aug 05, 2013 6:40 pm ]
Post subject:  Re: HELP WITH ERROR 4107

fx8000 wrote:Firstly, my congratulations to Steve and Shelley for a very formidable ea, the Bob and Shelley again.

I tried to modify the ea to enter by a pending order rather than buyopen/sellopen in order to avoid a premature entry like the one shown below.

I am getting error 4107. Tried goggling for help without any success.

Would appreciate any help from the brilliant coders in Steve's forum.

Thanks in advance.

peter

?? which lines of code did you modified to get Pending order ?
Author:  fx800 [ Mon Aug 05, 2013 6:46 pm ]
Post subject:  Re: HELP WITH ERROR 4107

phil_trade wrote:
fx8000 wrote:Firstly, my congratulations to Steve and Shelley for a very formidable ea, the Bob and Shelley again.

I tried to modify the ea to enter by a pending order rather than buyopen/sellopen in order to avoid a premature entry like the one shown below.

I am getting error 4107. Tried goggling for help without any success.

Would appreciate any help from the brilliant coders in Steve's forum.

Thanks in advance.

peter

?? which lines of code did you modified to get Pending order ?
I have added the functions Has Buy Filled and Has Sell Filled, and the Pending order code

Code: Select all

 void HasBuyFilled()
{
   //This function examines the Ask to see if a pending Buy price has been reached, and sends the trade if so.
   //Uses the Bid for buys also, as this is the price we see on the chart and the hi-lo is the Bid hi-lo.

   //Set pending price
   PendingPrice = 0;
   if (ObjectFind(pendingbuypriceline) > -1) PendingPrice = ObjectGet(pendingbuypriceline, OBJPROP_PRICE1);

   RefreshRates();
   if (Bid >= PendingPrice && PendingPrice > 0)
   {
      //Close existing trades
      // Note to self: Cannot delete pending price line before old trade is closed!
      if( SellOpen && CanCloseTrades )
      {
         CloseAllTrades();
         if (ForceTradeClosure)
         {
            OldBars = 0;
            return;
         }//if (ForceTradeClosure)
         else SellOpen = false;
      }//if (SellOpen)

      if ( !BuyOpen ) 
      {
         double take, stop, price;
         int type;
         double SendLot = Lot;
         bool CancelTrade = false;

         price = Ask;
         type = OP_BUY;

         take = CalculateTakeProfit(OP_BUY, price);
         stop = CalculateStopLoss(OP_BUY, price);
         
         if (!TradeLong)
         {
            CancelTrade = true;
         }
         
         //Check filters
         if( !IsTradingAllowed() ) CancelTrade = true;

         if (CancelTrade)
         {
            ObjectDelete(pendingbuypriceline);
            PendingBuy = false;
            return;
         }//if (CancelTrade)
         
         datetime ExpiryTime = TimeCurrent() + (PendingBarsTF * BarsToKeepPendings);//Dietcoke modification

         bool result = SendSingleTrade(Symbol(), type, MainTradeComment, SendLot, price, stop, take, ExpiryTime);
         if (result)
         {
            ObjectDelete(pendingbuypriceline);
            PendingBuy = false;
         }//if (result)
         else
         {
            OldBars = 0;   // Retry next tick
         }
      }
   }//if (Ask >= PendingPrice)
}//End void HasBuyFilled()

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void HasSellFilled()
{
   //This function examines the Bid to see if a pending Sell price has been reached, and sends the trade if so

   //Set pending price
   PendingPrice = 0;
   if (ObjectFind(pendingsellpriceline) > -1) PendingPrice = ObjectGet(pendingsellpriceline, OBJPROP_PRICE1);

   RefreshRates();
   if (Bid <= PendingPrice && PendingPrice > 0)
   {
      //Close existing trades
      if( BuyOpen && CanCloseTrades )
      {
         CloseAllTrades();
         if (ForceTradeClosure)
         {
            OldBars = 0;
            return;
         }//if (ForceTradeClosure)
         else BuyOpen = false;
      }//if (BuyOpen)

      if( !SellOpen )
      {
         double take, stop, price;
         int type;
         double SendLot = Lot;
         bool CancelTrade = false;

         price = NormalizeDouble(Bid, Digits);
         type = OP_SELL;

         take = CalculateTakeProfit(OP_SELL, price);
         stop = CalculateStopLoss(OP_SELL, price);
        
         if (!TradeShort) 
         {
            CancelTrade = true;
         } 
         
         //Check filters
         if (!IsTradingAllowed() ) CancelTrade = true;

         if (CancelTrade)
         {
            ObjectDelete(pendingsellpriceline);
            PendingSell = false;
            return;
         }//if (CancelTrade)

			datetime ExpiryTime = TimeCurrent() + (PendingBarsTF * BarsToKeepPendings);//Dietcoke modification

         bool result = SendSingleTrade(Symbol(), type, MainTradeComment, SendLot, price, stop, take, ExpiryTime);
         if (result)
         {
            ObjectDelete(pendingsellpriceline);
            PendingSell = false;
         }//if (result)
         else
         {
            OldBars = 0;   // Retry next tick
         }
      }
   }//if (Bid >= PendingPrice)
}//End void HasSellFilled()

Code: Select all

   
   
   //Long 
   if (SendLong)   {
      stype = " BuyStop ";
      type = OP_BUYSTOP;
      
      if (ObjectFind(pendingbuypriceline) == -1 && !BuyOpen)
      {
         target = NormalizeDouble(High[1] + (Buffer / factor), Digits);
         Print( "Drawing line ", pendingbuypriceline, " at price ", DoubleToStr(target,Digits) );
         ObjectCreate(pendingbuypriceline, OBJ_TREND, 0, Time[0], target, TimeCurrent() + (Period() * 60), target); 
         ObjectSet(pendingbuypriceline, OBJPROP_COLOR, Green); 
         ObjectSet(pendingbuypriceline, OBJPROP_WIDTH, 1); 
         ObjectSet(pendingbuypriceline, OBJPROP_STYLE, STYLE_DASH); 
         ObjectSet(pendingbuypriceline, OBJPROP_RAY, true);
      }//if (ObjectFind(pendingbuypriceline) == -1)
      
         
      if (!SendAlertNotTrade)
      {
         
         stop = CalculateStopLoss(OP_BUY, price);
         
         
         take = CalculateTakeProfit(OP_BUY, price);
         
         
         //Lot size calculated by risk
         if (RiskPercent > 0) SendLots = CalculateLotSize(price, NormalizeDouble(stop + (HiddenPips / factor), Digits) );

         type = OP_BUY;
         
      }//if (!SendAlertNotTrade)
      
      SendTrade = true;
      
   }//if (SendLong)
   
   //Short
   if (SendShort)
   {
      stype = " SellStop ";
      type = OP_SELLSTOP;
      
      if (ObjectFind(pendingsellpriceline) == -1 && !SellOpen)
      {
         target = NormalizeDouble(Low[1] - (Buffer / factor), Digits);
         Print( "Drawing line ", pendingsellpriceline, " at price ", DoubleToStr(target,Digits) );
         ObjectCreate(pendingsellpriceline, OBJ_TREND, 0, Time[0], target, TimeCurrent() + (Period() * 60), target); 
         ObjectSet(pendingsellpriceline, OBJPROP_COLOR, Red);
         ObjectSet(pendingsellpriceline, OBJPROP_WIDTH, 1); 
         ObjectSet(pendingsellpriceline, OBJPROP_STYLE, STYLE_DASH); 
         ObjectSet(pendingsellpriceline, OBJPROP_RAY, true);
      }//if (ObjectFind(pendingsellpriceline) == -1))
      

      if (!SendAlertNotTrade)
      {
         
         stop = CalculateStopLoss(OP_SELL, price);
         
         take = CalculateTakeProfit(OP_SELL, price);
         
         
         //Lot size calculated by risk
         if (RiskPercent > 0) SendLots = CalculateLotSize(price, NormalizeDouble(stop - (HiddenPips / factor), Digits) );

         type = OP_SELL;
      }//if (!SendAlertNotTrade)
         
      SendTrade = true;      
   
      
   }//if (SendShort)
   

   if (SendTrade)
   {
      if (!SendAlertNotTrade) 
      { 
         result = SendSingleTrade(Symbol(), type, MainTradeComment, SendLots, price, stop, take);
         if (result) 
         {
            if (EmailTradeNotification) SendMail("Trade sent ", Symbol() + stype + "trade at " + TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES));
            if (AlertPush) AlertNow(WindowExpertName() + " " + Symbol() + " " + stype + " " + DoubleToStr(price, Digits) );
            OrderSelect(TicketNo, SELECT_BY_TICKET, MODE_TRADES);
            CheckTpSlAreCorrect(type);
         }//if (result)          
      }//if (!SendAlertNotTrade) 
      
      if (SendAlertNotTrade && !AlertSent)
      {
         Alert(WindowExpertName(), " ", Symbol(), " ", stype, "trade has triggered. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
         SendMail("Trade alert. ", Symbol() + " " + stype + " trade has triggered. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
         if (AlertPush) AlertNow(WindowExpertName() + " " + Symbol() + " " + stype + " " + DoubleToStr(price, Digits) );         
         AlertSent=true;
       }//if (SendAlertNotTrade && !AlertSent)
   }//if (SendTrade)
   
   //Actions when trade send succeeds
   if (SendTrade && result)
   {      
      if (!SendAlertNotTrade && !CloseEnough(HiddenPips, 0) ) ReplaceMissingSlTpLines();
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
      OldBarsTime = 0;
   }//if (!result)
   
   
   if (ObjectFind(pendingbuypriceline) > -1) HasBuyFilled();
   if (ObjectFind(pendingsellpriceline) > -1) HasSellFilled();  
The same pending order code has been working fine in other ea's.
Author:  fx800 [ Tue Aug 06, 2013 9:50 am ]
Post subject:  Re: HELP WITH ERROR 4107

Two more examples where a pending order a few pips above High[1] would have avoided a premature entry.
Author:  phil_trade [ Tue Aug 06, 2013 10:08 am ]
Post subject:  Re: HELP WITH ERROR 4107

fx8000 wrote:Two more examples where a pending order a few pips above High[1] would have avoided a premature entry.
the better way to debug is to add Lprint() with Bid/ Pending Price, SL ans TP to see why OrderSend is rejected
Author:  fx800 [ Tue Aug 06, 2013 11:09 am ]
Post subject:  Re: HELP WITH ERROR 4107

I am often puzzled why using the following BuyStop/SellStop code doesn't work. Can someone please explain.

Thanks.

Code: Select all

       stype = " BuyStop ";
      type = OP_BUYSTOP;
      
      if (!BuyOpen)
      {
         price = NormalizeDouble(High[1] + (Buffer / factor), Digits);
      } 

Code: Select all

      stype = " SellStop ";
      type = OP_SELLSTOP;
      
      if (!SellOpen)
      {
         price = NormalizeDouble(Low[1] - (Buffer / factor), Digits);
      } 
Author:  phil_trade [ Tue Aug 06, 2013 11:29 am ]
Post subject:  Re: HELP WITH ERROR 4107

fx8000 wrote:I am often puzzled why using the following BuyStop/SellStop code doesn't work. Can someone please explain.

Thanks.

Code: Select all

       stype = " BuyStop ";
      type = OP_BUYSTOP;
      
      if (!BuyOpen)
      {
         price = NormalizeDouble(High[1] + (Buffer / factor), Digits);
      } 

Code: Select all

      stype = " SellStop ";
      type = OP_SELLSTOP;
      
      if (!SellOpen)
      {
         price = NormalizeDouble(Low[1] - (Buffer / factor), Digits);
      } 
what do you mean by "doesn't work" ?
All times are UTC Page 1 of 18