jcback 0.1.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.
jcback-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.4
2
+ Name: jcback
3
+ Version: 0.1.1
4
+ Summary: Event-driven bar replay backtest engine for China A-share, ETF, bond and futures
5
+ Author: jcback contributors
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: loguru>=0.7
10
+ Requires-Dist: numpy>=1.24
11
+ Requires-Dist: pandas>=2.0
12
+ Requires-Dist: PyYAML>=6.0
13
+ Provides-Extra: jcdata
14
+ Requires-Dist: jcdata>=0.1; extra == "jcdata"
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=7; extra == "dev"
17
+
18
+ # jcback
19
+
20
+ 事件驱动、逐 K 线推进的 A 股 / ETF / 可转债 / 期货回测库。
21
+
22
+ 支持函数式策略(`init` / `on_bar`,与**几策**平台写法一致)与类式策略(`Strategy` 子类),可自带 OHLCV、使用内置模拟数据,或通过 **[jcdata](https://pypi.org/project/jcdata)** 拉取行情。
23
+
24
+ ## 安装
25
+
26
+ ```bash
27
+ pip install jcback
28
+ ```
29
+
30
+ 需要 jcdata 行情时:
31
+
32
+ ```bash
33
+ pip install jcback[jcdata]
34
+ ```
35
+
36
+ 或单独安装:
37
+
38
+ ```bash
39
+ pip install jcdata
40
+ ```
41
+
42
+ 要求 **Python >= 3.10**。
43
+
44
+ ## 快速开始
45
+
46
+ ### 函数式策略 + 模拟数据
47
+
48
+ 无需外部行情,适合本地验证逻辑:
49
+
50
+ ```python
51
+ from jcback import run, MODE_BACKTEST, MATCH_NEXT_OPEN, ADJUST_PREV
52
+
53
+
54
+ def init(context):
55
+ context.subscribe(context.symbols, frequency="1d", wait_group=True)
56
+
57
+
58
+ def on_bar(context, bars):
59
+ for bar in bars:
60
+ context.order_target_percent(bar.symbol, 0.5)
61
+
62
+
63
+ result = run(
64
+ strategy_id="demo",
65
+ mode=MODE_BACKTEST,
66
+ symbols="600000.SH",
67
+ backtest_start_time="2025-01-02",
68
+ backtest_end_time="2025-03-31",
69
+ backtest_adjust=ADJUST_PREV,
70
+ backtest_match_mode=MATCH_NEXT_OPEN,
71
+ init_func=init,
72
+ on_bar=on_bar,
73
+ use_mock=True,
74
+ )
75
+
76
+ print(result.indicator["return_pct"], "%")
77
+ ```
78
+
79
+ ### 对接 jcdata 实盘行情
80
+
81
+ ```python
82
+ import jcdata
83
+ from jcback import run, MODE_BACKTEST, MATCH_NEXT_OPEN, print_backtest_report, setup_logger
84
+
85
+ jcdata.login() # 或 jcdata.login(token="YOUR_TOKEN", base_url="...")
86
+
87
+ setup_logger()
88
+
89
+ result = run(
90
+ strategy_id="demo",
91
+ mode=MODE_BACKTEST,
92
+ symbols=["600000.SH", "601318.SH"],
93
+ backtest_start_time="2025-01-02",
94
+ backtest_end_time="2025-06-30",
95
+ backtest_match_mode=MATCH_NEXT_OPEN,
96
+ init_func=init,
97
+ on_bar=on_bar,
98
+ use_jcdata=True,
99
+ )
100
+
101
+ print_backtest_report(result, "demo")
102
+ ```
103
+
104
+ ### 类式策略
105
+
106
+ ```python
107
+ from jcback import Strategy, run_backtest
108
+
109
+
110
+ class SmaCross(Strategy):
111
+ n_short, n_long = 5, 20
112
+
113
+ def init(self):
114
+ c = self.data.Close
115
+ self.ma_s = self.I(lambda x, n: x.rolling(n).mean(), c, self.n_short)
116
+ self.ma_l = self.I(lambda x, n: x.rolling(n).mean(), c, self.n_long)
117
+
118
+ def next(self):
119
+ if self.ma_s[-2] < self.ma_l[-2] and self.ma_s[-1] > self.ma_l[-1]:
120
+ self.buy()
121
+ elif self.ma_s[-2] > self.ma_l[-2] and self.ma_s[-1] < self.ma_l[-1]:
122
+ self.position.close()
123
+
124
+
125
+ result = run_backtest(
126
+ SmaCross,
127
+ symbols="600000.SH",
128
+ start_date="2025-01-02",
129
+ end_date="2025-06-30",
130
+ use_mock=True,
131
+ )
132
+ ```
133
+
134
+ ### 自备 OHLCV
135
+
136
+ `data` 列为 `Open` / `High` / `Low` / `Close` / `Volume`(可选 `Amount`),索引为时间:
137
+
138
+ ```python
139
+ run(..., data=ohlcv_df, symbols="600000.SH")
140
+ # 多标的:data={"600000.SH": df1, "601318.SH": df2}
141
+ ```
142
+
143
+ ## 常用常量
144
+
145
+ | 常量 | 含义 |
146
+ |------|------|
147
+ | `MODE_BACKTEST` | 回测模式 |
148
+ | `ADJUST_NONE` / `ADJUST_PREV` / `ADJUST_POST` | 不复权 / 前复权 / 后复权 |
149
+ | `MATCH_NEXT_OPEN` | 下一根 K 线开盘价撮合 |
150
+ | `MATCH_CURRENT_CLOSE` | 当前 K 线收盘价撮合 |
151
+
152
+ ## 手续费与交割
153
+
154
+ 未显式传入 `commission` 时,按包内 `config.yaml` 及 `product_fees.yaml` 的品类规则计算(股票、ETF、转债、期货等)。
155
+
156
+ `settlement_rule="T+1"`(股票默认)或 `"T+0"`(转债、期货等)控制当日买入是否可卖。
157
+
158
+ ## 主要导出
159
+
160
+ `run`、`run_backtest`、`Strategy`、`Backtest`、`Context`、`Bar`、`resolve_config`、
161
+ `load_from_jcdata`、`load_multi_ohlcv`、`jcdata_to_ohlcv`、`make_mock_jcdata`、
162
+ `get_last_result`、`serialize_for_ui`、`print_backtest_report`、`setup_logger`
163
+
164
+ 完整 API 见 `jcback.__all__` 或接口文档。
165
+
166
+ ## 许可证
167
+
168
+ MIT
jcback-0.1.1/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # jcback
2
+
3
+ 事件驱动、逐 K 线推进的 A 股 / ETF / 可转债 / 期货回测库。
4
+
5
+ 支持函数式策略(`init` / `on_bar`,与**几策**平台写法一致)与类式策略(`Strategy` 子类),可自带 OHLCV、使用内置模拟数据,或通过 **[jcdata](https://pypi.org/project/jcdata)** 拉取行情。
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ pip install jcback
11
+ ```
12
+
13
+ 需要 jcdata 行情时:
14
+
15
+ ```bash
16
+ pip install jcback[jcdata]
17
+ ```
18
+
19
+ 或单独安装:
20
+
21
+ ```bash
22
+ pip install jcdata
23
+ ```
24
+
25
+ 要求 **Python >= 3.10**。
26
+
27
+ ## 快速开始
28
+
29
+ ### 函数式策略 + 模拟数据
30
+
31
+ 无需外部行情,适合本地验证逻辑:
32
+
33
+ ```python
34
+ from jcback import run, MODE_BACKTEST, MATCH_NEXT_OPEN, ADJUST_PREV
35
+
36
+
37
+ def init(context):
38
+ context.subscribe(context.symbols, frequency="1d", wait_group=True)
39
+
40
+
41
+ def on_bar(context, bars):
42
+ for bar in bars:
43
+ context.order_target_percent(bar.symbol, 0.5)
44
+
45
+
46
+ result = run(
47
+ strategy_id="demo",
48
+ mode=MODE_BACKTEST,
49
+ symbols="600000.SH",
50
+ backtest_start_time="2025-01-02",
51
+ backtest_end_time="2025-03-31",
52
+ backtest_adjust=ADJUST_PREV,
53
+ backtest_match_mode=MATCH_NEXT_OPEN,
54
+ init_func=init,
55
+ on_bar=on_bar,
56
+ use_mock=True,
57
+ )
58
+
59
+ print(result.indicator["return_pct"], "%")
60
+ ```
61
+
62
+ ### 对接 jcdata 实盘行情
63
+
64
+ ```python
65
+ import jcdata
66
+ from jcback import run, MODE_BACKTEST, MATCH_NEXT_OPEN, print_backtest_report, setup_logger
67
+
68
+ jcdata.login() # 或 jcdata.login(token="YOUR_TOKEN", base_url="...")
69
+
70
+ setup_logger()
71
+
72
+ result = run(
73
+ strategy_id="demo",
74
+ mode=MODE_BACKTEST,
75
+ symbols=["600000.SH", "601318.SH"],
76
+ backtest_start_time="2025-01-02",
77
+ backtest_end_time="2025-06-30",
78
+ backtest_match_mode=MATCH_NEXT_OPEN,
79
+ init_func=init,
80
+ on_bar=on_bar,
81
+ use_jcdata=True,
82
+ )
83
+
84
+ print_backtest_report(result, "demo")
85
+ ```
86
+
87
+ ### 类式策略
88
+
89
+ ```python
90
+ from jcback import Strategy, run_backtest
91
+
92
+
93
+ class SmaCross(Strategy):
94
+ n_short, n_long = 5, 20
95
+
96
+ def init(self):
97
+ c = self.data.Close
98
+ self.ma_s = self.I(lambda x, n: x.rolling(n).mean(), c, self.n_short)
99
+ self.ma_l = self.I(lambda x, n: x.rolling(n).mean(), c, self.n_long)
100
+
101
+ def next(self):
102
+ if self.ma_s[-2] < self.ma_l[-2] and self.ma_s[-1] > self.ma_l[-1]:
103
+ self.buy()
104
+ elif self.ma_s[-2] > self.ma_l[-2] and self.ma_s[-1] < self.ma_l[-1]:
105
+ self.position.close()
106
+
107
+
108
+ result = run_backtest(
109
+ SmaCross,
110
+ symbols="600000.SH",
111
+ start_date="2025-01-02",
112
+ end_date="2025-06-30",
113
+ use_mock=True,
114
+ )
115
+ ```
116
+
117
+ ### 自备 OHLCV
118
+
119
+ `data` 列为 `Open` / `High` / `Low` / `Close` / `Volume`(可选 `Amount`),索引为时间:
120
+
121
+ ```python
122
+ run(..., data=ohlcv_df, symbols="600000.SH")
123
+ # 多标的:data={"600000.SH": df1, "601318.SH": df2}
124
+ ```
125
+
126
+ ## 常用常量
127
+
128
+ | 常量 | 含义 |
129
+ |------|------|
130
+ | `MODE_BACKTEST` | 回测模式 |
131
+ | `ADJUST_NONE` / `ADJUST_PREV` / `ADJUST_POST` | 不复权 / 前复权 / 后复权 |
132
+ | `MATCH_NEXT_OPEN` | 下一根 K 线开盘价撮合 |
133
+ | `MATCH_CURRENT_CLOSE` | 当前 K 线收盘价撮合 |
134
+
135
+ ## 手续费与交割
136
+
137
+ 未显式传入 `commission` 时,按包内 `config.yaml` 及 `product_fees.yaml` 的品类规则计算(股票、ETF、转债、期货等)。
138
+
139
+ `settlement_rule="T+1"`(股票默认)或 `"T+0"`(转债、期货等)控制当日买入是否可卖。
140
+
141
+ ## 主要导出
142
+
143
+ `run`、`run_backtest`、`Strategy`、`Backtest`、`Context`、`Bar`、`resolve_config`、
144
+ `load_from_jcdata`、`load_multi_ohlcv`、`jcdata_to_ohlcv`、`make_mock_jcdata`、
145
+ `get_last_result`、`serialize_for_ui`、`print_backtest_report`、`setup_logger`
146
+
147
+ 完整 API 见 `jcback.__all__` 或接口文档。
148
+
149
+ ## 许可证
150
+
151
+ MIT
@@ -0,0 +1,89 @@
1
+ """
2
+ jcback — 事件驱动 A 股回测框架。
3
+
4
+ 函数式策略(推荐,与几策平台 init / on_bar 写法一致)::
5
+
6
+ def init(context): ...
7
+ def on_bar(context, bars): ...
8
+
9
+ def run_main():
10
+ run(
11
+ strategy_id="demo",
12
+ mode=MODE_BACKTEST,
13
+ symbols="600000.SH",
14
+ backtest_start_time="2025-01-02",
15
+ backtest_end_time="2025-03-31",
16
+ backtest_match_mode=MATCH_NEXT_OPEN,
17
+ init_func=init,
18
+ on_bar=on_bar,
19
+ use_mock=True,
20
+ )
21
+
22
+ 类式策略(jcback.Strategy 子类)::
23
+
24
+ from jcback import run_backtest, Strategy
25
+ result = run_backtest(MyStrategy, use_mock=True, symbols="600000.SH", start_date="2025-01-02", ...)
26
+ """
27
+ from __future__ import annotations
28
+
29
+ from .sim.facade import Backtest, Strategy
30
+ from .runtime import (
31
+ ADJUST_NONE,
32
+ ADJUST_POST,
33
+ ADJUST_PREV,
34
+ Bar,
35
+ BacktestConfig,
36
+ BacktestEvent,
37
+ BacktestResult,
38
+ Context,
39
+ EventBacktest,
40
+ EventBus,
41
+ FunctionStrategy,
42
+ MATCH_CURRENT_CLOSE,
43
+ MATCH_NEXT_OPEN,
44
+ MODE_BACKTEST,
45
+ infer_asset_type,
46
+ jcdata_to_ohlcv,
47
+ load_from_jcdata,
48
+ load_multi_ohlcv,
49
+ make_mock_jcdata,
50
+ parse_symbols,
51
+ resolve_config,
52
+ )
53
+ from .runtime.export import emit_report_marker, get_last_result, serialize_for_ui
54
+ from .runtime.report import print_backtest_report, setup_logger
55
+ from .entry import default_backtest_window, run, run_backtest
56
+
57
+ __all__ = [
58
+ "ADJUST_NONE",
59
+ "ADJUST_POST",
60
+ "ADJUST_PREV",
61
+ "Backtest",
62
+ "BacktestConfig",
63
+ "BacktestEvent",
64
+ "BacktestResult",
65
+ "Bar",
66
+ "Context",
67
+ "EventBacktest",
68
+ "EventBus",
69
+ "FunctionStrategy",
70
+ "MATCH_CURRENT_CLOSE",
71
+ "MATCH_NEXT_OPEN",
72
+ "MODE_BACKTEST",
73
+ "Strategy",
74
+ "default_backtest_window",
75
+ "infer_asset_type",
76
+ "jcdata_to_ohlcv",
77
+ "load_from_jcdata",
78
+ "load_multi_ohlcv",
79
+ "make_mock_jcdata",
80
+ "parse_symbols",
81
+ "emit_report_marker",
82
+ "get_last_result",
83
+ "print_backtest_report",
84
+ "resolve_config",
85
+ "run",
86
+ "run_backtest",
87
+ "serialize_for_ui",
88
+ "setup_logger",
89
+ ]
@@ -0,0 +1,56 @@
1
+ # jcback 回测默认配置
2
+ # 手续费规则:按品种区分买卖、期货平昨/平今;支持固定费 + 成交额比例
3
+
4
+ commission:
5
+ # 未命中品种规则时的兜底
6
+ default:
7
+ buy_ratio: 0.0001
8
+ sell_ratio: 0.0001
9
+ fixed: 0.0
10
+ min_commission: 0.0
11
+ stamp_tax_ratio: 0.0
12
+
13
+ by_asset:
14
+ # A 股:买卖佣金不同,卖出另收印花税
15
+ stock:
16
+ buy_ratio: 0.00025
17
+ sell_ratio: 0.00025
18
+ fixed: 0.0
19
+ min_commission: 5.0
20
+ stamp_tax_ratio: 0.001
21
+
22
+ etf:
23
+ buy_ratio: 0.00025
24
+ sell_ratio: 0.00025
25
+ fixed: 0.0
26
+ min_commission: 5.0
27
+ stamp_tax_ratio: 0.0
28
+
29
+ # 可转债:买卖费率通常一致,无印花税
30
+ convertible_bond:
31
+ buy_ratio: 0.00005
32
+ sell_ratio: 0.00005
33
+ fixed: 0.0
34
+ min_commission: 0.0
35
+ stamp_tax_ratio: 0.0
36
+
37
+ bond:
38
+ buy_ratio: 0.00005
39
+ sell_ratio: 0.00005
40
+ fixed: 0.0
41
+ min_commission: 0.0
42
+ stamp_tax_ratio: 0.0
43
+
44
+ # 期货:通用兜底(未在 product_fees.yaml 列出的品种使用)
45
+ future:
46
+ multiplier: 1.0
47
+ open_ratio: 0.000023
48
+ open_fixed: 0.0
49
+ close_yesterday_ratio: 0.000023
50
+ close_yesterday_fixed: 0.0
51
+ close_today_ratio: 0.00023
52
+ close_today_fixed: 0.0
53
+ min_commission: 0.0
54
+
55
+ # 中国期货各品种交易所标准费率表(按品种代码 IF/RB/MA 等匹配)
56
+ future_fee_table: product_fees.yaml