问题描述
一时想不出聚宽怎么表达比较合适??
次日如果还有信号可以买入,但是当日例如上午先行卖出的股票下午又再次出现买入信号时避免再买
context.portfolio.positions这些怎么表达?请教老师们
解决方案
在聚宽(JoinQuant)平台中,context.portfolio.positions 记录的是当前时刻的持仓信息。当你把某只股票全部卖出后,它就会从持仓中消失(或者可用数量变为0)。因此,单靠 context.portfolio.positions 是无法判断这只股票“今天是否被卖出过”的。
要实现**“当日卖出的股票,当日不再买入,次日可恢复买入”**的逻辑,最标准且高效的做法是:利用全局变量 g 来维护一个“今日已卖出股票池(Set)”。
具体实现步骤如下:
1. 在每天开盘前清空记录
利用 before_trading_start 函数,在每天交易开始前,把“今日已卖出股票池”清空,这样次日就可以重新买入了。
2. 在卖出时记录该股票
当你的策略触发卖出信号并成功执行卖出后,将该股票代码加入到这个“今日已卖出股票池”中。
3. 在买入前增加条件判断
当策略触发买入信号时,先检查该股票是否在“今日已卖出股票池”中,如果在,则跳过不买。
完整代码示例
# 导入聚宽函数库
import jqdata
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 定义要操作的股票池
g.stocks = ['000001.XSHE', '000002.XSHE', '000004.XSHE']
# 初始化一个全局变量,用于记录当天卖出的股票
g.sold_today = set()
# 每天开盘前运行
def before_trading_start(context):
# 每天开盘前,清空“今日已卖出股票池”
# 这样次日如果出现买入信号,就可以正常买入了
g.sold_today = set()
log.info("新的一天,已清空当日卖出记录。")
# 盘中运行函数(例如按分钟运行)
def handle_data(context, data):
for security in g.stocks:
# 获取当前价格和均价(仅作示例信号)
price = data[security].close
vwap = data[security].vwap(3)
# ================= 卖出逻辑 =================
# 如果价格跌破均价,且当前有持仓可卖
if price < vwap * 0.995 and context.portfolio.positions[security].closeable_amount > 0:
# 执行卖出
order_target(security, 0)
log.info("卖出 %s" % security)
# 【关键步】:将卖出的股票加入今日已卖出集合
g.sold_today.add(security)
# ================= 买入逻辑 =================
# 如果价格突破均价,且有现金
elif price > vwap * 1.005 and context.portfolio.available_cash > 0:
# 【关键步】:判断该股票今天是否已经卖出过
if security in g.sold_today:
log.info("[%s] 今日已卖出过,忽略本次买入信号" % security)
continue # 跳过该股票,不执行买入
# 如果今天没卖出过,正常执行买入
order_value(security, 10000)
log.info("买入 %s" % security)
逻辑解析
g.sold_today = set():使用 Python 的集合(Set)数据结构,查找速度极快(O(1) 复杂度),且能自动去重。before_trading_start:聚宽引擎会在每个交易日的 09:00 自动调用此函数。在这里重置g.sold_today,完美契合了“次日可重新买入”的需求。if security in g.sold_today::在买入动作前加一道锁,彻底杜绝了“上午卖出、下午信号又满足导致接回”的日内反复震荡(T+0 变相交易)问题。