Skip to content

Commit ddf55c1

Browse files
authored
V0.9.63 更新一批代码 (#222)
* 0.9.63 start coding * 0.9.63 优化 get_symbols * 0.9.63 fix cal_symbols_factor * remove * 0.9.63 fix import * 0.9.63 fix import * 0.9.63 yearly_days 最大值限制在365 * 0.9.63 update * 0.9.63 删除 deprecated 函数 * 0.9.63 支持自定义数据库名称 * 0.9.63 删除不必要的类 * 0.9.63 使用 rs_czsc 替换几个函数 * 0.9.63 github actions 不再支持3.8 * 0.9.63 新增 rust 版本的简单测试 * 0.9.63 新增 rust 版本的简单测试
1 parent 8daa121 commit ddf55c1

25 files changed

+517
-2209
lines changed

.github/workflows/pythonpackage.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ name: Python package
55

66
on:
77
push:
8-
branches: [ master, 'V0.9.62' ]
8+
branches: [ master, 'V0.9.63' ]
99
pull_request:
1010
branches: [ master ]
1111

@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
matrix:
18-
python-version: [3.8, 3.9, '3.10', '3.11', '3.12']
18+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
1919

2020
steps:
2121
- uses: actions/checkout@v2

czsc/__init__.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,22 @@
44
email: zeng_bin8888@163.com
55
create_dt: 2019/10/29 15:01
66
"""
7+
from rs_czsc import (
8+
daily_performance,
9+
top_drawdowns,
10+
11+
# python版本:from czsc.traders.weight_backtest import WeightBacktest
12+
WeightBacktest,
13+
)
14+
715
from czsc import envs
816
from czsc import fsa
917
from czsc import utils
1018
from czsc import traders
1119
from czsc import sensors
1220
from czsc import aphorism
21+
from czsc.traders import rwc
22+
from czsc.traders import cwc
1323
from czsc.analyze import CZSC
1424
from czsc.objects import Freq, Operate, Direction, Signal, Factor, Event, RawBar, NewBar, Position, ZS
1525
from czsc.strategies import CzscStrategyBase, CzscJsonStrategy
@@ -25,27 +35,28 @@
2535
PairsPerformance,
2636
combine_holds_and_pairs,
2737
combine_dates_and_pairs,
28-
stock_holds_performance,
2938
DummyBacktest,
3039
SignalsParser,
3140
get_signals_config,
3241
get_signals_freqs,
3342

34-
WeightBacktest,
3543
stoploss_by_direction,
3644
get_ensemble_weight,
37-
long_short_equity,
3845

46+
OpensOptimize,
47+
ExitsOptimize,
48+
)
49+
50+
from czsc.traders.rwc import (
3951
RedisWeightsClient,
4052
get_strategy_mates,
53+
get_strategy_names,
4154
get_heartbeat_time,
4255
clear_strategy,
4356
get_strategy_weights,
4457
get_strategy_latest,
45-
46-
OpensOptimize,
47-
ExitsOptimize,
4858
)
59+
4960
from czsc.utils import (
5061
timeout_decorator,
5162
mac_address,
@@ -81,18 +92,13 @@
8192
risk_free_returns,
8293
resample_to_daily,
8394

84-
CrossSectionalPerformance,
8595
cross_sectional_ranker,
8696
cross_sectional_ic,
87-
SignalAnalyzer,
88-
SignalPerformance,
89-
daily_performance,
97+
# daily_performance,
9098
rolling_daily_performance,
91-
weekly_performance,
9299
holds_performance,
93-
net_value_stats,
94100
subtract_fee,
95-
top_drawdowns,
101+
# top_drawdowns,
96102
psi,
97103

98104
home_path,
@@ -138,7 +144,6 @@
138144
show_correlation,
139145
show_corr_graph,
140146
show_sectional_ic,
141-
show_factor_returns,
142147
show_factor_layering,
143148
show_symbol_factor_layering,
144149
show_weight_backtest,
@@ -175,7 +180,7 @@
175180
from czsc.utils.features import (
176181
normalize_feature,
177182
normalize_ts_feature,
178-
feture_cross_layering,
183+
feature_cross_layering,
179184
find_most_similarity,
180185
)
181186

@@ -221,13 +226,16 @@
221226
)
222227

223228

224-
__version__ = "0.9.62"
229+
__version__ = "0.9.63"
225230
__author__ = "zengbin93"
226231
__email__ = "zeng_bin8888@163.com"
227-
__date__ = "20241208"
232+
__date__ = "20250101"
228233

229234

230235
def welcome():
236+
from czsc import aphorism, envs
237+
from czsc.utils import get_dir_size, home_path
238+
231239
print(f"欢迎使用CZSC!当前版本标识为 {__version__}@{__date__}\n")
232240
aphorism.print_one()
233241

@@ -236,10 +244,8 @@ def welcome():
236244
f"czsc_min_bi_len = {envs.get_min_bi_len()}; "
237245
f"czsc_max_bi_num = {envs.get_max_bi_num()}; "
238246
)
239-
240-
241-
if envs.get_welcome():
242-
welcome()
247+
if get_dir_size(home_path) > pow(1024, 3):
248+
print(f"{home_path} 目录缓存超过1GB,请适当清理。调用 czsc.empty_cache_path() 可以直接清空缓存")
243249

244250

245251
if get_dir_size(home_path) > pow(1024, 3):

czsc/eda.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import numpy as np
1111
from typing import Callable
1212
from tqdm import tqdm
13-
from sklearn.linear_model import Ridge, LinearRegression, Lasso
1413

1514

1615
def vwap(price: np.array, volume: np.array, **kwargs) -> float:
@@ -45,6 +44,7 @@ def remove_beta_effects(df, **kwargs):
4544
4645
:return: DataFrame
4746
"""
47+
from sklearn.linear_model import Ridge, LinearRegression, Lasso
4848

4949
linear_model = kwargs.get("linear_model", "ridge")
5050
linear_model_params = kwargs.get("linear_model_params", {})
@@ -268,7 +268,7 @@ def cal_yearly_days(dts: list, **kwargs):
268268

269269
# 按年重采样并计算每年的交易日数量,取最大值
270270
yearly_days = dts.resample('YE').size().max()
271-
return yearly_days
271+
return min(yearly_days, 365)
272272

273273

274274
def cal_symbols_factor(dfk: pd.DataFrame, factor_function: Callable, **kwargs):
@@ -282,44 +282,55 @@ def cal_symbols_factor(dfk: pd.DataFrame, factor_function: Callable, **kwargs):
282282
- factor_params: dict, 因子计算参数
283283
- min_klines: int, 最小K线数据量,默认为 300
284284
- price_type: str, 交易价格类型,默认为 close,可选值为 close 或 next_open
285+
- strict: bool, 是否严格模式,默认为 True, 严格模式下,计算因子出错会抛出异常
285286
286287
:return: dff, pd.DataFrame, 计算后的因子数据
287288
"""
288289
logger = kwargs.get("logger", loguru.logger)
289290
min_klines = kwargs.get("min_klines", 300)
290291
factor_params = kwargs.get("factor_params", {})
291292
price_type = kwargs.get("price_type", "close")
293+
strict = kwargs.get("strict", True)
292294

293295
symbols = dfk["symbol"].unique().tolist()
294296
factor_name = factor_function.__name__
295297

298+
def __one_symbol(symbol):
299+
df = dfk[(dfk["symbol"] == symbol)].copy()
300+
df = df.sort_values("dt", ascending=True).reset_index(drop=True)
301+
if len(df) < min_klines:
302+
logger.warning(f"{symbol} 数据量过小,跳过;仅有 {len(df)} 条数据,需要 {min_klines} 条数据")
303+
return None
304+
305+
df = factor_function(df, **factor_params)
306+
if price_type == 'next_open':
307+
df["price"] = df["open"].shift(-1).fillna(df["close"])
308+
elif price_type == 'close':
309+
df["price"] = df["close"]
310+
else:
311+
raise ValueError("price_type 参数错误, 可选值为 close 或 next_open")
312+
313+
df["n1b"] = (df["price"].shift(-1) / df["price"] - 1).fillna(0)
314+
factor = [x for x in df.columns if x.startswith("F#")][0]
315+
316+
# df[factor] = df[factor].replace([np.inf, -np.inf], np.nan).ffill().fillna(0)
317+
# factor 中不能有 inf 和 -inf 值,也不能有 nan 值
318+
assert df[factor].isna().sum() == 0, f"{symbol} {factor} 存在 nan 值"
319+
assert df[factor].isin([np.inf, -np.inf]).sum() == 0, f"{symbol} {factor} 存在 inf 值"
320+
assert df[factor].var() != 0 and not np.isnan(df[factor].var()), f"{symbol} {factor} var is 0 or nan"
321+
return df
322+
296323
rows = []
297-
for symbol in tqdm(symbols, desc=f"{factor_name} 因子计算"):
298-
try:
299-
df = dfk[(dfk["symbol"] == symbol)].copy()
300-
df = df.sort_values("dt", ascending=True).reset_index(drop=True)
301-
if len(df) < min_klines:
302-
logger.warning(f"{symbol} 数据量过小,跳过;仅有 {len(df)} 条数据,需要 {min_klines} 条数据")
324+
for _symbol in tqdm(symbols, desc=f"{factor_name} 因子计算"):
325+
if strict:
326+
dfx = __one_symbol(_symbol)
327+
else:
328+
try:
329+
dfx = __one_symbol(_symbol)
330+
except Exception as e:
331+
logger.error(f"{factor_name} - {_symbol} - 计算因子出错:{e}")
303332
continue
304-
305-
df = factor_function(df, **factor_params)
306-
if price_type == 'next_open':
307-
df["price"] = df["open"].shift(-1).fillna(df["close"])
308-
elif price_type == 'close':
309-
df["price"] = df["close"]
310-
else:
311-
raise ValueError("price_type 参数错误, 可选值为 close 或 next_open")
312-
313-
df["n1b"] = (df["price"].shift(-1) / df["price"] - 1).fillna(0)
314-
315-
factor = [x for x in df.columns if x.startswith("F#")][0]
316-
df[factor] = df[factor].replace([np.inf, -np.inf], np.nan).ffill().fillna(0)
317-
if df[factor].var() == 0 or np.isnan(df[factor].var()):
318-
logger.warning(f"{symbol} {factor} var is 0 or nan")
319-
else:
320-
rows.append(df.copy())
321-
except Exception as e:
322-
logger.error(f"{factor_name} - {symbol} - 计算因子出错:{e}")
333+
rows.append(dfx)
323334

324335
dff = pd.concat(rows, ignore_index=True)
325336
return dff

0 commit comments

Comments
 (0)