问题描述
解决方案
在PTrade提供的API文档中,并没有直接提供计算布林带(Bollinger Bands)的内置函数(如 get_BOLL)。因此,我们需要利用 get_history 获取历史行情数据,结合 Python 的标准科学计算库 numpy 来手动计算。
布林带的计算公式通常如下:
- 中轨(MID):N日的收盘价简单移动平均(通常 N=20)。
- 标准差(STD):N日收盘价的标准差。
- 上轨(UP):中轨 + K * 标准差(通常 K=2)。
- 下轨(DOWN):中轨 - K * 标准差。
策略代码实现
以下是一个完整的策略示例,展示了如何在 handle_data 中计算布林带指标,并打印结果。
import numpy as np
def initialize(context):
# 设置我们要操作的股票,这里以恒生电子为例
g.security = '600570.SS'
# 设置股票池
set_universe(g.security)
# 布林带参数设置
g.n = 20 # 周期,通常为20
g.k = 2 # 标准差倍数,通常为2
def handle_data(context, data):
security = g.security
# 1. 获取历史收盘价数据
# 为了计算20日均线和标准差,我们需要获取过去20个交易日的数据
# 建议获取稍多一点的数据以防万一,但计算只需取最后20个
# fq='pre' 表示使用前复权数据,这在计算技术指标时很重要
history_data = get_history(g.n, '1d', 'close', security, fq='pre')
# 检查数据长度是否足够,如果是新股可能数据不足
if len(history_data) < g.n:
log.info("数据不足,无法计算布林带")
return
# 提取收盘价数组
close_prices = history_data['close'].values
# 2. 计算中轨 (MID):N日移动平均线
mid_band = np.mean(close_prices)
# 3. 计算标准差 (STD)
# ddof=0 表示总体标准差,ddof=1 表示样本标准差,通常金融计算中使用 ddof=0 或 1 差别不大,numpy默认是0
std_dev = np.std(close_prices)
# 4. 计算上轨 (UP) 和 下轨 (DOWN)
up_band = mid_band + g.k * std_dev
down_band = mid_band - g.k * std_dev
# 获取当前最新价格用于对比
current_price = data[security]['close']
# 5. 打印结果
log.info("股票: %s" % security)
log.info("当前价格: %.2f" % current_price)
log.info("布林带上轨: %.2f" % up_band)
log.info("布林带中轨: %.2f" % mid_band)
log.info("布林带下轨: %.2f" % down_band)
# 6. 简单的交易逻辑示例
# 如果价格突破上轨,可能视为超买,卖出
if current_price > up_band and get_position(security).amount > 0:
log.info("价格突破上轨,卖出")
order_target(security, 0)
# 如果价格跌破下轨,可能视为超卖,买入
elif current_price < down_band:
log.info("价格跌破下轨,买入")
# 使用当前现金买入
cash = context.portfolio.cash
if cash > 0:
order_value(security, cash)
代码解析
- 导入库:使用
import numpy as np,这是PTrade环境中预装的高效数值计算库。 - 获取数据:使用
get_history(g.n, '1d', 'close', ...)获取指定长度的历史收盘价。- 注意:
get_history获取的是不包含当前时刻(如果是日线回测,则是昨天及之前)的数据。如果你希望计算包含当日实时价格的动态布林带,需要手动将data[security]['close']追加到close_prices数组中,并取最近的 N 个数据。上述代码使用的是基于历史收盘价(标准静态指标)的计算方式。
- 注意:
- 计算逻辑:
np.mean()计算平均值(中轨)。np.std()计算标准差。- 根据公式加减标准差得到上下轨。
- 复权处理:在
get_history中设置fq='pre'(前复权)是非常重要的,否则股票分红派息导致的价格缺口会严重扭曲布林带的形态,导致错误的交易信号。
Q&A
Q: 为什么不直接使用类似 get_BOLL 的函数?
A: PTrade 的 API 文档中目前提供了 MACD、KDJ、RSI 等指标的直接计算函数,但尚未提供布林带(BOLL)的内置函数。因此需要使用通用的数学库 numpy 基于历史数据自行计算。
Q: 如何计算包含当日实时价格的布林带?
A: get_history 默认返回的是历史数据。如果你在盘中运行(分钟级别或日线盘中),希望指标包含当前最新价,可以先获取 N-1 个历史数据,然后将 data[security]['price'](最新价)append 到数组末尾,组成 N 个数据后再进行 np.mean 和 np.std 的计算。
Q: 计算标准差时 ddof 参数应该设为多少?
A: np.std 默认 ddof=0(总体标准差)。在某些看盘软件中,可能使用样本标准差(ddof=1)。两者在样本量 N=20 时差异很小,通常不会改变策略的买卖方向。如果需要与特定软件完全对齐,可以尝试修改为 np.std(close_prices, ddof=1)。