3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 VWAP (成交量加权平均价) 的日内趋势跟踪策略。
VWAP = 当日累计成交额 / 当日累计成交量。import numpy as np
import pandas as pd
def initialize(context):
"""
初始化函数,设置策略参数
"""
# 设置要操作的股票,这里以 贵州茅台(600519.SS) 为例
# 实际使用时可修改为其他流动性较好的标的
g.security = '600519.SS'
set_universe([g.security])
# 策略参数设置
g.threshold = 0.005 # 阈值 0.5%,用于过滤假突破
g.is_intraday = True # 是否强制日内交易(收盘平仓)
# 设置滑点和佣金(回测常用设置)
set_commission(commission_ratio=0.0003, min_commission=5.0, type="STOCK")
set_slippage(slippage=0.002)
# 注册尾盘定时任务,用于日内平仓
if g.is_intraday:
run_daily(context, close_all_positions, time='14:55')
def before_trading_start(context, data):
"""
盘前处理
"""
log.info("盘前准备: %s" % context.blotter.current_dt)
def handle_data(context, data):
"""
盘中每分钟运行一次
"""
# 1. 时间控制
current_dt = context.blotter.current_dt
current_time = current_dt.strftime('%H:%M')
# 避开开盘前15分钟,数据波动大且VWAP参考性弱
if current_time < '09:45':
return
# 避开尾盘平仓时段,防止逻辑冲突
if current_time >= '14:55':
return
security = g.security
# 2. 获取当日分钟级历史数据来计算 VWAP
# 获取当天开盘以来的分钟数据,最大取240根(4小时)
# 注意:get_history 返回的是包含当前分钟的数据
df = get_history(240, frequency='1m', field=['close', 'volume', 'money'], security_list=security, include=True)
if df is None or len(df) == 0:
return
# 筛选出当日的数据(PTrade get_history 可能返回跨日数据,需按日期过滤)
current_date_str = current_dt.strftime('%Y-%m-%d')
# 将索引转为字符串日期进行匹配
df['date_str'] = df.index.strftime('%Y-%m-%d')
today_df = df[df['date_str'] == current_date_str]
if len(today_df) == 0:
return
# 3. 计算 VWAP
# VWAP = 累计成交额 / 累计成交量
total_money = today_df['money'].sum()
total_volume = today_df['volume'].sum()
if total_volume == 0:
return
vwap = total_money / total_volume
# 获取当前最新价格
current_price = data[security]['price']
# 4. 获取当前持仓
position = get_position(security).amount
available_cash = context.portfolio.cash
# 5. 交易逻辑
# 信号:价格 > VWAP * (1 + 阈值) -> 看多
if current_price > vwap * (1 + g.threshold):
if position == 0 and available_cash > 0:
# 全仓买入
order_value(security, available_cash)
log.info("买入信号触发: 价格(%.2f) > VWAP(%.2f) * (1+%.3f)" % (current_price, vwap, g.threshold))
# 信号:价格 < VWAP * (1 - 阈值) -> 看空/止损
elif current_price < vwap * (1 - g.threshold):
if position > 0:
# 清仓卖出
order_target(security, 0)
log.info("卖出信号触发: 价格(%.2f) < VWAP(%.2f) * (1-%.3f)" % (current_price, vwap, g.threshold))
def close_all_positions(context):
"""
收盘强制平仓函数
"""
security = g.security
position = get_position(security).amount
if position > 0:
log.info("尾盘强制平仓: %s" % security)
order_target(security, 0)
VWAP 计算方法:
get_history 获取当日的分钟线数据。money 字段代表成交额,volume 代表成交量。today_df['money'].sum() / today_df['volume'].sum() 手动计算出截止当前分钟的 VWAP。数据过滤:
get_history(240, ...) 可能会获取到昨天尾盘的数据(如果是上午刚开盘)。df[df['date_str'] == current_date_str] 确保只计算当日的成交量和成交额,保证 VWAP 的准确性。阈值 (g.threshold):
Price > VWAP 容易在震荡市中产生大量无效交易(来回止损)。0.005 (0.5%) 的缓冲带,只有价格显著偏离 VWAP 时才开仓,这有助于过滤噪音。日内平仓:
run_daily(..., time='14:55') 注册定时任务。order_target 调整仓位,而不是从 0 买入)。Q: 如何在 A 股 T+1 制度下使用此策略?
A: 你需要有“底仓”。例如,你持有 1000 股茅台。
Q: 为什么计算 VWAP 时要过滤日期?
A: get_history(count=N) 取的是最近 N 根 K 线。如果在早上 9:40 调用,取 240 根 K 线会包含昨天的大部分数据,导致 VWAP 计算错误。VWAP 定义是“当日”加权均价,所以必须剔除昨日数据。