HELP WITH ERROR 4107
-
fx800
- Trader
- Posts: 1334
- Joined: Sun Dec 04, 2011 4:11 am
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
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
You do not have the required permissions to view the files attached to this post.
Last edited by Anonymous on Mon Aug 05, 2013 11:35 pm, edited 2 times in total.
-
phil_trade
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, ...);
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, ...);
-
fx800
- Trader
- Posts: 1334
- Joined: Sun Dec 04, 2011 4:11 am
Re: HELP WITH ERROR 4107
Many thanks, Phil Trade. I have applied NormalizeDouble to takeprofit and stoploss and wait to see if it fixes the problem.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, ...);
peter
-
phil_trade
Re: HELP WITH ERROR 4107
add a Print to see all prices ( Price/SL/TP and Bid) in journal so you can understand.Unfortunately, the error 4107 persists during demo despite applying NormalizeDouble to price, takeprofit and stoploss.
-
phil_trade
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 ?
-
fx800
- Trader
- Posts: 1334
- Joined: Sun Dec 04, 2011 4:11 am
Re: HELP WITH ERROR 4107
I have added the functions Has Buy Filled and Has Sell Filled, and the Pending order codephil_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 ?
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(); -
fx800
- Trader
- Posts: 1334
- Joined: Sun Dec 04, 2011 4:11 am
Re: HELP WITH ERROR 4107
Two more examples where a pending order a few pips above High[1] would have avoided a premature entry.
You do not have the required permissions to view the files attached to this post.
-
phil_trade
Re: HELP WITH ERROR 4107
the better way to debug is to add Lprint() with Bid/ Pending Price, SL ans TP to see why OrderSend is rejectedfx8000 wrote:Two more examples where a pending order a few pips above High[1] would have avoided a premature entry.
-
fx800
- Trader
- Posts: 1334
- Joined: Sun Dec 04, 2011 4:11 am
Re: HELP WITH ERROR 4107
I am often puzzled why using the following BuyStop/SellStop code doesn't work. Can someone please explain.
Thanks.
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);
} -
phil_trade
Re: HELP WITH ERROR 4107
what do you mean by "doesn't work" ?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); }