Skip to content

Releases: AmirMohammadBazdar/AlgoTradeKit

v1.2.0 - Notifications

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 23 Oct 09:22

[1.2.0] — 2026-10-23

Notifications. A trading session's events, chart pictures, price alerts and a
backtest's report go to Telegram, Discord, e-mail or a webhook, and Telegram
takes commands back. Trading never waits for a message, and nothing changes for
code that asks for none.

Added

  • notify module and TelegramNotifier — one bot and its named chats:
    people, groups, channels and forum topics. TelegramChat(chat_id, thread_id=, silent=, events=, symbols=) gives a chat its own topic, sound and filters. The
    token and every chat are checked when the notifier is created, with a sentence
    saying what to fix, and TelegramNotifier.find_chats(token) lists the chats
    that wrote to the bot. send_text() fills {time}, {date}, {symbol},
    {price} and {header}; timezone=, proxy= (HTTP, or SOCKS with the
    [notify] extra) and templates= shape what goes out. KIND_* names every
    kind of message.
  • A queue per notifier — every send waits its turn on the notifier's own
    thread: paced to the service's limits, retried after an error, held through an
    outage, and marked «⏱ N min late» when it arrives late.
  • Trading events to your chats — TraderConfig(notifiers=[...]), for
    run_live and Trader alike: signals, opens, risk-free moves, TP levels,
    closes, exit signals, the daily loss limit, reconciles, errors, the start and
    the stop, and a summary of the day at midnight in the notifier's time zone. A
    trade's later messages reply to its open. A chat that takes sl_move sees each
    move of the stop as an edit of the open message; by default a chat takes every
    kind but that one.
  • StartEvent, StopEvent and MessageEvent on the event stream, printed
    by the terminal log too, and BaseStrategy.notify(text): a strategy's own
    message, sent on a newly closed live candle, and never in a backtest, during
    the seed or on a forming candle.
  • Chart pictures — images={"open", "close"} puts a picture of the pair's
    chart on those trade messages. send_chart(chart, start, end) sends one of a
    Chart you built, or with broker=, symbol= and timeframe= of a venue's
    candles; send_photo(png) sends your own; send_report(report) sends a
    backtest's figures, its balance curve and its HTML report.
    Chart.screenshot(start, end, width=, height=, timezone=) makes them: a
    headless Chromium photographs the chart's own page.
    TraderConfig.chart_indicators puts indicators on a session's chart and its
    pictures.
  • Price alerts — bot.watch(broker, symbol, above=, below=, move_pct= with window=, on_close=, repeat=, rearm=, image=) returns an Alert: «🔔 BTCUSDT
    crossed above 65,000 · now 65,012.5», with no strategy and no trading.
    bot.alerts() lists them, alert.cancel() ends one, and bot.wait() keeps a
    script alive until none is armed.
  • Commands from Telegram — TelegramNotifier(..., commanders=[id]) answers
    /status, /positions, /chart, /stop and /help. /stop ends the
    session as Ctrl+C does; live trading first asks for /stop CONFIRM, within
    60 s. Commands sent while nothing listened are skipped, not run late, and
    anyone not in commanders is refused.
  • Discord, e-mail and webhooks — DiscordNotifier with DiscordWebhook,
    EmailNotifier with EmailRecipient, and WebhookNotifier with
    WebhookTarget, each with its error (DiscordError, EmailError,
    WebhookError). They take the same kinds, filters, templates, pictures and
    queue, and work wherever a Telegram bot does. E-mail goes over SMTP with
    STARTTLS or SSL and gathers a trade's messages into one e-mail every 15 minutes
    (digest_minutes=0 sends each at once). A webhook gets JSON with the text and
    the event's raw fields, signed with HMAC-SHA256 when given secret=. Discord
    cannot reply, e-mail cannot edit, and commands stay Telegram's.
  • [notify] extra (also as [telegram]) — PySocks for a SOCKS proxy and
    Playwright for pictures, then, once, playwright install chromium. Text needs
    nothing beyond the core install.
  • Runnable examples 04–09 — messages, paper trading's events, a chart
    picture, price alerts and commands on Telegram, then Discord, e-mail and a
    webhook. Each prints what to set when its variables are missing.

Changed

  • Chart.set_data is faster: it reads the frame by columns instead of
    iterrows. A 300-candle chart took 0.29 s of CPU and now takes 7 ms.
  • The README's Event Log sample shows the lines the printer really prints, the
    new events included.

Fixed

  • Live trading skipped the first candle to close after a start. The seed
    kept the candle that was still forming, so the feed's closed copy of it was
    skipped as a repeat: that candle never reached the strategy, and its row kept
    the values it had at the start. run_live, Trader and the Trader's
    real-fills chart now seed with closed candles only, judged by the venue's
    clock.
  • examples/01_backtest_report.py named the wrong file in its docstring.

v1.1.1 — Bar replay: zones drawn up to the cursor

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 03 Sep 19:54

[1.1.1] — 2026-09-03

Bar replay: shapes that outlive the cursor.

Fixed

  • A zone that ends in the future disappeared during replay. A box, trendline
    or Fibonacci drawn from candle N to N+10 vanished from the chart until the
    cursor passed N+10 — so a zone the trader could already see was missing for
    exactly the candles it mattered on. Any shape running past the cursor is now
    drawn up to the cursor: present, without giving away where it ends. Only
    a position box's label is still blanked, because that announces the outcome.
  • Placing a shape used candles replay had not revealed. The chart is asked
    where a moment sits on screen, and it only answers for candles the price
    scale is currently showing. While replaying, the far edge of such a shape
    lands on a hidden candle, so there was no answer — and no answer meant the
    whole shape was dropped, which is what made it disappear entirely rather than
    merely overshoot. Positions are now measured against the candles actually on
    screen.

v1.1.0 — Charting: timeframes, multi-chart pages, bar replay

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 24 Aug 14:02

[1.1.0] — 2026-08-24

Charting. One set of candles in, any timeframe out, several charts at once, and
history you can step through.

Added

  • Timeframe switching on the chart — Chart(display_timeframe=…),
    set_timeframe(), source_timeframe / timeframes, and a selector in the
    toolbar. Feed 1m candles and display any whole multiple of them; resampling
    and indicator maths run in Python, never in the browser. Only valid multiples
    are offered, so 4h data never offers 6h.
    Indicators added by spec (chart_indicators, the toolbar) are recomputed
    on the new candles; precomputed ones are thinned last-value-per-bucket and
    flagged approximate, and their original points are restored when you switch
    back. Streaming works through the conversion: 1m candles fed to a 5m display
    grow the forming 5m candle and close it on its boundary.
  • ChartPage — several charts on one page, on one port. page.add(chart)
    stacks rows; page.add(chart, row=n) puts a chart beside the ones already
    there, with dividers draggable on both axes. Charts scroll and crosshair
    together by time, so different timeframes stay aligned. Attaching a chart
    changes nothing about how you drive it — indicators, drawings, live positions,
    streaming and set_timeframe all work unchanged.
  • Bar replay — pick a candle and step history forward or back, play at
    0.25×–10×, with Space / Shift+← / Shift+→ / Esc. A step is one
    source candle, so a 5m chart built from 1m data is watched being built.
    Indicators stop at the last closed candle, while series that legitimately run
    ahead of the data (Ichimoku's projected spans) keep that overhang. Backtest
    positions never leak the future: a trade that has not opened is not drawn, and
    one still open at the cursor stops there with no result label. On a
    ChartPage one cursor drives every chart.
  • resample_ohlcv(), detect_timeframe(), validate_conversion(),
    can_convert()
    in AlgoTradeKit.data — the resampling maths as pure
    functions, no files and no printing. Converter now delegates to them, so
    there is one implementation. drop_incomplete=False keeps the candle that is
    still forming.
  • Runnable examples in examples/, shipped with the package: a backtest with
    its report, timeframe switching with bar replay, and a synchronised
    multi-chart page. They fetch a little public Binance data with no API key and
    fall back to synthetic candles offline.
  • A chart warns when its init payload runs to several megabytes, naming the
    candle and drawing counts. Every viewer downloads and draws all of it, and a
    ChartPage pays that once per chart in a single tab. Note that
    candle_count_limit on a live session bounds the simulation window — the
    report is recomputed over it — so use it deliberately.
  • [mt5] extra in pyproject.toml. pip install AlgoTradeKit[mt5] has been
    documented since v1.0.0 but never existed, so on Windows the native
    MetaTrader path failed with an error telling you to install something pip
    refused to install.

Fixed

  • Report: the trade popup could not be used. Clicking a trade dot on the
    balance chart opened a box with an "Open on Candle Chart" button that was
    unreachable — hover handlers hid the box before the pointer arrived, and it
    carried pointer-events: none besides. A click now pins it; it closes on an
    outside click, Esc, or its own ✕. The chart link also opened
    127.0.0.1, which is the viewer's own machine when the report comes from a
    VPS; it now uses the host the report was served from.
  • MetaTrader: a bridge that accepts the connection but never answers raised
    a bare TimeoutError instead of the guided error every other bridge failure
    gives. It now names the likely causes and the guide section.
  • MT5_WINE_SETUP.md was an earlier, shorter draft (Parts A–G). The Part
    letters the connector's error messages point at were therefore wrong, and the
    guide told you to install a Python version that does not work under Wine 9.
  • Chart servers leaked port reservations. Every Chart created but never
    shown held one for the life of the process, so building charts in a loop
    eventually exhausted the port range.
  • Chart and report servers now shut down cleanly instead of stopping the
    event loop under a running server, which raised out of the server thread.

v1.0.2 - trader module

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 24 Jul 11:46

[1.0.2] — 2026-07-24

Packaging fixes (no feature changes) — supersedes the withdrawn 1.0.0 and 1.0.1:

  • 1.0.0 was built from an incomplete tree and shipped without the
    trader module, the live-simulation core (simulate._live), the shared
    position maths (simulate._position_math), incremental indicators
    (strategy._incremental) and the MetaTrader native transport
    (broker.metatrader._native / _ops), so import AlgoTradeKit.trader failed.
  • 1.0.1 restored that source but its source distribution accidentally
    bundled repository-only files that do not belong in a release.

1.0.2 ships the complete library and nothing else: the source distribution
is now an explicit allow-list (src, tests, README, CHANGELOG, LICENSE,
MT5_WINE_SETUP.md, pyproject.toml). Upgrade with
pip install -U AlgoTradeKit.

v0.9.1 - broker module fix

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 01 Jul 18:24

[0.9.1] — 2026-07-01

Follow-up to the v0.9.0 broker module: a MetaTrader smoke-test demo, a
complete headless-setup guide, and a bridge fix for crypto / CFD symbols.

Added

  • MT5_WINE_SETUP.md — complete "MetaTrader 5 headless on a Linux VPS"
    guide: install Wine + Xvfb, run the bridge server, open the SSH tunnel, plus a
    troubleshooting table and optional systemd auto-start. Linked from the README.
  • MetaTraderBroker.list_symbols(group="*BTC*") — discover a broker's exact
    symbol spelling (they vary a lot between brokers).

Fixed

  • MetaTrader bridge now calls symbol_select before every copy_rates — crypto
    / CFD symbols are hidden from Market Watch by default and otherwise return no
    candles.

v0.9.0 - broker module

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 01 Jul 15:50

[0.9.0] — 2026-07-01

Added

broker module — unified exchange & MetaTrader access (new)

  • Broker(name, ...) — one entry point for every venue. name is
    case-insensitive: "binance-spot", "binance-futures", "metatrader"
    (aliases mt5 / forex). Credentials are optional — without them only
    public market-data calls work; private (account / trading) calls raise a clear
    AuthenticationError. Returns a concrete BaseBroker, so the whole library
    treats every venue identically.
  • BaseBroker unified interface: fetch_candles / fetch_last_candles /
    get_ticker / server_time, stream_candles / stream_ticker,
    get_balance / get_account_info, create_order (+ create_market_order /
    create_limit_order), cancel_order / cancel_all, open_orders,
    open_positions, close_position, set_leverage.
  • Unified types (Balance, AccountInfo, Ticker, Order, OrderResult,
    Position) and string constants (SIDE_BUY, ORDER_MARKET, MARKET_SPOT,
    …) re-exported from broker/__init__.py.
  • Binance connector (broker/exchange/binance/): spot and USD-M futures.
    • REST: klines, ticker, server time; signed account, order create/cancel,
      open orders, futures positions (positionRisk), balance, leverage.
      Signing is HMAC-SHA256 with the Python standard library — no new deps.
    • WebSocket: real-time kline and bookTicker streams, plus the private
      user-data stream (auto listen-key keepalive).
    • Futures create_order can attach stop_loss / take_profit as reduce-only
      protective orders. testnet=True points at Binance testnet.
  • MetaTrader 5 connector (broker/metatrader/) for headless Linux VPS:
    • bridge_server.py runs inside the Wine Python (where MetaTrader5 is
      importable) under xvfb — no GUI. It exposes MT5 over a tiny
      newline-delimited JSON socket (standard library only).
    • MetaTraderBroker runs on the normal Linux side and reaches MT5 only
      through that bridge, mapping candles / positions / orders / account onto the
      same unified types.
    • MetaTrader5 is never a dependency of AlgoTradeKit (it lives only in the
      Wine Python), so there is no dependency conflict.

data module — now backed by broker

  • All Binance REST kline logic moved into broker; data.sources.binance
    is now a thin adapter over it (public API unchanged).
  • Collector accepts a name or a Broker instance — pass
    Collector("binance-futures", …) (way 1, Collector builds the connector) or
    Collector(my_broker, …) / Collector(..., broker=my_broker) (way 2, bring
    your own — including an authenticated or MetaTrader forex connection).
  • Collector.stream(on_candle) — real-time candle subscription for both
    exchange (Binance WebSocket) and MetaTrader feeds.

Notes

  • Live-order safety: testnet is supported; live endpoints are the default.
  • Deferred to v0.9.1 (see v091.md): the trader live-order module,
    real-time simulation, live-updating chart/report, and the ichimoku live demo.

v0.8.0 - Indicator toolbar (add/edit) + chart_indicators

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 29 Jun 18:06

[0.8.0] — 2026-06-29

Added

visual module — working indicator toolbar (add / edit, backend-computed)

  • Indicator button now works. The chart toolbar's INDICATORS button was
    inert (it called an undefined sendMsg); the panel now ships the chosen spec
    to the backend over the WebSocket and the computed series returns as one or
    more add_indicator messages. The button (and its panel) were moved to the
    left of the toolbar.
  • Edit existing indicators. Every indicator in the legend / oscillator pane
    gains a ⚙ gear icon. Clicking it re-opens the panel pre-filled with that
    indicator's current settings; saving recomputes it in the backend (the old
    series is removed and replaced). Works for price-pane lines, the Ichimoku
    group, and oscillator sub-panes (RSI / MACD / ATR).
  • Chart.add_indicator_spec(params) — new public method that computes an
    indicator from the chart's stored OHLCV server-side and tags each
    resulting series with the resolved spec that produced it (so the front-end
    gear can round-trip it). Used by both the toolbar and chart_indicators.
  • Ichimoku Displacement is now an editable parameter in the panel and in
    indicator specs (defaults to 26).
  • Indicators added/edited live now survive a browser refresh (the server's
    init-replay cache is kept in sync).

simulate module — indicators on the simulation chart

  • SimulateConfig.chart_indicators — new field: a list of indicator-spec
    dicts (same schema as the toolbar) drawn on the show_chart=True candle
    chart. All maths run in the backend before the chart opens. Pass the
    strategy's own indicator parameters to mirror what it traded on, add extra
    indicators, or both. Validated in __post_init__ (must be a list of dicts,
    each with a "kind").

Fixed

  • Ichimoku from the toolbar computed with the wrong argument order
    (close, high, low instead of high, low, close), producing incorrect
    lines. Now correct and verified against a direct Ichimoku call.
  • RSI from the toolbar crashed on its default (ma_type="none" →
    None.upper()), and never showed its MA line because show_ma was not set.
    Both fixed.
  • VWAP / VWMA from the toolbar raised TypeError: got multiple values for argument … due to mixed positional/keyword construction. Now built with
    explicit keyword arguments.

Changed

  • ichimoku_strategy.py now passes chart_indicators so the simulation chart
    automatically renders the Ichimoku cloud + RSI (matching the strategy's
    parameters, including the non-standard displacement).

v0.7.4 - Dynamic SL/TP lines, indicator toolbar, keep-alive fix

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 24 Jun 12:33

[0.7.4] — 2026-06-24

Added

simulate module — dynamic SL/TP visualisation

  • ClosedTrade.sl_history — new tuple field recording every SL-state
    change throughout a trade's lifetime as an ordered sequence of dicts
    {"time": int_ms, "sl": float, "next_tp": float | None}. An entry is
    appended at position open (initial state) and again every time the SL
    advances: after each multi_rr TP level hit (SL walks to break-even /
    previous TP) or whenever the trailing SL moves to a new high-water mark.
    An empty history means the SL never moved; a single entry means the
    position opened but the SL never advanced before closing.

  • ClosedTrade.final_next_tp — new float | None field that records
    the TP target that was active at the exact moment the trade closed. For
    a multi_rr position that hit TP3 (moving next target to TP4) and was
    then stopped out at the TP3-advanced SL, this is TP4. None when all
    levels were consumed (position closed at the final TP) or no TP was
    configured.

  • ClosedTrade.peak_price — new float field storing the most
    favourable price reached during the trade (highest high for longs, lowest
    low for shorts). Used by the visual module as the top of the position box
    for trailing-SL trades (the peak marks the last price that drove the
    trailing SL to its tightest level).

  • SimulateReport.trade_markers now includes sl_history, final_next_tp,
    peak_price, and rr_levels_hit for every marker, enabling the
    chart-side rendering of dynamic SL/TP lines.

