跳转至

快速开始

在此处通过一个简单的例子来介绍如何使用 pybroker 来开发策略。

导入相关的模块和类

import pybroker as pb
from pybroker import Strategy, StrategyConfig, ExecContext
from pybroker.ext.data import AKShare

print(pb.__version__)
  1. pybroker 模块导入为 pb,这是一个约定俗成的做法,方便后续使用。
  2. pybroker 中导入 StrategyStrategyConfig 类,以及 AKShare 数据源。
  3. Strategy 类是 pybroker 中的策略基类,所有的策略都需要继承该类。
  4. StrategyConfig 类是 pybroker 中的策略配置基类,所有的策略配置都需要继承该类。
  5. AKShare 类是 pybroker 中的数据源类,用于获取数据。
  6. pb.__version__ 属性用于获取 pybroker 的版本。

配置策略

config = StrategyConfig(initial_cash=500_000)
  1. 创建一个策略配置对象,该对象用于配置策略的一些参数。
  2. initial_cash 参数用于配置策略的初始资金,默认为 10 万。
strategy = Strategy(
    data_source=AKShare(),
    start_date='20220101',
    end_date='20230916',
    config=config
)
  1. 创建一个策略对象,该对象用于运行策略。
  2. AKShare() 参数用于配置策略的数据源,该数据源为 akshare。
  3. 20220101 参数用于配置策略的开始日期。
  4. 20230916 参数用于配置策略的结束日期。
  5. config 参数用于配置策略的配置对象。
  6. strategy 对象用于运行策略。
  7. strategy 对象的 config 属性用于获取策略的配置对象。

定义规则

def buy_low(ctx: ExecContext):
    # 如果当前已经持有仓位,则不再买入。
    if ctx.long_pos():
        return
    # 如果当前的收盘价小于前一天的最低价,则下单买入。
    if ctx.bars >= 2 and ctx.close[-1] < ctx.low[-2]:
        # 计算买入的股票数量,该数量为当前资金的 25%。
        ctx.buy_shares = ctx.calc_target_shares(0.25)
        # 设置买入的限价,该限价为当前收盘价减去 0.01。
        ctx.buy_limit_price = ctx.close[-1] - 0.01
        # 设置持有仓位的时间,该时间为 3 个交易日。
        ctx.hold_bars = 3
  1. 定义一个名为 buy_low 的函数,该函数用于判断是否需要买入。
  2. ctx 参数是一个上下文对象,该对象包含了策略运行时的一些数据。
  3. ctx.long_pos() 方法用于判断是否已经持有仓位。
  4. ctx.bars 属性用于获取当前的交易日。

运行策略

可以通过调用 strategy.backtest() 方法来进行策略回测:

strategy.add_execution(fn=buy_low, symbols=['000001', '600000'])
result = strategy.backtest()

查看结果

查看绩效

print(result.metrics_df)
                      name         value
0              trade_count  6.000000e+01
1     initial_market_value  5.000000e+05
2         end_market_value  4.807408e+05
3                total_pnl -1.925923e+04
4           unrealized_pnl  1.818989e-11
5         total_return_pct -3.851846e+00
6             total_profit  4.150577e+04
7               total_loss -6.076500e+04
8               total_fees  0.000000e+00
9             max_drawdown -3.168807e+04
10        max_drawdown_pct -6.280127e+00
11                win_rate  4.745763e+01
12               loss_rate  5.254237e+01
13          winning_trades  2.800000e+01
14           losing_trades  3.100000e+01
15                 avg_pnl -3.209872e+02
16          avg_return_pct -2.623333e-01
17          avg_trade_bars  3.000000e+00
18              avg_profit  1.482349e+03
19          avg_profit_pct  1.242857e+00
20  avg_winning_trade_bars  3.000000e+00
21                avg_loss -1.960161e+03
22            avg_loss_pct -1.630323e+00
23   avg_losing_trade_bars  3.000000e+00
24             largest_win  4.888940e+03
25         largest_win_pct  4.060000e+00
26        largest_win_bars  3.000000e+00
27            largest_loss -7.065140e+03
28        largest_loss_pct -5.780000e+00
29       largest_loss_bars  3.000000e+00
30                max_wins  3.000000e+00
31              max_losses  5.000000e+00
32                  sharpe -4.184734e-02
33                 sortino -4.060695e-02
34           profit_factor  8.291367e-01
35             ulcer_index  6.942926e-01
36                     upi -1.328477e-02
37               equity_r2  6.199979e-01
38               std_error  6.892189e+03

查看订单

print(result.orders)
     type  symbol       date  shares  limit_price  fill_price  fees
