From e8d312401ad1ea1e881313c298b2cd2617a08217 Mon Sep 17 00:00:00 2001 From: zengbin93 Date: Sun, 25 Aug 2024 20:53:32 +0800 Subject: [PATCH] 0.9.58 update --- czsc/utils/st_components.py | 19 +++-- .../weight_backtest.py" | 7 +- ...66\347\233\212\345\210\206\346\236\220.py" | 17 ++++ examples/{ => dropit}/gm_0701.py | 0 examples/{ => dropit}/gm_backtest.py | 79 ++++++++++--------- examples/{ => dropit}/gm_realtime.py | 52 ++++++------ 6 files changed, 100 insertions(+), 74 deletions(-) create mode 100644 "examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/\346\227\245\346\224\266\347\233\212\345\210\206\346\236\220.py" rename examples/{ => dropit}/gm_0701.py (100%) rename examples/{ => dropit}/gm_backtest.py (55%) rename examples/{ => dropit}/gm_realtime.py (59%) diff --git a/czsc/utils/st_components.py b/czsc/utils/st_components.py index 9d65b0982..109cf5f45 100644 --- a/czsc/utils/st_components.py +++ b/czsc/utils/st_components.py @@ -23,6 +23,7 @@ def show_daily_return(df: pd.DataFrame, **kwargs): - use_st_table: bool,是否使用 st.table 展示绩效指标,默认为 False - plot_cumsum: bool,是否展示日收益累计曲线,默认为 True - yearly_days: int,年交易天数,默认为 252 + - show_dailys: bool,是否展示日收益数据详情,默认为 False """ if not df.index.dtype == "datetime64[ns]": @@ -84,17 +85,22 @@ def _stats(df_, type_="持有日"): with st.container(): sub_title = kwargs.get("sub_title", "") if sub_title: - st.subheader(sub_title, divider="rainbow") + st.subheader(sub_title, divider="rainbow", anchor=sub_title) + if kwargs.get("show_dailys", False): + with st.expander("日收益数据详情", expanded=False): + st.dataframe(df, use_container_width=True) with st.expander("交易日绩效指标", expanded=True): if use_st_table: st.table(_stats(df, type_="交易日")) else: st.dataframe(_stats(df, type_="交易日"), use_container_width=True) + st.caption("交易日:交易所指定的交易日,或者有收益发生变化的日期") if kwargs.get("stat_hold_days", True): with st.expander("持有日绩效指标", expanded=False): st.dataframe(_stats(df, type_="持有日"), use_container_width=True) + st.caption("持有日:在交易日的基础上,将收益率为0的日期删除") if kwargs.get("plot_cumsum", True): df = df.cumsum() @@ -131,7 +137,7 @@ def show_monthly_return(df, ret_col="total", sub_title="月度累计收益", **k df.sort_index(inplace=True, ascending=True) if sub_title: - st.subheader(sub_title, divider="rainbow") + st.subheader(sub_title, divider="rainbow", anchor=sub_title) monthly = df[[ret_col]].resample("ME").sum() monthly["year"] = monthly.index.year @@ -493,7 +499,7 @@ def show_splited_daily(df, ret_col, **kwargs): sub_title = kwargs.get("sub_title", "") if sub_title: - st.subheader(sub_title, divider="rainbow") + st.subheader(sub_title, divider="rainbow", anchor=sub_title) last_dt = df.index[-1] sdt_map = { @@ -617,8 +623,9 @@ def show_yearly_stats(df, ret_col, **kwargs): } ) - if kwargs.get("sub_title"): - st.subheader(kwargs.get("sub_title"), divider="rainbow") + sub_title = kwargs.get("sub_title", "") + if sub_title: + st.subheader(sub_title, divider="rainbow", anchor=sub_title) st.dataframe(stats, use_container_width=True) @@ -1029,7 +1036,7 @@ def show_rolling_daily_performance(df, ret_col, **kwargs): sub_title = kwargs.get("sub_title", "滚动日收益绩效") if sub_title: - st.subheader(sub_title, divider="rainbow") + st.subheader(sub_title, divider="rainbow", anchor=sub_title) c1, c2, c3 = st.columns(3) window = c1.number_input("滚动窗口(自然日)", value=365 * 3, min_value=365, max_value=3650) diff --git "a/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/weight_backtest.py" "b/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/weight_backtest.py" index 49f3b98df..3783b0ef4 100644 --- "a/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/weight_backtest.py" +++ "b/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/weight_backtest.py" @@ -6,8 +6,5 @@ dfw = pd.read_feather(r"C:\Users\zengb\Downloads\ST组件样例数据\时序持仓权重样例数据.feather") -if __name__ == "__main__": - st.subheader("时序持仓策略回测样例", anchor="时序持仓策略回测样例", divider="rainbow") - czsc.show_weight_backtest( - dfw, fee=2, digits=2, show_drawdowns=True, show_monthly_return=True, show_yearly_stats=True - ) +st.subheader("时序持仓策略回测样例", anchor="时序持仓策略回测样例", divider="rainbow") +czsc.show_weight_backtest(dfw, fee=2, digits=2, show_drawdowns=True, show_monthly_return=True, show_yearly_stats=True) diff --git "a/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/\346\227\245\346\224\266\347\233\212\345\210\206\346\236\220.py" "b/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/\346\227\245\346\224\266\347\233\212\345\210\206\346\236\220.py" new file mode 100644 index 000000000..64c442fa7 --- /dev/null +++ "b/examples/Streamlit\347\273\204\344\273\266\345\272\223\344\275\277\347\224\250\346\241\210\344\276\213/\346\227\245\346\224\266\347\233\212\345\210\206\346\236\220.py" @@ -0,0 +1,17 @@ +import czsc +import pandas as pd +import streamlit as st + +st.set_page_config(layout="wide") + +dfw = pd.read_feather(r"C:\Users\zengb\Downloads\ST组件样例数据\截面持仓权重样例数据.feather") +st.subheader("截面数据回测", divider="rainbow", anchor="截面数据回测") +czsc.show_holds_backtest( + dfw, + fee=2, + digits=2, + show_drawdowns=True, + show_splited_daily=True, + show_monthly_return=True, + show_yearly_stats=True, +) diff --git a/examples/gm_0701.py b/examples/dropit/gm_0701.py similarity index 100% rename from examples/gm_0701.py rename to examples/dropit/gm_0701.py diff --git a/examples/gm_backtest.py b/examples/dropit/gm_backtest.py similarity index 55% rename from examples/gm_backtest.py rename to examples/dropit/gm_backtest.py index 428cc9994..8fe3b9b89 100644 --- a/examples/gm_backtest.py +++ b/examples/dropit/gm_backtest.py @@ -32,36 +32,37 @@ os.environ['backtest_slippage_ratio'] = '0.0005' """ import sys -sys.path.insert(0, '.') -sys.path.insert(0, '..') + +sys.path.insert(0, "..") +sys.path.insert(0, "../..") from czsc.connectors.gm_connector import * from czsc.strategies import CzscStrategyExample2 -os.environ['strategy_id'] = 'b24661f5-838d-11ed-882c-988fe0675a5b' -os.environ['max_sym_pos'] = '0.5' -os.environ['path_gm_logs'] = 'C:/gm_logs' -os.environ['backtest_start_time'] = '2020-01-01 14:30:00' -os.environ['backtest_end_time'] = '2020-12-31 15:30:00' -os.environ['backtest_initial_cash'] = '100000000' -os.environ['backtest_transaction_ratio'] = '1' -os.environ['backtest_commission_ratio'] = '0.001' -os.environ['backtest_slippage_ratio'] = '0.0005' +os.environ["strategy_id"] = "b24661f5-838d-11ed-882c-988fe0675a5b" +os.environ["max_sym_pos"] = "0.5" +os.environ["path_gm_logs"] = "C:/gm_logs" +os.environ["backtest_start_time"] = "2020-01-01 14:30:00" +os.environ["backtest_end_time"] = "2020-12-31 15:30:00" +os.environ["backtest_initial_cash"] = "100000000" +os.environ["backtest_transaction_ratio"] = "1" +os.environ["backtest_commission_ratio"] = "0.001" +os.environ["backtest_slippage_ratio"] = "0.0005" def init(context): symbols = [ - 'SZSE.300014', - 'SHSE.600143', - 'SZSE.002216', - 'SZSE.300033', - 'SZSE.000795', - 'SZSE.002739', - 'SHSE.600000', - 'SHSE.600008', - 'SHSE.600006', - 'SHSE.600009', - 'SHSE.600010', - 'SHSE.600011' + "SZSE.300014", + "SHSE.600143", + "SZSE.002216", + "SZSE.300033", + "SZSE.000795", + "SZSE.002739", + "SHSE.600000", + "SHSE.600008", + "SHSE.600006", + "SHSE.600009", + "SHSE.600010", + "SHSE.600011", ] # 配置消息推送服务,支持飞书、企业微信通道 @@ -69,11 +70,11 @@ def init(context): "wx_key": "", "fs_app": { # 飞书应用的 app_id 和 app_secret - 'feishu_app_id': 'cli_a30770****39500e', - 'feishu_app_secret': 'jVoMf688Gbw2*****HhoVbZ7fiTkTkgg', + "feishu_app_id": "cli_a30770****39500e", + "feishu_app_secret": "jVoMf688Gbw2*****HhoVbZ7fiTkTkgg", # 指定消息推送给哪些飞书用户, - 'feishu_members': ['ou_6fa04b5b4d8*****fdc87d267e8f2a270'], - } + "feishu_members": ["ou_6fa04b5b4d8*****fdc87d267e8f2a270"], + }, } name = "stocks_sma5" @@ -84,14 +85,18 @@ def init(context): init_context_schedule(context) -if __name__ == '__main__': - run(filename=os.path.basename(__file__), token=gm_token, mode=MODE_BACKTEST, - strategy_id=os.environ['strategy_id'], - backtest_start_time=os.environ['backtest_start_time'], - backtest_end_time=os.environ['backtest_end_time'], - backtest_initial_cash=int(os.environ['backtest_initial_cash']), - backtest_transaction_ratio=float(os.environ['backtest_transaction_ratio']), - backtest_commission_ratio=float(os.environ['backtest_commission_ratio']), - backtest_slippage_ratio=float(os.environ['backtest_slippage_ratio']), +if __name__ == "__main__": + run( + filename=os.path.basename(__file__), + token=gm_token, + mode=MODE_BACKTEST, + strategy_id=os.environ["strategy_id"], + backtest_start_time=os.environ["backtest_start_time"], + backtest_end_time=os.environ["backtest_end_time"], + backtest_initial_cash=int(os.environ["backtest_initial_cash"]), + backtest_transaction_ratio=float(os.environ["backtest_transaction_ratio"]), + backtest_commission_ratio=float(os.environ["backtest_commission_ratio"]), + backtest_slippage_ratio=float(os.environ["backtest_slippage_ratio"]), backtest_adjust=ADJUST_PREV, - backtest_check_cache=1) + backtest_check_cache=1, + ) diff --git a/examples/gm_realtime.py b/examples/dropit/gm_realtime.py similarity index 59% rename from examples/gm_realtime.py rename to examples/dropit/gm_realtime.py index 48db60dd4..165d10b10 100644 --- a/examples/gm_realtime.py +++ b/examples/dropit/gm_realtime.py @@ -20,44 +20,45 @@ os.environ['path_gm_logs'] = 'C:/gm_logs' """ import sys -sys.path.insert(0, '.') -sys.path.insert(0, '..') + +sys.path.insert(0, "..") +sys.path.insert(0, "../..") from czsc.connectors.gm_connector import * from czsc.strategies import CzscStrategyExample2 -os.environ['strategy_id'] = '43b099b8-*****-11ed-99a6-988fe0675a5b' -os.environ['account_id'] = '613019f5-****-11ed-bdad-00163e18a8b3' -os.environ['max_sym_pos'] = '0.5' -os.environ['path_gm_logs'] = 'C:/gm_logs' +os.environ["strategy_id"] = "43b099b8-*****-11ed-99a6-988fe0675a5b" +os.environ["account_id"] = "613019f5-****-11ed-bdad-00163e18a8b3" +os.environ["max_sym_pos"] = "0.5" +os.environ["path_gm_logs"] = "C:/gm_logs" def init(context): # 股票池配置 symbols = [ - 'SZSE.300014', - 'SHSE.600143', - 'SZSE.002216', - 'SZSE.300033', - 'SZSE.000795', - 'SZSE.002739', - 'SHSE.600000', - 'SHSE.600008', - 'SHSE.600006', - 'SHSE.600009', - 'SHSE.600010', - 'SHSE.600011' + "SZSE.300014", + "SHSE.600143", + "SZSE.002216", + "SZSE.300033", + "SZSE.000795", + "SZSE.002739", + "SHSE.600000", + "SHSE.600008", + "SHSE.600006", + "SHSE.600009", + "SHSE.600010", + "SHSE.600011", ] # 配置消息推送服务,支持飞书、企业微信通道 context.push_msg_conf = { - "wx_key": os.environ.get('wx_key', None), + "wx_key": os.environ.get("wx_key", None), "fs_app": { # 飞书消息推送 - 'feishu_app_id': 'cli_*****015cc39500e', - 'feishu_app_secret': 'jV******688Gbw20fkR2HhoVbZ7fiTkTkgg', - 'feishu_members': ['ou_6fa*****d853e9fdc87d267e8f2a270'], - } + "feishu_app_id": "cli_*****015cc39500e", + "feishu_app_secret": "jV******688Gbw20fkR2HhoVbZ7fiTkTkgg", + "feishu_members": ["ou_6fa*****d853e9fdc87d267e8f2a270"], + }, } strategy = CzscStrategyExample2 init_context_universal(context, strategy.__name__) @@ -66,6 +67,5 @@ def init(context): init_context_schedule(context) -if __name__ == '__main__': - run(filename=os.path.basename(__file__), token=gm_token, mode=MODE_LIVE, strategy_id=os.environ['strategy_id']) - +if __name__ == "__main__": + run(filename=os.path.basename(__file__), token=gm_token, mode=MODE_LIVE, strategy_id=os.environ["strategy_id"])