AlgoTradeKit 0.7.0__tar.gz → 0.7.2__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.0 → algotradekit-0.7.2}/CHANGELOG.md +116 -0
  2. {algotradekit-0.7.0 → algotradekit-0.7.2}/PKG-INFO +85 -16
  3. {algotradekit-0.7.0 → algotradekit-0.7.2}/README.md +84 -15
  4. {algotradekit-0.7.0 → algotradekit-0.7.2}/pyproject.toml +1 -1
  5. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/__init__.py +1 -1
  6. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/__init__.py +2 -0
  7. algotradekit-0.7.2/src/AlgoTradeKit/data/normalizer.py +485 -0
  8. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/indicator/__init__.py +3 -0
  9. algotradekit-0.7.2/src/AlgoTradeKit/indicator/atr.py +140 -0
  10. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/indicator/ichimoku.py +32 -0
  11. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/report/static/report.html +72 -11
  12. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_engine.py +4 -2
  13. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/visual/chart.py +137 -1
  14. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/visual/server.py +46 -4
  15. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/visual/static/index.html +233 -7
  16. algotradekit-0.7.2/tests/test_data_normalizer.py +355 -0
  17. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_indicator.py +223 -2
  18. {algotradekit-0.7.0 → algotradekit-0.7.2}/.github/workflows/publish.yml +0 -0
  19. {algotradekit-0.7.0 → algotradekit-0.7.2}/.gitignore +0 -0
  20. {algotradekit-0.7.0 → algotradekit-0.7.2}/LICENSE +0 -0
  21. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/_utils.py +0 -0
  22. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/collector.py +0 -0
  23. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/converter.py +0 -0
  24. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/sources/__init__.py +0 -0
  25. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/sources/base.py +0 -0
  26. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/sources/binance.py +0 -0
  27. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/storage/__init__.py +0 -0
  28. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/data/storage/csv_handler.py +0 -0
  29. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/indicator/_base.py +0 -0
  30. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/indicator/ma.py +0 -0
  31. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/indicator/macd.py +0 -0
  32. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/indicator/rsi.py +0 -0
  33. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/report/__init__.py +0 -0
  34. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/report/_builder.py +0 -0
  35. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/report/_display.py +0 -0
  36. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/report/_server.py +0 -0
  37. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/__init__.py +0 -0
  38. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_config.py +0 -0
  39. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_lot.py +0 -0
  40. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_position.py +0 -0
  41. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_report.py +0 -0
  42. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_runner.py +0 -0
  43. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/simulate/_session.py +0 -0
  44. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/strategy/__init__.py +0 -0
  45. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/strategy/_base.py +0 -0
  46. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/strategy/_types.py +0 -0
  47. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/strategy/builtin/__init__.py +0 -0
  48. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/strategy/builtin/macd.py +0 -0
  49. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/visual/__init__.py +0 -0
  50. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/visual/indicator_renderer.py +0 -0
  51. {algotradekit-0.7.0 → algotradekit-0.7.2}/src/AlgoTradeKit/visual/models.py +0 -0
  52. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_data.py +0 -0
  53. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_data_converter.py +0 -0
  54. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_report.py +0 -0
  55. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_simulate.py +0 -0
  56. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_strategy.py +0 -0
  57. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_visual.py +0 -0
  58. {algotradekit-0.7.0 → algotradekit-0.7.2}/tests/test_visual__0_4_1.py +0 -0
@@ -7,6 +7,122 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.7.2] — 2026-06-20
11
+
12
+ ### Added
13
+
14
+ #### `data` module
15
+ - **`Normalizer`** — new class to ingest non-standard OHLCV CSV files and
16
+ convert them to the AlgoTradeKit standard format. Features:
17
+ - Auto-detects whether timestamps are in **Unix seconds** (`< 10^10`) or
18
+ **milliseconds** (`≥ 10^10`) and converts to ms automatically.
19
+ - Fills missing optional columns (`close_time`, `quote_volume`, `trades`,
20
+ `taker_buy_base`, `taker_buy_quote`) with `None`; `volume` defaults to `0`.
21
+ - Date-range filtering via `start` / `end` attributes before returning data
22
+ (integers are also auto-detected as seconds or ms).
23
+ - Three usage modes: `normalize()` → DataFrame, `save()` → CSV path,
24
+ `normalize_and_save()` → `(DataFrame, path)`.
25
+ - `Normalizer` is now exported from `AlgoTradeKit.data`.
26
+
27
+ #### `indicator` module
28
+ - **`ATR`** — Average True Range using Wilder's RMA smoothing (`alpha = 1 / period`,
29
+ `min_periods = period`). Matches TradingView `ta.atr()` output.
30
+ Exposes `atr` and `tr` properties and result-dict keys.
31
+ Default period: **14**. Exported from `AlgoTradeKit.indicator`.
32
+ - **`Ichimoku.span_a_raw`** and **`Ichimoku.span_b_raw`** — two new properties
33
+ (and `result` dict keys) exposing the **unshifted** Senkou Span A and B values
34
+ at each bar (i.e. `(tenkan + kijun) / 2` and the Span B donchian mid *before*
35
+ the displacement shift is applied). These are required for strategy entry/exit
36
+ logic where the current cloud position matters, not the displayed future cloud.
37
+ Fully backward-compatible — no existing keys or properties were changed.
38
+
39
+ #### `visual` module
40
+ - **`Chart.set_data(candle_range=...)`** — new optional `candle_range` dict
41
+ parameter filters which candles are rendered. Five modes:
42
+ - `{"start": ..., "end": ...}` — inclusive datetime range (either key optional)
43
+ - `{"start": ...}` — from date to the last available candle
44
+ - `{"end": ...}` — from the first candle to date
45
+ - `{"last_n": N}` — last N candles
46
+ - `{"first_n": N}` — first N candles
47
+
48
+ `start` / `end` accept `"YYYY/MM/DD"`, `"YYYY-MM-DD"` strings, `datetime`
49
+ objects, Unix-second `int`, or Unix-millisecond `int`.
50
+ - **`Chart.from_csv(candle_range=...)`** — `candle_range` forwarded from the
51
+ factory class method.
52
+
53
+ ### Tests
54
+ - `tests/test_data_normalizer.py` — 25+ unit tests for `Normalizer` covering
55
+ timestamp detection, date filtering, schema completeness, save/load round-trip,
56
+ and error paths.
57
+ - `tests/test_indicator.py` — extended with `TestATR` (15 tests) and
58
+ `TestIchimokuRawSpans` (10 tests) for the new indicator features.
59
+
60
+ ---
61
+
62
+ ## [0.7.1] — 2026-06-18
63
+
64
+ ### Fixed
65
+
66
+ #### `visual` module
67
+ - **Canvas clipping** — drawings (h-lines, trend lines, boxes, signals,
68
+ Ichimoku cloud, position boxes) no longer bleed over the right price axis,
69
+ the bottom time axis, or adjacent sub-chart pane areas when the chart is
70
+ panned or zoomed. A `getDrawingClipRect()` helper measures the actual axis
71
+ widths from the LWC DOM at render time and applies a canvas `clip()` in
72
+ both `redrawAll()` and `redrawGhost()`.
73
+ - **`navigate_to_candle` timing** — the chart now replies the last `init` and
74
+ last `navigate_to_candle` message to every newly-connecting browser tab.
75
+ Clicking "Open on Candle Chart" in the report now reliably scrolls the
76
+ chart to the position entry candle even when the chart tab was opened
77
+ after the navigate command was sent.
78
+ - **`chart_port` not set** — `Simulate._build_simulation_chart()` returned
79
+ `(chart, chart)` instead of `(chart, chart._server)` because `Chart.show()`
80
+ returns `self`. The returned server object is now `chart._server`, so
81
+ `report_data.chart_port` is set correctly and the "Open on Candle Chart"
82
+ button in the report opens/focuses the right URL.
83
+
84
+ #### `report` module
85
+ - **Equity balance chart panning** — replaced `chartjs-plugin-zoom` (which
86
+ failed to register mouse-drag pan events reliably with Chart.js 4.x) with a
87
+ direct `mousedown` / `mousemove` / `mouseup` listener. Holding left-click
88
+ and dragging now pans the balance chart left/right. Wheel scroll still
89
+ zooms. Double-click still resets to full range.
90
+
91
+ #### `simulate` module
92
+ - (no functional changes; only the `_build_simulation_chart` fix above)
93
+
94
+ ### Changed
95
+
96
+ #### `visual` module
97
+ - **Position box: resizable** — `position_box` drawings that are not locked
98
+ now render five resize handles:
99
+ - **Left / Right edge** (blue) — drag to change `open_time` / `close_time`
100
+ - **Entry line** (white) — drag to shift `entry_price` (TP and SL move with it)
101
+ - **TP line** (green/red) — drag to change `take_profit` / `visual_tp`
102
+ - **SL line** (red/green) — drag to change `stop_loss`
103
+ Moving the box interior moves the entire position. The R:R label updates
104
+ live as you resize.
105
+ - **Position box: toolbar shape** — a new `posbox` toolbar button (⬜ icon)
106
+ lets users draw position boxes interactively:
107
+ - Click once to set `entry_price` and `open_time`
108
+ - Click a second time to set the TP price and `close_time`
109
+ - Direction (long/short) is inferred from whether the TP is above or below entry
110
+ - SL is placed at 1R below/above entry automatically and can be dragged afterwards
111
+ - User-created boxes are **unlocked** by default; server-created (simulation)
112
+ boxes remain locked as before
113
+ - **Position box context menu** — right-click works on position boxes just
114
+ like on other drawings (lock/unlock, rename label, change color, delete).
115
+
116
+ ### Fixed (documentation)
117
+
118
+ - **README drawings examples** — corrected three code snippets that called
119
+ the removed `chart.add_drawing()` method:
120
+ - `chart.add_drawing(HorizontalLine(...))` → `chart.add_hline(...)`
121
+ - `chart.add_drawing(Box(...))` → `chart.add_box(...)`
122
+ - `chart.add_drawing(Signal(...))` → `chart.add_signal(...)`
123
+
124
+ ---
125
+
10
126
  ## [0.7.0] — 2026-06-17
11
127
 
12
128
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AlgoTradeKit
3
- Version: 0.7.0
3
+ Version: 0.7.2
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
@@ -125,6 +125,31 @@ import pandas as pd
125
125
  data = {"1h": pd.read_csv("data/binance-futures_BTCUSDT_1h.csv")}
126
126
  ```
127
127
 
128
+ **Normalizing non-standard CSVs** *(v0.7.2)*
129
+
130
+ Broker / MT5 exports often use Unix-second timestamps and omit optional columns.
131
+ `Normalizer` converts any OHLCV CSV to the library standard automatically:
132
+
133
+ ```python
134
+ from AlgoTradeKit.data import Normalizer
135
+
136
+ # Accepts: timestamp in seconds OR milliseconds (auto-detected)
137
+ # Required columns: timestamp, open, high, low, close
138
+ # Optional: volume (defaults to 0 if absent)
139
+ norm = Normalizer("USDJPY_1m.csv")
140
+ norm.start = "2022/01/01" # optional date filter
141
+ norm.end = "2024/01/01"
142
+
143
+ # Return as DataFrame (no file written)
144
+ df = norm.normalize()
145
+
146
+ # Save as library-standard CSV
147
+ path = norm.save(destination="data/")
148
+
149
+ # One-liner: normalize + save
150
+ df, path = Normalizer("USDJPY_1m.csv").normalize_and_save(destination="data/")
151
+ ```
152
+
128
153
  ---
129
154
 
130
155
  ## indicator — Technical Indicators
@@ -132,20 +157,41 @@ data = {"1h": pd.read_csv("data/binance-futures_BTCUSDT_1h.csv")}
132
157
  All indicators are **built from scratch** — no third-party TA wrappers.
133
158
 
134
159
  ```python
135
- from AlgoTradeKit.indicator import RSI, MACD, EMA, SMA, BollingerBands, ATR, Ichimoku
160
+ from AlgoTradeKit.indicator import ATR, RSI, MACD, EMA, SMA, Ichimoku
136
161
 
137
162
  close = df["close"] # pd.Series
138
163
 
139
- rsi = RSI(close, length=14) # rsi.value
164
+ rsi = RSI(close, length=14) # rsi.rsi
140
165
  macd = MACD(close, fast=12, slow=26, signal=9)
141
- # macd.macd_line, .signal_line, .histogram
142
- ema = EMA(close, length=20) # ema.value
143
- sma = SMA(close, length=50) # sma.value
144
- bb = BollingerBands(close, length=20, std=2.0)
145
- # bb.upper, .middle, .lower
146
- atr = ATR(df["high"], df["low"], close, length=14) # atr.value
166
+ # macd.macd, .signal, .histogram
167
+ ema = EMA(close, length=20) # ema.ema
168
+ sma = SMA(close, length=50) # sma.sma
169
+ atr = ATR(df["high"], df["low"], close, period=14) # atr.atr, atr.tr
147
170
  ichi = Ichimoku(df["high"], df["low"], close)
148
- # ichi.tenkan/kijun/senkou_a/senkou_b/chikou
171
+ # ichi.tenkan / kijun / senkou_a / senkou_b
172
+ # ichi.chikou / cloud_future_a / cloud_future_b
173
+ # ichi.span_a_raw / span_b_raw ← v0.7.2
174
+ ```
175
+
176
+ **`ATR` — Average True Range** *(v0.7.2)*
177
+
178
+ Wilder's smoothing (RMA, `alpha = 1/period`). Matches TradingView `ta.atr()`.
179
+
180
+ ```python
181
+ atr = ATR(df["high"], df["low"], df["close"], period=14)
182
+ df["atr"] = atr.atr.values # Wilder-smoothed ATR
183
+ df["tr"] = atr.tr.values # raw True Range
184
+ ```
185
+
186
+ **`Ichimoku.span_a_raw` / `.span_b_raw`** *(v0.7.2)*
187
+
188
+ Unshifted Senkou Span A and B (at the current bar, before the displacement shift
189
+ is applied). Useful in strategy logic where you need the live cloud value:
190
+
191
+ ```python
192
+ ichi = Ichimoku(high, low, close, displacement=26)
193
+ # ichi.senkou_a = span_a_raw.shift(26) — displayed cloud (forward-shifted)
194
+ # ichi.span_a_raw = (tenkan + kijun) / 2 — current bar value (unshifted)
149
195
  ```
150
196
 
151
197
  ---
@@ -324,6 +370,31 @@ chart = Chart.from_csv("data/binance-futures_BTCUSDT_1h.csv")
324
370
  chart.show(block=True)
325
371
  ```
326
372
 
373
+ **Candle range filter** *(v0.7.2)*
374
+
375
+ Restrict which candles are visible without modifying the source data:
376
+
377
+ ```python
378
+ # Show a specific datetime range
379
+ chart = Chart.from_csv("data/btc_1h.csv",
380
+ candle_range={"start": "2024/01/01", "end": "2024/06/01"})
381
+
382
+ # From a date to the last candle
383
+ chart = Chart.from_csv("data/btc_1h.csv",
384
+ candle_range={"start": "2024/06/01"})
385
+
386
+ # From the first candle to a date
387
+ chart = Chart.from_csv("data/btc_1h.csv",
388
+ candle_range={"end": "2024/01/01"})
389
+
390
+ # Last / first N candles
391
+ chart = Chart.from_csv("data/btc_1h.csv", candle_range={"last_n": 500})
392
+ chart = Chart.from_csv("data/btc_1h.csv", candle_range={"first_n": 200})
393
+
394
+ # Also available on set_data()
395
+ chart.set_data(df, candle_range={"start": "2023/01/01", "end": "2024/01/01"})
396
+ ```
397
+
327
398
  ### Add Indicators
328
399
 
329
400
  ```python
@@ -340,12 +411,10 @@ add_ichimoku(chart, Ichimoku(df["high"], df["low"], df["close"]),
340
411
  ### Drawings
341
412
 
342
413
  ```python
343
- from AlgoTradeKit.visual import HorizontalLine, TrendLine, Box, Signal
344
-
345
- chart.add_drawing(HorizontalLine(price=42_000, label="Support"))
346
- chart.add_drawing(Box(time1=1700000000, price1=41_000,
347
- time2=1700007200, price2=43_000, opacity=0.1))
348
- chart.add_drawing(Signal(time=1700000000, side="buy"))
414
+ chart.add_hline(price=42_000, label="Support")
415
+ chart.add_box(time1=1700000000, price1=41_000,
416
+ time2=1700007200, price2=43_000, opacity=0.1)
417
+ chart.add_signal(time=1700000000, side="buy")
349
418
  ```
350
419
 
351
420
  ### Position Boxes (v0.7.0)
@@ -69,6 +69,31 @@ import pandas as pd
69
69
  data = {"1h": pd.read_csv("data/binance-futures_BTCUSDT_1h.csv")}
70
70
  ```
71
71
 
72
+ **Normalizing non-standard CSVs** *(v0.7.2)*
73
+
74
+ Broker / MT5 exports often use Unix-second timestamps and omit optional columns.
75
+ `Normalizer` converts any OHLCV CSV to the library standard automatically:
76
+
77
+ ```python
78
+ from AlgoTradeKit.data import Normalizer
79
+
80
+ # Accepts: timestamp in seconds OR milliseconds (auto-detected)
81
+ # Required columns: timestamp, open, high, low, close
82
+ # Optional: volume (defaults to 0 if absent)
83
+ norm = Normalizer("USDJPY_1m.csv")
84
+ norm.start = "2022/01/01" # optional date filter
85
+ norm.end = "2024/01/01"
86
+
87
+ # Return as DataFrame (no file written)
88
+ df = norm.normalize()
89
+
90
+ # Save as library-standard CSV
91
+ path = norm.save(destination="data/")
92
+
93
+ # One-liner: normalize + save
94
+ df, path = Normalizer("USDJPY_1m.csv").normalize_and_save(destination="data/")
95
+ ```
96
+
72
97
  ---
73
98
 
74
99
  ## indicator — Technical Indicators
@@ -76,20 +101,41 @@ data = {"1h": pd.read_csv("data/binance-futures_BTCUSDT_1h.csv")}
76
101
  All indicators are **built from scratch** — no third-party TA wrappers.
77
102
 
78
103
  ```python
79
- from AlgoTradeKit.indicator import RSI, MACD, EMA, SMA, BollingerBands, ATR, Ichimoku
104
+ from AlgoTradeKit.indicator import ATR, RSI, MACD, EMA, SMA, Ichimoku
80
105
 
81
106
  close = df["close"] # pd.Series
82
107
 
83
- rsi = RSI(close, length=14) # rsi.value
108
+ rsi = RSI(close, length=14) # rsi.rsi
84
109
  macd = MACD(close, fast=12, slow=26, signal=9)
85
- # macd.macd_line, .signal_line, .histogram
86
- ema = EMA(close, length=20) # ema.value
87
- sma = SMA(close, length=50) # sma.value
88
- bb = BollingerBands(close, length=20, std=2.0)
89
- # bb.upper, .middle, .lower
90
- atr = ATR(df["high"], df["low"], close, length=14) # atr.value
110
+ # macd.macd, .signal, .histogram
111
+ ema = EMA(close, length=20) # ema.ema
112
+ sma = SMA(close, length=50) # sma.sma
113
+ atr = ATR(df["high"], df["low"], close, period=14) # atr.atr, atr.tr
91
114
  ichi = Ichimoku(df["high"], df["low"], close)
92
- # ichi.tenkan/kijun/senkou_a/senkou_b/chikou
115
+ # ichi.tenkan / kijun / senkou_a / senkou_b
116
+ # ichi.chikou / cloud_future_a / cloud_future_b
117
+ # ichi.span_a_raw / span_b_raw ← v0.7.2
118
+ ```
119
+
120
+ **`ATR` — Average True Range** *(v0.7.2)*
121
+
122
+ Wilder's smoothing (RMA, `alpha = 1/period`). Matches TradingView `ta.atr()`.
123
+
124
+ ```python
125
+ atr = ATR(df["high"], df["low"], df["close"], period=14)
126
+ df["atr"] = atr.atr.values # Wilder-smoothed ATR
127
+ df["tr"] = atr.tr.values # raw True Range
128
+ ```
129
+
130
+ **`Ichimoku.span_a_raw` / `.span_b_raw`** *(v0.7.2)*
131
+
132
+ Unshifted Senkou Span A and B (at the current bar, before the displacement shift
133
+ is applied). Useful in strategy logic where you need the live cloud value:
134
+
135
+ ```python
136
+ ichi = Ichimoku(high, low, close, displacement=26)
137
+ # ichi.senkou_a = span_a_raw.shift(26) — displayed cloud (forward-shifted)
138
+ # ichi.span_a_raw = (tenkan + kijun) / 2 — current bar value (unshifted)
93
139
  ```
