yfinance-ir 2026.9.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yfinance_ir-2026.9.2/LICENSE +21 -0
- yfinance_ir-2026.9.2/PKG-INFO +265 -0
- yfinance_ir-2026.9.2/README.md +218 -0
- yfinance_ir-2026.9.2/pyproject.toml +75 -0
- yfinance_ir-2026.9.2/setup.cfg +4 -0
- yfinance_ir-2026.9.2/tests/test_crypto.py +162 -0
- yfinance_ir-2026.9.2/tests/test_fundamentals.py +163 -0
- yfinance_ir-2026.9.2/tests/test_history.py +218 -0
- yfinance_ir-2026.9.2/tests/test_http.py +70 -0
- yfinance_ir-2026.9.2/tests/test_intraday.py +258 -0
- yfinance_ir-2026.9.2/tests/test_live.py +155 -0
- yfinance_ir-2026.9.2/tests/test_multi.py +86 -0
- yfinance_ir-2026.9.2/tests/test_options.py +119 -0
- yfinance_ir-2026.9.2/tests/test_resolver.py +94 -0
- yfinance_ir-2026.9.2/tests/test_sci.py +188 -0
- yfinance_ir-2026.9.2/yfinance_ir/__init__.py +44 -0
- yfinance_ir-2026.9.2/yfinance_ir/_cache.py +114 -0
- yfinance_ir-2026.9.2/yfinance_ir/_dates.py +99 -0
- yfinance_ir-2026.9.2/yfinance_ir/_http.py +132 -0
- yfinance_ir-2026.9.2/yfinance_ir/config.py +51 -0
- yfinance_ir-2026.9.2/yfinance_ir/exceptions.py +38 -0
- yfinance_ir-2026.9.2/yfinance_ir/fundamentals.py +219 -0
- yfinance_ir-2026.9.2/yfinance_ir/history.py +435 -0
- yfinance_ir-2026.9.2/yfinance_ir/intraday.py +255 -0
- yfinance_ir-2026.9.2/yfinance_ir/multi.py +112 -0
- yfinance_ir-2026.9.2/yfinance_ir/py.typed +0 -0
- yfinance_ir-2026.9.2/yfinance_ir/resolver.py +263 -0
- yfinance_ir-2026.9.2/yfinance_ir/search.py +51 -0
- yfinance_ir-2026.9.2/yfinance_ir/sources/__init__.py +1 -0
- yfinance_ir-2026.9.2/yfinance_ir/sources/codal.py +119 -0
- yfinance_ir-2026.9.2/yfinance_ir/sources/crypto.py +211 -0
- yfinance_ir-2026.9.2/yfinance_ir/sources/sci.py +215 -0
- yfinance_ir-2026.9.2/yfinance_ir/sources/tgju.py +139 -0
- yfinance_ir-2026.9.2/yfinance_ir/sources/tsetmc.py +182 -0
- yfinance_ir-2026.9.2/yfinance_ir/ticker.py +569 -0
- yfinance_ir-2026.9.2/yfinance_ir.egg-info/PKG-INFO +265 -0
- yfinance_ir-2026.9.2/yfinance_ir.egg-info/SOURCES.txt +38 -0
- yfinance_ir-2026.9.2/yfinance_ir.egg-info/dependency_links.txt +1 -0
- yfinance_ir-2026.9.2/yfinance_ir.egg-info/requires.txt +24 -0
- yfinance_ir-2026.9.2/yfinance_ir.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kiyarash Fazeli
|
|
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.
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yfinance-ir
|
|
3
|
+
Version: 2026.9.2
|
|
4
|
+
Summary: yfinance-style market data for Iranian markets (TSETMC, Codal, TGJU)
|
|
5
|
+
Author-email: Kiyarash Fazeli <caci96@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Fazel94/yfinance-ir
|
|
8
|
+
Project-URL: Repository, https://github.com/Fazel94/yfinance-ir
|
|
9
|
+
Project-URL: Issues, https://github.com/Fazel94/yfinance-ir/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/Fazel94/yfinance-ir/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: tsetmc,codal,tgju,iran,bourse,stocks,finance
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: requests>=2.28
|
|
26
|
+
Requires-Dist: pandas>=1.5
|
|
27
|
+
Requires-Dist: numpy>=1.21
|
|
28
|
+
Requires-Dist: jdatetime>=4
|
|
29
|
+
Requires-Dist: openpyxl>=3.1
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest; extra == "dev"
|
|
32
|
+
Requires-Dist: responses; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff; extra == "dev"
|
|
34
|
+
Provides-Extra: crypto
|
|
35
|
+
Requires-Dist: ccxt-ir>=4; extra == "crypto"
|
|
36
|
+
Provides-Extra: notebook
|
|
37
|
+
Requires-Dist: matplotlib>=3.8; extra == "notebook"
|
|
38
|
+
Requires-Dist: seaborn>=0.13; extra == "notebook"
|
|
39
|
+
Requires-Dist: scipy>=1.11; extra == "notebook"
|
|
40
|
+
Requires-Dist: statsmodels>=0.14; extra == "notebook"
|
|
41
|
+
Requires-Dist: backtrader>=1.9.78; extra == "notebook"
|
|
42
|
+
Requires-Dist: ipykernel; extra == "notebook"
|
|
43
|
+
Requires-Dist: nbconvert; extra == "notebook"
|
|
44
|
+
Requires-Dist: arabic-reshaper>=3.0; extra == "notebook"
|
|
45
|
+
Requires-Dist: python-bidi>=0.6; extra == "notebook"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# yfinance-ir
|
|
49
|
+
|
|
50
|
+
[](https://github.com/Fazel94/yfinance-ir/actions/workflows/ci.yml)
|
|
51
|
+

|
|
52
|
+
[](LICENSE)
|
|
53
|
+
|
|
54
|
+
[فارسی](README.fa.md)
|
|
55
|
+
|
|
56
|
+
<div dir="rtl">
|
|
57
|
+
|
|
58
|
+
دادههای بازار ایران با رابط آشنای `yfinance`: سهام، صندوقها و شاخصهای بورس تهران (TSETMC)،
|
|
59
|
+
صورتهای مالی کدال، دلار، طلا و سکه از TGJU، تورم مرکز آمار ایران و رمزارزها از صرافیهای ایرانی.
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
`yfinance`-shaped market data for the Iranian markets: TSETMC (equities, ETFs, indices),
|
|
64
|
+
Codal (financial statements), TGJU (FX, gold, coins), the Statistical Centre of Iran (CPI)
|
|
65
|
+
and, with the `crypto` extra, Iranian crypto exchanges through `ccxt-ir`.
|
|
66
|
+
|
|
67
|
+
> **Iranian IP required.** `cdn.tsetmc.com` drops foreign IPs.
|
|
68
|
+
|
|
69
|
+
[](examples/scoreboard.ipynb)
|
|
70
|
+
|
|
71
|
+
One `history()` call per bar: TSETMC indices, stocks and ETFs, TGJU's dollar, euro, gold
|
|
72
|
+
and coin, Nobitex bitcoin, measured against the SCI CPI and the free-market dollar.
|
|
73
|
+
[`examples/scoreboard.ipynb`](examples/scoreboard.ipynb) draws it, the same race as a
|
|
74
|
+
path since Nowruz and over five years, and a seven-window heatmap of real and dollar
|
|
75
|
+
returns. Charts are in Persian; install from `main` for its two text-shaping extras:
|
|
76
|
+
`pip install "yfinance-ir[crypto,notebook] @ git+https://github.com/Fazel94/yfinance-ir.git"`.
|
|
77
|
+
|
|
78
|
+
Monthly update of this chart: X [@_fazel94](https://x.com/_fazel94)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## Install
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install "yfinance-ir @ git+https://github.com/Fazel94/yfinance-ir.git@v2026.9.2" # TSETMC + Codal + TGJU + CPI
|
|
85
|
+
pip install "yfinance-ir[crypto] @ git+https://github.com/Fazel94/yfinance-ir.git@v2026.9.2" # adds BTC-IRT / ETH-USDT style pairs
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Not on PyPI yet: install from a release tag. Each [GitHub Release](https://github.com/Fazel94/yfinance-ir/releases) also carries the wheel and sdist.
|
|
89
|
+
|
|
90
|
+
## Quickstart
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import yfinance_ir as yf
|
|
94
|
+
|
|
95
|
+
folad = yf.Ticker("فولاد")
|
|
96
|
+
folad.history(period="1y") # adjusted daily OHLCV
|
|
97
|
+
folad.history(period="5d", interval="5m") # intraday bars rebuilt from TSETMC trades
|
|
98
|
+
folad.info["marketCap"]
|
|
99
|
+
folad.income_stmt # Codal, wide, newest period first
|
|
100
|
+
folad.cashflow # Codal cash-flow statement
|
|
101
|
+
yf.Ticker("اهرم").option_chain() # nearest expiration: calls, puts, underlying
|
|
102
|
+
|
|
103
|
+
yf.download(["فولاد", "فملی"], period="6mo")
|
|
104
|
+
yf.Ticker("USD").history(period="5y") # TGJU dollar, Rial
|
|
105
|
+
yf.Ticker("شاخص کل").history() # TEDPIX
|
|
106
|
+
yf.Ticker("CPI").history() # SCI consumer price index, monthly
|
|
107
|
+
yf.Ticker("BTC-IRT").history() # Nobitex, needs the `crypto` extra
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Example: فولاد in Rial, USD and real terms
|
|
111
|
+
|
|
112
|
+
[`examples/real_returns.py`](examples/real_returns.py) prices فولاد in TGJU dollars and
|
|
113
|
+
deflates it by the SCI CPI. Both series are forward-filled onto the stock's trading days.
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
import pandas as pd
|
|
117
|
+
|
|
118
|
+
folad = yf.Ticker("فولاد").history(period="5y")["Close"]
|
|
119
|
+
usd = yf.Ticker("USD").history(period="5y")["Close"].reindex(folad.index, method="ffill")
|
|
120
|
+
cpi = yf.Ticker("CPI").history(period="5y")["Close"].reindex(folad.index, method="ffill")
|
|
121
|
+
|
|
122
|
+
frame = pd.DataFrame({"Rial": folad, "USD": folad / usd, "Real": folad / cpi * cpi.iloc[-1]})
|
|
123
|
+
print(frame.iloc[-1] / frame.iloc[0] - 1)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Output on 2026-09-21:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
فولاد 2021-09-25 -> 2026-09-21 (5.0y)
|
|
130
|
+
total annualised
|
|
131
|
+
Rial +228.1% +26.9%
|
|
132
|
+
USD -60.8% -17.1%
|
|
133
|
+
Real -52.0% -13.7%
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
[examples/cookbook.ipynb](examples/cookbook.ipynb) runs the recipes of chapters 1, 2 and 7
|
|
137
|
+
of *Python for Finance Cookbook* (returns, CPI deflation, outliers, stylised facts,
|
|
138
|
+
SMA/Bollinger/RSI backtests with backtrader, 1/n portfolio, Monte Carlo efficient frontier)
|
|
139
|
+
on TSETMC stocks and Nobitex crypto pairs. Install its dependencies with
|
|
140
|
+
`pip install "yfinance-ir[crypto,notebook] @ git+https://github.com/Fazel94/yfinance-ir.git@v2026.9.2"`.
|
|
141
|
+
|
|
142
|
+
## Symbols
|
|
143
|
+
|
|
144
|
+
| You pass | Resolves to | Example |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| Persian symbol | TSETMC instrument | `Ticker("فولاد")`, `Ticker("اهرم")` |
|
|
147
|
+
| Persian index name | TSETMC index | `Ticker("شاخص کل")` |
|
|
148
|
+
| InsCode (10–20 digits) | TSETMC instrument | `Ticker("46348559193224090")` |
|
|
149
|
+
| TGJU alias or slug | FX / gold / coin | `Ticker("USD")`, `Ticker("geram18")` |
|
|
150
|
+
| `CPI`, `CPI_URBAN`, `CPI_RURAL` | SCI price index | `Ticker("CPI")` |
|
|
151
|
+
| `BASE-IRT` / `BASE-USDT` | crypto pair | `Ticker("BTC-IRT")` |
|
|
152
|
+
| ISIN | cache lookup only, see below | `Ticker("IRO1FOLD0009")` |
|
|
153
|
+
|
|
154
|
+
Persian and Arabic spellings are unified (`ی`/`ي`, `ک`/`ك`, ZWNJ). TGJU aliases and the
|
|
155
|
+
per-source rules are in [docs/data-sources.md](docs/data-sources.md). Resolutions are cached
|
|
156
|
+
in `~/.cache/yfinance_ir/symbols.sqlite`; `yf.cache.clear()` drops them,
|
|
157
|
+
`yf.set_config(cache_dir=...)` moves them.
|
|
158
|
+
|
|
159
|
+
## Ticker API
|
|
160
|
+
|
|
161
|
+
| Member | Source | Notes |
|
|
162
|
+
|---|---|---|
|
|
163
|
+
| `history(...)` | TSETMC / TGJU / SCI / crypto | daily OHLCV (monthly for CPI), adjusted by default; TSETMC also `1m`–`90m` and `1h` bars rebuilt from trades |
|
|
164
|
+
| `info` | TSETMC | yfinance-style keys: `marketCap`, `trailingPE`, `sharesOutstanding`, … |
|
|
165
|
+
| `dividends`, `splits`, `actions` | TSETMC adjust + share-change | see docs/conventions.md |
|
|
166
|
+
| `orderbook` | TSETMC / exchange | 5 levels, bid/ask price-volume-count |
|
|
167
|
+
| `client_types`, `client_type_history()` | TSETMC | individual vs institutional flow |
|
|
168
|
+
| `major_holders` | TSETMC | > 1 % shareholders |
|
|
169
|
+
| `news` | Codal summaries + TSETMC supervisor messages | |
|
|
170
|
+
| `income_stmt`, `balance_sheet`, `cashflow`, `quarterly_*` | Codal | wide frame, columns = period end |
|
|
171
|
+
| `options`, `option_chain(date)` | TSETMC option market watch | expirations; calls and puts with bid, ask, last, volume, open interest |
|
|
172
|
+
| `monthly_activity()` | Codal | monthly production/sales letters |
|
|
173
|
+
|
|
174
|
+
`Tickers("فولاد فملی")` bundles several tickers. `download([...])` returns the yfinance
|
|
175
|
+
`MultiIndex` layout: `group_by="column"` gives `(Price, Ticker)`, `group_by="ticker"` flips it.
|
|
176
|
+
|
|
177
|
+
## Compared with other packages
|
|
178
|
+
|
|
179
|
+
| | yfinance-ir | [pytse-client](https://github.com/Glyphack/pytse-client) | [finpy-tse](https://github.com/ARahimiQuant/finpy-tse) | [tehran-stocks](https://github.com/ghodsizadeh/tehran-stocks) |
|
|
180
|
+
|---|---|---|---|---|
|
|
181
|
+
| Sources | TSETMC, Codal, TGJU, SCI CPI, Nobitex (`crypto` extra) | TSETMC | TSETMC, free-market dollar | TSETMC |
|
|
182
|
+
| API shape | yfinance: `Ticker(...).history()`, `download([...])` | `Ticker(...).history` frame, `download(symbols=...)` | `Get_*_History()` functions | SQLAlchemy models + CLI |
|
|
183
|
+
| Adjusted daily history | dividends and capital increases | `adjust=True` | `adjust_price=True` | dividend and share tables, no adjusted series documented |
|
|
184
|
+
| Intraday bars | `1m`–`90m`, `1h`, rebuilt from trades | `30s`–`1h`, aggregated from trade details (`get_trade_details(..., timeframe=)`) | trade and order-book history, no bars | — |
|
|
185
|
+
| Order book, client types | yes | yes | yes | — |
|
|
186
|
+
| Codal statements | income, balance sheet, cash flow, monthly activity | — | — | — |
|
|
187
|
+
| Option chains | yes | — | — | — |
|
|
188
|
+
| FX, gold, coin | TGJU | — | USD only (`Get_USD_RIAL`) | — |
|
|
189
|
+
| CPI | SCI, monthly | — | — | — |
|
|
190
|
+
| Index history | any TSETMC index by name | `FinancialIndex(...).history` | `Get_CWI_History`, `Get_EWI_History`, sector indices | — |
|
|
191
|
+
| Jalali dates | input and output | `include_jdate=True` | `jalali_date=True` | output |
|
|
192
|
+
| Licence | MIT | GPL-3.0 | BSD-3-Clause | MIT |
|
|
193
|
+
| Last commit | 2026-10 | 2025-03 | 2024-04 | 2023-10 |
|
|
194
|
+
| PyPI | not yet, install from a release tag | yes | yes | yes |
|
|
195
|
+
|
|
196
|
+
Checked against each package's README on 2026-10-11; "—" means the README does not document it.
|
|
197
|
+
Corrections welcome as issues.
|
|
198
|
+
|
|
199
|
+
## Conventions
|
|
200
|
+
|
|
201
|
+
| Topic | Rule |
|
|
202
|
+
|---|---|
|
|
203
|
+
| Prices | TSETMC and TGJU in Rial; `*-IRT` crypto pairs in Toman |
|
|
204
|
+
| Columns | `Open High Low Close Volume Dividends "Stock Splits"`, plus TSETMC `Last`, `Value`, `Count`; `auto_adjust=False` adds `Adj Close` |
|
|
205
|
+
| Dates | Gregorian `DatetimeIndex`; `start`/`end` accept Gregorian, Jalali (`1403-01-01`), `dEven` ints, `date`/`datetime`; `end` exclusive; intraday bars carry a tz-aware `Datetime` index, `Asia/Tehran` for TSETMC and UTC for crypto |
|
|
206
|
+
| Adjustment | Dividend gaps from TSETMC `GetPriceAdjustList`; share-count changes it omits are bonus issues (`old / new`); markers land on the next bar |
|
|
207
|
+
| Non-trading rows | Zero-volume calendar rows while a symbol is suspended are dropped |
|
|
208
|
+
| Errors | `SymbolNotFound`, `BlockedError`, `RateLimitError`, `DataUnavailable`, all subclasses of `YFIRError` |
|
|
209
|
+
|
|
210
|
+
Full definitions: [docs/conventions.md](docs/conventions.md).
|
|
211
|
+
|
|
212
|
+
## Configuration
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
yf.set_config(
|
|
216
|
+
min_interval=0.1, # seconds between requests to the same host
|
|
217
|
+
timeout=20.0, # per-request timeout
|
|
218
|
+
threads=4, # download() workers
|
|
219
|
+
cache_dir=None, # default: $XDG_CACHE_HOME/yfinance_ir
|
|
220
|
+
crypto_exchange="nobitex",
|
|
221
|
+
trust_env=True, # honour HTTP(S)_PROXY
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Limitations
|
|
226
|
+
|
|
227
|
+
- Intraday bars exist for TSETMC instruments other than indices, span at most 3 months per
|
|
228
|
+
call and cost one request per trading day. Some of TSETMC's backends answer the trade feed
|
|
229
|
+
with HTTP 500 or an empty list; a failed request reconnects to reach another backend, and
|
|
230
|
+
a day still empty after 12 passes (about 3 minutes, long pauses logged at WARNING) raises
|
|
231
|
+
`DataUnavailable`. Other sources: TGJU is daily, crypto `1d`/`1h`, CPI monthly.
|
|
232
|
+
- Option chains have no implied volatility or last-trade date; TSETMC publishes neither.
|
|
233
|
+
- CPI downloads from `amar.org.ir` run with `verify=False` because the server omits its
|
|
234
|
+
intermediate certificate.
|
|
235
|
+
- ISIN lookup only hits the local cache; resolve by symbol or InsCode first.
|
|
236
|
+
- Index history has no open or volume.
|
|
237
|
+
- `ccxt-ir` 4.19.0's `fetch_ohlcv` and `fetch_order_book` are broken; Nobitex is served
|
|
238
|
+
through its public REST API instead, other exchanges re-raise the ccxt error.
|
|
239
|
+
|
|
240
|
+
Reasons and endpoint details: [docs/data-sources.md](docs/data-sources.md).
|
|
241
|
+
|
|
242
|
+
## Development
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
python -m venv .venv && .venv/bin/pip install -e ".[dev,crypto]"
|
|
246
|
+
.venv/bin/python -m ruff check .
|
|
247
|
+
.venv/bin/python -m pytest # 95 offline tests, replayed fixtures
|
|
248
|
+
.venv/bin/python -m pytest -m live # 12 smoke tests, needs an Iranian IP
|
|
249
|
+
.venv/bin/python tests/capture_fixtures.py # re-record tests/fixtures/
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Offline tests run through `responses` against the exact URLs the package calls, so a wrong
|
|
253
|
+
path in `yfinance_ir/sources/` fails a test instead of hitting the network.
|
|
254
|
+
|
|
255
|
+
Versions are CalVer, `YYYY.M.MICRO`. [CHANGELOG.md](CHANGELOG.md) names breaking changes;
|
|
256
|
+
the number does not encode them. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
257
|
+
|
|
258
|
+
> **Not affiliated** with yfinance, Yahoo, TSETMC, Codal, TGJU or the Statistical Centre of
|
|
259
|
+
> Iran. The package reads their public endpoints and copies the `yfinance` API shape. No
|
|
260
|
+
> accuracy guarantee, not investment advice; each source's terms of use are your
|
|
261
|
+
> responsibility.
|
|
262
|
+
|
|
263
|
+
## License
|
|
264
|
+
|
|
265
|
+
MIT, Copyright (c) 2026 Kiyarash Fazeli. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# yfinance-ir
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Fazel94/yfinance-ir/actions/workflows/ci.yml)
|
|
4
|
+

|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
[فارسی](README.fa.md)
|
|
8
|
+
|
|
9
|
+
<div dir="rtl">
|
|
10
|
+
|
|
11
|
+
دادههای بازار ایران با رابط آشنای `yfinance`: سهام، صندوقها و شاخصهای بورس تهران (TSETMC)،
|
|
12
|
+
صورتهای مالی کدال، دلار، طلا و سکه از TGJU، تورم مرکز آمار ایران و رمزارزها از صرافیهای ایرانی.
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
`yfinance`-shaped market data for the Iranian markets: TSETMC (equities, ETFs, indices),
|
|
17
|
+
Codal (financial statements), TGJU (FX, gold, coins), the Statistical Centre of Iran (CPI)
|
|
18
|
+
and, with the `crypto` extra, Iranian crypto exchanges through `ccxt-ir`.
|
|
19
|
+
|
|
20
|
+
> **Iranian IP required.** `cdn.tsetmc.com` drops foreign IPs.
|
|
21
|
+
|
|
22
|
+
[](examples/scoreboard.ipynb)
|
|
23
|
+
|
|
24
|
+
One `history()` call per bar: TSETMC indices, stocks and ETFs, TGJU's dollar, euro, gold
|
|
25
|
+
and coin, Nobitex bitcoin, measured against the SCI CPI and the free-market dollar.
|
|
26
|
+
[`examples/scoreboard.ipynb`](examples/scoreboard.ipynb) draws it, the same race as a
|
|
27
|
+
path since Nowruz and over five years, and a seven-window heatmap of real and dollar
|
|
28
|
+
returns. Charts are in Persian; install from `main` for its two text-shaping extras:
|
|
29
|
+
`pip install "yfinance-ir[crypto,notebook] @ git+https://github.com/Fazel94/yfinance-ir.git"`.
|
|
30
|
+
|
|
31
|
+
Monthly update of this chart: X [@_fazel94](https://x.com/_fazel94)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install "yfinance-ir @ git+https://github.com/Fazel94/yfinance-ir.git@v2026.9.2" # TSETMC + Codal + TGJU + CPI
|
|
38
|
+
pip install "yfinance-ir[crypto] @ git+https://github.com/Fazel94/yfinance-ir.git@v2026.9.2" # adds BTC-IRT / ETH-USDT style pairs
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Not on PyPI yet: install from a release tag. Each [GitHub Release](https://github.com/Fazel94/yfinance-ir/releases) also carries the wheel and sdist.
|
|
42
|
+
|
|
43
|
+
## Quickstart
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import yfinance_ir as yf
|
|
47
|
+
|
|
48
|
+
folad = yf.Ticker("فولاد")
|
|
49
|
+
folad.history(period="1y") # adjusted daily OHLCV
|
|
50
|
+
folad.history(period="5d", interval="5m") # intraday bars rebuilt from TSETMC trades
|
|
51
|
+
folad.info["marketCap"]
|
|
52
|
+
folad.income_stmt # Codal, wide, newest period first
|
|
53
|
+
folad.cashflow # Codal cash-flow statement
|
|
54
|
+
yf.Ticker("اهرم").option_chain() # nearest expiration: calls, puts, underlying
|
|
55
|
+
|
|
56
|
+
yf.download(["فولاد", "فملی"], period="6mo")
|
|
57
|
+
yf.Ticker("USD").history(period="5y") # TGJU dollar, Rial
|
|
58
|
+
yf.Ticker("شاخص کل").history() # TEDPIX
|
|
59
|
+
yf.Ticker("CPI").history() # SCI consumer price index, monthly
|
|
60
|
+
yf.Ticker("BTC-IRT").history() # Nobitex, needs the `crypto` extra
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Example: فولاد in Rial, USD and real terms
|
|
64
|
+
|
|
65
|
+
[`examples/real_returns.py`](examples/real_returns.py) prices فولاد in TGJU dollars and
|
|
66
|
+
deflates it by the SCI CPI. Both series are forward-filled onto the stock's trading days.
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import pandas as pd
|
|
70
|
+
|
|
71
|
+
folad = yf.Ticker("فولاد").history(period="5y")["Close"]
|
|
72
|
+
usd = yf.Ticker("USD").history(period="5y")["Close"].reindex(folad.index, method="ffill")
|
|
73
|
+
cpi = yf.Ticker("CPI").history(period="5y")["Close"].reindex(folad.index, method="ffill")
|
|
74
|
+
|
|
75
|
+
frame = pd.DataFrame({"Rial": folad, "USD": folad / usd, "Real": folad / cpi * cpi.iloc[-1]})
|
|
76
|
+
print(frame.iloc[-1] / frame.iloc[0] - 1)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Output on 2026-09-21:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
فولاد 2021-09-25 -> 2026-09-21 (5.0y)
|
|
83
|
+
total annualised
|
|
84
|
+
Rial +228.1% +26.9%
|
|
85
|
+
USD -60.8% -17.1%
|
|
86
|
+
Real -52.0% -13.7%
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
[examples/cookbook.ipynb](examples/cookbook.ipynb) runs the recipes of chapters 1, 2 and 7
|
|
90
|
+
of *Python for Finance Cookbook* (returns, CPI deflation, outliers, stylised facts,
|
|
91
|
+
SMA/Bollinger/RSI backtests with backtrader, 1/n portfolio, Monte Carlo efficient frontier)
|
|
92
|
+
on TSETMC stocks and Nobitex crypto pairs. Install its dependencies with
|
|
93
|
+
`pip install "yfinance-ir[crypto,notebook] @ git+https://github.com/Fazel94/yfinance-ir.git@v2026.9.2"`.
|
|
94
|
+
|
|
95
|
+
## Symbols
|
|
96
|
+
|
|
97
|
+
| You pass | Resolves to | Example |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Persian symbol | TSETMC instrument | `Ticker("فولاد")`, `Ticker("اهرم")` |
|
|
100
|
+
| Persian index name | TSETMC index | `Ticker("شاخص کل")` |
|
|
101
|
+
| InsCode (10–20 digits) | TSETMC instrument | `Ticker("46348559193224090")` |
|
|
102
|
+
| TGJU alias or slug | FX / gold / coin | `Ticker("USD")`, `Ticker("geram18")` |
|
|
103
|
+
| `CPI`, `CPI_URBAN`, `CPI_RURAL` | SCI price index | `Ticker("CPI")` |
|
|
104
|
+
| `BASE-IRT` / `BASE-USDT` | crypto pair | `Ticker("BTC-IRT")` |
|
|
105
|
+
| ISIN | cache lookup only, see below | `Ticker("IRO1FOLD0009")` |
|
|
106
|
+
|
|
107
|
+
Persian and Arabic spellings are unified (`ی`/`ي`, `ک`/`ك`, ZWNJ). TGJU aliases and the
|
|
108
|
+
per-source rules are in [docs/data-sources.md](docs/data-sources.md). Resolutions are cached
|
|
109
|
+
in `~/.cache/yfinance_ir/symbols.sqlite`; `yf.cache.clear()` drops them,
|
|
110
|
+
`yf.set_config(cache_dir=...)` moves them.
|
|
111
|
+
|
|
112
|
+
## Ticker API
|
|
113
|
+
|
|
114
|
+
| Member | Source | Notes |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| `history(...)` | TSETMC / TGJU / SCI / crypto | daily OHLCV (monthly for CPI), adjusted by default; TSETMC also `1m`–`90m` and `1h` bars rebuilt from trades |
|
|
117
|
+
| `info` | TSETMC | yfinance-style keys: `marketCap`, `trailingPE`, `sharesOutstanding`, … |
|
|
118
|
+
| `dividends`, `splits`, `actions` | TSETMC adjust + share-change | see docs/conventions.md |
|
|
119
|
+
| `orderbook` | TSETMC / exchange | 5 levels, bid/ask price-volume-count |
|
|
120
|
+
| `client_types`, `client_type_history()` | TSETMC | individual vs institutional flow |
|
|
121
|
+
| `major_holders` | TSETMC | > 1 % shareholders |
|
|
122
|
+
| `news` | Codal summaries + TSETMC supervisor messages | |
|
|
123
|
+
| `income_stmt`, `balance_sheet`, `cashflow`, `quarterly_*` | Codal | wide frame, columns = period end |
|
|
124
|
+
| `options`, `option_chain(date)` | TSETMC option market watch | expirations; calls and puts with bid, ask, last, volume, open interest |
|
|
125
|
+
| `monthly_activity()` | Codal | monthly production/sales letters |
|
|
126
|
+
|
|
127
|
+
`Tickers("فولاد فملی")` bundles several tickers. `download([...])` returns the yfinance
|
|
128
|
+
`MultiIndex` layout: `group_by="column"` gives `(Price, Ticker)`, `group_by="ticker"` flips it.
|
|
129
|
+
|
|
130
|
+
## Compared with other packages
|
|
131
|
+
|
|
132
|
+
| | yfinance-ir | [pytse-client](https://github.com/Glyphack/pytse-client) | [finpy-tse](https://github.com/ARahimiQuant/finpy-tse) | [tehran-stocks](https://github.com/ghodsizadeh/tehran-stocks) |
|
|
133
|
+
|---|---|---|---|---|
|
|
134
|
+
| Sources | TSETMC, Codal, TGJU, SCI CPI, Nobitex (`crypto` extra) | TSETMC | TSETMC, free-market dollar | TSETMC |
|
|
135
|
+
| API shape | yfinance: `Ticker(...).history()`, `download([...])` | `Ticker(...).history` frame, `download(symbols=...)` | `Get_*_History()` functions | SQLAlchemy models + CLI |
|
|
136
|
+
| Adjusted daily history | dividends and capital increases | `adjust=True` | `adjust_price=True` | dividend and share tables, no adjusted series documented |
|
|
137
|
+
| Intraday bars | `1m`–`90m`, `1h`, rebuilt from trades | `30s`–`1h`, aggregated from trade details (`get_trade_details(..., timeframe=)`) | trade and order-book history, no bars | — |
|
|
138
|
+
| Order book, client types | yes | yes | yes | — |
|
|
139
|
+
| Codal statements | income, balance sheet, cash flow, monthly activity | — | — | — |
|
|
140
|
+
| Option chains | yes | — | — | — |
|
|
141
|
+
| FX, gold, coin | TGJU | — | USD only (`Get_USD_RIAL`) | — |
|
|
142
|
+
| CPI | SCI, monthly | — | — | — |
|
|
143
|
+
| Index history | any TSETMC index by name | `FinancialIndex(...).history` | `Get_CWI_History`, `Get_EWI_History`, sector indices | — |
|
|
144
|
+
| Jalali dates | input and output | `include_jdate=True` | `jalali_date=True` | output |
|
|
145
|
+
| Licence | MIT | GPL-3.0 | BSD-3-Clause | MIT |
|
|
146
|
+
| Last commit | 2026-10 | 2025-03 | 2024-04 | 2023-10 |
|
|
147
|
+
| PyPI | not yet, install from a release tag | yes | yes | yes |
|
|
148
|
+
|
|
149
|
+
Checked against each package's README on 2026-10-11; "—" means the README does not document it.
|
|
150
|
+
Corrections welcome as issues.
|
|
151
|
+
|
|
152
|
+
## Conventions
|
|
153
|
+
|
|
154
|
+
| Topic | Rule |
|
|
155
|
+
|---|---|
|
|
156
|
+
| Prices | TSETMC and TGJU in Rial; `*-IRT` crypto pairs in Toman |
|
|
157
|
+
| Columns | `Open High Low Close Volume Dividends "Stock Splits"`, plus TSETMC `Last`, `Value`, `Count`; `auto_adjust=False` adds `Adj Close` |
|
|
158
|
+
| Dates | Gregorian `DatetimeIndex`; `start`/`end` accept Gregorian, Jalali (`1403-01-01`), `dEven` ints, `date`/`datetime`; `end` exclusive; intraday bars carry a tz-aware `Datetime` index, `Asia/Tehran` for TSETMC and UTC for crypto |
|
|
159
|
+
| Adjustment | Dividend gaps from TSETMC `GetPriceAdjustList`; share-count changes it omits are bonus issues (`old / new`); markers land on the next bar |
|
|
160
|
+
| Non-trading rows | Zero-volume calendar rows while a symbol is suspended are dropped |
|
|
161
|
+
| Errors | `SymbolNotFound`, `BlockedError`, `RateLimitError`, `DataUnavailable`, all subclasses of `YFIRError` |
|
|
162
|
+
|
|
163
|
+
Full definitions: [docs/conventions.md](docs/conventions.md).
|
|
164
|
+
|
|
165
|
+
## Configuration
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
yf.set_config(
|
|
169
|
+
min_interval=0.1, # seconds between requests to the same host
|
|
170
|
+
timeout=20.0, # per-request timeout
|
|
171
|
+
threads=4, # download() workers
|
|
172
|
+
cache_dir=None, # default: $XDG_CACHE_HOME/yfinance_ir
|
|
173
|
+
crypto_exchange="nobitex",
|
|
174
|
+
trust_env=True, # honour HTTP(S)_PROXY
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Limitations
|
|
179
|
+
|
|
180
|
+
- Intraday bars exist for TSETMC instruments other than indices, span at most 3 months per
|
|
181
|
+
call and cost one request per trading day. Some of TSETMC's backends answer the trade feed
|
|
182
|
+
with HTTP 500 or an empty list; a failed request reconnects to reach another backend, and
|
|
183
|
+
a day still empty after 12 passes (about 3 minutes, long pauses logged at WARNING) raises
|
|
184
|
+
`DataUnavailable`. Other sources: TGJU is daily, crypto `1d`/`1h`, CPI monthly.
|
|
185
|
+
- Option chains have no implied volatility or last-trade date; TSETMC publishes neither.
|
|
186
|
+
- CPI downloads from `amar.org.ir` run with `verify=False` because the server omits its
|
|
187
|
+
intermediate certificate.
|
|
188
|
+
- ISIN lookup only hits the local cache; resolve by symbol or InsCode first.
|
|
189
|
+
- Index history has no open or volume.
|
|
190
|
+
- `ccxt-ir` 4.19.0's `fetch_ohlcv` and `fetch_order_book` are broken; Nobitex is served
|
|
191
|
+
through its public REST API instead, other exchanges re-raise the ccxt error.
|
|
192
|
+
|
|
193
|
+
Reasons and endpoint details: [docs/data-sources.md](docs/data-sources.md).
|
|
194
|
+
|
|
195
|
+
## Development
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
python -m venv .venv && .venv/bin/pip install -e ".[dev,crypto]"
|
|
199
|
+
.venv/bin/python -m ruff check .
|
|
200
|
+
.venv/bin/python -m pytest # 95 offline tests, replayed fixtures
|
|
201
|
+
.venv/bin/python -m pytest -m live # 12 smoke tests, needs an Iranian IP
|
|
202
|
+
.venv/bin/python tests/capture_fixtures.py # re-record tests/fixtures/
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Offline tests run through `responses` against the exact URLs the package calls, so a wrong
|
|
206
|
+
path in `yfinance_ir/sources/` fails a test instead of hitting the network.
|
|
207
|
+
|
|
208
|
+
Versions are CalVer, `YYYY.M.MICRO`. [CHANGELOG.md](CHANGELOG.md) names breaking changes;
|
|
209
|
+
the number does not encode them. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
210
|
+
|
|
211
|
+
> **Not affiliated** with yfinance, Yahoo, TSETMC, Codal, TGJU or the Statistical Centre of
|
|
212
|
+
> Iran. The package reads their public endpoints and copies the `yfinance` API shape. No
|
|
213
|
+
> accuracy guarantee, not investment advice; each source's terms of use are your
|
|
214
|
+
> responsibility.
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT, Copyright (c) 2026 Kiyarash Fazeli. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "yfinance-ir"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "yfinance-style market data for Iranian markets (TSETMC, Codal, TGJU)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Kiyarash Fazeli", email = "caci96@gmail.com" }]
|
|
14
|
+
keywords = ["tsetmc", "codal", "tgju", "iran", "bourse", "stocks", "finance"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Topic :: Office/Business :: Financial :: Investment",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"requests>=2.28",
|
|
29
|
+
"pandas>=1.5",
|
|
30
|
+
"numpy>=1.21",
|
|
31
|
+
"jdatetime>=4",
|
|
32
|
+
"openpyxl>=3.1",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
dev = ["pytest", "responses", "ruff"]
|
|
37
|
+
crypto = ["ccxt-ir>=4"]
|
|
38
|
+
notebook = [
|
|
39
|
+
"matplotlib>=3.8",
|
|
40
|
+
"seaborn>=0.13",
|
|
41
|
+
"scipy>=1.11",
|
|
42
|
+
"statsmodels>=0.14",
|
|
43
|
+
"backtrader>=1.9.78",
|
|
44
|
+
"ipykernel",
|
|
45
|
+
"nbconvert",
|
|
46
|
+
"arabic-reshaper>=3.0",
|
|
47
|
+
"python-bidi>=0.6",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Homepage = "https://github.com/Fazel94/yfinance-ir"
|
|
52
|
+
Repository = "https://github.com/Fazel94/yfinance-ir"
|
|
53
|
+
Issues = "https://github.com/Fazel94/yfinance-ir/issues"
|
|
54
|
+
Changelog = "https://github.com/Fazel94/yfinance-ir/blob/main/CHANGELOG.md"
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.dynamic]
|
|
57
|
+
version = { attr = "yfinance_ir.__version__" }
|
|
58
|
+
|
|
59
|
+
[tool.setuptools.packages.find]
|
|
60
|
+
include = ["yfinance_ir*"]
|
|
61
|
+
|
|
62
|
+
[tool.setuptools.package-data]
|
|
63
|
+
yfinance_ir = ["py.typed"]
|
|
64
|
+
|
|
65
|
+
[tool.ruff]
|
|
66
|
+
line-length = 110
|
|
67
|
+
target-version = "py39"
|
|
68
|
+
|
|
69
|
+
[tool.ruff.lint]
|
|
70
|
+
select = ["E", "F", "I", "W"]
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
markers = ["live: hits the real network (requires an Iranian IP)"]
|
|
74
|
+
addopts = '-m "not live"'
|
|
75
|
+
testpaths = ["tests"]
|