quantcli 0.2.2__tar.gz → 0.2.6__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.
- {quantcli-0.2.2/quantcli.egg-info → quantcli-0.2.6}/PKG-INFO +1 -1
- {quantcli-0.2.2 → quantcli-0.2.6}/pyproject.toml +1 -1
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/cli.py +99 -13
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/mysql.py +13 -5
- {quantcli-0.2.2 → quantcli-0.2.6/quantcli.egg-info}/PKG-INFO +1 -1
- {quantcli-0.2.2 → quantcli-0.2.6}/LICENSE +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/README.md +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/core/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/core/backtest.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/core/data.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/core/factor.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/akshare.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/baostock.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/base.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/cache.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/fundamentals/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/fundamentals/provider.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/mixed.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/sync/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/sync/akshare.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/sync/base.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/sync/gm.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/datasources/sync/gm_fundamental.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_001.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_002.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_003.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_004.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_005.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_006.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_007.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_008.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_009.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_010.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_011.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_012.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_013.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_014.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_015.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_016.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_017.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_018.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_019.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_020.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_021.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_022.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_023.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_024.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_025.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_026.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_027.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_028.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_029.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_030.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_031.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_032.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_033.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_034.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_035.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_036.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_037.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_038.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_039.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/alpha101/alpha_040.yaml +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/base.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/compute.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/loader.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/pipeline.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/ranking.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/ranking_executor.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/screening.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/factors/screening_executor.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/models/bar.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/parser/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/parser/constants.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/parser/formula.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/__init__.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/env.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/logger.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/path.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/symbol_utils.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/time.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli/utils/validate.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli.egg-info/SOURCES.txt +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli.egg-info/dependency_links.txt +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli.egg-info/entry_points.txt +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli.egg-info/requires.txt +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/quantcli.egg-info/top_level.txt +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/setup.cfg +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_akshare_integration.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_builtin_factors.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_cli.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_data_manager.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_datasources.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_factors.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_gm_executors.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_mixed_datasource.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_multi_factor.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_pipeline_integration.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_symbol_utils.py +0 -0
- {quantcli-0.2.2 → quantcli-0.2.6}/tests/test_time.py +0 -0
|
@@ -107,7 +107,7 @@ def data(ctx):
|
|
|
107
107
|
@click.option(
|
|
108
108
|
"--source",
|
|
109
109
|
type=click.Choice(["akshare", "baostock", "mixed", "mysql"]),
|
|
110
|
-
default="
|
|
110
|
+
default="mysql",
|
|
111
111
|
help="数据源 (akshare/baostock/mixed/mysql)",
|
|
112
112
|
)
|
|
113
113
|
@click.option("--use-cache/--no-cache", default=True, help="是否使用缓存")
|
|
@@ -173,7 +173,93 @@ def data_fetch(ctx, symbol, start, end, source, use_cache, cache_raw, output):
|
|
|
173
173
|
click.echo(f"Saved to {output}")
|
|
174
174
|
|
|
175
175
|
except Exception as e:
|
|
176
|
-
|
|
176
|
+
error_msg = str(e)
|
|
177
|
+
if "Access denied" in error_msg or "Connection refused" in error_msg:
|
|
178
|
+
click.echo(f"MySQL 连接失败: 请检查数据库配置", err=True)
|
|
179
|
+
click.echo(
|
|
180
|
+
"提示: 使用 --source akshare 或 --source baostock 可以切换到其他数据源",
|
|
181
|
+
err=True,
|
|
182
|
+
)
|
|
183
|
+
else:
|
|
184
|
+
click.echo(f"Error: {e}", err=True)
|
|
185
|
+
sys.exit(1)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@data.command("fetch-fundamental")
|
|
189
|
+
@click.argument("symbols", type=str, nargs=-1)
|
|
190
|
+
@click.option(
|
|
191
|
+
"--date",
|
|
192
|
+
type=date_type,
|
|
193
|
+
default=None,
|
|
194
|
+
help="截止日期 (YYYY-MM-DD,默认今天)",
|
|
195
|
+
)
|
|
196
|
+
@click.option(
|
|
197
|
+
"--source",
|
|
198
|
+
type=click.Choice(["mysql", "baostock"]),
|
|
199
|
+
default="mysql",
|
|
200
|
+
help="数据源 (mysql/baostock)",
|
|
201
|
+
)
|
|
202
|
+
@click.option(
|
|
203
|
+
"--output",
|
|
204
|
+
"-o",
|
|
205
|
+
type=click.Path(),
|
|
206
|
+
default=None,
|
|
207
|
+
help="输出文件路径 (如: data.csv)",
|
|
208
|
+
)
|
|
209
|
+
@click.pass_context
|
|
210
|
+
def data_fetch_fundamental(ctx, symbols, date, source, output):
|
|
211
|
+
"""获取股票基本面数据
|
|
212
|
+
|
|
213
|
+
股票代码:
|
|
214
|
+
000001 - 平安银行
|
|
215
|
+
600519 - 贵州茅台
|
|
216
|
+
|
|
217
|
+
示例:
|
|
218
|
+
quantcli data fetch-fundamental 000001 600519
|
|
219
|
+
quantcli data fetch-fundamental 600519 --date 2024-12-31
|
|
220
|
+
quantcli data fetch-fundamental 000001 --source baostock -o fundamentals.csv
|
|
221
|
+
"""
|
|
222
|
+
if not symbols:
|
|
223
|
+
click.echo("Error: At least one symbol is required")
|
|
224
|
+
sys.exit(1)
|
|
225
|
+
|
|
226
|
+
if date is None:
|
|
227
|
+
date = today()
|
|
228
|
+
|
|
229
|
+
click.echo(
|
|
230
|
+
f"Fetching fundamental data for {len(symbols)} symbols at {format_date(date)}..."
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
config = DataConfig(source=source)
|
|
234
|
+
dm = DataManager(config)
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
df = dm.datasource.get_fundamental(list(symbols), date)
|
|
238
|
+
|
|
239
|
+
if df.empty:
|
|
240
|
+
click.echo(f"No fundamental data found for symbols")
|
|
241
|
+
return
|
|
242
|
+
|
|
243
|
+
click.echo(f"Retrieved {len(df)} rows")
|
|
244
|
+
|
|
245
|
+
click.echo(df.to_string())
|
|
246
|
+
|
|
247
|
+
if output:
|
|
248
|
+
if output.endswith(".csv"):
|
|
249
|
+
df.to_csv(output, index=False)
|
|
250
|
+
elif output.endswith(".parquet"):
|
|
251
|
+
df.to_parquet(output, index=False)
|
|
252
|
+
else:
|
|
253
|
+
df.to_csv(output, index=False)
|
|
254
|
+
click.echo(f"Saved to {output}")
|
|
255
|
+
|
|
256
|
+
except Exception as e:
|
|
257
|
+
error_msg = str(e)
|
|
258
|
+
if "Access denied" in error_msg or "Connection refused" in error_msg:
|
|
259
|
+
click.echo(f"MySQL 连接失败: 请检查数据库配置", err=True)
|
|
260
|
+
click.echo("提示: 使用 --source baostock 可以切换到其他数据源", err=True)
|
|
261
|
+
else:
|
|
262
|
+
click.echo(f"Error: {e}", err=True)
|
|
177
263
|
sys.exit(1)
|
|
178
264
|
|
|
179
265
|
|
|
@@ -195,7 +281,7 @@ def data_cache(ctx):
|
|
|
195
281
|
@click.pass_context
|
|
196
282
|
def data_cache_ls(ctx, pattern, sort):
|
|
197
283
|
"""列出缓存文件"""
|
|
198
|
-
config = DataConfig()
|
|
284
|
+
config = DataConfig(source="mysql")
|
|
199
285
|
dm = DataManager(config)
|
|
200
286
|
sizes = dm.get_cache_size()
|
|
201
287
|
|
|
@@ -233,7 +319,7 @@ def data_cache_ls(ctx, pattern, sort):
|
|
|
233
319
|
@click.pass_context
|
|
234
320
|
def data_cache_clean(ctx, older_than):
|
|
235
321
|
"""清理缓存文件"""
|
|
236
|
-
config = DataConfig()
|
|
322
|
+
config = DataConfig(source="mysql")
|
|
237
323
|
dm = DataManager(config)
|
|
238
324
|
|
|
239
325
|
count = dm.clear_cache(older_than=older_than)
|
|
@@ -244,7 +330,7 @@ def data_cache_clean(ctx, older_than):
|
|
|
244
330
|
@click.pass_context
|
|
245
331
|
def data_health(ctx):
|
|
246
332
|
"""检查数据源健康状态"""
|
|
247
|
-
config = DataConfig()
|
|
333
|
+
config = DataConfig(source="mysql")
|
|
248
334
|
dm = DataManager(config)
|
|
249
335
|
health = dm.health_check()
|
|
250
336
|
|
|
@@ -309,7 +395,7 @@ def factor_run(ctx, name, expr, symbol, start, end, output):
|
|
|
309
395
|
click.echo(f"Computing factor '{name}'...")
|
|
310
396
|
|
|
311
397
|
# 创建引擎
|
|
312
|
-
config = DataConfig()
|
|
398
|
+
config = DataConfig(source="mysql")
|
|
313
399
|
dm = DataManager(config)
|
|
314
400
|
engine = FactorEngine(dm)
|
|
315
401
|
|
|
@@ -370,7 +456,7 @@ def factor_eval(ctx, name, symbol, start, end, method):
|
|
|
370
456
|
|
|
371
457
|
click.echo(f"Evaluating factor '{name}'...")
|
|
372
458
|
|
|
373
|
-
config = DataConfig()
|
|
459
|
+
config = DataConfig(source="mysql")
|
|
374
460
|
dm = DataManager(config)
|
|
375
461
|
engine = FactorEngine(dm)
|
|
376
462
|
|
|
@@ -735,7 +821,7 @@ def filter_run(
|
|
|
735
821
|
if daily_conditions:
|
|
736
822
|
# 只对候选获取日线数据
|
|
737
823
|
click.echo(f"Fetching daily data for {len(candidates)} candidates...")
|
|
738
|
-
dm = DataManager(DataConfig(source="
|
|
824
|
+
dm = DataManager(DataConfig(source="mysql"))
|
|
739
825
|
|
|
740
826
|
price_data = {}
|
|
741
827
|
for symbol in candidates:
|
|
@@ -833,7 +919,7 @@ def filter_run(
|
|
|
833
919
|
# 阶段2: 日线
|
|
834
920
|
click.echo(f"\n=== Stage 2: Daily Screening ===")
|
|
835
921
|
click.echo(f"Fetching daily data for {len(candidates)} candidates...")
|
|
836
|
-
dm = DataManager(DataConfig(source="
|
|
922
|
+
dm = DataManager(DataConfig(source="mysql"))
|
|
837
923
|
|
|
838
924
|
price_data = {}
|
|
839
925
|
for symbol in candidates:
|
|
@@ -889,7 +975,7 @@ def filter_run(
|
|
|
889
975
|
return
|
|
890
976
|
|
|
891
977
|
click.echo(f"Fetching price data for {len(candidates)} candidates...")
|
|
892
|
-
dm = DataManager(DataConfig(source="
|
|
978
|
+
dm = DataManager(DataConfig(source="mysql"))
|
|
893
979
|
|
|
894
980
|
price_data = {}
|
|
895
981
|
for symbol in candidates:
|
|
@@ -1307,7 +1393,7 @@ def analyze_ic(ctx, expr, name, symbol, start, end, period, window, method):
|
|
|
1307
1393
|
click.echo(f"Forward period: {period} days, Window: {window}")
|
|
1308
1394
|
|
|
1309
1395
|
# 获取数据
|
|
1310
|
-
config = DataConfig()
|
|
1396
|
+
config = DataConfig(source="mysql")
|
|
1311
1397
|
dm = DataManager(config)
|
|
1312
1398
|
df = dm.get_daily(symbol, start, end)
|
|
1313
1399
|
|
|
@@ -1426,7 +1512,7 @@ def analyze_batch(ctx, dir, symbol, start, end, period, window, top, output):
|
|
|
1426
1512
|
click.echo(f"Analyzing with period={period}d, window={window}...\n")
|
|
1427
1513
|
|
|
1428
1514
|
# 获取数据
|
|
1429
|
-
config = DataConfig()
|
|
1515
|
+
config = DataConfig(source="mysql")
|
|
1430
1516
|
dm = DataManager(config)
|
|
1431
1517
|
df = dm.get_daily(symbol, start, end)
|
|
1432
1518
|
|
|
@@ -1545,7 +1631,7 @@ def config():
|
|
|
1545
1631
|
@click.pass_context
|
|
1546
1632
|
def config_show(ctx):
|
|
1547
1633
|
"""显示当前配置"""
|
|
1548
|
-
config = DataConfig()
|
|
1634
|
+
config = DataConfig(source="mysql")
|
|
1549
1635
|
click.echo("QuantCLI Configuration:")
|
|
1550
1636
|
click.echo(f" data.source: {config.source}")
|
|
1551
1637
|
click.echo(f" data.cache_dir: {config.cache_dir}")
|
|
@@ -88,9 +88,14 @@ class MySQLDataSource(DataSource):
|
|
|
88
88
|
self._prefix = config_dict["table_prefix"]
|
|
89
89
|
self._autocommit = autocommit
|
|
90
90
|
self._conn = None
|
|
91
|
+
self._tables_initialized = False
|
|
91
92
|
|
|
92
|
-
|
|
93
|
+
def _ensure_tables(self):
|
|
94
|
+
"""确保数据库表已初始化(懒加载)"""
|
|
95
|
+
if self._tables_initialized:
|
|
96
|
+
return
|
|
93
97
|
self._init_tables()
|
|
98
|
+
self._tables_initialized = True
|
|
94
99
|
|
|
95
100
|
def _get_connection(self):
|
|
96
101
|
"""获取数据库连接"""
|
|
@@ -196,7 +201,8 @@ class MySQLDataSource(DataSource):
|
|
|
196
201
|
cursor.execute(sql.format(table=table_name))
|
|
197
202
|
logger.info(f"Table {table_name} ready")
|
|
198
203
|
except Exception as e:
|
|
199
|
-
|
|
204
|
+
if "already exists" not in str(e).lower():
|
|
205
|
+
logger.warning(f"Failed to create table {table_name}: {e}")
|
|
200
206
|
|
|
201
207
|
# ==================== 价格数据 ====================
|
|
202
208
|
|
|
@@ -208,9 +214,8 @@ class MySQLDataSource(DataSource):
|
|
|
208
214
|
"""批量转换为 MySQL 新格式"""
|
|
209
215
|
return [to_mysql(s) for s in symbols]
|
|
210
216
|
|
|
211
|
-
def get_daily(
|
|
212
|
-
self
|
|
213
|
-
) -> pd.DataFrame:
|
|
217
|
+
def get_daily(self, symbol: str, start_date, end_date) -> pd.DataFrame:
|
|
218
|
+
self._ensure_tables()
|
|
214
219
|
"""获取日线数据
|
|
215
220
|
|
|
216
221
|
Args:
|
|
@@ -559,6 +564,7 @@ class MySQLDataSource(DataSource):
|
|
|
559
564
|
# ==================== 股票列表和日历 ====================
|
|
560
565
|
|
|
561
566
|
def get_stock_list(self, market: str = "all") -> pd.DataFrame:
|
|
567
|
+
self._ensure_tables()
|
|
562
568
|
"""获取股票列表"""
|
|
563
569
|
conn = self._get_connection()
|
|
564
570
|
|
|
@@ -595,6 +601,7 @@ class MySQLDataSource(DataSource):
|
|
|
595
601
|
)
|
|
596
602
|
|
|
597
603
|
def get_trading_calendar(self, exchange: str = "SSE") -> List[date]:
|
|
604
|
+
self._ensure_tables()
|
|
598
605
|
"""获取交易日历"""
|
|
599
606
|
conn = self._get_connection()
|
|
600
607
|
|
|
@@ -619,6 +626,7 @@ class MySQLDataSource(DataSource):
|
|
|
619
626
|
def get_fundamental(
|
|
620
627
|
self, symbols: List[str], date, indicators: Optional[List[str]] = None
|
|
621
628
|
) -> pd.DataFrame:
|
|
629
|
+
self._ensure_tables()
|
|
622
630
|
"""获取基本面数据
|
|
623
631
|
|
|
624
632
|
Args:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|