id                                                                 
1     buy  000001 2022-01-17      44      2822.91     2818.04   0.0
2    sell  000001 2022-01-20      44          NaN     2922.06   0.0
3     buy  000001 2022-01-25      42      2964.31     2922.88   0.0
4     buy  600000 2022-01-25    1497        84.20       83.74   0.0
5    sell  000001 2022-01-28      42          NaN     2791.23   0.0
..    ...     ...        ...     ...          ...         ...   ...
116  sell  000001 2023-08-29      57          NaN     2090.42   0.0
117   buy  000001 2023-08-30      57      2090.40     2072.54   0.0
118   buy  600000 2023-08-30    1525        78.33       78.24   0.0
119  sell  000001 2023-09-04      57          NaN     2114.79   0.0
120  sell  600000 2023-09-04    1525          NaN       78.44   0.0
[120 rows x 7 columns]

查看持仓

print(result.positions)
                   long_shares  short_shares  ...  margin  unrealized_pnl
symbol date                                   ...                        
000001 2022-01-17           44             0  ...     0.0         -572.00
       2022-01-18           44             0  ...     0.0         1573.44
       2022-01-19           44             0  ...     0.0         1430.44
600000 2022-01-25         1497             0  ...     0.0         -583.83
000001 2022-01-25           42             0  ...     0.0         -648.48
                        ...           ...  ...     ...             ...
       2023-08-30           57             0  ...     0.0         -648.66
600000 2023-08-31         1525             0  ...     0.0         -762.50
000001 2023-08-31           57             0  ...     0.0         -648.66
600000 2023-09-01         1525             0  ...     0.0         -457.50
000001 2023-09-01           57             0  ...     0.0         1111.50
[180 rows x 7 columns]

查看投资组合

print(result.portfolio)
                 cash     equity  margin  ...       pnl  unrealized_pnl  fees
date                                      ...                                
2022-01-04  500000.00  500000.00     0.0  ...      0.00             0.0   0.0
2022-01-05  500000.00  500000.00     0.0  ...      0.00             0.0   0.0
2022-01-06  500000.00  500000.00     0.0  ...      0.00             0.0   0.0
2022-01-07  500000.00  500000.00     0.0  ...      0.00             0.0   0.0
2022-01-10  500000.00  500000.00     0.0  ...      0.00             0.0   0.0
               ...        ...     ...  ...       ...             ...   ...
2023-09-11  480740.77  480740.77     0.0  ... -19259.23             0.0   0.0
2023-09-12  480740.77  480740.77     0.0  ... -19259.23             0.0   0.0
2023-09-13  480740.77  480740.77     0.0  ... -19259.23             0.0   0.0
2023-09-14  480740.77  480740.77     0.0  ... -19259.23             0.0   0.0
2023-09-15  480740.77  480740.77     0.0  ... -19259.23             0.0   0.0
[415 rows x 7 columns]

查看交易

print(result.trades)
    type  symbol entry_date  exit_date  ...   agg_pnl  bars  pnl_per_bar  stop
