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.
- {algotradekit-0.7.3 → algotradekit-0.7.4}/CHANGELOG.md +112 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/PKG-INFO +32 -2
- {algotradekit-0.7.3 → algotradekit-0.7.4}/README.md +31 -1
- {algotradekit-0.7.3 → algotradekit-0.7.4}/pyproject.toml +1 -1
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/__init__.py +1 -1
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_engine.py +177 -71
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_position.py +38 -1
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_report.py +15 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_runner.py +4 -4
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/chart.py +222 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/indicator_renderer.py +230 -21
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/models.py +18 -16
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/static/index.html +267 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_simulate.py +328 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/.github/workflows/publish.yml +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/.gitignore +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/LICENSE +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/_utils.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/collector.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/converter.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/normalizer.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/sources/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/sources/base.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/sources/binance.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/storage/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/data/storage/csv_handler.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/_base.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/atr.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/ichimoku.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/ma.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/macd.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/indicator/rsi.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/_builder.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/_display.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/_server.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/report/static/report.html +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_config.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_lot.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/simulate/_session.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/_base.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/_types.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/builtin/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/strategy/builtin/macd.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/__init__.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/src/AlgoTradeKit/visual/server.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_data.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_data_converter.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_data_normalizer.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_indicator.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_report.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_strategy.py +0 -0
- {algotradekit-0.7.3 → algotradekit-0.7.4}/tests/test_visual.py +0 -0
- {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
|
+
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.
|
|
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" }
|