quantcli 0.2.0__tar.gz → 0.2.1__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.0/quantcli.egg-info → quantcli-0.2.1}/PKG-INFO +1 -1
- {quantcli-0.2.0 → quantcli-0.2.1}/pyproject.toml +1 -1
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/akshare.py +30 -1
- {quantcli-0.2.0 → quantcli-0.2.1/quantcli.egg-info}/PKG-INFO +1 -1
- {quantcli-0.2.0 → quantcli-0.2.1}/LICENSE +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/README.md +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/cli.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/core/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/core/backtest.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/core/data.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/core/factor.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/baostock.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/base.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/cache.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/fundamentals/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/fundamentals/provider.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/mixed.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/mysql.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/sync/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/sync/akshare.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/sync/base.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/sync/gm.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/datasources/sync/gm_fundamental.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_001.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_002.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_003.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_004.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_005.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_006.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_007.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_008.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_009.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_010.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_011.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_012.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_013.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_014.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_015.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_016.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_017.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_018.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_019.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_020.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_021.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_022.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_023.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_024.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_025.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_026.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_027.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_028.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_029.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_030.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_031.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_032.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_033.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_034.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_035.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_036.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_037.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_038.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_039.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/alpha101/alpha_040.yaml +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/base.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/compute.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/loader.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/pipeline.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/ranking.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/ranking_executor.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/screening.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/factors/screening_executor.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/models/bar.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/parser/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/parser/constants.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/parser/formula.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/__init__.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/env.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/logger.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/path.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/symbol_utils.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/time.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli/utils/validate.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli.egg-info/SOURCES.txt +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli.egg-info/dependency_links.txt +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli.egg-info/entry_points.txt +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli.egg-info/requires.txt +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/quantcli.egg-info/top_level.txt +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/setup.cfg +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_akshare_integration.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_builtin_factors.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_cli.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_data_manager.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_datasources.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_factors.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_gm_executors.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_mixed_datasource.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_multi_factor.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_pipeline_integration.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_symbol_utils.py +0 -0
- {quantcli-0.2.0 → quantcli-0.2.1}/tests/test_time.py +0 -0
|
@@ -235,13 +235,16 @@ class AkshareDataSource(DataSource):
|
|
|
235
235
|
"""获取交易日历"""
|
|
236
236
|
if self.config.use_cache:
|
|
237
237
|
cached = self._calendar_cache.get_calendar(exchange)
|
|
238
|
-
if cached is not None:
|
|
238
|
+
if cached is not None and self._validate_calendar(cached):
|
|
239
239
|
return sorted(pd.to_datetime(cached["trade_date"]).dt.date.tolist())
|
|
240
240
|
|
|
241
241
|
df = self._ak.tool_trade_date_hist_sina()
|
|
242
242
|
if df.empty:
|
|
243
243
|
return []
|
|
244
244
|
|
|
245
|
+
if not self._validate_calendar(df):
|
|
246
|
+
return []
|
|
247
|
+
|
|
245
248
|
trading_dates = pd.to_datetime(df["trade_date"]).dt.date.tolist()
|
|
246
249
|
|
|
247
250
|
if self.config.use_cache:
|
|
@@ -249,6 +252,32 @@ class AkshareDataSource(DataSource):
|
|
|
249
252
|
|
|
250
253
|
return sorted(trading_dates)
|
|
251
254
|
|
|
255
|
+
def _validate_calendar(self, df: pd.DataFrame) -> bool:
|
|
256
|
+
"""验证交易日历是否完整"""
|
|
257
|
+
if df.empty:
|
|
258
|
+
return False
|
|
259
|
+
|
|
260
|
+
dates = pd.to_datetime(df["trade_date"])
|
|
261
|
+
min_date = dates.min()
|
|
262
|
+
max_date = dates.max()
|
|
263
|
+
|
|
264
|
+
# 检查日期范围(默认应该覆盖近1年)
|
|
265
|
+
from datetime import timedelta
|
|
266
|
+
|
|
267
|
+
one_year_ago = pd.Timestamp.now() - timedelta(days=365)
|
|
268
|
+
|
|
269
|
+
if min_date > one_year_ago:
|
|
270
|
+
return False
|
|
271
|
+
|
|
272
|
+
# 检查数量(1年应该有约250个交易日)
|
|
273
|
+
expected_min = 200
|
|
274
|
+
actual = len(dates)
|
|
275
|
+
|
|
276
|
+
if actual < expected_min:
|
|
277
|
+
return False
|
|
278
|
+
|
|
279
|
+
return True
|
|
280
|
+
|
|
252
281
|
# ==================== 辅助方法 ====================
|
|
253
282
|
|
|
254
283
|
def _filter_fields(
|
|
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
|
|
File without changes
|