TradeChart 2.1.2__tar.gz → 2.2.0__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 (39) hide show
  1. {tradechart-2.1.2 → tradechart-2.2.0}/PKG-INFO +98 -12
  2. {tradechart-2.1.2 → tradechart-2.2.0}/README.md +97 -11
  3. {tradechart-2.1.2 → tradechart-2.2.0}/TradeChart.egg-info/PKG-INFO +98 -12
  4. {tradechart-2.1.2 → tradechart-2.2.0}/TradeChart.egg-info/SOURCES.txt +1 -0
  5. {tradechart-2.1.2 → tradechart-2.2.0}/pyproject.toml +1 -1
  6. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/__init__.py +166 -3
  7. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/config/settings.py +20 -1
  8. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/data/fetcher.py +15 -0
  9. tradechart-2.2.0/tradechart/data/store.py +96 -0
  10. tradechart-2.2.0/tradechart_examples/discord_demo_bot/discord_bot.py +991 -0
  11. tradechart-2.1.2/tradechart_examples/discord_demo_bot/discord_bot.py +0 -665
  12. {tradechart-2.1.2 → tradechart-2.2.0}/LICENSE +0 -0
  13. {tradechart-2.1.2 → tradechart-2.2.0}/TradeChart.egg-info/dependency_links.txt +0 -0
  14. {tradechart-2.1.2 → tradechart-2.2.0}/TradeChart.egg-info/requires.txt +0 -0
  15. {tradechart-2.1.2 → tradechart-2.2.0}/TradeChart.egg-info/top_level.txt +0 -0
  16. {tradechart-2.1.2 → tradechart-2.2.0}/setup.cfg +0 -0
  17. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/charts/__init__.py +0 -0
  18. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/charts/heatmap.py +0 -0
  19. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/charts/indicators.py +0 -0
  20. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/charts/renderer.py +0 -0
  21. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/charts/themes.py +0 -0
  22. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/charts/watermark.py +0 -0
  23. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/config/__init__.py +0 -0
  24. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/config/logger.py +0 -0
  25. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/core/__init__.py +0 -0
  26. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/core/engine.py +0 -0
  27. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/data/__init__.py +0 -0
  28. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/data/groups.py +0 -0
  29. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/data/models.py +0 -0
  30. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/data/provider_base.py +0 -0
  31. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/providers/__init__.py +0 -0
  32. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/providers/stooq_provider.py +0 -0
  33. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/providers/tradingview_provider.py +0 -0
  34. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/providers/yfinance_provider.py +0 -0
  35. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/utils/__init__.py +0 -0
  36. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/utils/exceptions.py +0 -0
  37. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/utils/formatting.py +0 -0
  38. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/utils/install.py +0 -0
  39. {tradechart-2.1.2 → tradechart-2.2.0}/tradechart/utils/validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TradeChart
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: Production-quality financial chart generator — candlestick, line, area, OHLC, Heikin-Ashi, performance heatmaps, and sector group charts.
5
5
  Author-email: "TRADELY.DEV" <dev@tradely.dev>
6
6
  License: Apache-2.0
@@ -45,11 +45,11 @@ Requires-Dist: build>=1.0; extra == "dev"
45
45
  Requires-Dist: twine>=5.0; extra == "dev"
46
46
  Dynamic: license-file
47
47
 
48
- # TradeChart — Library Edition v2.1.2
48
+ # TradeChart — Library Edition v2.2.0
49
49
 
50
50
  **Python → Financial Charts**
51
51
  Generate production-quality candlestick, line, area, OHLC, Heikin-Ashi, and performance heatmap charts from code.
52
- Automatic multi-provider data fetching · 7 technical indicators · 3 themes · PNG/SVG/PDF output · 14 built-in sector groups.
52
+ Automatic multi-provider data fetching · persistent disk store · 7 technical indicators · 3 themes · PNG/SVG/PDF output · 14 built-in sector groups.
53
53
 
54
54
  ---
55
55
 
@@ -84,6 +84,81 @@ tc.chart("AAPL", "1mo", "candle", indicators=["sma", "bollinger"])
84
84
 
85
85
  ---
86
86
 
