Metadata-Version: 2.4
Name: jcback
Version: 0.1.1
Summary: Event-driven bar replay backtest engine for China A-share, ETF, bond and futures
Author: jcback contributors
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: loguru>=0.7
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: PyYAML>=6.0
Provides-Extra: jcdata
Requires-Dist: jcdata>=0.1; extra == "jcdata"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"

# jcback

事件驱动、逐 K 线推进的 A 股 / ETF / 可转债 / 期货回测库。

支持函数式策略（`init` / `on_bar`，与**几策**平台写法一致）与类式策略（`Strategy` 子类），可自带 OHLCV、使用内置模拟数据，或通过 **[jcdata](https://pypi.org/project/jcdata)** 拉取行情。

## 安装

```bash
pip install jcback
```

需要 jcdata 行情时：

```bash
pip install jcback[jcdata]
```

或单独安装：

```bash
pip install jcdata
```

要求 **Python >= 3.10**。

## 快速开始

### 函数式策略 + 模拟数据

无需外部行情，适合本地验证逻辑：

```python
from jcback import run, MODE_BACKTEST, MATCH_NEXT_OPEN, ADJUST_PREV


def init(context):
    context.subscribe(context.symbols, frequency="1d", wait_group=True)


def on_bar(context, bars):
    for bar in bars:
        context.order_target_percent(bar.symbol, 0.5)


result = run(
    strategy_id="demo",
    mode=MODE_BACKTEST,
    symbols="600000.SH",
    backtest_start_time="2025-01-02",
    backtest_end_time="2025-03-31",
    backtest_adjust=ADJUST_PREV,
    backtest_match_mode=MATCH_NEXT_OPEN,
    init_func=init,
    on_bar=on_bar,
    use_mock=True,
)

print(result.indicator["return_pct"], "%")
```

### 对接 jcdata 实盘行情

```python
import jcdata
from jcback import run, MODE_BACKTEST, MATCH_NEXT_OPEN, print_backtest_report, setup_logger

jcdata.login()  # 或 jcdata.login(token="YOUR_TOKEN", base_url="...")

setup_logger()

result = run(
    strategy_id="demo",
    mode=MODE_BACKTEST,
    symbols=["600000.SH", "601318.SH"],
    backtest_start_time="2025-01-02",
    backtest_end_time="2025-06-30",
    backtest_match_mode=MATCH_NEXT_OPEN,
    init_func=init,
    on_bar=on_bar,
    use_jcdata=True,
)

print_backtest_report(result, "demo")
```

### 类式策略

```python
from jcback import Strategy, run_backtest


class SmaCross(Strategy):
    n_short, n_long = 5, 20

    def init(self):
        c = self.data.Close
        self.ma_s = self.I(lambda x, n: x.rolling(n).mean(), c, self.n_short)
        self.ma_l = self.I(lambda x, n: x.rolling(n).mean(), c, self.n_long)

    def next(self):
        if self.ma_s[-2] < self.ma_l[-2] and self.ma_s[-1] > self.ma_l[-1]:
            self.buy()
        elif self.ma_s[-2] > self.ma_l[-2] and self.ma_s[-1] < self.ma_l[-1]:
            self.position.close()


result = run_backtest(
    SmaCross,
    symbols="600000.SH",
    start_date="2025-01-02",
    end_date="2025-06-30",
    use_mock=True,
)
```

### 自备 OHLCV

`data` 列为 `Open` / `High` / `Low` / `Close` / `Volume`（可选 `Amount`），索引为时间：

```python
run(..., data=ohlcv_df, symbols="600000.SH")
# 多标的：data={"600000.SH": df1, "601318.SH": df2}
```

## 常用常量

| 常量 | 含义 |
|------|------|
| `MODE_BACKTEST` | 回测模式 |
| `ADJUST_NONE` / `ADJUST_PREV` / `ADJUST_POST` | 不复权 / 前复权 / 后复权 |
| `MATCH_NEXT_OPEN` | 下一根 K 线开盘价撮合 |
| `MATCH_CURRENT_CLOSE` | 当前 K 线收盘价撮合 |

## 手续费与交割

未显式传入 `commission` 时，按包内 `config.yaml` 及 `product_fees.yaml` 的品类规则计算（股票、ETF、转债、期货等）。

`settlement_rule="T+1"`（股票默认）或 `"T+0"`（转债、期货等）控制当日买入是否可卖。

## 主要导出

`run`、`run_backtest`、`Strategy`、`Backtest`、`Context`、`Bar`、`resolve_config`、  
`load_from_jcdata`、`load_multi_ohlcv`、`jcdata_to_ohlcv`、`make_mock_jcdata`、  
`get_last_result`、`serialize_for_ui`、`print_backtest_report`、`setup_logger`

完整 API 见 `jcback.__all__` 或接口文档。

## 许可证

MIT
