Skip to content

format_kline truncates K-line prices to 4 decimals regardless of exchange tick size #218

Description

@z20251130

Describe the bug

backend_api_python/app/data_sources/base.py format_kline rounds every OHLC price with round(float(x), 4). Exchange tick sizes are not a fixed 4 decimals: several Binance perpetual symbols trade at 5–6 decimal ticks (verified from fapi.binance.com/exchangeInfo):

symbol PRICE_FILTER tickSize
TUT/USDT:USDT 0.0000100 (5 dp)
TAG/USDT:USDT 0.0000010 (6 dp)
JCT/USDT:USDT 0.0000010 (6 dp)
CYS/USDT:USDT / BEAT/USDT:USDT 0.0001000 (4 dp, unaffected)

So for low-priced symbols the persisted price loses 1–2 decimal places versus real quotes. Every consumer of get_kline — Strategy V2 backtests, indicators, AI features, charts — then works on prices that differ from the market. Price-threshold logic (e.g. breakout close > prior_high) fires on the wrong bars for these symbols.

Steps to reproduce

  1. Fetch one bar via ccxt directly: exchange.fetch_ohlcv('TUT/USDT:USDT', '5m') → close 0.01038 (5 dp).
  2. Fetch the same bar via DataSourceFactory.get_kline(market='Crypto', symbol='TUT/USDT', timeframe='5m', market_type='swap') → close 0.0104 (4 dp, rounded).
  3. Run any Strategy V2 breakout backtest on a universe that includes low-priced perps; compare full-precision frames vs the rounded frames → different entry bars, trade counts, and per-symbol PnL.

Expected behavior

K-line prices should preserve the exchange's actual tick precision (or round to the per-symbol PRICE_FILTER.tickSize), not a fixed 4 decimals.

Deployment method

Docker Compose

Relevant logs

ccxt fetch_ohlcv('TUT/USDT:USDT','5m') 2026-02-25T16:10:00Z close=0.01038
get_kline TUT/USDT swap same bar            close=0.0104

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions