代码问题
问题1:先买后检查止损
order(stk, 100) # 先买入
...
if ret < -0.01:
order_target(stk, 0) # 再止损
问题:刚买入的股票也可能触发止损(如果之前已有持仓且亏损)。 应该先检查再买:
# 正确顺序
if stk in context.portfolio.positions:
# 先检查止损
if ret < -0.01:
order_target(stk, 0)
continue
# 再买入
order(stk, 100)
问题2:首次买入可能报错
cost = context.portfolio.positions[stk].avg_cost
问题:如果该股票还没有持仓,positions[stk] 会返回空仓位,avg_cost 为 0,导致除零错误。 修复:
if stk in context.portfolio.positions:
pos = context.portfolio.positions[stk]
if pos.total_amount > 0 and pos.avg_cost > 0:
ret = pos.price / pos.avg_cost - 1
if ret < -0.01:
order_target(stk, 0)
问题3:每个bar都买入
每分钟/每天都买100股,资金很快耗尽。
改进版本
def initialize(context):
run_daily(period, time='open')
g.security = ['000001.XSHE', '000002.XSHE']
def period(context):
for stk in g.security:
# 先检查是否持仓
if stk in context.portfolio.positions:
pos = context.portfolio.positions[stk]
if pos.total_amount > 0 and pos.avg_cost > 0:
ret = pos.price / pos.avg_cost - 1
# 止损
if ret < -0.01:
order_target(stk, 0)
log.info(f'{stk} 触发止损,收益率: {ret:.2%}')
continue # 止损后不再买入
# 未持仓则买入
if stk not in context.portfolio.positions or \
context.portfolio.positions[stk].total_amount == 0:
order(stk, 100)
log.info(f'买入 {stk} 100股')
改进点 说明
time='open' 每天只执行一次
先检查止损 避免止损后又买入
判断持仓存在 避免报错
log.info 替代 print,更规范
2026-01-02