Skip to content

回测 - 风险管理规则

风控规则用于在策略信号的基础上叠加风险控制逻辑。规则可以全局应用,也可以按策略分别绑定。

基本用法

from jh_quant.backtest import backtest
from jh_quant.backtest import (
StrategyTurtle,
StopLossRule,
TakeProfitRule,
TrailingStopRule,
)
# 方式一:全局规则(所有策略共用)
trading_history, perf = backtest(
strategies={"海龟": StrategyTurtle()},
price_data=stock_price,
rules=[StopLossRule(0.05), TakeProfitRule(0.10)],
)
# 方式二:按策略绑定不同规则
trading_history, perf = backtest(
strategies={"海龟": StrategyTurtle()},
price_data=stock_price,
rules={
"海龟": [StopLossRule(0.05), TrailingStopRule(0.03)],
},
)
# 方式三:混合使用
trading_history, perf = backtest(
strategies={
"海龟": StrategyTurtle(entry_window=20),
"激进海龟": StrategyTurtle(entry_window=10),
},
price_data=stock_price,
rules={
"海龟": [StopLossRule(0.05)],
# "激进海龟" 不指定 → 无风控
},
)

规则总览

规则触发条件关键参数
StopLossRule亏损超过固定比例pct
TakeProfitRule盈利超过固定比例pct
TrailingStopRule从最高点回撤超过比例pct
ATRTrailingStopRule从最高点回撤超过 ATR 倍数multiplier, window
MaxHoldingBarsRule持仓 K 线数超过限制bars
MaxConsecutiveRisingBarsRule连续上涨超过限制bars
MaxConsecutiveFallingBarsRule连续下跌超过限制bars

StopLossRule

固定比例止损。

rule = StopLossRule(pct=0.05) # 亏损 5% 止损

TakeProfitRule

固定比例止盈。

rule = TakeProfitRule(pct=0.10) # 盈利 10% 止盈

TrailingStopRule

移动止损(回撤止盈)。从持仓期间的最高点回撤超过指定比例时卖出。

rule = TrailingStopRule(pct=0.03) # 从最高点回撤 3% 止损

与 StopLossRule 的区别:StopLossRule 基于入场价,TrailingStopRule 基于持仓期间最高价。后者允许利润奔跑,只在趋势反转时离场。

ATRTrailingStopRule

基于 ATR(平均真实波幅)的移动止损。

rule = ATRTrailingStopRule(
multiplier=2.0, # ATR 倍数
window=14, # ATR 计算窗口
)

MaxHoldingBarsRule

最大持仓 K 线数限制。

rule = MaxHoldingBarsRule(bars=20) # 最多持有 20 个交易日

MaxConsecutiveRisingBarsRule

连续上涨超出限制后止盈。

rule = MaxConsecutiveRisingBarsRule(bars=5) # 连涨 5 天后卖出

MaxConsecutiveFallingBarsRule

连续下跌超出限制后止损。

rule = MaxConsecutiveFallingBarsRule(bars=5) # 连跌 5 天后卖出

规则执行顺序

当绑定多个规则时,按列表顺序依次检查。任一规则触发卖出,后续规则不再执行。建议将止损类规则放在最前面。

自定义规则

继承 RiskRule 基类:

from jh_quant.backtest import RiskRule, PositionState
import pandas as pd
class GapDownStopRule(RiskRule):
"""跳空低开止损"""
def __init__(self, pct=0.03):
self.pct = pct
def on_tick(self, i: int, df: pd.DataFrame, state: PositionState) -> bool:
if i == 0 or not state.in_position:
return False
gap = (df.iloc[i]['open'] - df.iloc[i-1]['close']) / df.iloc[i-1]['close']
return gap <= -self.pct
钩子方法调用时机返回值
on_enter(i, df, state)买入信号触发后True 阻止入场
on_tick(i, df, state)每个持仓交易日True 触发卖出
should_sell(i, df, state)卖出信号评估时True 确认卖出