87
+ ## Persistent Data Store
88
+
89
+ `tc.store()` adds a two-level cache on top of the existing in-memory TTL cache: data fetched from any provider is written to a `tradechart_FetchData/` folder and reloaded automatically in future sessions, eliminating redundant network requests.
90
+
91
+ ### Set the store location
92
+
93
+ Call `tc.store()` once with a filesystem path. The folder `tradechart_FetchData/` is created there automatically.
94
+
95
+ ```python
96
+ import tradechart as tc
97
+
98
+ tc.store("/data/myproject") # absolute path
99
+ tc.store(".") # current working directory
100
+ tc.store("~/market_data") # tilde expansion supported
101
+ ```
102
+
103
+ ### Pre-fetch tickers and groups
104
+
105
+ After setting the path, call `tc.store()` again on subsequent lines listing any combination of individual ticker symbols, named sector group keys, or plain lists. An optional duration string as the last argument controls the fetch window (defaults to `"1mo"`).
106
+
107
+ ```python
108
+ tc.store("AAPL") # single ticker, default duration (1mo)
109
+ tc.store("AAPL", "MSFT", "NVDA", "3mo") # three tickers for 3 months
110
+ tc.store("mag7", "6mo") # named group — fetches all 7 tickers
111
+ tc.store("tech", "finance", "1y") # two named groups for 1 year
112
+ tc.store(tc.SECTOR_GROUPS["crypto"], "3mo") # list passed directly
113
+ ```
114
+
115
+ Any valid `SECTOR_GROUPS` key (`"mag7"`, `"tech"`, `"finance"`, `"energy"`, …) is expanded to its full ticker list automatically.
116
+
117
+ ### How it works
118
+
119
+ Once a store path is configured, every call to `chart()`, `data()`, `export()`, `compare()`, or `heatmap()` checks the disk store before touching the network:
120
+
121
+ 1. **In-memory cache** — sub-millisecond, TTL-based (existing behaviour).
122
+ 2. **Disk store** — CSV file per `(ticker, duration)` pair, persists across sessions.
123
+ 3. **Live provider chain** — yfinance → TradingView → Stooq. On success the result is written to disk automatically.
124
+
125
+ ```python
126
+ tc.store("/data/myproject")
127
+ tc.store("AAPL", "MSFT", "mag7", "3mo") # fetch once, write to disk
128
+
129
+ # Later — same session or a completely new one:
130
+ tc.chart("AAPL", "3mo") # served from disk, no network call
131
+ tc.data("MSFT", "3mo") # same
132
+ tc.heatmap(tc.SECTOR_GROUPS["mag7"], "3mo") # same
133
+ ```
134
+
135
+ ### Clearing stored data
136
+
137
+ ```python
138
+ tc.clear_cache() # flush in-memory cache only (default)
139
+ tc.clear_cache(disk=True) # also delete all CSV files in tradechart_FetchData/
140
+ ```
141
+
142
+ ### Store folder layout
143
+
144
+ ```
145
+ /data/myproject/
146
+ └── tradechart_FetchData/
147
+ ├── AAPL_3mo.csv
148
+ ├── MSFT_3mo.csv
149
+ ├── NVDA_3mo.csv
150
+ └── ...
151
+ ```
152
+
153
+ | Parameter | Type | Description |
154
+ |---|---|---|
155
+ | `*args` | `str \| list \| tuple` | A single path string **or** any mix of ticker symbols, named sector group keys, and/or lists — optionally ending with a duration string. |
156
+ | `duration` | `str` (keyword) | Fallback duration when none is provided in `*args`. Default `"1mo"`. |
157
+
158
+ **Returns:** the `tradechart_FetchData/` `Path` when setting the store; `None` when pre-fetching.
159
+
160
+ ---
161
+
87
162
  ## Ticker Groups — Averaged Series
88
163
 
89
164
  `tc.chart()`, `tc.data()`, and `tc.export()` accept a **list or tuple of ticker symbols** in addition to a single string. When a group is supplied the library:
@@ -137,12 +212,14 @@ If one or more tickers in the group fail to fetch data, they are **skipped with
137
212
  | `tc.theme(name)` | Set chart colour theme |
138
213
  | `tc.watermark(enabled)` | Toggle the TRADELY logo watermark |
139
214
  | `tc.config(**kwargs)` | Batch-set multiple global options at once |
215
+ | `tc.store(path)` | Set persistent data-store directory |
216
+ | `tc.store(ticker, ...)` | Pre-fetch and persist tickers / groups |
140
217
  | `tc.chart(...)` | Fetch data and render a chart image |
141
218
  | `tc.compare(...)` | Overlay multiple tickers on one chart |
142
219
  | `tc.heatmap(...)` | Render a performance heatmap for a ticker group |
143
220
  | `tc.data(...)` | Fetch raw OHLCV data as a DataFrame |
144
221
  | `tc.export(...)` | Export market data to CSV / JSON / XLSX |
145
- | `tc.clear_cache()` | Flush the in-memory data cache |
222
+ | `tc.clear_cache(disk=False)` | Flush in-memory cache; optionally wipe disk store |
146
223
  | `tc.SECTOR_GROUPS` | Dict of 14 pre-defined ticker lists (sectors, indices, crypto, …) |
