Posting this in case it helps someone, because it took me a while to work out.
I run a few long-only strategies on Wall Street and Nasdaq. They take half the position off at a profit target and let the rest run. The position size changes with the account balance, so it ends up on odd numbers like 0.3, 0.7 or 1.1 contracts.
To take half off, I used halfSize = posSize / 2. Looks fine. It backtested perfectly over 16 years.
Then it went live and the half-off orders started getting rejected by IG because half of 0.3 is 0.15. Half of 0.7 is 0.35. IG only accepts sizes in steps of 0.1, so it refuses those orders. But, the ProRealTime backtester fills them without complaint. So the backtest and the live account quietly stop matching.
It gets worse on a scale-out. When the half-off order is rejected, the code still thinks it happened and flips into “runner” mode. So the strategy believes it’s holding a small runner, while the account is actually still holding the full position — and the stop is gone.
The fix is to round the size to a valid step, and to work out the runner size separately instead of assuming it’s the other half:
halfSize = ROUND(posSize * 0.5 * 10) / 10
IF halfSize < 0.1 THEN
halfSize = 0.1
ENDIF
IF halfSize > posSize - 0.1 THEN
halfSize = posSize - 0.1
ENDIF
runnerSize = posSize - halfSize
Then sell halfSize at the target and runnerSize on the runner exit — never assume the two are equal.
Two takeaways:
- A clean backtest doesn’t mean it will run live. The backtester fills fractional sizes the broker rejects, so the only real test is watching an actual part-exit happen live.
- If your sizes step in even tenths (0.2, 0.4, 0.6…), the halves are always valid and this never happens. Worth building in from the start.
Happy to compare notes if anyone else runs scale-out exits under ProOrder.
You can round to one single digit with:
halfSize = ROUND(posSize * 0.5, 1)
The second argument is the decimal quantity. If that help 😉
See:
ROUND
JSParticipant
Veteran
Thanks for sharing…
I’m using an IG CFD account, and position sizes with two decimal places are accepted and executed without any issues…
Perhaps the minimum size increment depends on the account type… (spread betting)