reportify-sdk 0.2.0__py3-none-any.whl → 0.2.2__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/quant.py CHANGED
@@ -2,22 +2,30 @@
2
2
  Quant Module
3
3
 
4
4
  Provides quantitative analysis tools including indicators, factors, quotes, and backtesting.
5
+ Based on Mai-language syntax compatible with TongDaXin/TongHuaShun.
5
6
  """
6
7
 
7
- from typing import Any
8
+ from typing import Any, Literal
8
9
 
9
10
  import pandas as pd
10
11
 
11
12
 
13
+ StockMarket = Literal["cn", "hk", "us"]
14
+
15
+
12
16
  class QuantModule:
13
17
  """
14
18
  Quantitative analysis module
15
19
 
16
- Access technical indicators, factors, quotes, and backtesting functionality.
20
+ Access technical indicators, factors, OHLCV quotes, and backtesting functionality.
21
+ Uses Mai-language syntax for formulas.
17
22
 
18
23
  Example:
19
24
  >>> quant = client.quant
20
- >>> indicators = quant.indicators(symbols=["US:AAPL"], indicators=["ma", "rsi"])
25
+ >>> # Compute RSI indicator
26
+ >>> df = quant.compute_indicators(["000001"], "RSI(14)")
27
+ >>> # Screen stocks by formula
28
+ >>> stocks = quant.screen(formula="RSI(14) < 30")
21
29
  """
22
30
 
23
31
  def __init__(self, client):
@@ -27,231 +35,285 @@ class QuantModule:
27
35
  # Indicators
28
36
  # -------------------------------------------------------------------------
29
37
 
30
- def indicators(
38
+ def list_indicators(self) -> list[dict[str, Any]]:
39
+ """
40
+ Get list of available technical indicators
41
+
42
+ Returns:
43
+ List of indicator definitions with name, description, and fields
44
+
45
+ Example:
46
+ >>> indicators = client.quant.list_indicators()
47
+ >>> for ind in indicators:
48
+ ... print(f"{ind['name']}: {ind['description']}")
49
+ ... print(f" Fields: {ind['fields']}")
50
+ """
51
+ return self._client._get("/v1/quant/indicators")
52
+
53
+ def compute_indicators(
31
54
  self,
32
55
  symbols: list[str],
33
- indicators: list[str],
56
+ formula: str,
34
57
  *,
58
+ market: StockMarket = "cn",
35
59
  start_date: str | None = None,
36
60
  end_date: str | None = None,
37
- interval: str = "1d",
38
- params: dict[str, Any] | None = None,
39
61
  ) -> pd.DataFrame:
40
62
  """
41
- Get technical indicators for given symbols
63
+ Compute indicator values for given symbols
42
64
 
43
65
  Args:
44
- symbols: List of stock symbols (e.g., ["US:AAPL", "US:MSFT"])
45
- indicators: List of indicator names (e.g., ["ma", "rsi", "macd", "bollinger"])
46
- start_date: Start date (YYYY-MM-DD)
47
- end_date: End date (YYYY-MM-DD)
48
- interval: Data interval ("1d", "1w", "1m")
49
- params: Additional indicator parameters (e.g., {"ma_period": 20})
66
+ symbols: List of stock codes (e.g., ["000001", "600519"])
67
+ formula: Indicator formula (e.g., "RSI(14)", "MACD()", "MACD(12,26,9)")
68
+ market: Stock market ("cn", "hk", "us"), default "cn"
69
+ start_date: Start date (YYYY-MM-DD), default 3 months ago
70
+ end_date: End date (YYYY-MM-DD), default today
50
71
 
51
72
  Returns:
52
73
  DataFrame with indicator values
53
74
 
54
75
  Example:
55
- >>> df = client.quant.indicators(
56
- ... symbols=["US:AAPL"],
57
- ... indicators=["ma", "rsi"],
58
- ... params={"ma_period": 20, "rsi_period": 14}
59
- ... )
60
- >>> print(df[["close", "ma_20", "rsi_14"]])
76
+ >>> # RSI indicator
77
+ >>> df = client.quant.compute_indicators(["000001"], "RSI(14)")
78
+ >>> print(df[["symbol", "date", "rsi"]])
79
+
80
+ >>> # MACD indicator
81
+ >>> df = client.quant.compute_indicators(["000001"], "MACD()")
82
+ >>> print(df[["symbol", "date", "dif", "dea", "macd"]])
83
+
84
+ >>> # KDJ indicator
85
+ >>> df = client.quant.compute_indicators(["000001"], "KDJ(9,3,3)")
86
+ >>> print(df[["symbol", "date", "k", "d", "j"]])
61
87
  """
62
88
  data: dict[str, Any] = {
63
89
  "symbols": symbols,
64
- "indicators": indicators,
65
- "interval": interval,
90
+ "formula": formula,
91
+ "market": market,
66
92
  }
67
93
  if start_date:
68
94
  data["start_date"] = start_date
69
95
  if end_date:
70
96
  data["end_date"] = end_date
71
- if params:
72
- data["params"] = params
73
97
 
74
- response = self._client._post("/v2/quant/indicators", json=data)
75
- return self._to_dataframe(response.get("data", []))
98
+ response = self._client._post("/v1/quant/indicators/compute", json=data)
99
+ return self._to_dataframe(response.get("datas", []))
100
+
101
+ # -------------------------------------------------------------------------
102
+ # Factors
103
+ # -------------------------------------------------------------------------
76
104
 
77
- def indicator_list(self) -> list[dict[str, Any]]:
105
+ def list_factors(self) -> list[dict[str, Any]]:
78
106
  """
79
- Get list of available technical indicators
107
+ Get list of available factors (variables and functions)
108
+
109
+ 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.
80
114
 
81
115
  Returns:
82
- List of indicator definitions with name, description, and parameters
116
+ List of factor definitions
83
117
 
84
118
  Example:
85
- >>> indicators = client.quant.indicator_list()
86
- >>> for ind in indicators:
87
- ... print(f"{ind['name']}: {ind['description']}")
119
+ >>> factors = client.quant.list_factors()
120
+ >>> for f in factors:
121
+ ... print(f"{f['name']} ({f['type']}, level {f['level']})")
88
122
  """
89
- response = self._client._get("/v2/quant/indicators")
90
- return response.get("indicators", [])
91
-
92
- # -------------------------------------------------------------------------
93
- # Factors
94
- # -------------------------------------------------------------------------
123
+ return self._client._get("/v1/quant/factors")
95
124
 
96
- def factors(
125
+ def compute_factors(
97
126
  self,
98
127
  symbols: list[str],
99
- factors: list[str],
128
+ formula: str,
100
129
  *,
130
+ market: StockMarket = "cn",
101
131
  start_date: str | None = None,
102
132
  end_date: str | None = None,
103
- frequency: str = "daily",
104
133
  ) -> pd.DataFrame:
105
134
  """
106
- Get factor data for given symbols
135
+ Compute factor values for given symbols
136
+
137
+ Uses Mai-language syntax compatible with TongDaXin/TongHuaShun.
107
138
 
108
139
  Args:
109
- symbols: List of stock symbols
110
- factors: List of factor names (e.g., ["momentum", "value", "quality", "size"])
111
- start_date: Start date (YYYY-MM-DD)
112
- end_date: End date (YYYY-MM-DD)
113
- frequency: Data frequency ("daily", "weekly", "monthly")
140
+ symbols: List of stock codes
141
+ formula: Factor formula using Mai-language syntax
142
+ market: Stock market ("cn", "hk", "us"), default "cn"
143
+ start_date: Start date (YYYY-MM-DD), default 3 months ago
144
+ end_date: End date (YYYY-MM-DD), default today
114
145
 
115
146
  Returns:
116
147
  DataFrame with factor values
117
148
 
118
149
  Example:
119
- >>> df = client.quant.factors(
120
- ... symbols=["US:AAPL", "US:MSFT"],
121
- ... factors=["momentum", "value"],
122
- ... frequency="monthly"
123
- ... )
150
+ >>> # Simple indicator
151
+ >>> df = client.quant.compute_factors(["000001"], "RSI(14)")
152
+
153
+ >>> # MACD DIF line
154
+ >>> df = client.quant.compute_factors(["000001"], "MACD().dif")
155
+
156
+ >>> # Close above 20-day MA (boolean)
157
+ >>> df = client.quant.compute_factors(["000001"], "CLOSE > MA(20)")
158
+
159
+ >>> # Deviation from MA20 in percent
160
+ >>> df = client.quant.compute_factors(["000001"], "(CLOSE - MA(20)) / MA(20) * 100")
161
+
162
+ Supported Operators:
163
+ - Comparison: >, <, >=, <=, ==, !=
164
+ - Logical AND: & (NOT "AND")
165
+ - Logical OR: | (NOT "OR")
166
+ - Arithmetic: +, -, *, /
167
+
168
+ Supported Variables:
169
+ - CLOSE, C: Close price
170
+ - OPEN, O: Open price
171
+ - HIGH, H: High price
172
+ - LOW, L: Low price
173
+ - VOLUME, V, VOL: Volume
124
174
  """
125
175
  data: dict[str, Any] = {
126
176
  "symbols": symbols,
127
- "factors": factors,
128
- "frequency": frequency,
177
+ "formula": formula,
178
+ "market": market,
129
179
  }
130
180
  if start_date:
131
181
  data["start_date"] = start_date
132
182
  if end_date:
133
183
  data["end_date"] = end_date
134
184
 
135
- response = self._client._post("/v2/quant/factors", json=data)
136
- return self._to_dataframe(response.get("data", []))
137
-
138
- def factor_list(self) -> list[dict[str, Any]]:
139
- """
140
- Get list of available factors
185
+ response = self._client._post("/v1/quant/factors/compute", json=data)
186
+ return self._to_dataframe(response.get("datas", []))
141
187
 
142
- Returns:
143
- List of factor definitions
144
-
145
- Example:
146
- >>> factors = client.quant.factor_list()
147
- >>> for f in factors:
148
- ... print(f"{f['name']}: {f['category']}")
149
- """
150
- response = self._client._get("/v2/quant/factors")
151
- return response.get("factors", [])
152
-
153
- def factor_exposure(
188
+ def screen(
154
189
  self,
155
- symbols: list[str],
190
+ formula: str,
156
191
  *,
157
- date: str | None = None,
192
+ market: StockMarket = "cn",
193
+ check_date: str | None = None,
194
+ symbols: list[str] | None = None,
158
195
  ) -> pd.DataFrame:
159
196
  """
160
- Get factor exposure for given symbols
197
+ Screen stocks based on factor formula
198
+
199
+ Returns stocks where the formula evaluates to True (for boolean formulas)
200
+ or non-null (for numeric formulas).
161
201
 
162
202
  Args:
163
- symbols: List of stock symbols
164
- date: Specific date (YYYY-MM-DD), defaults to latest
203
+ formula: Screening formula using Mai-language syntax
204
+ market: Stock market ("cn", "hk", "us"), default "cn"
205
+ check_date: Check date (YYYY-MM-DD), default latest trading day
206
+ symbols: Stock codes to screen (None = full market)
165
207
 
166
208
  Returns:
167
- DataFrame with factor exposures for each symbol
209
+ DataFrame with stocks that passed the filter
168
210
 
169
211
  Example:
170
- >>> exposure = client.quant.factor_exposure(["US:AAPL", "US:GOOGL"])
171
- >>> print(exposure[["symbol", "momentum", "value", "quality"]])
212
+ >>> # RSI oversold
213
+ >>> stocks = client.quant.screen(formula="RSI(14) < 30")
214
+
215
+ >>> # Golden cross
216
+ >>> stocks = client.quant.screen(formula="CROSS(MA(5), MA(10))")
217
+
218
+ >>> # Uptrend
219
+ >>> stocks = client.quant.screen(formula="(CLOSE > MA(20)) & (MA(20) > MA(60))")
220
+
221
+ >>> # Above upper Bollinger Band
222
+ >>> stocks = client.quant.screen(formula="CLOSE > BOLL(20, 2).upper")
223
+
224
+ >>> # Screen specific stocks
225
+ >>> stocks = client.quant.screen(
226
+ ... formula="RSI(14) < 30",
227
+ ... symbols=["000001", "600519", "000002"]
228
+ ... )
172
229
  """
173
- data: dict[str, Any] = {"symbols": symbols}
174
- if date:
175
- data["date"] = date
230
+ data: dict[str, Any] = {
231
+ "formula": formula,
232
+ "market": market,
233
+ }
234
+ if check_date:
235
+ data["check_date"] = check_date
236
+ if symbols:
237
+ data["symbols"] = symbols
176
238
 
177
- response = self._client._post("/v2/quant/factors/exposure", json=data)
178
- return self._to_dataframe(response.get("data", []))
239
+ response = self._client._post("/v1/quant/factors/screen", json=data)
240
+ return self._to_dataframe(response.get("datas", []))
179
241
 
180
242
  # -------------------------------------------------------------------------
181
243
  # Quotes
182
244
  # -------------------------------------------------------------------------
183
245
 
184
- def quotes(
246
+ def ohlcv(
185
247
  self,
186
- symbols: list[str],
248
+ symbol: str,
187
249
  *,
188
- fields: list[str] | None = None,
250
+ market: StockMarket = "cn",
251
+ start_date: str | None = None,
252
+ end_date: str | None = None,
189
253
  ) -> pd.DataFrame:
190
254
  """
191
- Get real-time quotes for given symbols
255
+ Get OHLCV (Open, High, Low, Close, Volume) daily data for a single symbol
192
256
 
193
257
  Args:
194
- symbols: List of stock symbols
195
- fields: Specific fields to return (default: all)
258
+ symbol: Stock code
259
+ market: Stock market ("cn", "hk", "us"), default "cn"
260
+ start_date: Start date (YYYY-MM-DD), default 1 month ago
261
+ end_date: End date (YYYY-MM-DD), default today
196
262
 
197
263
  Returns:
198
- DataFrame with quote data
264
+ DataFrame with OHLCV data
199
265
 
200
266
  Example:
201
- >>> quotes = client.quant.quotes(["US:AAPL", "US:MSFT"])
202
- >>> print(quotes[["symbol", "price", "change", "volume"]])
267
+ >>> df = client.quant.ohlcv("000001")
268
+ >>> print(df[["open", "high", "low", "close", "volume"]])
203
269
  """
204
- data: dict[str, Any] = {"symbols": symbols}
205
- if fields:
206
- data["fields"] = fields
270
+ params: dict[str, Any] = {
271
+ "symbol": symbol,
272
+ "market": market,
273
+ }
274
+ if start_date:
275
+ params["start_date"] = start_date
276
+ if end_date:
277
+ params["end_date"] = end_date
207
278
 
208
- response = self._client._post("/v2/quant/quotes", json=data)
209
- return self._to_dataframe(response.get("data", []))
279
+ response = self._client._get("/v1/quant/quotes/ohlcv", params=params)
280
+ return self._to_dataframe(response.get("datas", []))
210
281
 
211
- def quotes_history(
282
+ def ohlcv_batch(
212
283
  self,
213
284
  symbols: list[str],
214
285
  *,
286
+ market: StockMarket = "cn",
215
287
  start_date: str | None = None,
216
288
  end_date: str | None = None,
217
- interval: str = "1d",
218
- adjust: str = "forward",
219
- limit: int = 100,
220
289
  ) -> pd.DataFrame:
221
290
  """
222
- Get historical quotes data
291
+ Get OHLCV data for multiple symbols
223
292
 
224
293
  Args:
225
- symbols: List of stock symbols
226
- start_date: Start date (YYYY-MM-DD)
227
- end_date: End date (YYYY-MM-DD)
228
- interval: Data interval ("1d", "1w", "1m")
229
- adjust: Adjustment type ("forward", "backward", "none")
230
- limit: Maximum records per symbol
294
+ symbols: List of stock codes
295
+ market: Stock market ("cn", "hk", "us"), default "cn"
296
+ start_date: Start date (YYYY-MM-DD), default 1 month ago
297
+ end_date: End date (YYYY-MM-DD), default today
231
298
 