147
224
 
148
225
  ---
@@ -252,7 +329,7 @@ Tile sizes use a **squarified treemap** algorithm to minimise wasted space while
252
329
 
253
330
  ## `tc.SECTOR_GROUPS` — Pre-defined Ticker Lists
254
331
 
255
- A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, or `tc.export()`.
332
+ A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, `tc.store()`, or `tc.export()`.
256
333
 
257
334
  ```python
258
335
  import tradechart as tc
@@ -417,10 +494,15 @@ The TRADELY logo is stamped in the bottom-left corner of every chart by default.
417
494
  ## `tc.clear_cache()` — Flush Data Cache
418
495
 
419
496
  ```python
420
- tc.clear_cache()
497
+ tc.clear_cache() # flush in-memory cache only
498
+ tc.clear_cache(disk=True) # also wipe all CSVs in tradechart_FetchData/
421
499
  ```
422
500
 
423
- Clears all in-memory cached market data, forcing the next fetch to go to the network. Useful after a TTL has not yet expired but you need fresh data (e.g. during live market hours).
501
+ | Parameter | Type | Default | Description |
502
+ |---|---|---|---|
503
+ | `disk` | `bool` | `False` | When `True`, deletes all CSV files in the disk store (the folder is kept). Has no effect if no store path has been set. |
504
+
505
+ Clears in-memory cached market data, forcing the next fetch to check the disk store (or go to the network if no store is configured). Useful during live market hours when TTL has not yet expired but you need a fresh quote.
424
506
 
425
507
  ---
426
508
 
@@ -475,18 +557,22 @@ TradeChart tries providers in priority order and falls back automatically on fai
475
557
 
476
558
  | Priority | Provider | Requires | Notes |
477
559
  |---|---|---|---|
478
- | 1 | **yfinance** | Included by default | Primary source. Covers stocks, ETFs, indices, crypto, forex. |
560
+ | 0 | **Disk store** | `tc.store(path)` called once | Fastest — served from local CSV, no network. Persists across sessions. |
561
+ | 1 | **yfinance** | Included by default | Primary live source. Covers stocks, ETFs, indices, crypto, forex. |
479
562
  | 2 | **TradingView** | `pip install TradeChart[tradingview]` | Tried if yfinance returns empty or fails. Attempts multiple exchanges automatically (`NASDAQ`, `NYSE`, `AMEX`, `CRYPTO`, `FX`). |
480
563
  | 3 | **Stooq** | Nothing — free CSV endpoint | Final fallback. No API key required. Duration mapped to a rolling date range. |
481
564
 
482
- If all three providers fail, a `DataFetchError` is raised with a list of each provider's error message.
565
+ If all live providers fail and no disk data exists, a `DataFetchError` is raised with a list of each provider's error message.
483
566
 
484
567
  ---
485
568
 
486
569
  ## Notes
487
570
 
488
- **Caching**
489
- Fetched data is cached in-memory for `cache_ttl` seconds (default 300 s / 5 minutes). All subsequent calls with the same ticker and duration within that window are served from cache. Call `tc.clear_cache()` to force a re-fetch, or set `tc.config(cache_ttl=0)` to disable caching entirely.
571
+ **Persistent disk store**
572
+ When `tc.store()` is configured, every successful live fetch is written to `tradechart_FetchData/` as a CSV file. Subsequent fetches — even in a new Python session — read from disk rather than the network. Use `tc.clear_cache(disk=True)` to wipe stored files and force a fresh fetch from providers.
573
+
574
+ **In-memory caching**
575
+ Fetched data is also cached in-memory for `cache_ttl` seconds (default 300 s / 5 minutes). All subsequent calls with the same ticker and duration within that window are served from the memory cache. Call `tc.clear_cache()` to force re-evaluation (disk store is still checked before going to the network). Set `tc.config(cache_ttl=0)` to disable the memory cache entirely.
490
576
 
491
577
  **File collision handling**
492
578
  By default (`overwrite=False`), TradeChart appends a counter to avoid overwriting existing files: `chart.png` → `chart_1.png` → `chart_2.png`. Set `tc.config(overwrite=True)` to overwrite silently.
@@ -518,7 +604,7 @@ All TradeChart exceptions inherit from `TradeChartError`.
518
604
  | `InvalidTickerError` | The ticker string fails validation (too long, invalid characters) |
519
605
  | `RenderError` | Chart rendering fails (e.g. empty dataset after cleaning) |
520
606
  | `OutputError` | The chart cannot be saved (e.g. permission denied) |
521
- | `ConfigError` | An unknown key is passed to `tc.config()` |
607
+ | `ConfigError` | An unknown key is passed to `tc.config()`, or `tc.store()` is called with tickers before a path is set |
522
608
 
523
609
  ```python
