AlgoTradeKit 0.7.3__tar.gz → 0.7.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {algotradekit-0.7.3 → algotradekit-0.7.4}/CHANGELOG.md +112 -0
  2. {algotradekit-0.7.3 → algotradekit-0.7.4}/PKG-INFO +32 -2
  3. {algotradekit-0.7.3 → algotradekit-0.7.4}/README.md +31 -1
  4. {algotradekit-0.7.3 → algotradekit-0.7.4}/pyproject.toml +1 -1
  5. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/__init__.py +1 -1
  6. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_engine.py +177 -71
  7. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_position.py +38 -1
  8. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_report.py +15 -0
  9. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_runner.py +4 -4
  10. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/chart.py +222 -0
  11. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/indicator_renderer.py +230 -21
  12. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/models.py +18 -16
  13. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/static/index.html +267 -0
  14. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_simulate.py +328 -0
  15. {algotradekit-0.7.3 → algotradekit-0.7.4}/.github/workflows/publish.yml +0 -0
  16. {algotradekit-0.7.3 → algotradekit-0.7.4}/.gitignore +0 -0
  17. {algotradekit-0.7.3 → algotradekit-0.7.4}/LICENSE +0 -0
  18. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/__init__.py +0 -0
  19. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/_utils.py +0 -0
  20. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/collector.py +0 -0
  21. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/converter.py +0 -0
  22. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/normalizer.py +0 -0
  23. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/sources/__init__.py +0 -0
  24. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/sources/base.py +0 -0
  25. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/sources/binance.py +0 -0
  26. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/storage/__init__.py +0 -0
  27. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/storage/csv_handler.py +0 -0
  28. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/__init__.py +0 -0
  29. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/_base.py +0 -0
  30. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/atr.py +0 -0
  31. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/ichimoku.py +0 -0
  32. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/ma.py +0 -0
  33. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/macd.py +0 -0
  34. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/rsi.py +0 -0
  35. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/__init__.py +0 -0
  36. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/_builder.py +0 -0
  37. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/_display.py +0 -0
  38. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/_server.py +0 -0
  39. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/static/report.html +0 -0
  40. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/__init__.py +0 -0
  41. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_config.py +0 -0
  42. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_lot.py +0 -0
  43. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_session.py +0 -0
  44. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/__init__.py +0 -0
  45. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/_base.py +0 -0
  46. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/_types.py +0 -0
  47. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/builtin/__init__.py +0 -0
  48. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/builtin/macd.py +0 -0
  49. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/__init__.py +0 -0
  50. {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/server.py +0 -0
  51. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_data.py +0 -0
  52. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_data_converter.py +0 -0
  53. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_data_normalizer.py +0 -0
  54. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_indicator.py +0 -0
  55. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_report.py +0 -0
  56. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_strategy.py +0 -0
  57. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_visual.py +0 -0
  58. {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_visual__0_4_1.py +0 -0
@@ -7,6 +7,118 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.7.4] — 2026-06-24
11
+
12
+ ### Added
13
+
14
+ #### `simulate` module — dynamic SL/TP visualisation
15
+
16
+ - **`ClosedTrade.sl_history`** — new `tuple` field recording every SL-state
17
+ change throughout a trade's lifetime as an ordered sequence of dicts
18
+ `{"time": int_ms, "sl": float, "next_tp": float | None}`. An entry is
19
+ appended at position open (initial state) and again every time the SL
20
+ advances: after each `multi_rr` TP level hit (SL walks to break-even /
21
+ previous TP) or whenever the trailing SL moves to a new high-water mark.
22
+ An empty history means the SL never moved; a single entry means the
23
+ position opened but the SL never advanced before closing.
24
+
25
+ - **`ClosedTrade.final_next_tp`** — new `float | None` field that records
26
+ the TP target that was active at the exact moment the trade closed. For
27
+ a `multi_rr` position that hit TP3 (moving next target to TP4) and was
28
+ then stopped out at the TP3-advanced SL, this is TP4. `None` when all
29
+ levels were consumed (position closed at the final TP) or no TP was
30
+ configured.
31
+
32
+ - **`ClosedTrade.peak_price`** — new `float` field storing the most
33
+ favourable price reached during the trade (highest high for longs, lowest
34
+ low for shorts). Used by the visual module as the top of the position box
35
+ for trailing-SL trades (the peak marks the last price that drove the
36
+ trailing SL to its tightest level).
37
+
38
+ - **`SimulateReport.trade_markers`** now includes `sl_history`, `final_next_tp`,
39
+ `peak_price`, and `rr_levels_hit` for every marker, enabling the
40
+ chart-side rendering of dynamic SL/TP lines.
41
+
42
+ #### `visual` module — dynamic SL/TP lines on chart
43
+
44
+ - **`add_simulation_positions`** (in `indicator_renderer.py`) enhanced with:
45
+ - **Dynamic SL line segments** — for `multi_rr` and `trailing` positions,
46
+ coloured horizontal `TrendLine` drawings are added alongside each position
47
+ box showing where the stop-loss was at each stage of the trade:
48
+ - **Red** — SL is in the loss zone (below entry for long)
49
+ - **Amber/yellow** — SL is at break-even (entry price)
50
+ - **Cyan** — SL is in profit territory (above entry for long)
51
+ - **Green TP lines** (`multi_rr` only) — for each SL segment, a matching
52
+ green horizontal line shows the next TP target that was being aimed at.
53
+ - **Posbox TP fix** — the profit-zone boundary of the position box now
54
+ shows `final_next_tp` (the TP at closing time) rather than the initial
55
+ TP at entry. After hitting TP3 with next target TP4, the box correctly
56
+ displays TP4 instead of staying stuck at TP1.
57
+ - **Trailing posbox top** — for `sl_mode="trailing"`, the top of the
58
+ position box is set to `peak_price` (the highest price the trailing SL
59
+ ever chased), giving a natural view of the profit zone that was available.
60
+ - **Partial-close grouping** — multiple `ClosedTrade` rows sharing a
61
+ `trade_id` (from `tp_level_close_fractions`) are now collapsed into a
62
+ single position box (one box per unique trade, not one per slice).
63
+ - New `config` parameter on `add_simulation_positions` — pass the
64
+ `SimulateConfig` used for the simulation to enable automatic mode
65
+ detection (`tp_mode`/`sl_mode`) for the correct line style.
66
+
67
+ - **Indicator toolbar** — a new 📈 button in the chart toolbar opens an
68
+ "Add Indicator" panel where the user can add technical indicators to the
69
+ live candle chart without writing any code:
70
+ - **Moving averages**: EMA, SMA, WMA, SMMA, DEMA, TEMA, HMA, VWMA, VWAP
71
+ - **Oscillators**: RSI (with optional MA), MACD, ATR (pure Python — no
72
+ third-party TA library)
73
+ - **Trend**: Ichimoku Cloud
74
+ - Each indicator type shows its own parameter form (period, source, MA
75
+ type, fast/slow/signal periods, Tenkan/Kijun/Senkou B, etc.).
76
+ - A colour picker lets the user override the default series colour.
77
+ - The "Add to Chart" button sends a `compute_indicator` WebSocket message
78
+ to the `Chart` server, which computes the indicator from the stored OHLCV
79
+ `DataFrame` and broadcasts the result as one or more `add_indicator`
80
+ messages; the chart renders them immediately.
81
+
82
+ ### Fixed
83
+
84
+ - **Trailing SL false gap-open trigger** — the trailing SL was previously
85
+ advanced in step A (before close checks), which could cause a "gap open
86
+ past SL" close on the very candle that caused the SL to jump, when the
87
+ candle's open price was between the old and new SL levels. The trailing
88
+ SL is now advanced inside `_check_close` *after* the gap-open test, so
89
+ the gap check always uses the SL from the end of the previous candle.
90
+ This fix applies to both the single-pair `Simulate` engine and the
91
+ multi-pair `run_multi` engine (`_runner.py`).
92
+
93
+ - **Chart and report tabs disconnecting immediately** — the
94
+ `ChartServer` and `ReportServer` both run in daemon threads, which Python
95
+ kills the instant the script's main thread exits. Previously,
96
+ `Simulate.run()` started both servers non-blocking and returned, so all
97
+ user code after the call (printing stats, saving CSV history, etc.) ran
98
+ normally — but as soon as `main()` returned the process died, closing both
99
+ browser tabs before the user could interact with them. A one-time `atexit`
100
+ handler is now registered whenever a browser UI is opened; it blocks with
101
+ a `while True: sleep(1)` loop (identical to `chart.show(block=True)`) after
102
+ all user code has finished, keeping the process alive until the user presses
103
+ **Ctrl+C**. The handler registers only once per process invocation, so
104
+ multiple `Simulate.run()` calls (batch/multi-symbol) produce a single
105
+ blocking handler at exit.
106
+
107
+ ### Tests
108
+
109
+ - `tests/test_simulate.py` — new `TestSlHistory` class (13 tests) covering:
110
+ - `sl_history` length and content after 0, 1, and 2 `multi_rr` TP hits
111
+ - timestamp presence and ordering in `sl_history`
112
+ - `final_next_tp` value after partial and final TP consumption
113
+ - `peak_price` captured correctly for trailing-SL trades
114
+ - backward-compatibility: plain `signal` SL mode produces exactly one
115
+ `sl_history` entry (no SL movement)
116
+ - `add_simulation_positions` smoke test: one posbox per unique `trade_id`
117
+ - dynamic SL `TrendLine` drawings added when `sl_history` length > 1
118
+ - posbox `take_profit` uses `final_next_tp` not initial TP
119
+
120
+ ---
121
+
10
122
  ## [0.7.3] — 2026-06-21
11
123
 
12
124
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AlgoTradeKit
3
- Version: 0.7.3
3
+ Version: 0.7.4
4
4
  Summary: Algorithmic Trading Toolkit — data collection, indicators, strategy, simulation, and live trading
5
5
  Project-URL: Homepage, https://github.com/AmirMohammadBazdar/AlgoTradeKit
6
6
  Project-URL: Repository, https://github.com/AmirMohammadBazdar/AlgoTradeKit
@@ -461,10 +461,25 @@ TradingView-style position boxes showing SL/TP zones with R:R labels:
461
461
  from AlgoTradeKit.visual.indicator_renderer import add_simulation_positions
462
462
 
463
463
  chart = Chart.from_csv("data/binance-futures_BTCUSDT_1h.csv")
464
- add_simulation_positions(chart, report, opacity=0.15)
464
+ add_simulation_positions(chart, report, opacity=0.15, config=sim_config)
465
465
  chart.show(block=True)
466
466
  ```
467
467
 
468
+ **Dynamic SL/TP lines *(v0.7.4)*** — when `config` is passed, coloured
469
+ horizontal lines are drawn on the chart for every trade where the SL moved:
470
+
471
+ | Colour | Meaning |
472
+ |--------|---------|
473
+ | 🔴 Red | SL is in the loss zone (below entry for long) |
474
+ | 🟡 Amber | SL is at break-even (entry price) |
475
+ | 🔵 Cyan | SL is in profit territory |
476
+ | 🟢 Green | Next TP target (`multi_rr` only) |
477
+
478
+ The position box's profit-zone boundary is also corrected to show the TP
479
+ target that was active at the *moment of closing* rather than the initial TP
480
+ at entry. For trailing-SL trades the box top is set to `peak_price` (the
481
+ highest price the trailing SL ever chased).
482
+
468
483
  Manual single box:
469
484
  ```python
470
485
  chart.add_position_box(
@@ -475,6 +490,21 @@ chart.add_position_box(
475
490
  )
476
491
  ```
477
492
 
493
+ ### Indicator Toolbar *(v0.7.4)*
494
+
495
+ The chart toolbar now has an **Add Indicator** (📈) button. Clicking it
496
+ opens a panel where indicators can be added interactively at runtime — no
497
+ code required:
498
+
499
+ - **Moving averages**: EMA, SMA, WMA, SMMA, DEMA, TEMA, HMA, VWMA, VWAP
500
+ - **Oscillators**: RSI (with optional MA), MACD, ATR
501
+ - **Trend**: Ichimoku Cloud
502
+
503
+ Each type shows its own parameter form. After clicking *Add to Chart*, the
504
+ server computes the indicator from the OHLCV data and the chart updates
505
+ immediately. Indicators added this way work exactly like those added via
506
+ `add_ma()` / `add_rsi()` / etc. in Python code.
507
+
478
508
  ### Strategy Drawings (v0.7.0)
479
509
 
480
510
  ```python
@@ -405,10 +405,25 @@ TradingView-style position boxes showing SL/TP zones with R:R labels:
405
405
  from AlgoTradeKit.visual.indicator_renderer import add_simulation_positions
406
406
 
407
407
  chart = Chart.from_csv("data/binance-futures_BTCUSDT_1h.csv")
408
- add_simulation_positions(chart, report, opacity=0.15)
408
+ add_simulation_positions(chart, report, opacity=0.15, config=sim_config)
409
409
  chart.show(block=True)
410
410
  ```
411
411
 
412
+ **Dynamic SL/TP lines *(v0.7.4)*** — when `config` is passed, coloured
413
+ horizontal lines are drawn on the chart for every trade where the SL moved:
414
+
415
+ | Colour | Meaning |
416
+ |--------|---------|
417
+ | 🔴 Red | SL is in the loss zone (below entry for long) |
418
+ | 🟡 Amber | SL is at break-even (entry price) |
419
+ | 🔵 Cyan | SL is in profit territory |
420
+ | 🟢 Green | Next TP target (`multi_rr` only) |
421
+
422
+ The position box's profit-zone boundary is also corrected to show the TP
423
+ target that was active at the *moment of closing* rather than the initial TP
424
+ at entry. For trailing-SL trades the box top is set to `peak_price` (the
425
+ highest price the trailing SL ever chased).
426
+
412
427
  Manual single box:
413
428
  ```python
414
429
  chart.add_position_box(
@@ -419,6 +434,21 @@ chart.add_position_box(
419
434
  )
420
435
  ```
421
436
 
437
+ ### Indicator Toolbar *(v0.7.4)*
438
+
439
+ The chart toolbar now has an **Add Indicator** (📈) button. Clicking it
440
+ opens a panel where indicators can be added interactively at runtime — no
441
+ code required:
442
+
443
+ - **Moving averages**: EMA, SMA, WMA, SMMA, DEMA, TEMA, HMA, VWMA, VWAP
444
+ - **Oscillators**: RSI (with optional MA), MACD, ATR
445
+ - **Trend**: Ichimoku Cloud
446
+
447
+ Each type shows its own parameter form. After clicking *Add to Chart*, the
448
+ server computes the indicator from the OHLCV data and the chart updates
449
+ immediately. Indicators added this way work exactly like those added via
450
+ `add_ma()` / `add_rsi()` / etc. in Python code.
451
+
422
452
  ### Strategy Drawings (v0.7.0)
423
453
 
424
454
  ```python
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "AlgoTradeKit"
7
- version = "0.7.3"
7
+ version = "0.7.4"
8
8
  description = "Algorithmic Trading Toolkit — data collection, indicators, strategy, simulation, and live trading"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -1,4 +1,4 @@
1
1
  """AlgoTradeKit — Algorithmic Trading Toolkit"""
2
2
 
3
- __version__ = "0.7.3"
3
+ __version__ = "0.7.4"
4
4
  __author__ = "Amir Mohammad Bazdar"