visual module — dynamic SL/TP lines on chart

  • add_simulation_positions (in indicator_renderer.py) enhanced with:

    • Dynamic SL line segments — for multi_rr and trailing positions,
      coloured horizontal TrendLine drawings are added alongside each position
      box showing where the stop-loss was at each stage of the trade:
      • Red — SL is in the loss zone (below entry for long)
      • Amber/yellow — SL is at break-even (entry price)
      • Cyan — SL is in profit territory (above entry for long)
    • Green TP lines (multi_rr only) — for each SL segment, a matching
      green horizontal line shows the next TP target that was being aimed at.
    • Posbox TP fix — the profit-zone boundary of the position box now
      shows final_next_tp (the TP at closing time) rather than the initial
      TP at entry. After hitting TP3 with next target TP4, the box correctly
      displays TP4 instead of staying stuck at TP1.
    • Trailing posbox top — for sl_mode="trailing", the top of the
      position box is set to peak_price (the highest price the trailing SL
      ever chased), giving a natural view of the profit zone that was available.
    • Partial-close grouping — multiple ClosedTrade rows sharing a
      trade_id (from tp_level_close_fractions) are now collapsed into a
      single position box (one box per unique trade, not one per slice).
    • New config parameter on add_simulation_positions — pass the
      SimulateConfig used for the simulation to enable automatic mode
      detection (tp_mode/sl_mode) for the correct line style.
  • Indicator toolbar — a new 📈 button in the chart toolbar opens an
    "Add Indicator" panel where the user can add technical indicators to the
    live candle chart without writing any code:

    • Moving averages: EMA, SMA, WMA, SMMA, DEMA, TEMA, HMA, VWMA, VWAP
    • Oscillators: RSI (with optional MA), MACD, ATR (pure Python — no
      third-party TA library)
    • Trend: Ichimoku Cloud
    • Each indicator type shows its own parameter form (period, source, MA
      type, fast/slow/signal periods, Tenkan/Kijun/Senkou B, etc.).
    • A colour picker lets the user override the default series colour.
    • The "Add to Chart" button sends a compute_indicator WebSocket message
      to the Chart server, which computes the indicator from the stored OHLCV
      DataFrame and broadcasts the result as one or more add_indicator
      messages; the chart renders them immediately.