524
610
  import tradechart as tc
@@ -1,8 +1,8 @@
1
- # TradeChart — Library Edition v2.1.2
1
+ # TradeChart — Library Edition v2.2.0
2
2
 
3
3
  **Python → Financial Charts**
4
4
  Generate production-quality candlestick, line, area, OHLC, Heikin-Ashi, and performance heatmap charts from code.
5
- Automatic multi-provider data fetching · 7 technical indicators · 3 themes · PNG/SVG/PDF output · 14 built-in sector groups.
5
+ Automatic multi-provider data fetching · persistent disk store · 7 technical indicators · 3 themes · PNG/SVG/PDF output · 14 built-in sector groups.
6
6
 
7
7
  ---
8
8
 
@@ -37,6 +37,81 @@ tc.chart("AAPL", "1mo", "candle", indicators=["sma", "bollinger"])
37
37
 
38
38
  ---
39
39
 
40
+ ## Persistent Data Store
41
+
42
+ `tc.store()` adds a two-level cache on top of the existing in-memory TTL cache: data fetched from any provider is written to a `tradechart_FetchData/` folder and reloaded automatically in future sessions, eliminating redundant network requests.
43
+
44
+ ### Set the store location
45
+
46
+ Call `tc.store()` once with a filesystem path. The folder `tradechart_FetchData/` is created there automatically.
47
+
48
+ ```python
49
+ import tradechart as tc
50
+
51
+ tc.store("/data/myproject") # absolute path
52
+ tc.store(".") # current working directory
53
+ tc.store("~/market_data") # tilde expansion supported
54
+ ```
55
+
56
+ ### Pre-fetch tickers and groups
57
+
58
+ After setting the path, call `tc.store()` again on subsequent lines listing any combination of individual ticker symbols, named sector group keys, or plain lists. An optional duration string as the last argument controls the fetch window (defaults to `"1mo"`).
59
+
60
+ ```python
61
+ tc.store("AAPL") # single ticker, default duration (1mo)
62
+ tc.store("AAPL", "MSFT", "NVDA", "3mo") # three tickers for 3 months
63
+ tc.store("mag7", "6mo") # named group — fetches all 7 tickers
64
+ tc.store("tech", "finance", "1y") # two named groups for 1 year
65
+ tc.store(tc.SECTOR_GROUPS["crypto"], "3mo") # list passed directly
66
+ ```
67
+
68
+ Any valid `SECTOR_GROUPS` key (`"mag7"`, `"tech"`, `"finance"`, `"energy"`, …) is expanded to its full ticker list automatically.
69
+
70
+ ### How it works
71
+
72
+ Once a store path is configured, every call to `chart()`, `data()`, `export()`, `compare()`, or `heatmap()` checks the disk store before touching the network:
73
+
74
+ 1. **In-memory cache** — sub-millisecond, TTL-based (existing behaviour).
75
+ 2. **Disk store** — CSV file per `(ticker, duration)` pair, persists across sessions.
76
+ 3. **Live provider chain** — yfinance → TradingView → Stooq. On success the result is written to disk automatically.
77
+
78
+ ```python
79
+ tc.store("/data/myproject")
80
+ tc.store("AAPL", "MSFT", "mag7", "3mo") # fetch once, write to disk
81
+
82
+ # Later — same session or a completely new one:
83
+ tc.chart("AAPL", "3mo") # served from disk, no network call
84
+ tc.data("MSFT", "3mo") # same
85
+ tc.heatmap(tc.SECTOR_GROUPS["mag7"], "3mo") # same
86
+ ```
87
+
88
+ ### Clearing stored data
89
+
90
+ ```python
91
+ tc.clear_cache() # flush in-memory cache only (default)
92
+ tc.clear_cache(disk=True) # also delete all CSV files in tradechart_FetchData/
93
+ ```
94
+
95
+ ### Store folder layout
96
+
97
+ ```
98
+ /data/myproject/
99
+ └── tradechart_FetchData/
100
+ ├── AAPL_3mo.csv
101
+ ├── MSFT_3mo.csv
102
+ ├── NVDA_3mo.csv
103
+ └── ...
104
+ ```
105
+
106
+ | Parameter | Type | Description |
107
+ |---|---|---|
108
+ | `*args` | `str \| list \| tuple` | A single path string **or** any mix of ticker symbols, named sector group keys, and/or lists — optionally ending with a duration string. |
109
+ | `duration` | `str` (keyword) | Fallback duration when none is provided in `*args`. Default `"1mo"`. |
110
+
111
+ **Returns:** the `tradechart_FetchData/` `Path` when setting the store; `None` when pre-fetching.
112
+
113
+ ---
114
+
40
115
  ## Ticker Groups — Averaged Series
