Skip to content

Fix the USD/KRW minimum price variation - #9656

Merged
Martin-Molinero merged 1 commit into
QuantConnect:masterfrom
AlexCatarino:remove-ib-usdkrw-spdb-row
Aug 5, 2026
Merged

Fix the USD/KRW minimum price variation#9656
Martin-Molinero merged 1 commit into
QuantConnect:masterfrom
AlexCatarino:remove-ib-usdkrw-spdb-row

Conversation

@AlexCatarino

Copy link
Copy Markdown
Member

Description

Sets the USD/KRW minimum price variation to 0.01 and removes the duplicated
interactivebrokers entry, leaving a single row for the pair:

-interactivebrokers,USDKRW,forex,USD/KRW,KRW,1,0.01,1
-oanda,USDKRW,forex,USD/KRW,KRW,1,0.00001,1
+oanda,USDKRW,forex,USD/KRW,KRW,1,0.01,1

Related Issue

Follow up of #9585 and #9652, which added the two USD/KRW entries.

Motivation and Context

The oanda entry declared 0.00001, the generic five decimal forex default, for a pair
quoted around 1430. That is three orders of magnitude finer than its real tick, and out of
line with the other big number oanda pairs, which do scale it: USD/JPY, USD/HUF, USD/INR
and USD/THB all use 0.001.

The 0.01 comes from Interactive Brokers itself. Placing a limit order for USD/KRW at
1395.123 on a live IB connection, the brokerage looked the tick up with
reqContractDetails and rounded the price before sending it:

PROBE PLACING FOREX ORDER: USDKRW limit buy 25000 @ 1395.123
                           (market price=1423.705, symbol properties mpv=0.00001)
PROBE ORDER TICKET: id=1 status=New limitAfterLeanRounding=1395.12300
Brokerage Warning: To meet brokerage precision requirements, price was rounded to 1395.12
                   from 1395.12300 due to minimum tick size constraint (0.01).

Note the middle line: LEAN rounds order prices with the symbol properties value, so the
0.00001 let the sub tick price through untouched and only the brokerage, which asks IB
for the real tick, kept it from being used. That is why the wrong value was invisible in
live trading. In a backtest there is no such correction and limit orders rest at prices the
venue cannot represent.

The same tick shows up in the data. Over 48 hours of USD/KRW minute history from IB, the
smallest bid to bid steps are 0.009 x8, 0.010 x142, 0.011 x5, 0.019 x21, 0.02 x104:
nothing below 0.009, everything clustered on the 0.01 grid. The occasional third decimal
(1430.791) is a double to decimal conversion artifact, always a thousandth below a 0.01
grid point. For comparison, USD/JPY over the same window steps 0.001 x167, 0.002 x221,
0.003 x141, a dense ladder starting exactly at its declared 0.001.

The interactivebrokers entry is removed because it is unreachable in practice: forex
resolves through the brokerage model default market, which is Market.Oanda for Interactive
Brokers, so only an explicit AddForex("USDKRW", ..., Market.InteractiveBrokers) would pick
it. Subscribing without the market parameter and with the entry removed keeps resolving to
the same IB contract, CASH USD KRW IDEALPRO, with no subscription errors, and history and
streaming are unchanged.

Requires Documentation Change

No.

How Has This Been Tested?

SymbolPropertiesDatabaseTests passes (42 tests).

Live against IB: subscribed to USD/KRW without a market parameter and with the
interactivebrokers entry removed, confirming it resolves to the oanda symbol and the same
IDEALPRO contract, returns 2870 minute bars over two days with data in every hour, and
streams quotes, all identical to the behaviour before the removal. The order above provided
the tick value.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which improves implementation)
  • Performance (non-breaking change which improves performance. Please add associated performance test and results)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Non-functional change (xml comments/documentation/etc)

Checklist:

  • My code follows the code style of this project.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My branch follows the naming convention bug-<issue#>-<description> or feature-<issue#>-<description>

🤖 Generated with Claude Code

The oanda USD/KRW entry declared a 0.00001 minimum price variation, the
generic five decimal forex default, for a pair that IB quotes around
1430: three orders of magnitude finer than its real tick, and out of
line with the other big number oanda pairs, which scale it (USD/JPY,
USD/HUF, USD/INR and USD/THB all use 0.001).

Interactive Brokers reports 0.01 as the minimum tick of its USD/KRW
IDEALPRO contract, so a limit order priced at 1395.123 is rounded down
to 1395.12 before it is sent. LEAN rounds order prices with the symbol
properties value, so the brokerage was the only thing keeping sub tick
prices from being used, and a backtest would rest limit orders at prices
the venue cannot represent.

The interactivebrokers entry, added by QuantConnect#9585 with the correct tick, is
removed: forex resolves through the brokerage model default market,
which is oanda for Interactive Brokers, so it is only reachable by
passing the market explicitly and it duplicates the oanda one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Martin-Molinero
Martin-Molinero merged commit 42b9d76 into QuantConnect:master Aug 5, 2026
7 of 8 checks passed
@AlexCatarino
AlexCatarino deleted the remove-ib-usdkrw-spdb-row branch August 5, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants