pyzdata 1.0.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.
- pyzdata-1.0.0/LICENSE +21 -0
- pyzdata-1.0.0/PKG-INFO +286 -0
- pyzdata-1.0.0/README.md +250 -0
- pyzdata-1.0.0/pyproject.toml +77 -0
- pyzdata-1.0.0/pyzdata/__init__.py +42 -0
- pyzdata-1.0.0/pyzdata/_app.py +842 -0
- pyzdata-1.0.0/pyzdata/auth.py +141 -0
- pyzdata-1.0.0/pyzdata/cli.py +164 -0
- pyzdata-1.0.0/pyzdata/client.py +269 -0
- pyzdata-1.0.0/pyzdata/config.py +85 -0
- pyzdata-1.0.0/pyzdata/downloader.py +302 -0
- pyzdata-1.0.0/pyzdata/exceptions.py +34 -0
- pyzdata-1.0.0/pyzdata/instruments.py +161 -0
- pyzdata-1.0.0/pyzdata/models.py +27 -0
- pyzdata-1.0.0/pyzdata/py.typed +0 -0
- pyzdata-1.0.0/pyzdata/run_web.py +44 -0
- pyzdata-1.0.0/pyzdata.egg-info/PKG-INFO +286 -0
- pyzdata-1.0.0/pyzdata.egg-info/SOURCES.txt +26 -0
- pyzdata-1.0.0/pyzdata.egg-info/dependency_links.txt +1 -0
- pyzdata-1.0.0/pyzdata.egg-info/entry_points.txt +3 -0
- pyzdata-1.0.0/pyzdata.egg-info/requires.txt +11 -0
- pyzdata-1.0.0/pyzdata.egg-info/top_level.txt +1 -0
- pyzdata-1.0.0/setup.cfg +4 -0
- pyzdata-1.0.0/tests/test_auth.py +118 -0
- pyzdata-1.0.0/tests/test_cli.py +156 -0
- pyzdata-1.0.0/tests/test_config.py +92 -0
- pyzdata-1.0.0/tests/test_downloader.py +249 -0
- pyzdata-1.0.0/tests/test_instruments.py +163 -0
pyzdata-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Vikas Sharma
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pyzdata-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyzdata
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Historical OHLCV market data downloader for Zerodha (Kite API)
|
|
5
|
+
Author-email: Vikas Sharma <Jnv2252@Gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/vikassharma545/Historical-Market-data-From-Zerodha
|
|
8
|
+
Project-URL: Repository, https://github.com/vikassharma545/Historical-Market-data-From-Zerodha
|
|
9
|
+
Project-URL: Issues, https://github.com/vikassharma545/Historical-Market-data-From-Zerodha/issues
|
|
10
|
+
Keywords: zerodha,kite,market-data,ohlcv,trading,finance,india
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: pandas>=1.3.0
|
|
27
|
+
Requires-Dist: requests>=2.25.0
|
|
28
|
+
Requires-Dist: urllib3>=1.26.0
|
|
29
|
+
Provides-Extra: web
|
|
30
|
+
Requires-Dist: streamlit>=1.20.0; extra == "web"
|
|
31
|
+
Requires-Dist: openpyxl>=3.0.0; extra == "web"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-mock>=3.10; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# PyZData – Zerodha Historical Market Data Downloader
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+