41
116
 
42
117
  `tc.chart()`, `tc.data()`, and `tc.export()` accept a **list or tuple of ticker symbols** in addition to a single string. When a group is supplied the library:
@@ -90,12 +165,14 @@ If one or more tickers in the group fail to fetch data, they are **skipped with
90
165
  | `tc.theme(name)` | Set chart colour theme |
91
166
  | `tc.watermark(enabled)` | Toggle the TRADELY logo watermark |
92
167
  | `tc.config(**kwargs)` | Batch-set multiple global options at once |
168
+ | `tc.store(path)` | Set persistent data-store directory |
169
+ | `tc.store(ticker, ...)` | Pre-fetch and persist tickers / groups |
93
170
  | `tc.chart(...)` | Fetch data and render a chart image |
94
171
  | `tc.compare(...)` | Overlay multiple tickers on one chart |
95
172
  | `tc.heatmap(...)` | Render a performance heatmap for a ticker group |
96
173
  | `tc.data(...)` | Fetch raw OHLCV data as a DataFrame |
97
174
  | `tc.export(...)` | Export market data to CSV / JSON / XLSX |
98
- | `tc.clear_cache()` | Flush the in-memory data cache |
175
+ | `tc.clear_cache(disk=False)` | Flush in-memory cache; optionally wipe disk store |
99
176
  | `tc.SECTOR_GROUPS` | Dict of 14 pre-defined ticker lists (sectors, indices, crypto, …) |
100
177
 
101
178
  ---
@@ -205,7 +282,7 @@ Tile sizes use a **squarified treemap** algorithm to minimise wasted space while
205
282
 
206
283
  ## `tc.SECTOR_GROUPS` — Pre-defined Ticker Lists
207
284
 
208
- A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, or `tc.export()`.
285
+ A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, `tc.store()`, or `tc.export()`.
209
286
 
210
287
  ```python
211
288
  import tradechart as tc
@@ -370,10 +447,15 @@ The TRADELY logo is stamped in the bottom-left corner of every chart by default.
370
447
  ## `tc.clear_cache()` — Flush Data Cache
371
448
 
372
449
  ```python
373
- tc.clear_cache()
450
+ tc.clear_cache() # flush in-memory cache only
451
+ tc.clear_cache(disk=True) # also wipe all CSVs in tradechart_FetchData/
374
452
  ```
375
453
 
376
- Clears all in-memory cached market data, forcing the next fetch to go to the network. Useful after a TTL has not yet expired but you need fresh data (e.g. during live market hours).
454
+ | Parameter | Type | Default | Description |
455
+ |---|---|---|---|
456
+ | `disk` | `bool` | `False` | When `True`, deletes all CSV files in the disk store (the folder is kept). Has no effect if no store path has been set. |
457
+
458
+ Clears in-memory cached market data, forcing the next fetch to check the disk store (or go to the network if no store is configured). Useful during live market hours when TTL has not yet expired but you need a fresh quote.
377
459
 
378
460
  ---
379
461
 
@@ -428,18 +510,22 @@ TradeChart tries providers in priority order and falls back automatically on fai
428
510
 
429
511
  | Priority | Provider | Requires | Notes |
430
512
  |---|---|---|---|
431
- | 1 | **yfinance** | Included by default | Primary source. Covers stocks, ETFs, indices, crypto, forex. |
513
+ | 0 | **Disk store** | `tc.store(path)` called once | Fastest — served from local CSV, no network. Persists across sessions. |
514
+ | 1 | **yfinance** | Included by default | Primary live source. Covers stocks, ETFs, indices, crypto, forex. |
432
515
  | 2 | **TradingView** | `pip install TradeChart[tradingview]` | Tried if yfinance returns empty or fails. Attempts multiple exchanges automatically (`NASDAQ`, `NYSE`, `AMEX`, `CRYPTO`, `FX`). |
433
516
  | 3 | **Stooq** | Nothing — free CSV endpoint | Final fallback. No API key required. Duration mapped to a rolling date range. |
434
517
 
435
- If all three providers fail, a `DataFetchError` is raised with a list of each provider's error message.
518
+ If all live providers fail and no disk data exists, a `DataFetchError` is raised with a list of each provider's error message.
436
519
 
437
520
  ---
438
521
 
439
522
  ## Notes
440
523
 
441
- **Caching**
442
- Fetched data is cached in-memory for `cache_ttl` seconds (default 300 s / 5 minutes). All subsequent calls with the same ticker and duration within that window are served from cache. Call `tc.clear_cache()` to force a re-fetch, or set `tc.config(cache_ttl=0)` to disable caching entirely.
524
+ **Persistent disk store**
525
+ When `tc.store()` is configured, every successful live fetch is written to `tradechart_FetchData/` as a CSV file. Subsequent fetches — even in a new Python session — read from disk rather than the network. Use `tc.clear_cache(disk=True)` to wipe stored files and force a fresh fetch from providers.
526
+
527
+ **In-memory caching**
528
+ Fetched data is also cached in-memory for `cache_ttl` seconds (default 300 s / 5 minutes). All subsequent calls with the same ticker and duration within that window are served from the memory cache. Call `tc.clear_cache()` to force re-evaluation (disk store is still checked before going to the network). Set `tc.config(cache_ttl=0)` to disable the memory cache entirely.
443
529
 
444
530
  **File collision handling**
445
531
  By default (`overwrite=False`), TradeChart appends a counter to avoid overwriting existing files: `chart.png` → `chart_1.png` → `chart_2.png`. Set `tc.config(overwrite=True)` to overwrite silently.
@@ -471,7 +557,7 @@ All TradeChart exceptions inherit from `TradeChartError`.
471
557
  | `InvalidTickerError` | The ticker string fails validation (too long, invalid characters) |
472
558
  | `RenderError` | Chart rendering fails (e.g. empty dataset after cleaning) |
473
559
  | `OutputError` | The chart cannot be saved (e.g. permission denied) |
474
- | `ConfigError` | An unknown key is passed to `tc.config()` |
560
+ | `ConfigError` | An unknown key is passed to `tc.config()`, or `tc.store()` is called with tickers before a path is set |
475
561
 
476
562
  ```python
477
563
  import tradechart as tc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TradeChart
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: Production-quality financial chart generator — candlestick, line, area, OHLC, Heikin-Ashi, performance heatmaps, and sector group charts.
5
5
  Author-email: "TRADELY.DEV" <dev@tradely.dev>
6
6
  License: Apache-2.0
@@ -45,11 +45,11 @@ Requires-Dist: build>=1.0; extra == "dev"
45
45
  Requires-Dist: twine>=5.0; extra == "dev"
46
46
  Dynamic: license-file
47
47
 
48
- # TradeChart — Library Edition v2.1.2
48
+ # TradeChart — Library Edition v2.2.0
49
49
 
50
50
  **Python → Financial Charts**
51
51
  Generate production-quality candlestick, line, area, OHLC, Heikin-Ashi, and performance heatmap charts from code.
52
- Automatic multi-provider data fetching · 7 technical indicators · 3 themes · PNG/SVG/PDF output · 14 built-in sector groups.
52
+ Automatic multi-provider data fetching · persistent disk store · 7 technical indicators · 3 themes · PNG/SVG/PDF output · 14 built-in sector groups.
53
53
 
54
54
  ---
55
55
 
@@ -84,6 +84,81 @@ tc.chart("AAPL", "1mo", "candle", indicators=["sma", "bollinger"])
84
84
 
85
85
  ---
86
86
 
