I have run into an intermittent problem with the OrderCalcProfit() function, can anyone help me see what might be causing it? I am using OrderCalcProfit() to determine the lot-size of a position such that it has a given risk based on percentage of my account. e.g. I want each trade to lose 0.5% of my account if the stoploss is hit.
Occasionally, this function will compute a value for profit of 0, despite having valid inputs, returning true and no error being signaled via GetLastError().
I have spent quite a while reading through other posts before making my own, I do believe this is an issue that isn't obviously talked about elsewhere. This post is the closet I could find: https://www.mql5.com/en/forum/430265/page2#comment_43066510
Here is some code to illustrate the problem. I caveat, that most of the time it works OK, but about 25-50% of the time in a live account I get the issue described.
As an example, here are some parameters from a trade this EA attempted to execute today:
- order_type = ORDER_TYPE_SELL
- symbol = "GPBJPY.a"
- entry = 194.072
- stoploss = 194.595
- risk = 22.29 (computed from 0.5% of account balance)
While I don't fully understand the problem, I have diagnosed a number of characteristics of when it goes wrong:
- OrderCalcProfit() returns true, but profit is set to 0.0 - this is really the root cause, but I don't understand why it is happening
- This leads to a division by zero (uncaught) and lots_rough is set to infinity
- Then, lots_aligned is set to lots_max (equivalent to SYMBOL_VOLUME_MAX)
- The order is built and executed, but rejected by the server as my account doesn't have enough money
Any ideas what might cause this? I have a chart open on the symbol that is being traded. Data is being received from the server and plotted on the chart. The previous trade might have worked fine, but arbitrary ones unfold as I describe above. This is all in an EA where I access pricing data via iHigh()/iLow() methods.
Please print all the values used with OrderCalcProfit(), then show us the output log when it returns 0.
Thanks for looking! I have updated the code with a print statement that provides what you ask for.
double LotsFixedRiskDollars(const ENUM_ORDER_TYPE order_type, const string symbol, const double entry, const double stoploss, const double risk) { double lots_min = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); double lots_max = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); double lots_step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP); double profit; if ((order_type != ORDER_TYPE_BUY) && (order_type != ORDER_TYPE_SELL)) { ERROR("order_type must be ORDER_TYPE_BUY or ORDER_TYPE_SELL"); return -1.0; } else if (OrderCalcProfit(order_type, symbol, lots_max, entry, stoploss, profit)) { double lots_rough = MathRound(risk * lots_max / (-profit * lots_step)); double lots_aligned = MathMin(MathMax(lots_rough * lots_step, lots_min), lots_max); PrintFormat("LOTS INFO!!! (%s,%s,%f,%f,%f) (%f,%f,%f,%f) (%f,%f)", EnumToString(order_type), symbol, entry, stoploss, risk, lots_min, lots_max, lots_step, profit, lots_rough, lots_aligned); return lots_aligned; } else { ERROR("OrderCalcProfit() returned false"); return -1.0; } }
Here are three examples that happened earlier today. I cannot recreate the problem on demand, but have recent examples to reference.
2024.10.09 07:00:02.111 Range Breakout (DE40.a,M30) LOTS INFO!!! (ORDER_TYPE_BUY,DE40.a,19099.500000,19055.500000,22.292500) (0.100000,250.000000,0.100000,-0.000000) (inf,250.000000) 2024.10.09 07:00:02.191 Range Breakout (GBPJPY.a,M30) LOTS INFO!!! (ORDER_TYPE_BUY,GBPJPY.a,194.595000,194.072000,22.292500) (0.010000,100.000000,0.010000,-0.000000) (inf,100.000000) 2024.10.09 07:00:04.031 Range Breakout (GBPJPY.a,M30) LOTS INFO!!! (ORDER_TYPE_SELL,GBPJPY.a,194.072000,194.595000,22.292500) (0.010000,100.000000,0.010000,-0.000000) (inf,100.000000)
Is this perhaps running in an Indicator?
I ask because, as far as I remember, the function does not run correctly in an Indicator, only on an EA and Script.
Is this perhaps running in an Indicator?
I ask because, as far as I remember, the function does not run correctly in an Indicator, only on an EA and Script.
No, this is run in an EA.
This particular code is being invoked from OnTick(). Ideally, this is determining the lot size of an order that the EA will submit.
Thanks for looking! I have updated the code with a print statement that provides what you ask for.
Here are three examples that happened earlier today. I cannot recreate the problem on demand, but have recent examples to reference.
What is your account currency ?
You said occasionally it returns 0.0, is it for the same symbol (GBPJPY.a for example) ?
Why are you running OrderCalcProfit with lots_max ?
To calculate the lot size for a desired risk amount in account equity/balance.
I have followed the pattern from @Fernando Carreiro, for example: https://www.mql5.com/en/forum/430265/page2#comment_41590903
By calculating the loss associated with hitting stop-loss for a maximum volume trade, you can then scale the lot-size back down to a multiple of SYMBOL_VOLUME_STEP that is as close as possible to your desired risk.
- 2022.08.23
- Fernando Carreiro
- www.mql5.com
What is your account currency ?
You said occasionally it returns 0.0, is it for the same symbol (GBPJPY.a for example) ?
My account currency is AUD.
I do not trade any symbol in that currency though.
So far I have noticed this problem with DE40.a (German stock index) and some FX pairs (GBPJPY.a, GBPUSD.a, USDJPY.a)
My account currency is AUD.
I do not trade any symbol in that currency though.
So far I have noticed this problem with DE40.a (German stock index) and some FX pairs (GBPJPY.a, GBPUSD.a, USDJPY.a)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I have run into an intermittent problem with the OrderCalcProfit() function, can anyone help me see what might be causing it? I am using OrderCalcProfit() to determine the lot-size of a position such that it has a given risk based on percentage of my account. e.g. I want each trade to lose 0.5% of my account if the stoploss is hit.
Occasionally, this function will compute a value for profit of 0, despite having valid inputs, returning true and no error being signaled via GetLastError().
I have spent quite a while reading through other posts before making my own, I do believe this is an issue that isn't obviously talked about elsewhere. This post is the closet I could find: https://www.mql5.com/en/forum/430265/page2#comment_43066510
Here is some code to illustrate the problem. I caveat, that most of the time it works OK, but about 25-50% of the time in a live account I get the issue described.
As an example, here are some parameters from a trade this EA attempted to execute today:
While I don't fully understand the problem, I have diagnosed a number of characteristics of when it goes wrong:
Any ideas what might cause this? I have a chart open on the symbol that is being traded. Data is being received from the server and plotted on the chart. The previous trade might have worked fine, but arbitrary ones unfold as I describe above. This is all in an EA where I access pricing data via iHigh()/iLow() methods.