Fixed

  • Trailing SL false gap-open trigger — the trailing SL was previously
    advanced in step A (before close checks), which could cause a "gap open
    past SL" close on the very candle that caused the SL to jump, when the
    candle's open price was between the old and new SL levels. The trailing
    SL is now advanced inside _check_close after the gap-open test, so
    the gap check always uses the SL from the end of the previous candle.
    This fix applies to both the single-pair Simulate engine and the
    multi-pair run_multi engine (_runner.py).

  • Chart and report tabs disconnecting immediately — the
    ChartServer and ReportServer both run in daemon threads, which Python
    kills the instant the script's main thread exits. Previously,
    Simulate.run() started both servers non-blocking and returned, so all
    user code after the call (printing stats, saving CSV history, etc.) ran
    normally — but as soon as main() returned the process died, closing both
    browser tabs before the user could interact with them. A one-time atexit
    handler is now registered whenever a browser UI is opened; it blocks with
    a while True: sleep(1) loop (identical to chart.show(block=True)) after
    all user code has finished, keeping the process alive until the user presses
    Ctrl+C. The handler registers only once per process invocation, so
    multiple Simulate.run() calls (batch/multi-symbol) produce a single
    blocking handler at exit.

Tests

  • tests/test_simulate.py — new TestSlHistory class (13 tests) covering:
    • sl_history length and content after 0, 1, and 2 multi_rr TP hits
    • timestamp presence and ordering in sl_history
    • final_next_tp value after partial and final TP consumption
    • peak_price captured correctly for trailing-SL trades
    • backward-compatibility: plain signal SL mode produces exactly one
      sl_history entry (no SL movement)
    • add_simulation_positions smoke test: one posbox per unique trade_id
    • dynamic SL TrendLine drawings added when sl_history length > 1
    • posbox take_profit uses final_next_tp not initial TP

v0.7.3 - Per-signal position sizing and partial multi-RR take-profit closes

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 21 Jun 20:30

[0.7.3] — 2026-06-21

Added

strategy module

  • Signal.risk_multiplier — new optional field (default 1.0) that scales
    the size/risk a single signal receives relative to the run's global
    SimulateConfig sizing (risk_percent / fixed_amount / fixed_lot).
    Lets a strategy vary risk per signal instead of using one fixed sizing
    rule for every trade in a backtest — e.g. half size on a tentative
    "limit" entry vs. full size on a confirmed one, or splitting one trade
    idea into several sub-positions whose sizes sum to one risk unit
    (three signals at 1/3 each, targeting 1R/2R/3R, to emulate scaling out
    of a position). Default 1.0 is fully backward compatible.