87
+ ## Persistent Data Store
88
+
89
+ `tc.store()` adds a two-level cache on top of the existing in-memory TTL cache: data fetched from any provider is written to a `tradechart_FetchData/` folder and reloaded automatically in future sessions, eliminating redundant network requests.
90
+
91
+ ### Set the store location
92
+
93
+ Call `tc.store()` once with a filesystem path. The folder `tradechart_FetchData/` is created there automatically.
94
+
95
+ ```python
96
+ import tradechart as tc
97
+
98
+ tc.store("/data/myproject") # absolute path
99
+ tc.store(".") # current working directory
100
+ tc.store("~/market_data") # tilde expansion supported
101
+ ```
102
+
103
+ ### Pre-fetch tickers and groups
104
+
105
+ After setting the path, call `tc.store()` again on subsequent lines listing any combination of individual ticker symbols, named sector group keys, or plain lists. An optional duration string as the last argument controls the fetch window (defaults to `"1mo"`).
106
+
107
+ ```python
108
+ tc.store("AAPL") # single ticker, default duration (1mo)
109
+ tc.store("AAPL", "MSFT", "NVDA", "3mo") # three tickers for 3 months
110
+ tc.store("mag7", "6mo") # named group — fetches all 7 tickers
111
+ tc.store("tech", "finance", "1y") # two named groups for 1 year
112
+ tc.store(tc.SECTOR_GROUPS["crypto"], "3mo") # list passed directly
113
+ ```
114
+
115
+ Any valid `SECTOR_GROUPS` key (`"mag7"`, `"tech"`, `"finance"`, `"energy"`, …) is expanded to its full ticker list automatically.
116
+
117
+ ### How it works
118
+
119
+ Once a store path is configured, every call to `chart()`, `data()`, `export()`, `compare()`, or `heatmap()` checks the disk store before touching the network:
120
+
121
+ 1. **In-memory cache** — sub-millisecond, TTL-based (existing behaviour).
122
+ 2. **Disk store** — CSV file per `(ticker, duration)` pair, persists across sessions.
123
+ 3. **Live provider chain** — yfinance → TradingView → Stooq. On success the result is written to disk automatically.
124
+
125
+ ```python
126
+ tc.store("/data/myproject")
127
+ tc.store("AAPL", "MSFT", "mag7", "3mo") # fetch once, write to disk
128
+
129
+ # Later — same session or a completely new one:
130
+ tc.chart("AAPL", "3mo") # served from disk, no network call
131
+ tc.data("MSFT", "3mo") # same
132
+ tc.heatmap(tc.SECTOR_GROUPS["mag7"], "3mo") # same
133
+ ```
134
+
135
+ ### Clearing stored data
136
+
137
+ ```python
138
+ tc.clear_cache() # flush in-memory cache only (default)
139
+ tc.clear_cache(disk=True) # also delete all CSV files in tradechart_FetchData/
140
+ ```
141
+
142
+ ### Store folder layout
143
+
144
+ ```
145
+ /data/myproject/
146
+ └── tradechart_FetchData/
147
+ ├── AAPL_3mo.csv
148
+ ├── MSFT_3mo.csv
149
+ ├── NVDA_3mo.csv
150
+ └── ...
151
+ ```
152
+
153
+ | Parameter | Type | Description |
154
+ |---|---|---|
155
+ | `*args` | `str \| list \| tuple` | A single path string **or** any mix of ticker symbols, named sector group keys, and/or lists — optionally ending with a duration string. |
156
+ | `duration` | `str` (keyword) | Fallback duration when none is provided in `*args`. Default `"1mo"`. |
157
+
158
+ **Returns:** the `tradechart_FetchData/` `Path` when setting the store; `None` when pre-fetching.
159
+
160
+ ---
161
+
87
162
  ## Ticker Groups — Averaged Series
88
163
 
89
164
  `tc.chart()`, `tc.data()`, and `tc.export()` accept a **list or tuple of ticker symbols** in addition to a single string. When a group is supplied the library:
@@ -137,12 +212,14 @@ If one or more tickers in the group fail to fetch data, they are **skipped with
137
212
  | `tc.theme(name)` | Set chart colour theme |
138
213
  | `tc.watermark(enabled)` | Toggle the TRADELY logo watermark |
139
214
  | `tc.config(**kwargs)` | Batch-set multiple global options at once |
215
+ | `tc.store(path)` | Set persistent data-store directory |
216
+ | `tc.store(ticker, ...)` | Pre-fetch and persist tickers / groups |
140
217
  | `tc.chart(...)` | Fetch data and render a chart image |
141
218
  | `tc.compare(...)` | Overlay multiple tickers on one chart |
142
219
  | `tc.heatmap(...)` | Render a performance heatmap for a ticker group |
143
220
  | `tc.data(...)` | Fetch raw OHLCV data as a DataFrame |
144
221
  | `tc.export(...)` | Export market data to CSV / JSON / XLSX |
145
- | `tc.clear_cache()` | Flush the in-memory data cache |
222
+ | `tc.clear_cache(disk=False)` | Flush in-memory cache; optionally wipe disk store |
146
223
  | `tc.SECTOR_GROUPS` | Dict of 14 pre-defined ticker lists (sectors, indices, crypto, …) |
147
224
 
148
225
  ---
@@ -252,7 +329,7 @@ Tile sizes use a **squarified treemap** algorithm to minimise wasted space while
252
329
 
253
330
  ## `tc.SECTOR_GROUPS` — Pre-defined Ticker Lists
254
331
 
255
- A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, or `tc.export()`.
332
+ A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, `tc.store()`, or `tc.export()`.
256
333
 
257
334
  ```python
258
335
  import tradechart as tc
@@ -417,10 +494,15 @@ The TRADELY logo is stamped in the bottom-left corner of every chart by default.
417
494
  ## `tc.clear_cache()` — Flush Data Cache
418
495
 
419
496
  ```python