232
299
  Returns:
233
- DataFrame with historical OHLCV data
300
+ DataFrame with OHLCV data sorted by date (descending), then by symbol
234
301
 
235
302
  Example:
236
- >>> history = client.quant.quotes_history(
237
- ... ["US:AAPL"],
238
- ... start_date="2024-01-01",
239
- ... interval="1d"
240
- ... )
303
+ >>> df = client.quant.ohlcv_batch(["000001", "600519"])
304
+ >>> print(df[["symbol", "date", "close", "volume"]])
241
305
  """
242
306
  data: dict[str, Any] = {
243
307
  "symbols": symbols,
244
- "interval": interval,
245
- "adjust": adjust,
246
- "limit": limit,
308
+ "market": market,
247
309
  }
248
310
  if start_date:
249
311
  data["start_date"] = start_date
250
312
  if end_date:
251
313
  data["end_date"] = end_date
252
314
 
253
- response = self._client._post("/v2/quant/quotes/history", json=data)
254
- return self._to_dataframe(response.get("data", []))
315
+ response = self._client._post("/v1/quant/quotes/ohlcv/batch", json=data)
316
+ return self._to_dataframe(response.get("datas", []))
255
317
 
256
318
  # -------------------------------------------------------------------------
257
319
  # Backtest
@@ -259,99 +321,100 @@ class QuantModule:
259
321
 
260
322
  def backtest(
261
323
  self,
262
- strategy: dict[str, Any],
263
- *,
264
324
  start_date: str,
265
325
  end_date: str,
266
- initial_capital: float = 1000000.0,
267
- benchmark: str | None = None,
326
+ symbol: str,
327
+ entry_formula: str,
328
+ *,
329
+ exit_formula: str | None = None,
330
+ market: StockMarket = "cn",
331
+ initial_cash: float = 100000.0,
332
+ commission: float = 0.0,
333
+ stop_loss: float = 0.0,
334
+ sizer_percent: int = 99,
335
+ auto_close: bool = True,
336
+ labels: dict[str, str] | None = None,
268
337
  ) -> dict[str, Any]:
269
338
  """
270
- Run a backtest for a given strategy
339
+ Execute strategy backtest
271
340
 
272
341
  Args:
273
- strategy: Strategy definition dict
274
342
  start_date: Backtest start date (YYYY-MM-DD)
275
343
  end_date: Backtest end date (YYYY-MM-DD)
276
- initial_capital: Starting capital (default: 1,000,000)
277
- benchmark: Benchmark symbol for comparison (e.g., "US:SPY")
344
+ symbol: Stock code
345
+ market: Stock market ("cn", "hk", "us"), default "cn"
346
+ entry_formula: Buy/long entry formula (result > 0 triggers buy)
347
+ exit_formula: Sell/close formula (result > 0 triggers sell), optional
348
+ initial_cash: Initial capital (default: 100000.0)
349
+ commission: Commission rate (default: 0.0)
350
+ stop_loss: Stop loss setting (default: 0.0, no stop loss)
351
+ sizer_percent: Position percentage (default: 99%)
352
+ auto_close: Auto close positions (default: True)
353
+ labels: Label dict for returning extra indicator values, e.g. {"up": "CROSS(MA(20), MA(60))"}
278
354
 
279
355
  Returns:
280
- Backtest results including returns, metrics, and trades
356
+ Backtest results including:
357
+ - success: Whether backtest succeeded
358
+ - initial_cash: Initial capital
359
+ - final_cash: Final capital
360
+ - total_return: Total return
361
+ - total_return_pct: Total return percentage
362
+ - max_drawdown: Maximum drawdown
363
+ - profit_factor: Profit factor
364
+ - win_rate: Win rate
365
+ - total_trades: Total number of trades
366
+ - trades: List of trade details
281
367
 
