Skip to content

Commit

Permalink
0.9.27 优化持仓权重回测
Browse files Browse the repository at this point in the history
  • Loading branch information
zengbin93 committed Aug 15, 2023
1 parent 19af1e2 commit 28d229d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
33 changes: 18 additions & 15 deletions czsc/traders/weight_backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ class WeightBacktest:
def __init__(self, dfw, digits=2, **kwargs) -> None:
"""持仓权重回测
:param dfw: pd.DataFrame, columns = ['dt', 'symbol', 'weight', 'price'], 持仓权重数据,
其中
dt 为结束时间
symbol 为合约代码,
weight 为持仓权重
price 为结束时间对应的交易价格,可以是当前K线的收盘价,或者下一根K线的开盘价,或者未来N根K线的TWAP、VWAP等
:param dfw: pd.DataFrame, columns = ['dt', 'symbol', 'weight', 'price'], 持仓权重数据,其中
dt 为K线结束时间
symbol 为合约代码,
weight 为K线结束时间对应的持仓权重
price 为结束时间对应的交易价格,可以是当前K线的收盘价,或者下一根K线的开盘价,或者未来N根K线的TWAP、VWAP等
数据样例如下:
=================== ======== ======== =======
dt symbol weight price
Expand All @@ -88,7 +88,10 @@ def __init__(self, dfw, digits=2, **kwargs) -> None:
:param digits: int, 权重列保留小数位数
:param kwargs:
- fee_rate: float,单边交易成本,包括手续费与冲击成本, 默认为 0.0002
- res_path: str,回测结果保存路径,默认为 "weight_backtest"
"""
self.kwargs = kwargs
self.dfw = dfw.copy()
Expand Down Expand Up @@ -139,10 +142,7 @@ def get_symbol_daily(self, symbol):
def get_symbol_pairs(self, symbol):
"""获取某个合约的开平交易记录"""
dfs = self.dfw[self.dfw['symbol'] == symbol].copy()
dfs['direction'] = 0
dfs.loc[dfs['weight'] > 0, 'direction'] = 1
dfs.loc[dfs['weight'] < 0, 'direction'] = -1
dfs['volume'] = (dfs['weight'] * pow(10, self.digits)).astype(int) * dfs['direction']
dfs['volume'] = (dfs['weight'] * pow(10, self.digits)).astype(int)
dfs['bar_id'] = list(range(1, len(dfs)+1))

# 根据权重变化生成开平仓记录
Expand Down Expand Up @@ -227,7 +227,9 @@ def backtest(self):
dret = pd.concat([v['daily'] for v in res.values()], ignore_index=True)
dret = pd.pivot_table(dret, index='date', columns='symbol', values='return').fillna(0)
dret['total'] = dret[list(res.keys())].mean(axis=1)
logger.info(f"品种等权费后日收益率:{daily_performance(dret['total'])}")
stats = {"开始日期": dret.index.min().strftime("%Y%m%d"), "结束日期": dret.index.max().strftime("%Y%m%d")}
stats.update(daily_performance(dret['total']))
logger.info(f"品种等权费后日收益率:{stats}")
dret.to_excel(self.res_path.joinpath("daily_return.xlsx"), index=True)
logger.info(f"品种等权费后日收益率已保存到 {self.res_path.joinpath('daily_return.xlsx')}")

Expand All @@ -243,7 +245,8 @@ def backtest(self):
pairs_stats = evaluate_pairs(dfp)
pairs_stats = {k: v for k, v in pairs_stats.items() if k in ['单笔收益', '持仓K线数', '交易胜率', '持仓天数']}
logger.info(f"所有开平交易记录的表现:{pairs_stats}")
save_json(pairs_stats, self.res_path.joinpath("pairs_stats.json"))
logger.info(f"所有开平交易记录的表现已保存到 {self.res_path.joinpath('pairs_stats.json')}")

stats.update(pairs_stats)
logger.info(f"策略评价:{stats}")
save_json(stats, self.res_path.joinpath("stats.json"))
res['stats'] = stats
return res
22 changes: 22 additions & 0 deletions examples/cal_ensemble_weight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import czsc
import pandas as pd


def run_by_weights():
"""从持仓权重样例数据中回测"""
dfw = pd.read_feather(r"C:\Users\zengb\Desktop\230814\weight_example.feather")
wb = czsc.WeightBacktest(dfw, digits=1, fee_rate=0.0002, res_path=r"C:\Users\zengb\Desktop\230814\weight_example")
res = wb.backtest()


def run_by_ensemble():
"""从单个 trader 中获取持仓权重,然后回测"""
trader = czsc.dill_load(r"C:\Users\zengb\Desktop\230814\DLi9001.trader")

def __ensemble_method(x):
return x['A股日线SMA#5多头'] + 0.5 * x['A股日线SMA#5空头']

dfw = czsc.get_ensemble_weight(trader, method=__ensemble_method)
wb = czsc.WeightBacktest(dfw, digits=1, fee_rate=0.0002, res_path=r"C:\Users\zengb\Desktop\230814\DLi9001_ensemble")
res = wb.backtest()

0 comments on commit 28d229d

Please sign in to comment.