420
- tc.clear_cache()
497
+ tc.clear_cache() # flush in-memory cache only
498
+ tc.clear_cache(disk=True) # also wipe all CSVs in tradechart_FetchData/
421
499
  ```
422
500
 
423
- Clears all in-memory cached market data, forcing the next fetch to go to the network. Useful after a TTL has not yet expired but you need fresh data (e.g. during live market hours).
501
+ | Parameter | Type | Default | Description |
502
+ |---|---|---|---|
503
+ | `disk` | `bool` | `False` | When `True`, deletes all CSV files in the disk store (the folder is kept). Has no effect if no store path has been set. |
504
+
505
+ Clears in-memory cached market data, forcing the next fetch to check the disk store (or go to the network if no store is configured). Useful during live market hours when TTL has not yet expired but you need a fresh quote.
424
506
 
425
507
  ---
426
508
 
@@ -475,18 +557,22 @@ TradeChart tries providers in priority order and falls back automatically on fai
475
557
 
476
558
  | Priority | Provider | Requires | Notes |
477
559
  |---|---|---|---|
478
- | 1 | **yfinance** | Included by default | Primary source. Covers stocks, ETFs, indices, crypto, forex. |
560
+ | 0 | **Disk store** | `tc.store(path)` called once | Fastest — served from local CSV, no network. Persists across sessions. |
561
+ | 1 | **yfinance** | Included by default | Primary live source. Covers stocks, ETFs, indices, crypto, forex. |
479
562
  | 2 | **TradingView** | `pip install TradeChart[tradingview]` | Tried if yfinance returns empty or fails. Attempts multiple exchanges automatically (`NASDAQ`, `NYSE`, `AMEX`, `CRYPTO`, `FX`). |
480
563
  | 3 | **Stooq** | Nothing — free CSV endpoint | Final fallback. No API key required. Duration mapped to a rolling date range. |
481
564
 
482
- If all three providers fail, a `DataFetchError` is raised with a list of each provider's error message.
565
+ If all live providers fail and no disk data exists, a `DataFetchError` is raised with a list of each provider's error message.
483
566
 
484
567
  ---
485
568
 
486
569
  ## Notes
487
570
 
488
- **Caching**
489
- Fetched data is cached in-memory for `cache_ttl` seconds (default 300 s / 5 minutes). All subsequent calls with the same ticker and duration within that window are served from cache. Call `tc.clear_cache()` to force a re-fetch, or set `tc.config(cache_ttl=0)` to disable caching entirely.
571
+ **Persistent disk store**
572
+ When `tc.store()` is configured, every successful live fetch is written to `tradechart_FetchData/` as a CSV file. Subsequent fetches — even in a new Python session — read from disk rather than the network. Use `tc.clear_cache(disk=True)` to wipe stored files and force a fresh fetch from providers.
573
+
574
+ **In-memory caching**
575
+ Fetched data is also cached in-memory for `cache_ttl` seconds (default 300 s / 5 minutes). All subsequent calls with the same ticker and duration within that window are served from the memory cache. Call `tc.clear_cache()` to force re-evaluation (disk store is still checked before going to the network). Set `tc.config(cache_ttl=0)` to disable the memory cache entirely.
490
576
 
491
577
  **File collision handling**
492
578
  By default (`overwrite=False`), TradeChart appends a counter to avoid overwriting existing files: `chart.png` → `chart_1.png` → `chart_2.png`. Set `tc.config(overwrite=True)` to overwrite silently.
@@ -518,7 +604,7 @@ All TradeChart exceptions inherit from `TradeChartError`.
518
604
  | `InvalidTickerError` | The ticker string fails validation (too long, invalid characters) |
519
605
  | `RenderError` | Chart rendering fails (e.g. empty dataset after cleaning) |
520
606
  | `OutputError` | The chart cannot be saved (e.g. permission denied) |
521
- | `ConfigError` | An unknown key is passed to `tc.config()` |
607
+ | `ConfigError` | An unknown key is passed to `tc.config()`, or `tc.store()` is called with tickers before a path is set |
522
608
 
523
609
  ```python
524
610
  import tradechart as tc
@@ -23,6 +23,7 @@ tradechart/data/fetcher.py
23
23
  tradechart/data/groups.py
24
24
  tradechart/data/models.py
25
25
  tradechart/data/provider_base.py
26
+ tradechart/data/store.py
26
27
  tradechart/providers/__init__.py
27
28
  tradechart/providers/stooq_provider.py
28
29
  tradechart/providers/tradingview_provider.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "TradeChart"
7
- version = "2.1.2"
7
+ version = "2.2.0"
8
8
  description = "Production-quality financial chart generator — candlestick, line, area, OHLC, Heikin-Ashi, performance heatmaps, and sector group charts."
9
9
  readme = "README.md"
10
10
  license = {text = "Apache-2.0"}