reportify-sdk 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl
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.
- reportify_sdk/__init__.py +1 -1
- reportify_sdk/client.py +1 -1
- reportify_sdk/docs.py +2 -0
- reportify_sdk/quant.py +49 -62
- reportify_sdk/stock.py +15 -4
- {reportify_sdk-0.3.1.dist-info → reportify_sdk-0.3.3.dist-info}/METADATA +1 -1
- {reportify_sdk-0.3.1.dist-info → reportify_sdk-0.3.3.dist-info}/RECORD +10 -10
- {reportify_sdk-0.3.1.dist-info → reportify_sdk-0.3.3.dist-info}/WHEEL +0 -0
- {reportify_sdk-0.3.1.dist-info → reportify_sdk-0.3.3.dist-info}/licenses/LICENSE +0 -0
- {reportify_sdk-0.3.1.dist-info → reportify_sdk-0.3.3.dist-info}/top_level.txt +0 -0
reportify_sdk/__init__.py
CHANGED
reportify_sdk/client.py
CHANGED
reportify_sdk/docs.py
CHANGED
reportify_sdk/quant.py
CHANGED
|
@@ -39,6 +39,8 @@ class QuantModule:
|
|
|
39
39
|
"""
|
|
40
40
|
Get list of available technical indicators
|
|
41
41
|
|
|
42
|
+
All indicators are functions and require parentheses when used (e.g., MA(20), RSI(14), MACD()).
|
|
43
|
+
|
|
42
44
|
Returns:
|
|
43
45
|
List of indicator definitions with name, description, and fields
|
|
44
46
|
|
|
@@ -62,6 +64,10 @@ class QuantModule:
|
|
|
62
64
|
"""
|
|
63
65
|
Compute indicator values for given symbols
|
|
64
66
|
|
|
67
|
+
Variables vs Functions:
|
|
68
|
+
- Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME (aliases: C, O, H, L, V, VOL)
|
|
69
|
+
- Functions (with parentheses): MA(20), RSI(14), MACD(), etc.
|
|
70
|
+
|
|
65
71
|
Args:
|
|
66
72
|
symbols: List of stock codes (e.g., ["000001", "600519"])
|
|
67
73
|
formula: Indicator formula (e.g., "RSI(14)", "MACD()", "MACD(12,26,9)")
|
|
@@ -84,6 +90,9 @@ class QuantModule:
|
|
|
84
90
|
>>> # KDJ indicator
|
|
85
91
|
>>> df = client.quant.compute_indicators(["000001"], "KDJ(9,3,3)")
|
|
86
92
|
>>> print(df[["symbol", "date", "k", "d", "j"]])
|
|
93
|
+
|
|
94
|
+
>>> # Standard deviation
|
|
95
|
+
>>> df = client.quant.compute_indicators(["000001"], "STD(CLOSE, 20)")
|
|
87
96
|
"""
|
|
88
97
|
data: dict[str, Any] = {
|
|
89
98
|
"symbols": symbols,
|
|
@@ -106,11 +115,15 @@ class QuantModule:
|
|
|
106
115
|
"""
|
|
107
116
|
Get list of available factors (variables and functions)
|
|
108
117
|
|
|
118
|
+
Variables vs Functions:
|
|
119
|
+
- Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME, PE_TTM, ROE_TTM, etc.
|
|
120
|
+
- Functions (with parentheses): MA(20), PE(), ROE(), RSI(14), etc.
|
|
121
|
+
|
|
109
122
|
Returns factors organized by level:
|
|
110
|
-
- Level 0 Variables: CLOSE, OPEN, HIGH, LOW, VOLUME
|
|
111
|
-
- Level 0 Functions: MA, EMA, REF, HHV, LLV, STD, etc.
|
|
112
|
-
- Level 1 Functions: CROSS, COUNT, EVERY, etc.
|
|
113
|
-
- Level 2 Functions: MACD, KDJ, RSI, BOLL, etc.
|
|
123
|
+
- Level 0 Variables: CLOSE, OPEN, HIGH, LOW, VOLUME (price data, no parentheses)
|
|
124
|
+
- Level 0 Functions: MA(), EMA(), REF(), HHV(), LLV(), STD(), etc. (require parentheses)
|
|
125
|
+
- Level 1 Functions: CROSS(), COUNT(), EVERY(), etc. (require parentheses)
|
|
126
|
+
- Level 2 Functions: MACD(), KDJ(), RSI(), BOLL(), PE(), ROE(), etc. (require parentheses)
|
|
114
127
|
|
|
115
128
|
Returns:
|
|
116
129
|
List of factor definitions
|
|
@@ -136,6 +149,10 @@ class QuantModule:
|
|
|
136
149
|
|
|
137
150
|
Uses Mai-language syntax compatible with TongDaXin/TongHuaShun.
|
|
138
151
|
|
|
152
|
+
Variables vs Functions:
|
|
153
|
+
- Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME
|
|
154
|
+
- Functions (with parentheses): MA(20), PE(), ROE(), RSI(14), etc.
|
|
155
|
+
|
|
139
156
|
Args:
|
|
140
157
|
symbols: List of stock codes
|
|
141
158
|
formula: Factor formula using Mai-language syntax
|
|
@@ -158,6 +175,10 @@ class QuantModule:
|
|
|
158
175
|
|
|
159
176
|
>>> # Deviation from MA20 in percent
|
|
160
177
|
>>> df = client.quant.compute_factors(["000001"], "(CLOSE - MA(20)) / MA(20) * 100")
|
|
178
|
+
|
|
179
|
+
>>> # Fundamental factors (note: functions require parentheses)
|
|
180
|
+
>>> df = client.quant.compute_factors(["000001"], "PE()")
|
|
181
|
+
>>> df = client.quant.compute_factors(["000001"], "ROE()")
|
|
161
182
|
|
|
162
183
|
Supported Operators:
|
|
163
184
|
- Comparison: >, <, >=, <=, ==, !=
|
|
@@ -165,12 +186,16 @@ class QuantModule:
|
|
|
165
186
|
- Logical OR: | (NOT "OR")
|
|
166
187
|
- Arithmetic: +, -, *, /
|
|
167
188
|
|
|
168
|
-
Supported Variables:
|
|
189
|
+
Supported Variables (no parentheses):
|
|
169
190
|
- CLOSE, C: Close price
|
|
170
191
|
- OPEN, O: Open price
|
|
171
192
|
- HIGH, H: High price
|
|
172
193
|
- LOW, L: Low price
|
|
173
194
|
- VOLUME, V, VOL: Volume
|
|
195
|
+
|
|
196
|
+
Supported Functions (require parentheses):
|
|
197
|
+
- Technical: MA(), EMA(), RSI(), MACD(), BOLL(), etc.
|
|
198
|
+
- Fundamental: PE(), PB(), ROE(), ROA(), etc.
|
|
174
199
|
"""
|
|
175
200
|
data: dict[str, Any] = {
|
|
176
201
|
"symbols": symbols,
|
|
@@ -199,6 +224,10 @@ class QuantModule:
|
|
|
199
224
|
Returns stocks where the formula evaluates to True (for boolean formulas)
|
|
200
225
|
or non-null (for numeric formulas).
|
|
201
226
|
|
|
227
|
+
Variables vs Functions:
|
|
228
|
+
- Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME
|
|
229
|
+
- Functions (with parentheses): MA(20), PE(), ROE(), RSI(14), etc.
|
|
230
|
+
|
|
202
231
|
Args:
|
|
203
232
|
formula: Screening formula using Mai-language syntax
|
|
204
233
|
market: Stock market ("cn", "hk", "us"), default "cn"
|
|
@@ -221,6 +250,9 @@ class QuantModule:
|
|
|
221
250
|
>>> # Above upper Bollinger Band
|
|
222
251
|
>>> stocks = client.quant.screen(formula="CLOSE > BOLL(20, 2).upper")
|
|
223
252
|
|
|
253
|
+
>>> # Fundamental screening (note: functions require parentheses)
|
|
254
|
+
>>> stocks = client.quant.screen(formula="(PE() < 20) & (ROE() > 0.15)")
|
|
255
|
+
|
|
224
256
|
>>> # Screen specific stocks
|
|
225
257
|
>>> stocks = client.quant.screen(
|
|
226
258
|
... formula="RSI(14) < 30",
|
|
@@ -315,63 +347,6 @@ class QuantModule:
|
|
|
315
347
|
response = self._client._post("/v1/quant/quotes/ohlcv/batch", json=data)
|
|
316
348
|
return self._to_dataframe(response.get("datas", []))
|
|
317
349
|
|
|
318
|
-
# -------------------------------------------------------------------------
|
|
319
|
-
# Financials
|
|
320
|
-
# -------------------------------------------------------------------------
|
|
321
|
-
|
|
322
|
-
def financials(
|
|
323
|
-
self,
|
|
324
|
-
financial_type: Literal["income", "cashflow", "balancesheet", "equity"],
|
|
325
|
-
symbol: str,
|
|
326
|
-
*,
|
|
327
|
-
market: StockMarket = "cn",
|
|
328
|
-
start_year: int | None = None,
|
|
329
|
-
end_year: int | None = None,
|
|
330
|
-
) -> pd.DataFrame:
|
|
331
|
-
"""
|
|
332
|
-
Get historical financial statement data for a single symbol
|
|
333
|
-
|
|
334
|
-
Args:
|
|
335
|
-
financial_type: Type of financial statement
|
|
336
|
-
- "income": Income statement (利润表)
|
|
337
|
-
- "cashflow": Cash flow statement (现金流量表)
|
|
338
|
-
- "balancesheet": Balance sheet (资产负债表)
|
|
339
|
-
- "equity": Equity statement (股东权益变动表)
|
|
340
|
-
symbol: Stock code
|
|
341
|
-
market: Stock market ("cn", "hk", "us"), default "cn"
|
|
342
|
-
start_year: Start year (default: 3 years ago)
|
|
343
|
-
end_year: End year (default: current year)
|
|
344
|
-
|
|
345
|
-
Returns:
|
|
346
|
-
DataFrame with financial data sorted by report period
|
|
347
|
-
|
|
348
|
-
Example:
|
|
349
|
-
>>> # Get income statement
|
|
350
|
-
>>> df = client.quant.financials("income", "000001")
|
|
351
|
-
>>> print(df[["report_period", "revenue", "net_profit"]])
|
|
352
|
-
|
|
353
|
-
>>> # Get balance sheet for specific years
|
|
354
|
-
>>> df = client.quant.financials(
|
|
355
|
-
... "balancesheet", "600519",
|
|
356
|
-
... start_year=2020,
|
|
357
|
-
... end_year=2024
|
|
358
|
-
... )
|
|
359
|
-
|
|
360
|
-
>>> # Get cash flow statement for HK stock
|
|
361
|
-
>>> df = client.quant.financials("cashflow", "00700", market="hk")
|
|
362
|
-
"""
|
|
363
|
-
params: dict[str, Any] = {
|
|
364
|
-
"symbol": symbol,
|
|
365
|
-
"market": market,
|
|
366
|
-
}
|
|
367
|
-
if start_year:
|
|
368
|
-
params["start_year"] = start_year
|
|
369
|
-
if end_year:
|
|
370
|
-
params["end_year"] = end_year
|
|
371
|
-
|
|
372
|
-
response = self._client._get(f"/v1/quant/financials/{financial_type}", params=params)
|
|
373
|
-
return self._to_dataframe(response.get("datas", []))
|
|
374
|
-
|
|
375
350
|
# -------------------------------------------------------------------------
|
|
376
351
|
# Backtest
|
|
377
352
|
# -------------------------------------------------------------------------
|
|
@@ -395,6 +370,10 @@ class QuantModule:
|
|
|
395
370
|
"""
|
|
396
371
|
Execute strategy backtest
|
|
397
372
|
|
|
373
|
+
Variables vs Functions:
|
|
374
|
+
- Variables (no parentheses): CLOSE, OPEN, HIGH, LOW, VOLUME
|
|
375
|
+
- Functions (with parentheses): MA(20), PE(), ROE(), RSI(14), etc.
|
|
376
|
+
|
|
398
377
|
Args:
|
|
399
378
|
start_date: Backtest start date (YYYY-MM-DD)
|
|
400
379
|
end_date: Backtest end date (YYYY-MM-DD)
|
|
@@ -444,6 +423,14 @@ class QuantModule:
|
|
|
444
423
|
... exit_formula="CROSSDOWN(MA(5), MA(20))" # Sell signal
|
|
445
424
|
... )
|
|
446
425
|
|
|
426
|
+
>>> # Fundamental screening backtest (note: functions require parentheses)
|
|
427
|
+
>>> result = client.quant.backtest(
|
|
428
|
+
... start_date="2023-01-01",
|
|
429
|
+
... end_date="2024-01-01",
|
|
430
|
+
... symbol="000001",
|
|
431
|
+
... entry_formula="(PE() < 20) & (ROE() > 0.15)",
|
|
432
|
+
... )
|
|
433
|
+
|
|
447
434
|
>>> # With custom labels for analysis
|
|
448
435
|
>>> result = client.quant.backtest(
|
|
449
436
|
... start_date="2023-01-01",
|
reportify_sdk/stock.py
CHANGED
|
@@ -591,7 +591,14 @@ class StockModule:
|
|
|
591
591
|
elif isinstance(data, dict):
|
|
592
592
|
# Handle nested data structures
|
|
593
593
|
if "data" in data:
|
|
594
|
-
|
|
594
|
+
inner_data = data["data"]
|
|
595
|
+
if isinstance(inner_data, list):
|
|
596
|
+
df = pd.DataFrame(inner_data)
|
|
597
|
+
elif isinstance(inner_data, dict):
|
|
598
|
+
# If data is a dict with scalar values, wrap it in a list
|
|
599
|
+
df = pd.DataFrame([inner_data])
|
|
600
|
+
else:
|
|
601
|
+
df = pd.DataFrame([data])
|
|
595
602
|
elif "items" in data:
|
|
596
603
|
df = pd.DataFrame(data["items"])
|
|
597
604
|
elif "records" in data:
|
|
@@ -606,8 +613,12 @@ class StockModule:
|
|
|
606
613
|
date_columns = ["date", "period", "fiscal_date", "report_date"]
|
|
607
614
|
for col in date_columns:
|
|
608
615
|
if col in df.columns:
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
616
|
+
try:
|
|
617
|
+
df[col] = pd.to_datetime(df[col])
|
|
618
|
+
df = df.set_index(col)
|
|
619
|
+
break
|
|
620
|
+
except (ValueError, TypeError):
|
|
621
|
+
# Skip columns that can't be converted to datetime
|
|
622
|
+
continue
|
|
612
623
|
|
|
613
624
|
return df
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
reportify_sdk/__init__.py,sha256=
|
|
1
|
+
reportify_sdk/__init__.py,sha256=IyHi12_4qJqkiy4apx5p4103d8ztlnt97aHxBPIN4SY,662
|
|
2
2
|
reportify_sdk/agent.py,sha256=y1iP4Jq7-ESMxeCWB_vxkAvwCjUCWT8K-ZSeJswU6nQ,6358
|
|
3
3
|
reportify_sdk/channels.py,sha256=VbBCispCiP2Mzqn5lmBWVNWog4ElVni46mK2zg7KKzg,3518
|
|
4
4
|
reportify_sdk/chat.py,sha256=GQVfre4p2H9Kb0imX1-LvGqMrtnsuGhjQskBNUqUI_I,3613
|
|
5
|
-
reportify_sdk/client.py,sha256=
|
|
5
|
+
reportify_sdk/client.py,sha256=gf_d6uxfI5zzcLPxkJDinfU05p-s7J1W5I4WJ9rLTmg,8206
|
|
6
6
|
reportify_sdk/concepts.py,sha256=XlHPuuZacFFUccMthyeb5R2OTayFYxXgIODKNfJLa_c,1891
|
|
7
|
-
reportify_sdk/docs.py,sha256=
|
|
7
|
+
reportify_sdk/docs.py,sha256=T5RO_FQe7ARRlav8eZQrgggDNmbCb8Cgiaq8YtEoaFA,16850
|
|
8
8
|
reportify_sdk/exceptions.py,sha256=r2_C_kTh6tCrQnfA3UozSqMMA-2OBnoP3pGpgYeqcdU,1049
|
|
9
9
|
reportify_sdk/kb.py,sha256=3e82_56hvnGQ2fI404g3DAem9javPY7OpE5B8goYOB8,2895
|
|
10
|
-
reportify_sdk/quant.py,sha256=
|
|
10
|
+
reportify_sdk/quant.py,sha256=EWjCHMfkXJMRoLy159BeUKL7axmgWl8n-UcWcnwhsnA,17411
|
|
11
11
|
reportify_sdk/search.py,sha256=rzleME8_DwdiJ-__0qPjXkQZmaJ6JXH-ycJ_mUlkkNw,11866
|
|
12
|
-
reportify_sdk/stock.py,sha256=
|
|
12
|
+
reportify_sdk/stock.py,sha256=OcDb8REompgVEtZA6msWEWj6BilryQGZHpzWbyt9sxY,21996
|
|
13
13
|
reportify_sdk/timeline.py,sha256=7ZbF5-0eGoF_N5h9swEyYgZSaMb54PMwLDXlaqFS4ns,5396
|
|
14
14
|
reportify_sdk/user.py,sha256=lsdhvaovllEwYiz4fhhSwl8PMX8tKswzABAvZbB0iJw,1261
|
|
15
|
-
reportify_sdk-0.3.
|
|
16
|
-
reportify_sdk-0.3.
|
|
17
|
-
reportify_sdk-0.3.
|
|
18
|
-
reportify_sdk-0.3.
|
|
19
|
-
reportify_sdk-0.3.
|
|
15
|
+
reportify_sdk-0.3.3.dist-info/licenses/LICENSE,sha256=zBUq4DL4lE-fZU_PMkr0gnxkYS1LhdRHFw8_LmCb-ek,1066
|
|
16
|
+
reportify_sdk-0.3.3.dist-info/METADATA,sha256=w652XBK5mNEgaNEthMoq19zw-6t6Td0oMXhaMiSQsNQ,6451
|
|
17
|
+
reportify_sdk-0.3.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
18
|
+
reportify_sdk-0.3.3.dist-info/top_level.txt,sha256=tc_dzCSWIDsNbHSi-FlyEEX8xwinhN9gl-CwyLRE4B0,14
|
|
19
|
+
reportify_sdk-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|