94
140
 
95
141
  ---
@@ -268,6 +314,31 @@ chart = Chart.from_csv("data/binance-futures_BTCUSDT_1h.csv")
268
314
  chart.show(block=True)
269
315
  ```
270
316
 
317
+ **Candle range filter** *(v0.7.2)*
318
+
319
+ Restrict which candles are visible without modifying the source data:
320
+
321
+ ```python
322
+ # Show a specific datetime range
323
+ chart = Chart.from_csv("data/btc_1h.csv",
324
+ candle_range={"start": "2024/01/01", "end": "2024/06/01"})
325
+
326
+ # From a date to the last candle
327
+ chart = Chart.from_csv("data/btc_1h.csv",
328
+ candle_range={"start": "2024/06/01"})
329
+
330
+ # From the first candle to a date
331
+ chart = Chart.from_csv("data/btc_1h.csv",
332
+ candle_range={"end": "2024/01/01"})
333
+
334
+ # Last / first N candles
335
+ chart = Chart.from_csv("data/btc_1h.csv", candle_range={"last_n": 500})
336
+ chart = Chart.from_csv("data/btc_1h.csv", candle_range={"first_n": 200})
337
+
338
+ # Also available on set_data()
339
+ chart.set_data(df, candle_range={"start": "2023/01/01", "end": "2024/01/01"})
340
+ ```
341
+
271
342
  ### Add Indicators
272
343
 
273
344
  ```python
@@ -284,12 +355,10 @@ add_ichimoku(chart, Ichimoku(df["high"], df["low"], df["close"]),
284
355
  ### Drawings
285
356
 
286
357
  ```python
287
- from AlgoTradeKit.visual import HorizontalLine, TrendLine, Box, Signal
288
-
289
- chart.add_drawing(HorizontalLine(price=42_000, label="Support"))
290
- chart.add_drawing(Box(time1=1700000000, price1=41_000,
291
- time2=1700007200, price2=43_000, opacity=0.1))
292
- chart.add_drawing(Signal(time=1700000000, side="buy"))
358
+ chart.add_hline(price=42_000, label="Support")
359
+ chart.add_box(time1=1700000000, price1=41_000,
360
+ time2=1700007200, price2=43_000, opacity=0.1)
361
+ chart.add_signal(time=1700000000, side="buy")
293
362
  ```
294
363
 
295
364
  ### Position Boxes (v0.7.0)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "AlgoTradeKit"
7
- version = "0.7.0"
7
+ version = "0.7.2"
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.0"
3
+ __version__ = "0.7.2"
4
4
  __author__ = "Amir Mohammad Bazdar"
@@ -1,5 +1,6 @@
1
1
  from .collector import Collector
2
2
  from .converter import Converter
3
+ from .normalizer import Normalizer
3
4
  from .sources import get_source
4
5
  from .sources.base import BaseSource
5
6
  from .sources.binance import BinanceSource
@@ -8,6 +9,7 @@ from .storage.csv_handler import CSVHandler
8
9
  __all__ = [
9
10
  "Collector",
10
11
  "Converter",
12
+ "Normalizer",
11
13
  "get_source",
12
14
  "BaseSource",
13
15
  "BinanceSource",