|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
Download historical OHLCV and Open Interest candle data for any stock, index, or F&O instrument from **Zerodha** — as a Python library, a CLI command, or a browser-based web app.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## What you can do with PyZData
|
|
50
|
+
|
|
51
|
+
- Download price history for **any stock or index** listed on Zerodha (NSE, BSE, NFO, MCX)
|
|
52
|
+
- Choose intervals from **1-minute to daily**
|
|
53
|
+
- Export clean **pandas DataFrames** ready for backtesting, charting, or ML
|
|
54
|
+
- Use the **web app** — no coding needed
|
|
55
|
+
- Use the **CLI** — one-liner downloads from the terminal
|
|
56
|
+
- Use the **Python library** — import and integrate into your own scripts
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Web Interface (no coding required)
|
|
61
|
+
|
|
62
|
+
The easiest way to use PyZData is the built-in Streamlit web app.
|
|
63
|
+
|
|
64
|
+
**Run it:**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install "git+https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git#egg=pyzdata[web]"
|
|
68
|
+
pyzdata-web
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then open `http://localhost:8501` in your browser.
|
|
72
|
+
|
|
73
|
+
**Features:**
|
|
74
|
+
- Click popular stocks (NIFTY 50, RELIANCE, TCS, HDFC Bank …) — no typing needed
|
|
75
|
+
- Quick date presets: Last Week, Last Month, Last Year, Last 3 Years …
|
|
76
|
+
- Plain-English frequency selector with descriptions
|
|
77
|
+
- Download result as **CSV** or **Excel (.xlsx)**
|
|
78
|
+
- Built-in Help tab with step-by-step guides
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Installation
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Library only (Python API + CLI)
|
|
86
|
+
pip install git+https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git
|
|
87
|
+
|
|
88
|
+
# Library + web interface (adds streamlit and openpyxl)
|
|
89
|
+
pip install "git+https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git#egg=pyzdata[web]"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Requirements:** Python 3.8+, pandas ≥ 1.3, requests ≥ 2.25
|
|
93
|
+
|
|
94
|
+
For development:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
git clone https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git
|
|
98
|
+
cd Historical-Market-data-From-Zerodha
|
|
99
|
+
pip install -e ".[web,dev]"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Python Library
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from pyzdata import PyZData, Interval
|
|
108
|
+
|
|
109
|
+
# Login with enctoken (paste from browser cookies after logging into kite.zerodha.com)
|
|
110
|
+
client = PyZData(enctoken="your_enctoken_here")
|
|
111
|
+
|
|
112
|
+
# OR login with credentials
|
|
113
|
+
client = PyZData(user_id="AB1234", password="your_password", totp="123456")
|
|
114
|
+
|
|
115
|
+
# Find the instrument token for a symbol
|
|
116
|
+
token = client.get_instrument_token("NIFTY 50", "NSE")
|
|
117
|
+
|
|
118
|
+
# Not sure of the exact symbol name? Search for it
|
|
119
|
+
results = client.search_instruments("NIFTY", exchange="NSE")
|
|
120
|
+
print(results[["tradingsymbol", "instrument_token", "exchange"]])
|
|
121
|
+
|
|
122
|
+
# Download daily candles for a full year
|
|
123
|
+
df = client.get_data(token, "2024-01-01", "2024-12-31", Interval.DAY)
|
|
124
|
+
print(df.head())
|
|
125
|
+
|
|
126
|
+
# Download 1-minute candles with Open Interest (F&O instruments)
|
|
127
|
+
fut_token = client.get_instrument_token("NIFTY24JANFUT", "NFO")
|
|
128
|
+
df = client.get_data(fut_token, "2024-01-02", "2024-01-25", Interval.MINUTE_1, oi=True)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Output columns:** `tradingsymbol, datetime, open, high, low, close, volume` (+ `open_interest` when `oi=True`)
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## CLI
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Daily data for NIFTY 50 — print to terminal
|
|
139
|
+
pyzdata download --enctoken TOKEN --symbol "NIFTY 50" --exchange NSE \
|
|
140
|
+
--start 2024-01-01 --end 2024-12-31
|
|
141
|
+
|
|
142
|
+
# 1-minute data — save to CSV
|
|
143
|
+
pyzdata download --enctoken TOKEN --symbol RELIANCE --exchange NSE \
|
|
144
|
+
--start 2024-01-01 --end 2024-06-30 \
|
|
145
|
+
--interval minute --output reliance.csv
|
|
146
|
+
|
|
147
|
+
# Login with credentials
|
|
148
|
+
pyzdata download --user-id AB1234 --password pw --totp 123456 \
|
|
149
|
+
--symbol RELIANCE --exchange NSE \
|
|
150
|
+
--start 2024-01-01 --end 2024-01-31
|
|
151
|
+
|
|
152
|
+
# Search for a symbol
|
|
153
|
+
pyzdata search --enctoken TOKEN --query HDFC --exchange NSE
|
|
154
|
+
|
|
155
|
+
# All options
|
|
156
|
+
pyzdata download --help
|
|
157
|
+
pyzdata search --help
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Available Intervals
|
|
163
|
+
|
|
164
|
+
| Enum | Interval | Best for |
|
|
165
|
+
|------|----------|----------|
|
|
166
|
+
| `Interval.MINUTE_1` | 1 minute | Intraday scalping analysis |
|
|
167
|
+
| `Interval.MINUTE_5` | 5 minutes | Intraday charts |
|
|
168
|
+
| `Interval.MINUTE_15` | 15 minutes | Intraday / short-term |
|
|
169
|
+
| `Interval.MINUTE_30` | 30 minutes | Swing trading |
|
|
170
|
+
| `Interval.HOUR_1` | 1 hour | Swing / positional |
|
|
171
|
+
| `Interval.DAY` | Daily | Long-term investing & backtesting |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Configuration
|
|
176
|
+
|
|
177
|
+
Copy `.env.example` to `.env` and set any values you want to override:
|
|
178
|
+
|
|
179
|
+
| Variable | Default | Description |
|
|
180
|
+
|----------|---------|-------------|
|
|
181
|
+
| `PYZDATA_MAX_WORKERS` | `4` | Parallel download threads |
|
|
182
|
+
| `PYZDATA_MAX_RETRIES` | `5` | Retry attempts on failures |
|
|
183
|
+
| `PYZDATA_TIMEOUT` | `30` | HTTP timeout in seconds |
|
|
184
|
+
| `PYZDATA_CACHE_TTL_HOURS` | `24` | How long to cache the instruments list |
|
|
185
|
+
| `PYZDATA_LOG_LEVEL` | `WARNING` | `DEBUG` / `INFO` / `WARNING` / `ERROR` |
|
|
186
|
+
|
|
187
|
+
Or pass a `Config` object in code:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from pyzdata import Config, PyZData
|
|
191
|
+
|
|
192
|
+
cfg = Config(max_workers=8, log_level="DEBUG")
|
|
193
|
+
client = PyZData(enctoken="...", config=cfg)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Error Handling
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from pyzdata.exceptions import (
|
|
202
|
+
AuthenticationError, # wrong credentials or expired enctoken
|
|
203
|
+
InstrumentNotFoundError, # symbol not found
|
|
204
|
+
DataFetchError, # API or network failure
|
|
205
|
+
PyZDataError, # catch-all base class
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
try:
|
|
209
|
+
client = PyZData(enctoken="...")
|
|
210
|
+
token = client.get_instrument_token("RELIANCE", "NSE")
|
|
211
|
+
df = client.get_data(token, "2024-01-01", "2024-12-31", Interval.DAY)
|
|
212
|
+
except AuthenticationError as e:
|
|
213
|
+
print(f"Login failed: {e}")
|
|
214
|
+
except InstrumentNotFoundError as e:
|
|
215
|
+
print(f"Symbol not found: {e}")
|
|
216
|
+
except DataFetchError as e:
|
|
217
|
+
print(f"Download failed: {e}")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Project Structure
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
pyzdata/
|
|
226
|
+
├── client.py PyZData — main entry point
|
|
227
|
+
├── auth.py Two-step Zerodha login
|
|
228
|
+
├── instruments.py Symbol lookup with 24-hour disk cache
|
|
229
|
+
├── downloader.py Parallel monthly data fetching
|
|
230
|
+
├── models.py Interval enum
|
|
231
|
+
├── config.py Settings + environment variable loading
|
|
232
|
+
├── exceptions.py Typed exception hierarchy
|
|
233
|
+
├── cli.py pyzdata command-line tool
|
|
234
|
+
├── _app.py Streamlit web interface
|
|
235
|
+
└── py.typed PEP 561 type-checking marker
|
|
236
|
+
|
|
237
|
+
app.py Local dev launcher for Streamlit
|
|
238
|
+
tests/ Unit tests (no credentials needed)
|
|
239
|
+
CONTRIBUTING.md How to contribute
|
|
240
|
+
CHANGELOG.md Release history
|
|
241
|
+
SECURITY.md Security policy
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Running Tests
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
pip install -e ".[dev]"
|
|
250
|
+
pytest
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
No Zerodha account or internet connection needed — all HTTP calls are mocked.
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## How to get your enctoken
|
|
258
|
+
|
|
259
|
+
1. Log in to [kite.zerodha.com](https://kite.zerodha.com)
|
|
260
|
+
2. Press **F12** → **Application** tab → **Cookies** → `kite.zerodha.com`
|
|
261
|
+
3. Copy the value of the `enctoken` cookie
|
|
262
|
+
4. Paste it into the app or pass it as `PyZData(enctoken="...")`
|
|
263
|
+
|
|
264
|
+
The enctoken refreshes each time you log in to Kite.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
MIT — see [LICENSE](LICENSE)
|
|
271
|
+
|
|
272
|
+
## Contributing
|
|
273
|
+
|
|
274
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
275
|
+
|
|
276
|
+
## Changelog
|
|
277
|
+
|
|
278
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full release history.
|
|
279
|
+
|
|
280
|
+
## Security
|
|
281
|
+
|
|
282
|
+
To report a vulnerability, see [SECURITY.md](SECURITY.md).
|
|
283
|
+
|
|
284
|
+
## Author
|
|
285
|
+
|
|
286
|
+
Built by [Vikas Sharma](https://github.com/vikassharma545)
|
pyzdata-1.0.0/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# PyZData – Zerodha Historical Market Data Downloader
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
Download historical OHLCV and Open Interest candle data for any stock, index, or F&O instrument from **Zerodha** — as a Python library, a CLI command, or a browser-based web app.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What you can do with PyZData
|
|
14
|
+
|
|
15
|
+
- Download price history for **any stock or index** listed on Zerodha (NSE, BSE, NFO, MCX)
|
|
16
|
+
- Choose intervals from **1-minute to daily**
|
|
17
|
+
- Export clean **pandas DataFrames** ready for backtesting, charting, or ML
|
|
18
|
+
- Use the **web app** — no coding needed
|
|
19
|
+
- Use the **CLI** — one-liner downloads from the terminal
|
|
20
|
+
- Use the **Python library** — import and integrate into your own scripts
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Web Interface (no coding required)
|
|
25
|
+
|
|
26
|
+
The easiest way to use PyZData is the built-in Streamlit web app.
|
|
27
|
+
|
|
28
|
+
**Run it:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install "git+https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git#egg=pyzdata[web]"
|
|
32
|
+
pyzdata-web
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Then open `http://localhost:8501` in your browser.
|
|
36
|
+
|
|
37
|
+
**Features:**
|
|
38
|
+
- Click popular stocks (NIFTY 50, RELIANCE, TCS, HDFC Bank …) — no typing needed
|
|
39
|
+
- Quick date presets: Last Week, Last Month, Last Year, Last 3 Years …
|
|
40
|
+
- Plain-English frequency selector with descriptions
|
|
41
|
+
- Download result as **CSV** or **Excel (.xlsx)**
|
|
42
|
+
- Built-in Help tab with step-by-step guides
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Library only (Python API + CLI)
|
|
50
|
+
pip install git+https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git
|
|
51
|
+
|
|
52
|
+
# Library + web interface (adds streamlit and openpyxl)
|
|
53
|
+
pip install "git+https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git#egg=pyzdata[web]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Requirements:** Python 3.8+, pandas ≥ 1.3, requests ≥ 2.25
|
|
57
|
+
|
|
58
|
+
For development:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/vikassharma545/Historical-Market-data-From-Zerodha.git
|
|
62
|
+
cd Historical-Market-data-From-Zerodha
|
|
63
|
+
pip install -e ".[web,dev]"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Python Library
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from pyzdata import PyZData, Interval
|
|
72
|
+
|
|
73
|
+
# Login with enctoken (paste from browser cookies after logging into kite.zerodha.com)
|
|
74
|
+
client = PyZData(enctoken="your_enctoken_here")
|
|
75
|
+
|
|
76
|
+
# OR login with credentials
|
|
77
|
+
client = PyZData(user_id="AB1234", password="your_password", totp="123456")
|
|
78
|
+
|
|
79
|
+
# Find the instrument token for a symbol
|
|
80
|
+
token = client.get_instrument_token("NIFTY 50", "NSE")
|
|
81
|
+
|
|
82
|
+
# Not sure of the exact symbol name? Search for it
|
|
83
|
+
results = client.search_instruments("NIFTY", exchange="NSE")
|
|
84
|
+
print(results[["tradingsymbol", "instrument_token", "exchange"]])
|
|
85
|
+
|
|
86
|
+
# Download daily candles for a full year
|
|
87
|
+
df = client.get_data(token, "2024-01-01", "2024-12-31", Interval.DAY)
|
|
88
|
+
print(df.head())
|
|
89
|
+
|
|
90
|
+
# Download 1-minute candles with Open Interest (F&O instruments)
|
|
91
|
+
fut_token = client.get_instrument_token("NIFTY24JANFUT", "NFO")
|
|
92
|
+
df = client.get_data(fut_token, "2024-01-02", "2024-01-25", Interval.MINUTE_1, oi=True)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Output columns:** `tradingsymbol, datetime, open, high, low, close, volume` (+ `open_interest` when `oi=True`)
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## CLI
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Daily data for NIFTY 50 — print to terminal
|
|
103
|
+
pyzdata download --enctoken TOKEN --symbol "NIFTY 50" --exchange NSE \
|
|
104
|
+
--start 2024-01-01 --end 2024-12-31
|
|
105
|
+
|
|
106
|
+
# 1-minute data — save to CSV
|
|
107
|
+
pyzdata download --enctoken TOKEN --symbol RELIANCE --exchange NSE \
|
|
108
|
+
--start 2024-01-01 --end 2024-06-30 \
|
|
109
|
+
--interval minute --output reliance.csv
|
|
110
|
+
|
|
111
|
+
# Login with credentials
|
|
112
|
+
pyzdata download --user-id AB1234 --password pw --totp 123456 \
|
|
113
|
+
--symbol RELIANCE --exchange NSE \
|
|
114
|
+
--start 2024-01-01 --end 2024-01-31
|
|
115
|
+
|
|
116
|
+
# Search for a symbol
|
|
117
|
+
pyzdata search --enctoken TOKEN --query HDFC --exchange NSE
|
|
118
|
+
|
|
119
|
+
# All options
|
|
120
|
+
pyzdata download --help
|
|
121
|
+
pyzdata search --help
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Available Intervals
|
|
127
|
+
|
|
128
|
+
| Enum | Interval | Best for |
|
|
129
|
+
|------|----------|----------|
|
|
130
|
+
| `Interval.MINUTE_1` | 1 minute | Intraday scalping analysis |
|
|
131
|
+
| `Interval.MINUTE_5` | 5 minutes | Intraday charts |
|
|
132
|
+
| `Interval.MINUTE_15` | 15 minutes | Intraday / short-term |
|
|
133
|
+
| `Interval.MINUTE_30` | 30 minutes | Swing trading |
|
|
134
|
+
| `Interval.HOUR_1` | 1 hour | Swing / positional |
|
|
135
|
+
| `Interval.DAY` | Daily | Long-term investing & backtesting |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Configuration
|
|
140
|
+
|
|
141
|
+
Copy `.env.example` to `.env` and set any values you want to override:
|
|
142
|
+
|
|
143
|
+
| Variable | Default | Description |
|
|
144
|
+
|----------|---------|-------------|
|
|
145
|
+
| `PYZDATA_MAX_WORKERS` | `4` | Parallel download threads |
|
|
146
|
+
| `PYZDATA_MAX_RETRIES` | `5` | Retry attempts on failures |
|
|
147
|
+
| `PYZDATA_TIMEOUT` | `30` | HTTP timeout in seconds |
|
|
148
|
+
| `PYZDATA_CACHE_TTL_HOURS` | `24` | How long to cache the instruments list |
|
|
149
|
+
| `PYZDATA_LOG_LEVEL` | `WARNING` | `DEBUG` / `INFO` / `WARNING` / `ERROR` |
|
|
150
|
+
|
|
151
|
+
Or pass a `Config` object in code:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from pyzdata import Config, PyZData
|
|
155
|
+
|
|
156
|
+
cfg = Config(max_workers=8, log_level="DEBUG")
|
|
157
|
+
client = PyZData(enctoken="...", config=cfg)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Error Handling
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from pyzdata.exceptions import (
|
|
166
|
+
AuthenticationError, # wrong credentials or expired enctoken
|
|
167
|
+
InstrumentNotFoundError, # symbol not found
|
|
168
|
+
DataFetchError, # API or network failure
|
|
169
|
+
PyZDataError, # catch-all base class
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
client = PyZData(enctoken="...")
|
|
174
|
+
token = client.get_instrument_token("RELIANCE", "NSE")
|
|
175
|
+
df = client.get_data(token, "2024-01-01", "2024-12-31", Interval.DAY)
|
|
176
|
+
except AuthenticationError as e:
|
|
177
|
+
print(f"Login failed: {e}")
|
|
178
|
+
except InstrumentNotFoundError as e:
|
|
179
|
+
print(f"Symbol not found: {e}")
|
|
180
|
+
except DataFetchError as e:
|
|
181
|
+
print(f"Download failed: {e}")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Project Structure
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
pyzdata/
|
|
190
|
+
├── client.py PyZData — main entry point
|
|
191
|
+
├── auth.py Two-step Zerodha login
|
|
192
|
+
├── instruments.py Symbol lookup with 24-hour disk cache
|
|
193
|
+
├── downloader.py Parallel monthly data fetching
|
|
194
|
+
├── models.py Interval enum
|
|
195
|
+
├── config.py Settings + environment variable loading
|
|
196
|
+
├── exceptions.py Typed exception hierarchy
|
|
197
|
+
├── cli.py pyzdata command-line tool
|
|
198
|
+
├── _app.py Streamlit web interface
|
|
199
|
+
└── py.typed PEP 561 type-checking marker
|
|
200
|
+
|
|
201
|
+
app.py Local dev launcher for Streamlit
|
|
202
|
+
tests/ Unit tests (no credentials needed)
|
|
203
|
+
CONTRIBUTING.md How to contribute
|
|
204
|
+
CHANGELOG.md Release history
|
|
205
|
+
SECURITY.md Security policy
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Running Tests
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
pip install -e ".[dev]"
|
|
214
|
+
pytest
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
No Zerodha account or internet connection needed — all HTTP calls are mocked.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## How to get your enctoken
|
|
222
|
+
|
|
223
|
+
1. Log in to [kite.zerodha.com](https://kite.zerodha.com)
|
|
224
|
+
2. Press **F12** → **Application** tab → **Cookies** → `kite.zerodha.com`
|
|
225
|
+
3. Copy the value of the `enctoken` cookie
|
|
226
|
+
4. Paste it into the app or pass it as `PyZData(enctoken="...")`
|
|
227
|
+
|
|
228
|
+
The enctoken refreshes each time you log in to Kite.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
MIT — see [LICENSE](LICENSE)
|
|
235
|
+
|
|
236
|
+
## Contributing
|
|
237
|
+
|
|
238
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
239
|
+
|
|
240
|
+
## Changelog
|
|
241
|
+
|
|
242
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full release history.
|
|
243
|
+
|
|
244
|
+
## Security
|
|
245
|
+
|
|
246
|
+
To report a vulnerability, see [SECURITY.md](SECURITY.md).
|
|
247
|
+
|
|
248
|
+
## Author
|
|
249
|
+
|
|
250
|
+
Built by [Vikas Sharma](https://github.com/vikassharma545)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pyzdata"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Historical OHLCV market data downloader for Zerodha (Kite API)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Vikas Sharma", email = "Jnv2252@Gmail.com" }
|
|
13
|
+
]
|
|
14
|
+
requires-python = ">=3.8"
|
|
15
|
+
keywords = ["zerodha", "kite", "market-data", "ohlcv", "trading", "finance", "india"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 5 - Production/Stable",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Topic :: Office/Business :: Financial :: Investment",
|
|
28
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
29
|
+
]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"pandas>=1.3.0",
|
|
32
|
+
"requests>=2.25.0",
|
|
33
|
+
"urllib3>=1.26.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
# Web interface: pip install "pyzdata[web]"
|
|
38
|
+
web = [
|
|
39
|
+
"streamlit>=1.20.0",
|
|
40
|
+
"openpyxl>=3.0.0",
|
|
41
|
+
]
|
|
42
|
+
# Development / testing: pip install "pyzdata[dev]"
|
|
43
|
+
dev = [
|
|
44
|
+
"pytest>=7.0",
|
|
45
|
+
"pytest-mock>=3.10",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://github.com/vikassharma545/Historical-Market-data-From-Zerodha"
|
|
50
|
+
Repository = "https://github.com/vikassharma545/Historical-Market-data-From-Zerodha"
|
|
51
|
+
Issues = "https://github.com/vikassharma545/Historical-Market-data-From-Zerodha/issues"
|
|
52
|
+
|
|
53
|
+
[project.scripts]
|
|
54
|
+
pyzdata = "pyzdata.cli:main"
|
|
55
|
+
pyzdata-web = "pyzdata.run_web:main"
|
|
56
|
+
|
|
57
|
+
[tool.setuptools.packages.find]
|
|
58
|
+
where = ["."]
|
|
59
|
+
include = ["pyzdata*"]
|
|
60
|
+
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
# pytest
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
[tool.pytest.ini_options]
|
|
65
|
+
testpaths = ["tests"]
|
|
66
|
+
addopts = "-v --tb=short"
|
|
67
|
+
|
|
68
|
+
# ---------------------------------------------------------------------------
|
|
69
|
+
# ruff (optional linting — install with: pip install ruff)
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
[tool.ruff]
|
|
72
|
+
line-length = 100
|
|
73
|
+
target-version = "py38"
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint]
|
|
76
|
+
select = ["E", "F", "W", "I"]
|
|
77
|
+
ignore = ["E501"]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""PyZData – Zerodha historical market data downloader.
|
|
2
|
+
|
|
3
|
+
Quick start::
|
|
4
|
+
|
|
5
|
+
from pyzdata import PyZData, Interval
|
|
6
|
+
|
|
7
|
+
client = PyZData(enctoken="your_enctoken")
|
|
8
|
+
|
|
9
|
+
token = client.get_instrument_token("NIFTY 50", "NSE")
|
|
10
|
+
df = client.get_data(token, "2024-01-01", "2024-12-31", Interval.DAY)
|
|
11
|
+
print(df.head())
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from .client import PyZData
|
|
15
|
+
from .config import Config
|
|
16
|
+
from .exceptions import (
|
|
17
|
+
AuthenticationError,
|
|
18
|
+
ConfigurationError,
|
|
19
|
+
DataFetchError,
|
|
20
|
+
InstrumentNotFoundError,
|
|
21
|
+
PyZDataError,
|
|
22
|
+
)
|
|
23
|
+
from .models import Interval
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"PyZData",
|
|
27
|
+
"Interval",
|
|
28
|
+
"Config",
|
|
29
|
+
# Exceptions — exported so callers can write `except pyzdata.DataFetchError`
|
|
30
|
+
"PyZDataError",
|
|
31
|
+
"AuthenticationError",
|
|
32
|
+
"InstrumentNotFoundError",
|
|
33
|
+
"DataFetchError",
|
|
34
|
+
"ConfigurationError",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
from importlib.metadata import version as _pkg_version
|
|
39
|
+
|
|
40
|
+
__version__ = _pkg_version("pyzdata")
|
|
41
|
+
except Exception: # package not installed (editable / dev checkout)
|
|
42
|
+
__version__ = "0.0.0-dev"
|