id                                      ...                                   
1   long  000001 2022-01-17 2022-01-20  ...   4576.88     3      1525.63   bar
2   long  000001 2022-01-25 2022-01-28  ...   -952.42     3     -1843.10   bar
3   long  600000 2022-01-25 2022-01-28  ...  -2524.27     3      -523.95   bar
4   long  000001 2022-02-15 2022-02-18  ...  -1441.10     3       361.06   bar
5   long  600000 2022-02-15 2022-02-18  ...  -1188.31     3        84.26   bar
6   long  000001 2022-02-23 2022-02-28  ...  -4084.39     3      -965.36   bar
7   long  000001 2022-03-07 2022-03-10  ...  -7784.63     3     -1233.41   bar
8   long  600000 2022-03-07 2022-03-10  ... -11308.67     3     -1174.68   bar
9   long  000001 2022-04-12 2022-04-15  ...  -9666.50     3       547.39   bar
10  long  600000 2022-04-22 2022-04-27  ... -11531.88     3      -621.79   bar
11  long  000001 2022-04-26 2022-04-29  ...  -6642.94     3      1629.65   bar
12  long  000001 2022-05-05 2022-05-10  ... -13708.08     3     -2355.05   bar
13  long  600000 2022-05-09 2022-05-12  ... -13302.74     3       135.11   bar
14  long  000001 2022-05-25 2022-05-30  ... -15136.34     3      -611.20   bar
15  long  000001 2022-06-06 2022-06-09  ... -12149.79     3       995.52   bar
16  long  600000 2022-07-04 2022-07-07  ... -12961.75     3      -270.65   bar
17  long  000001 2022-07-07 2022-07-12  ... -12649.75     3       104.00   bar
18  long  000001 2022-07-14 2022-07-19  ... -13804.68     3      -384.98   bar
19  long  600000 2022-07-14 2022-07-19  ... -13897.56     3       -30.96   bar
20  long  000001 2022-07-22 2022-07-27  ... -13638.92     3        86.21   bar
21  long  000001 2022-08-01 2022-08-04  ... -17386.55     3     -1249.21   bar
22  long  600000 2022-08-01 2022-08-04  ... -19096.76     3      -570.07   bar
23  long  000001 2022-08-30 2022-09-02  ... -17780.24     3       438.84   bar
24  long  000001 2022-09-05 2022-09-08  ... -18770.81     3      -330.19   bar
25  long  000001 2022-09-27 2022-09-30  ... -19576.01     3      -268.40   bar
26  long  600000 2022-09-27 2022-09-30  ... -19844.44     3       -89.48   bar
27  long  000001 2022-10-20 2022-10-25  ... -24840.56     3     -1665.37   bar
28  long  600000 2022-10-24 2022-10-27  ... -25142.66     3      -100.70   bar
29  long  000001 2022-10-31 2022-11-03  ... -23732.16     3       470.17   bar
30  long  600000 2022-10-31 2022-11-03  ... -23891.56     3       -53.13   bar
31  long  000001 2022-11-17 2022-11-22  ... -24114.86     3       -74.43   bar
32  long  600000 2022-11-18 2022-11-23  ... -23060.95     3       351.30   bar
33  long  600000 2022-12-26 2022-12-29  ... -22132.15     3       309.60   bar
34  long  000001 2023-02-02 2023-02-07  ... -24748.17     3      -872.01   bar
35  long  600000 2023-02-02 2023-02-07  ... -25848.33     3      -366.72   bar
36  long  000001 2023-02-17 2023-02-22  ... -22225.27     3      1207.69   bar
37  long  600000 2023-02-24 2023-03-01  ... -22225.27     3         0.00   bar
38  long  000001 2023-02-27 2023-03-02  ... -18559.03     3      1222.08   bar
39  long  000001 2023-03-08 2023-03-13  ... -21546.07     3      -995.68   bar
40  long  600000 2023-03-13 2023-03-16  ... -21031.93     3       171.38   bar
41  long  000001 2023-03-20 2023-03-23  ... -20482.29     3       183.21   bar
42  long  000001 2023-04-12 2023-04-17  ... -18328.90     3       717.80   bar
43  long  000001 2023-04-20 2023-04-25  ... -22681.82     3     -1450.97   bar
44  long  600000 2023-05-15 2023-05-18  ... -21994.58     3       229.08   bar
45  long  000001 2023-05-24 2023-05-29  ... -22608.56     3      -204.66   bar
46  long  600000 2023-05-24 2023-05-29  ... -22411.35     3        65.74   bar
47  long  000001 2023-05-31 2023-06-05  ... -20623.85     3       595.83   bar
48  long  000001 2023-06-13 2023-06-16  ... -19349.29     3       424.85   bar
49  long  000001 2023-06-20 2023-06-27  ... -20805.29     3      -485.33   bar
50  long  600000 2023-06-20 2023-06-27  ... -22283.69     3      -492.80   bar
51  long  000001 2023-07-07 2023-07-12  ... -21681.77     3       200.64   bar
52  long  000001 2023-07-18 2023-07-21  ... -21079.85     3       200.64   bar
53  long  000001 2023-08-02 2023-08-07  ... -20218.60     3       287.08   bar
54  long  000001 2023-08-08 2023-08-11  ... -20433.78     3       -71.73   bar
55  long  600000 2023-08-08 2023-08-11  ... -21923.53     3      -496.58   bar
56  long  000001 2023-08-14 2023-08-17  ... -22844.77     3      -307.08   bar
57  long  600000 2023-08-14 2023-08-17  ... -23130.72     3       -95.32   bar
58  long  000001 2023-08-24 2023-08-29  ... -21972.48     3       386.08   bar
59  long  000001 2023-08-30 2023-09-04  ... -19564.23     3       802.75   bar
60  long  600000 2023-08-30 2023-09-04  ... -19259.23     3       101.67   bar
[60 rows x 13 columns]

策略代码

# 导入相关模块和类
import pybroker as pb
from pybroker import Strategy, StrategyConfig, ExecContext
from pybroker.ext.data import AKShare

# 查看当前版本
print(pb.__version__)

# 策略配置
config = StrategyConfig(initial_cash=500_000)
strategy = Strategy(
    data_source=AKShare(),
    start_date='20220101',
    end_date='20230916',
    config=config
)

# 定义规则
def buy_low(ctx: ExecContext):
    # 如果当前已经持有仓位,则不再买入。
    if ctx.long_pos():
        return
    # 如果当前的收盘价小于前一天的最低价,则下单买入。
    if ctx.bars >= 2 and ctx.close[-1] < ctx.low[-2]:
        # 计算买入的股票数量,该数量为当前资金的 25%。
        ctx.buy_shares = ctx.calc_target_shares(0.25)
        # 设置买入的限价,该限价为当前收盘价减去 0.01。
        ctx.buy_limit_price = ctx.close[-1] - 0.01
        # 设置持有仓位的时间,该时间为 3 个交易日。
        ctx.hold_bars = 3

# 执行回测
strategy.add_execution(fn=buy_low, symbols=['000001', '600000'])
result = strategy.backtest()

# 查看结果
print(result.metrics_df)  # 查看绩效
print(result.orders)  # 查看订单
print(result.positions)  # 查看持仓
print(result.portfolio)  # 查看投资组合
print(result.trades)  # 查看交易