282
368
  Example:
369
+ >>> # Simple golden cross strategy
283
370
  >>> result = client.quant.backtest(
284
- ... strategy={
285
- ... "type": "momentum",
286
- ... "universe": ["US:AAPL", "US:MSFT", "US:GOOGL"],
287
- ... "rebalance": "monthly",
288
- ... "top_n": 2
289
- ... },
290
- ... start_date="2020-01-01",
371
+ ... start_date="2023-01-01",
291
372
  ... end_date="2024-01-01",
292
- ... benchmark="US:SPY"
373
+ ... symbol="000001",
374
+ ... entry_formula="CROSS(MA(5), MA(20))", # Buy when MA5 crosses above MA20
375
+ ... initial_cash=100000
376
+ ... )
377
+ >>> print(f"Total Return: {result['total_return_pct']:.2%}")
378
+ >>> print(f"Max Drawdown: {result['max_drawdown']:.2%}")
379
+ >>> print(f"Win Rate: {result['win_rate']:.2%}")
380
+
381
+ >>> # Strategy with entry and exit signals
382
+ >>> result = client.quant.backtest(
383
+ ... start_date="2023-01-01",
384
+ ... end_date="2024-01-01",
385
+ ... symbol="000001",
386
+ ... entry_formula="CROSS(MA(5), MA(20))", # Buy signal
387
+ ... exit_formula="CROSSDOWN(MA(5), MA(20))" # Sell signal
388
+ ... )
389
+
390
+ >>> # With custom labels for analysis
391
+ >>> result = client.quant.backtest(
392
+ ... start_date="2023-01-01",
393
+ ... end_date="2024-01-01",
394
+ ... symbol="000001",
395
+ ... entry_formula="RSI(14) < 30",
396
+ ... exit_formula="RSI(14) > 70",
397
+ ... labels={"rsi": "RSI(14)", "ma20": "MA(20)"}
293
398
  ... )
294
- >>> print(f"Total Return: {result['metrics']['total_return']:.2%}")
295
399
  """
296
400
  data = {
297
- "strategy": strategy,
298
401
  "start_date": start_date,
299
402
  "end_date": end_date,
300
- "initial_capital": initial_capital,
403
+ "symbol": symbol,
404
+ "market": market,
405
+ "entry_formula": entry_formula,
406
+ "initial_cash": initial_cash,
407
+ "commission": commission,
408
+ "stop_loss": stop_loss,
409
+ "sizer_percent": sizer_percent,
410
+ "auto_close": auto_close,
301
411
  }
302
- if benchmark:
303
- data["benchmark"] = benchmark
304
-
305
- return self._client._post("/v2/quant/backtest", json=data)
306
-
307
- def backtest_result(self, backtest_id: str) -> dict[str, Any]:
308
- """
309
- Get backtest result by ID
310
-
311
- Args:
312
- backtest_id: Backtest job ID
313
-
314
- Returns:
315
- Backtest results
316
-
317
- Example:
318
- >>> result = client.quant.backtest_result("bt_abc123")
319
- """
320
- return self._client._get(f"/v2/quant/backtest/{backtest_id}")
321
-
322
- def backtest_returns(self, backtest_id: str) -> pd.DataFrame:
323
- """
324
- Get backtest return series
412
+ if exit_formula is not None:
413
+ data["exit_formula"] = exit_formula
414
+ if labels is not None:
415
+ data["labels"] = labels
325
416
 