simulate module

  • SimulateConfig.tp_level_close_fractions — optional list, parallel to
    tp_levels, that turns on true partial closes for tp_mode="multi_rr".
    Each entry is the fraction of the position's original size to realise
    when the corresponding level is reached, instead of only moving the SL.
    None (default) preserves the exact pre-0.7.3 behaviour (SL-only
    advancement, single full close at the final level). When set:

    • fractions summing to 1.0 give a full progressive scale-out
      (e.g. [1/3, 1/3, 1/3]) — profit is banked level by level instead of
      all-or-nothing at the end.
    • all-zero fractions give a "let it run" position: the SL just walks
      through every level and the full size stays open, trailing at the
      last level's price, until eventually stopped out.
    • any mix is valid — partially bank some levels, let others purely
      advance the SL.

    Each partial close produces its own ClosedTrade sharing the position's
    trade_id, so SimulateReport statistics (win rate, profit factor,
    equity curve) count every realised slice on its own line, the same way
    a real scaled-out position would appear on a broker statement.
    Commission (pre-charged once, in full, at entry) is split proportionally
    across every slice so the total charged across one position's full
    lifetime never changes.

  • CLOSE_REASON_TP_PARTIAL is now exported from AlgoTradeKit.simulate.
    It existed on ClosedTrade since an earlier release (with is_tp
    already wired to recognise it) but no code path had ever produced it
    until tp_level_close_fractions above.

  • run_multi() gained the identical partial-close handling as the
    single-pair Simulate engine, so shared-wallet multi-symbol portfolios
    behave the same way; run_batch() needed no changes (it only wraps
    Simulate(cfg).run()).

Tests

  • tests/test_strategy.py — TestSignal extended with 5 tests for
    risk_multiplier (default, custom value, <= 0 validation, positional-
    construction backward compatibility).
  • tests/test_simulate.py — new TestEngineRiskMultiplier (4 tests) and
    TestEngineMultiRRPartialClose (8 tests, including a hand-derived PnL
    ground truth and an end-to-end wallet-conservation check) and
    TestSimulateConfigPartialTPValidation (8 tests). All 171 pre-existing
    tests in these two files continue to pass unmodified.

v0.7.2 - Normalizer, ATR indicator, Ichimoku raw spans, Chart candle range

Choose a tag to compare

@AmirMohammadBazdar AmirMohammadBazdar released this 20 Jun 15:28

[0.7.2] — 2026-06-20

Added

data module

  • Normalizer — new class to ingest non-standard OHLCV CSV files and
    convert them to the AlgoTradeKit standard format. Features:
    • Auto-detects whether timestamps are in Unix seconds (< 10^10) or
      milliseconds (≥ 10^10) and converts to ms automatically.
    • Fills missing optional columns (close_time, quote_volume, trades,
      taker_buy_base, taker_buy_quote) with None; volume defaults to 0.
    • Date-range filtering via start / end attributes before returning data
      (integers are also auto-detected as seconds or ms).
    • Three usage modes: normalize() → DataFrame, save() → CSV path,
      normalize_and_save() → (DataFrame, path).
    • Normalizer is now exported from AlgoTradeKit.data.

indicator module

  • ATR — Average True Range using Wilder's RMA smoothing (alpha = 1 / period,
    min_periods = period). Matches TradingView ta.atr() output.
    Exposes atr and tr properties and result-dict keys.
    Default period: 14. Exported from AlgoTradeKit.indicator.
  • Ichimoku.span_a_raw and Ichimoku.span_b_raw — two new properties
    (and result dict keys) exposing the unshifted Senkou Span A and B values
    at each bar (i.e. (tenkan + kijun) / 2 and the Span B donchian mid before
    the displacement shift is applied). These are required for strategy entry/exit
    logic where the current cloud position matters, not the displayed future cloud.
    Fully backward-compatible — no existing keys or properties were changed.

visual module

  • Chart.set_data(candle_range=...) — new optional candle_range dict
    parameter filters which candles are rendered. Five modes:

    • {"start": ..., "end": ...} — inclusive datetime range (either key optional)
    • {"start": ...} — from date to the last available candle
    • {"end": ...} — from the first candle to date
    • {"last_n": N} — last N candles
    • {"first_n": N} — first N candles

    start / end accept "YYYY/MM/DD", "YYYY-MM-DD" strings, datetime
    objects, Unix-second int, or Unix-millisecond int.

  • Chart.from_csv(candle_range=...) — candle_range forwarded from the
    factory class method.

Tests

  • tests/test_data_normalizer.py — 25+ unit tests for Normalizer covering
    timestamp detection, date filtering, schema completeness, save/load round-trip,
    and error paths.
  • tests/test_indicator.py — extended with TestATR (15 tests) and
    TestIchimokuRawSpans (10 tests) for the new indicator features.