TradeChart 2.1.2__tar.gz → 2.2.1__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.
- {tradechart-2.1.2 → tradechart-2.2.1}/PKG-INFO +110 -12
- {tradechart-2.1.2 → tradechart-2.2.1}/README.md +109 -11
- {tradechart-2.1.2 → tradechart-2.2.1}/TradeChart.egg-info/PKG-INFO +110 -12
- {tradechart-2.1.2 → tradechart-2.2.1}/TradeChart.egg-info/SOURCES.txt +1 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/pyproject.toml +1 -1
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/__init__.py +166 -3
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/config/settings.py +20 -1
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/data/fetcher.py +65 -9
- tradechart-2.2.1/tradechart/data/store.py +131 -0
- tradechart-2.2.1/tradechart_examples/discord_demo_bot/discord_bot.py +998 -0
- tradechart-2.1.2/tradechart_examples/discord_demo_bot/discord_bot.py +0 -665
- {tradechart-2.1.2 → tradechart-2.2.1}/LICENSE +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/TradeChart.egg-info/dependency_links.txt +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/TradeChart.egg-info/requires.txt +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/TradeChart.egg-info/top_level.txt +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/setup.cfg +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/charts/__init__.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/charts/heatmap.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/charts/indicators.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/charts/renderer.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/charts/themes.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/charts/watermark.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/config/__init__.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/config/logger.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/core/__init__.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/core/engine.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/data/__init__.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/data/groups.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/data/models.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/data/provider_base.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/providers/__init__.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/providers/stooq_provider.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/providers/tradingview_provider.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/providers/yfinance_provider.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/utils/__init__.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/utils/exceptions.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/utils/formatting.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/utils/install.py +0 -0
- {tradechart-2.1.2 → tradechart-2.2.1}/tradechart/utils/validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: TradeChart
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
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
|
|
48
|
+
# TradeChart — Library Edition v2.2.1
|
|
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,93 @@ 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()` uses a three-level lookup before touching the network:
|
|
120
|
+
|
|
121
|
+
1. **In-memory cache** — sub-millisecond, TTL-based (existing behaviour).
|
|
122
|
+
2. **Disk store (fresh)** — if the stored file is younger than the bar-resolution threshold, it is served as-is. No network call.
|
|
123
|
+
3. **Disk store (stale) + live fetch** — if the stored file is older than the threshold, the library fetches the current window from a live provider to get the missing bars, then **merges** those new rows on top of the stored history. Historical bars are never discarded or re-requested. The merged result is written back to disk and served.
|
|
124
|
+
|
|
125
|
+
The staleness threshold matches the resolution of the data so charts are never more than one bar behind:
|
|
126
|
+
|
|
127
|
+
| Duration | Bar resolution | Refreshes after |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| `"1d"`, `"5d"` | 5 / 15-min bars | 4 hours |
|
|
130
|
+
| `"1mo"`, `"3mo"`, `"6mo"` | Daily bars | 24 hours |
|
|
131
|
+
| `"1y"`, `"2y"`, `"5y"` | Weekly bars | 7 days |
|
|
132
|
+
| `"10y"`, `"max"` | Monthly bars | 30 days |
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
tc.store("/data/myproject")
|
|
136
|
+
tc.store("AAPL", "MSFT", "mag7", "3mo") # fetch once, write to disk
|
|
137
|
+
|
|
138
|
+
# Later — same session or a completely new one:
|
|
139
|
+
tc.chart("AAPL", "3mo") # served from disk, no network call
|
|
140
|
+
tc.data("MSFT", "3mo") # same
|
|
141
|
+
|
|
142
|
+
# After 24 hours (daily bars): only the new day's bar is fetched and merged
|
|
143
|
+
# in — the months of stored history are kept and reused as-is
|
|
144
|
+
tc.chart("AAPL", "3mo") # delta fetch + merge, then cached
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Clearing stored data
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
tc.clear_cache() # flush in-memory cache only (default)
|
|
151
|
+
tc.clear_cache(disk=True) # also delete all CSV files in tradechart_FetchData/
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Store folder layout
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
/data/myproject/
|
|
158
|
+
└── tradechart_FetchData/
|
|
159
|
+
├── AAPL_3mo.csv
|
|
160
|
+
├── MSFT_3mo.csv
|
|
161
|
+
├── NVDA_3mo.csv
|
|
162
|
+
└── ...
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
| Parameter | Type | Description |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `*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. |
|
|
168
|
+
| `duration` | `str` (keyword) | Fallback duration when none is provided in `*args`. Default `"1mo"`. |
|
|
169
|
+
|
|
170
|
+
**Returns:** the `tradechart_FetchData/` `Path` when setting the store; `None` when pre-fetching.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
87
174
|
## Ticker Groups — Averaged Series
|
|
88
175
|
|
|
89
176
|
`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 +224,14 @@ If one or more tickers in the group fail to fetch data, they are **skipped with
|
|
|
137
224
|
| `tc.theme(name)` | Set chart colour theme |
|
|
138
225
|
| `tc.watermark(enabled)` | Toggle the TRADELY logo watermark |
|
|
139
226
|
| `tc.config(**kwargs)` | Batch-set multiple global options at once |
|
|
227
|
+
| `tc.store(path)` | Set persistent data-store directory |
|
|
228
|
+
| `tc.store(ticker, ...)` | Pre-fetch and persist tickers / groups |
|
|
140
229
|
| `tc.chart(...)` | Fetch data and render a chart image |
|
|
141
230
|
| `tc.compare(...)` | Overlay multiple tickers on one chart |
|
|
142
231
|
| `tc.heatmap(...)` | Render a performance heatmap for a ticker group |
|
|
143
232
|
| `tc.data(...)` | Fetch raw OHLCV data as a DataFrame |
|
|
144
233
|
| `tc.export(...)` | Export market data to CSV / JSON / XLSX |
|
|
145
|
-
| `tc.clear_cache()` | Flush
|
|
234
|
+
| `tc.clear_cache(disk=False)` | Flush in-memory cache; optionally wipe disk store |
|
|
146
235
|
| `tc.SECTOR_GROUPS` | Dict of 14 pre-defined ticker lists (sectors, indices, crypto, …) |
|
|
147
236
|
|
|
148
237
|
---
|
|
@@ -252,7 +341,7 @@ Tile sizes use a **squarified treemap** algorithm to minimise wasted space while
|
|
|
252
341
|
|
|
253
342
|
## `tc.SECTOR_GROUPS` — Pre-defined Ticker Lists
|
|
254
343
|
|
|
255
|
-
A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, or `tc.export()`.
|
|
344
|
+
A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, `tc.store()`, or `tc.export()`.
|
|
256
345
|
|
|
257
346
|
```python
|
|
258
347
|
import tradechart as tc
|
|
@@ -417,10 +506,15 @@ The TRADELY logo is stamped in the bottom-left corner of every chart by default.
|
|
|
417
506
|
## `tc.clear_cache()` — Flush Data Cache
|
|
418
507
|
|
|
419
508
|
```python
|
|
420
|
-
tc.clear_cache()
|
|
509
|
+
tc.clear_cache() # flush in-memory cache only
|
|
510
|
+
tc.clear_cache(disk=True) # also wipe all CSVs in tradechart_FetchData/
|
|
421
511
|
```
|
|
422
512
|
|
|
423
|
-
|
|
513
|
+
| Parameter | Type | Default | Description |
|
|
514
|
+
|---|---|---|---|
|
|
515
|
+
| `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. |
|
|
516
|
+
|
|
517
|
+
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
518
|
|
|
425
519
|
---
|
|
426
520
|
|
|
@@ -475,18 +569,22 @@ TradeChart tries providers in priority order and falls back automatically on fai
|
|
|
475
569
|
|
|
476
570
|
| Priority | Provider | Requires | Notes |
|
|
477
571
|
|---|---|---|---|
|
|
478
|
-
|
|
|
572
|
+
| 0 | **Disk store** | `tc.store(path)` called once | Served from local CSV when fresh. When stale, only the missing bars are fetched from a live provider and merged on top — historical rows are never re-requested. |
|
|
573
|
+
| 1 | **yfinance** | Included by default | Primary live source. Covers stocks, ETFs, indices, crypto, forex. |
|
|
479
574
|
| 2 | **TradingView** | `pip install TradeChart[tradingview]` | Tried if yfinance returns empty or fails. Attempts multiple exchanges automatically (`NASDAQ`, `NYSE`, `AMEX`, `CRYPTO`, `FX`). |
|
|
480
575
|
| 3 | **Stooq** | Nothing — free CSV endpoint | Final fallback. No API key required. Duration mapped to a rolling date range. |
|
|
481
576
|
|
|
482
|
-
If all
|
|
577
|
+
If all live providers fail and no disk data exists, a `DataFetchError` is raised with a list of each provider's error message.
|
|
483
578
|
|
|
484
579
|
---
|
|
485
580
|
|
|
486
581
|
## Notes
|
|
487
582
|
|
|
488
|
-
**
|
|
489
|
-
|
|
583
|
+
**Persistent disk store**
|
|
584
|
+
When `tc.store()` is configured, every successful live fetch is written to `tradechart_FetchData/` as a CSV file. On subsequent requests the library checks whether the stored data is fresh enough (based on bar resolution — 24 hours for daily bars, 4 hours for intraday, etc.). If fresh, it is served directly with no network call. If stale, only the most recent bars are fetched from a live provider and merged on top of the stored history — historical rows are never discarded or re-fetched. Use `tc.clear_cache(disk=True)` to wipe stored files and force a full re-fetch.
|
|
585
|
+
|
|
586
|
+
**In-memory caching**
|
|
587
|
+
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
588
|
|
|
491
589
|
**File collision handling**
|
|
492
590
|
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 +616,7 @@ All TradeChart exceptions inherit from `TradeChartError`.
|
|
|
518
616
|
| `InvalidTickerError` | The ticker string fails validation (too long, invalid characters) |
|
|
519
617
|
| `RenderError` | Chart rendering fails (e.g. empty dataset after cleaning) |
|
|
520
618
|
| `OutputError` | The chart cannot be saved (e.g. permission denied) |
|
|
521
|
-
| `ConfigError` | An unknown key is passed to `tc.config()` |
|
|
619
|
+
| `ConfigError` | An unknown key is passed to `tc.config()`, or `tc.store()` is called with tickers before a path is set |
|
|
522
620
|
|
|
523
621
|
```python
|
|
524
622
|
import tradechart as tc
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# TradeChart — Library Edition v2.1
|
|
1
|
+
# TradeChart — Library Edition v2.2.1
|
|
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,93 @@ 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()` uses a three-level lookup before touching the network:
|
|
73
|
+
|
|
74
|
+
1. **In-memory cache** — sub-millisecond, TTL-based (existing behaviour).
|
|
75
|
+
2. **Disk store (fresh)** — if the stored file is younger than the bar-resolution threshold, it is served as-is. No network call.
|
|
76
|
+
3. **Disk store (stale) + live fetch** — if the stored file is older than the threshold, the library fetches the current window from a live provider to get the missing bars, then **merges** those new rows on top of the stored history. Historical bars are never discarded or re-requested. The merged result is written back to disk and served.
|
|
77
|
+
|
|
78
|
+
The staleness threshold matches the resolution of the data so charts are never more than one bar behind:
|
|
79
|
+
|
|
80
|
+
| Duration | Bar resolution | Refreshes after |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `"1d"`, `"5d"` | 5 / 15-min bars | 4 hours |
|
|
83
|
+
| `"1mo"`, `"3mo"`, `"6mo"` | Daily bars | 24 hours |
|
|
84
|
+
| `"1y"`, `"2y"`, `"5y"` | Weekly bars | 7 days |
|
|
85
|
+
| `"10y"`, `"max"` | Monthly bars | 30 days |
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
tc.store("/data/myproject")
|
|
89
|
+
tc.store("AAPL", "MSFT", "mag7", "3mo") # fetch once, write to disk
|
|
90
|
+
|
|
91
|
+
# Later — same session or a completely new one:
|
|
92
|
+
tc.chart("AAPL", "3mo") # served from disk, no network call
|
|
93
|
+
tc.data("MSFT", "3mo") # same
|
|
94
|
+
|
|
95
|
+
# After 24 hours (daily bars): only the new day's bar is fetched and merged
|
|
96
|
+
# in — the months of stored history are kept and reused as-is
|
|
97
|
+
tc.chart("AAPL", "3mo") # delta fetch + merge, then cached
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Clearing stored data
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
tc.clear_cache() # flush in-memory cache only (default)
|
|
104
|
+
tc.clear_cache(disk=True) # also delete all CSV files in tradechart_FetchData/
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Store folder layout
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
/data/myproject/
|
|
111
|
+
└── tradechart_FetchData/
|
|
112
|
+
├── AAPL_3mo.csv
|
|
113
|
+
├── MSFT_3mo.csv
|
|
114
|
+
├── NVDA_3mo.csv
|
|
115
|
+
└── ...
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| Parameter | Type | Description |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `*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. |
|
|
121
|
+
| `duration` | `str` (keyword) | Fallback duration when none is provided in `*args`. Default `"1mo"`. |
|
|
122
|
+
|
|
123
|
+
**Returns:** the `tradechart_FetchData/` `Path` when setting the store; `None` when pre-fetching.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
40
127
|
## Ticker Groups — Averaged Series
|
|
41
128
|
|
|
42
129
|
`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 +177,14 @@ If one or more tickers in the group fail to fetch data, they are **skipped with
|
|
|
90
177
|
| `tc.theme(name)` | Set chart colour theme |
|
|
91
178
|
| `tc.watermark(enabled)` | Toggle the TRADELY logo watermark |
|
|
92
179
|
| `tc.config(**kwargs)` | Batch-set multiple global options at once |
|
|
180
|
+
| `tc.store(path)` | Set persistent data-store directory |
|
|
181
|
+
| `tc.store(ticker, ...)` | Pre-fetch and persist tickers / groups |
|
|
93
182
|
| `tc.chart(...)` | Fetch data and render a chart image |
|
|
94
183
|
| `tc.compare(...)` | Overlay multiple tickers on one chart |
|
|
95
184
|
| `tc.heatmap(...)` | Render a performance heatmap for a ticker group |
|
|
96
185
|
| `tc.data(...)` | Fetch raw OHLCV data as a DataFrame |
|
|
97
186
|
| `tc.export(...)` | Export market data to CSV / JSON / XLSX |
|
|
98
|
-
| `tc.clear_cache()` | Flush
|
|
187
|
+
| `tc.clear_cache(disk=False)` | Flush in-memory cache; optionally wipe disk store |
|
|
99
188
|
| `tc.SECTOR_GROUPS` | Dict of 14 pre-defined ticker lists (sectors, indices, crypto, …) |
|
|
100
189
|
|
|
101
190
|
---
|
|
@@ -205,7 +294,7 @@ Tile sizes use a **squarified treemap** algorithm to minimise wasted space while
|
|
|
205
294
|
|
|
206
295
|
## `tc.SECTOR_GROUPS` — Pre-defined Ticker Lists
|
|
207
296
|
|
|
208
|
-
A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, or `tc.export()`.
|
|
297
|
+
A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, `tc.store()`, or `tc.export()`.
|
|
209
298
|
|
|
210
299
|
```python
|
|
211
300
|
import tradechart as tc
|
|
@@ -370,10 +459,15 @@ The TRADELY logo is stamped in the bottom-left corner of every chart by default.
|
|
|
370
459
|
## `tc.clear_cache()` — Flush Data Cache
|
|
371
460
|
|
|
372
461
|
```python
|
|
373
|
-
tc.clear_cache()
|
|
462
|
+
tc.clear_cache() # flush in-memory cache only
|
|
463
|
+
tc.clear_cache(disk=True) # also wipe all CSVs in tradechart_FetchData/
|
|
374
464
|
```
|
|
375
465
|
|
|
376
|
-
|
|
466
|
+
| Parameter | Type | Default | Description |
|
|
467
|
+
|---|---|---|---|
|
|
468
|
+
| `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. |
|
|
469
|
+
|
|
470
|
+
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
471
|
|
|
378
472
|
---
|
|
379
473
|
|
|
@@ -428,18 +522,22 @@ TradeChart tries providers in priority order and falls back automatically on fai
|
|
|
428
522
|
|
|
429
523
|
| Priority | Provider | Requires | Notes |
|
|
430
524
|
|---|---|---|---|
|
|
431
|
-
|
|
|
525
|
+
| 0 | **Disk store** | `tc.store(path)` called once | Served from local CSV when fresh. When stale, only the missing bars are fetched from a live provider and merged on top — historical rows are never re-requested. |
|
|
526
|
+
| 1 | **yfinance** | Included by default | Primary live source. Covers stocks, ETFs, indices, crypto, forex. |
|
|
432
527
|
| 2 | **TradingView** | `pip install TradeChart[tradingview]` | Tried if yfinance returns empty or fails. Attempts multiple exchanges automatically (`NASDAQ`, `NYSE`, `AMEX`, `CRYPTO`, `FX`). |
|
|
433
528
|
| 3 | **Stooq** | Nothing — free CSV endpoint | Final fallback. No API key required. Duration mapped to a rolling date range. |
|
|
434
529
|
|
|
435
|
-
If all
|
|
530
|
+
If all live providers fail and no disk data exists, a `DataFetchError` is raised with a list of each provider's error message.
|
|
436
531
|
|
|
437
532
|
---
|
|
438
533
|
|
|
439
534
|
## Notes
|
|
440
535
|
|
|
441
|
-
**
|
|
442
|
-
|
|
536
|
+
**Persistent disk store**
|
|
537
|
+
When `tc.store()` is configured, every successful live fetch is written to `tradechart_FetchData/` as a CSV file. On subsequent requests the library checks whether the stored data is fresh enough (based on bar resolution — 24 hours for daily bars, 4 hours for intraday, etc.). If fresh, it is served directly with no network call. If stale, only the most recent bars are fetched from a live provider and merged on top of the stored history — historical rows are never discarded or re-fetched. Use `tc.clear_cache(disk=True)` to wipe stored files and force a full re-fetch.
|
|
538
|
+
|
|
539
|
+
**In-memory caching**
|
|
540
|
+
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
541
|
|
|
444
542
|
**File collision handling**
|
|
445
543
|
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 +569,7 @@ All TradeChart exceptions inherit from `TradeChartError`.
|
|
|
471
569
|
| `InvalidTickerError` | The ticker string fails validation (too long, invalid characters) |
|
|
472
570
|
| `RenderError` | Chart rendering fails (e.g. empty dataset after cleaning) |
|
|
473
571
|
| `OutputError` | The chart cannot be saved (e.g. permission denied) |
|
|
474
|
-
| `ConfigError` | An unknown key is passed to `tc.config()` |
|
|
572
|
+
| `ConfigError` | An unknown key is passed to `tc.config()`, or `tc.store()` is called with tickers before a path is set |
|
|
475
573
|
|
|
476
574
|
```python
|
|
477
575
|
import tradechart as tc
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: TradeChart
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
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
|
|
48
|
+
# TradeChart — Library Edition v2.2.1
|
|
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,93 @@ 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()` uses a three-level lookup before touching the network:
|
|
120
|
+
|
|
121
|
+
1. **In-memory cache** — sub-millisecond, TTL-based (existing behaviour).
|
|
122
|
+
2. **Disk store (fresh)** — if the stored file is younger than the bar-resolution threshold, it is served as-is. No network call.
|
|
123
|
+
3. **Disk store (stale) + live fetch** — if the stored file is older than the threshold, the library fetches the current window from a live provider to get the missing bars, then **merges** those new rows on top of the stored history. Historical bars are never discarded or re-requested. The merged result is written back to disk and served.
|
|
124
|
+
|
|
125
|
+
The staleness threshold matches the resolution of the data so charts are never more than one bar behind:
|
|
126
|
+
|
|
127
|
+
| Duration | Bar resolution | Refreshes after |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| `"1d"`, `"5d"` | 5 / 15-min bars | 4 hours |
|
|
130
|
+
| `"1mo"`, `"3mo"`, `"6mo"` | Daily bars | 24 hours |
|
|
131
|
+
| `"1y"`, `"2y"`, `"5y"` | Weekly bars | 7 days |
|
|
132
|
+
| `"10y"`, `"max"` | Monthly bars | 30 days |
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
tc.store("/data/myproject")
|
|
136
|
+
tc.store("AAPL", "MSFT", "mag7", "3mo") # fetch once, write to disk
|
|
137
|
+
|
|
138
|
+
# Later — same session or a completely new one:
|
|
139
|
+
tc.chart("AAPL", "3mo") # served from disk, no network call
|
|
140
|
+
tc.data("MSFT", "3mo") # same
|
|
141
|
+
|
|
142
|
+
# After 24 hours (daily bars): only the new day's bar is fetched and merged
|
|
143
|
+
# in — the months of stored history are kept and reused as-is
|
|
144
|
+
tc.chart("AAPL", "3mo") # delta fetch + merge, then cached
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Clearing stored data
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
tc.clear_cache() # flush in-memory cache only (default)
|
|
151
|
+
tc.clear_cache(disk=True) # also delete all CSV files in tradechart_FetchData/
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Store folder layout
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
/data/myproject/
|
|
158
|
+
└── tradechart_FetchData/
|
|
159
|
+
├── AAPL_3mo.csv
|
|
160
|
+
├── MSFT_3mo.csv
|
|
161
|
+
├── NVDA_3mo.csv
|
|
162
|
+
└── ...
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
| Parameter | Type | Description |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `*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. |
|
|
168
|
+
| `duration` | `str` (keyword) | Fallback duration when none is provided in `*args`. Default `"1mo"`. |
|
|
169
|
+
|
|
170
|
+
**Returns:** the `tradechart_FetchData/` `Path` when setting the store; `None` when pre-fetching.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
87
174
|
## Ticker Groups — Averaged Series
|
|
88
175
|
|
|
89
176
|
`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 +224,14 @@ If one or more tickers in the group fail to fetch data, they are **skipped with
|
|
|
137
224
|
| `tc.theme(name)` | Set chart colour theme |
|
|
138
225
|
| `tc.watermark(enabled)` | Toggle the TRADELY logo watermark |
|
|
139
226
|
| `tc.config(**kwargs)` | Batch-set multiple global options at once |
|
|
227
|
+
| `tc.store(path)` | Set persistent data-store directory |
|
|
228
|
+
| `tc.store(ticker, ...)` | Pre-fetch and persist tickers / groups |
|
|
140
229
|
| `tc.chart(...)` | Fetch data and render a chart image |
|
|
141
230
|
| `tc.compare(...)` | Overlay multiple tickers on one chart |
|
|
142
231
|
| `tc.heatmap(...)` | Render a performance heatmap for a ticker group |
|
|
143
232
|
| `tc.data(...)` | Fetch raw OHLCV data as a DataFrame |
|
|
144
233
|
| `tc.export(...)` | Export market data to CSV / JSON / XLSX |
|
|
145
|
-
| `tc.clear_cache()` | Flush
|
|
234
|
+
| `tc.clear_cache(disk=False)` | Flush in-memory cache; optionally wipe disk store |
|
|
146
235
|
| `tc.SECTOR_GROUPS` | Dict of 14 pre-defined ticker lists (sectors, indices, crypto, …) |
|
|
147
236
|
|
|
148
237
|
---
|
|
@@ -252,7 +341,7 @@ Tile sizes use a **squarified treemap** algorithm to minimise wasted space while
|
|
|
252
341
|
|
|
253
342
|
## `tc.SECTOR_GROUPS` — Pre-defined Ticker Lists
|
|
254
343
|
|
|
255
|
-
A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, or `tc.export()`.
|
|
344
|
+
A dictionary of curated ticker groups ready to pass into `tc.heatmap()`, `tc.compare()`, `tc.chart()`, `tc.store()`, or `tc.export()`.
|
|
256
345
|
|
|
257
346
|
```python
|
|
258
347
|
import tradechart as tc
|
|
@@ -417,10 +506,15 @@ The TRADELY logo is stamped in the bottom-left corner of every chart by default.
|
|
|
417
506
|
## `tc.clear_cache()` — Flush Data Cache
|
|
418
507
|
|
|
419
508
|
```python
|
|
420
|
-
tc.clear_cache()
|
|
509
|
+
tc.clear_cache() # flush in-memory cache only
|
|
510
|
+
tc.clear_cache(disk=True) # also wipe all CSVs in tradechart_FetchData/
|
|
421
511
|
```
|
|
422
512
|
|
|
423
|
-
|
|
513
|
+
| Parameter | Type | Default | Description |
|
|
514
|
+
|---|---|---|---|
|
|
515
|
+
| `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. |
|
|
516
|
+
|
|
517
|
+
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
518
|
|
|
425
519
|
---
|
|
426
520
|
|
|
@@ -475,18 +569,22 @@ TradeChart tries providers in priority order and falls back automatically on fai
|
|
|
475
569
|
|
|
476
570
|
| Priority | Provider | Requires | Notes |
|
|
477
571
|
|---|---|---|---|
|
|
478
|
-
|
|
|
572
|
+
| 0 | **Disk store** | `tc.store(path)` called once | Served from local CSV when fresh. When stale, only the missing bars are fetched from a live provider and merged on top — historical rows are never re-requested. |
|
|
573
|
+
| 1 | **yfinance** | Included by default | Primary live source. Covers stocks, ETFs, indices, crypto, forex. |
|
|
479
574
|
| 2 | **TradingView** | `pip install TradeChart[tradingview]` | Tried if yfinance returns empty or fails. Attempts multiple exchanges automatically (`NASDAQ`, `NYSE`, `AMEX`, `CRYPTO`, `FX`). |
|
|
480
575
|
| 3 | **Stooq** | Nothing — free CSV endpoint | Final fallback. No API key required. Duration mapped to a rolling date range. |
|
|
481
576
|
|
|
482
|
-
If all
|
|
577
|
+
If all live providers fail and no disk data exists, a `DataFetchError` is raised with a list of each provider's error message.
|
|
483
578
|
|
|
484
579
|
---
|
|
485
580
|
|
|
486
581
|
## Notes
|
|
487
582
|
|
|
488
|
-
**
|
|
489
|
-
|
|
583
|
+
**Persistent disk store**
|
|
584
|
+
When `tc.store()` is configured, every successful live fetch is written to `tradechart_FetchData/` as a CSV file. On subsequent requests the library checks whether the stored data is fresh enough (based on bar resolution — 24 hours for daily bars, 4 hours for intraday, etc.). If fresh, it is served directly with no network call. If stale, only the most recent bars are fetched from a live provider and merged on top of the stored history — historical rows are never discarded or re-fetched. Use `tc.clear_cache(disk=True)` to wipe stored files and force a full re-fetch.
|
|
585
|
+
|
|
586
|
+
**In-memory caching**
|
|
587
|
+
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
588
|
|
|
491
589
|
**File collision handling**
|
|
492
590
|
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 +616,7 @@ All TradeChart exceptions inherit from `TradeChartError`.
|
|
|
518
616
|
| `InvalidTickerError` | The ticker string fails validation (too long, invalid characters) |
|
|
519
617
|
| `RenderError` | Chart rendering fails (e.g. empty dataset after cleaning) |
|
|
520
618
|
| `OutputError` | The chart cannot be saved (e.g. permission denied) |
|
|
521
|
-
| `ConfigError` | An unknown key is passed to `tc.config()` |
|
|
619
|
+
| `ConfigError` | An unknown key is passed to `tc.config()`, or `tc.store()` is called with tickers before a path is set |
|
|
522
620
|
|
|
523
621
|
```python
|
|
524
622
|
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
|
|
7
|
+
version = "2.2.1"
|
|
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"}
|