3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT 平台的 VWAP(成交量加权平均价) 交易策略。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
"""
初始化函数,策略启动时调用一次
"""
# 设置要交易的股票代码,这里以浦发银行为例
ContextInfo.stock_code = '600000.SH'
# 设置股票池
ContextInfo.set_universe([ContextInfo.stock_code])
# 设置交易账号(请替换为您真实的资金账号)
ContextInfo.account_id = 'YOUR_ACCOUNT_ID'
ContextInfo.set_account(ContextInfo.account_id)
# 定义一个全局变量记录持仓状态 (1: 持仓, 0: 空仓)
# 注意:实盘中建议使用 get_trade_detail_data 获取真实持仓
ContextInfo.holding = 0
# 每次下单的数量(股)
ContextInfo.trade_vol = 1000
def handlebar(ContextInfo):
"""
行情事件函数,每根 K 线运行一次
"""
# 获取当前 K 线的位置
index = ContextInfo.barpos
# 获取当前时间戳
timetag = ContextInfo.get_bar_timetag(index)
# 将时间戳转换为日期字符串 (格式 YYYYMMDD),用于判断是否为同一天
# format参数根据需求设定,这里只需要日期部分
current_date_str = timetag_to_datetime(timetag, '%Y%m%d')
# 获取行情数据
# 为了计算日内 VWAP,我们需要获取当天开盘以来的数据
# 假设是分钟线,一天最多240根K线,取最近240根足以覆盖当天
data_map = ContextInfo.get_market_data_ex(
['close', 'amount', 'volume'],
[ContextInfo.stock_code],
period=ContextInfo.period,
count=240,
dividend_type='follow'
)
if ContextInfo.stock_code not in data_map:
return
df = data_map[ContextInfo.stock_code]
# 确保数据不为空
if df.empty:
return
# --- 核心逻辑:计算日内 VWAP ---
# 1. 将索引(时间字符串)转换为日期格式,以便筛选当天数据
# 注意:get_market_data_ex 返回的 DataFrame index 是字符串格式的时间
df['datetime_str'] = df.index
# 提取日期部分 (假设索引格式为 YYYYMMDDHHMMSS)
df['date'] = df['datetime_str'].apply(lambda x: x[0:8])
# 2. 筛选出属于“今天”的数据
today_df = df[df['date'] == current_date_str]
if today_df.empty:
return
# 3. 计算累计成交额和累计成交量
cumulative_amount = today_df['amount'].sum()
cumulative_volume = today_df['volume'].sum()
# 4. 计算 VWAP
if cumulative_volume == 0:
return
vwap = cumulative_amount / cumulative_volume
# 获取当前 K 线的收盘价
current_close = today_df['close'].iloc[-1]
# --- 交易逻辑 ---
# 打印调试信息 (可在日志中查看)
print(f"时间: {timetag_to_datetime(timetag, '%Y-%m-%d %H:%M:%S')}, 收盘价: {current_close:.2f}, VWAP: {vwap:.2f}")
# 信号 1: 价格上穿 VWAP -> 买入
if current_close > vwap and ContextInfo.holding == 0:
print("信号触发: 价格高于 VWAP,买入")
# 下单买入
order_shares(ContextInfo.stock_code, ContextInfo.trade_vol, 'fix', current_close, ContextInfo, ContextInfo.account_id)
ContextInfo.holding = 1
# 信号 2: 价格下穿 VWAP -> 卖出 (平仓)
elif current_close < vwap and ContextInfo.holding > 0:
print("信号触发: 价格低于 VWAP,卖出")
# 下单卖出 (负数代表卖出)
order_shares(ContextInfo.stock_code, -ContextInfo.trade_vol, 'fix', current_close, ContextInfo, ContextInfo.account_id)
ContextInfo.holding = 0
数据获取 (get_market_data_ex):
amount (成交额) 和 volume (成交量)。count=240:因为 A 股一天大约有 240 分钟的交易时间,获取最近 240 根分钟 K 线通常能覆盖当天的所有数据。日内数据筛选:
timetag_to_datetime 获取当前 K 线的日期,并在 DataFrame 中筛选出 date 等于当前日期的所有行,从而实现仅基于当天数据计算 VWAP。VWAP 公式:
Sum(当日所有K线成交额) / Sum(当日所有K线成交量)。交易执行 (order_shares):
order_shares 进行指定股数下单。'fix' 表示限价单(这里用的是当前收盘价作为委托价,回测中通常能成交,实盘中可能需要用对手价 'COMPETE' 或市价以保证成交)。init 函数中将 YOUR_ACCOUNT_ID 替换为您真实的资金账号。passorder 函数并指定开空操作码)。Q: 如何将此策略改为期货策略(支持开空单)?
A: 需要将 order_shares 替换为 buy_open (买入开仓), sell_close (卖出平仓), sell_open (卖出开仓), buy_close (买入平仓) 等期货专用函数,或者使用 passorder 函数配合期货的操作码(如 0:开多, 3:开空)。
Q: 为什么 VWAP 计算要筛选当天的日期?
A: VWAP 的定义是“成交量加权平均价”,通常指当日的均价。如果不重置,计算的就是过去 N 天的移动 VWAP,这与通用的 VWAP 交易逻辑不同。
Q: ContextInfo.holding 变量在实盘中可靠吗?
A: 不完全可靠。在实盘中,程序重启后变量会重置。建议在实盘中使用 get_trade_detail_data(ContextInfo.account_id, 'stock', 'position') 来查询真实的账户持仓情况。