326
- Args:
327
- backtest_id: Backtest job ID
328
-
329
- Returns:
330
- DataFrame with daily returns
331
-
332
- Example:
333
- >>> returns = client.quant.backtest_returns("bt_abc123")
334
- >>> print(returns[["date", "portfolio_value", "daily_return"]])
335
- """
336
- response = self._client._get(f"/v2/quant/backtest/{backtest_id}/returns")
337
- return self._to_dataframe(response.get("data", []))
338
-
339
- def backtest_trades(self, backtest_id: str) -> pd.DataFrame:
340
- """
341
- Get backtest trade history
342
-
343
- Args:
344
- backtest_id: Backtest job ID
345
-
346
- Returns:
347
- DataFrame with all trades
348
-
349
- Example:
350
- >>> trades = client.quant.backtest_trades("bt_abc123")
351
- >>> print(trades[["date", "symbol", "action", "quantity", "price"]])
352
- """
353
- response = self._client._get(f"/v2/quant/backtest/{backtest_id}/trades")
354
- return self._to_dataframe(response.get("data", []))
417
+ return self._client._post("/v1/quant/backtest", json=data)
355
418
 
356
419
  # -------------------------------------------------------------------------
357
420
  # Helper Methods
@@ -363,9 +426,7 @@ class QuantModule:
363
426
  return pd.DataFrame()
364
427
  df = pd.DataFrame(data)
365
428
  # Convert date columns if present
366
- for col in ["date", "timestamp", "trade_date"]:
429
+ for col in ["date", "check_date", "trade_date"]:
367
430
  if col in df.columns:
368
431
  df[col] = pd.to_datetime(df[col])
369
- df = df.set_index(col)
370
- break
371
432
  return df
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reportify-sdk
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Python SDK for Reportify API - Financial data and document search
5
5
  Author-email: Reportify <support@reportify.cn>
6
6
  License-Expression: MIT
@@ -3,11 +3,11 @@ reportify_sdk/client.py,sha256=P56qBme48UPkZhMb9BlDnLMLXwHK-DjU7qDhGFFxMI0,11019
3
3
  reportify_sdk/docs.py,sha256=O30I1J4qTC8zpkVP_qu1cgT8nv6ysXNClqvaiRb0lhY,4957
4
4
  reportify_sdk/exceptions.py,sha256=r2_C_kTh6tCrQnfA3UozSqMMA-2OBnoP3pGpgYeqcdU,1049
5
5
  reportify_sdk/kb.py,sha256=-4UHWtudFncGRBB42B4YEoMPsEHr4QOtY55_8hKyogE,2240
6
- reportify_sdk/quant.py,sha256=xXh4mz4B_iUh4PRbc0KI5e2FVtO0Hawvw_TMP_5rji4,11658
6
+ reportify_sdk/quant.py,sha256=9rWKWo2UlG3GfsQC-jpEgXUl25ojEabpvOGISyGMamM,15110
7
7
  reportify_sdk/stock.py,sha256=NcEhV9JfIQm2BsfYM1k-JVcxHhnnil32dp-bedGG4BU,13513
8
8
  reportify_sdk/timeline.py,sha256=b5Zj5SjXT4gP0dvEl8gXCWDZJHemyU7NSYahet2nHhc,4075
9
- reportify_sdk-0.2.0.dist-info/licenses/LICENSE,sha256=zBUq4DL4lE-fZU_PMkr0gnxkYS1LhdRHFw8_LmCb-ek,1066
10
- reportify_sdk-0.2.0.dist-info/METADATA,sha256=kmE-VtAC7lDLy6E4X8mWMVcq8gBpv-ukuFKple3J0F8,4311
11
- reportify_sdk-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
- reportify_sdk-0.2.0.dist-info/top_level.txt,sha256=tc_dzCSWIDsNbHSi-FlyEEX8xwinhN9gl-CwyLRE4B0,14
13
- reportify_sdk-0.2.0.dist-info/RECORD,,
9
+ reportify_sdk-0.2.2.dist-info/licenses/LICENSE,sha256=zBUq4DL4lE-fZU_PMkr0gnxkYS1LhdRHFw8_LmCb-ek,1066
10
+ reportify_sdk-0.2.2.dist-info/METADATA,sha256=mKL0oZbmcTLi0pGVLPZDYiULHI5g_qZ_-PDjnNOinz0,4311
11
+ reportify_sdk-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
+ reportify_sdk-0.2.2.dist-info/top_level.txt,sha256=tc_dzCSWIDsNbHSi-FlyEEX8xwinhN9gl-CwyLRE4B0,14
13
+ reportify_sdk-0.2.2.dist-info/RECORD,,