
两个条件同时满足 → 次日开盘买入
1,当日收盘价 ≥ 20 日均线(MA20),
2,MACD 指标形成 金叉(DIF 上穿 DEA)
卖出条件
收盘价 跌破 20 日均线 → 次日开盘卖出
确实简单,我就写了代码做了回测,回测时间是2020年-2026年6月:

策略收益是61.88%,年化是8.07%,我猜他可能还有科创综指,另外跨境ETF可能加上了中韩半导体这种收益大的,我这边是恒科,所以我这个收益比不上他。
这个回测时间也掐的很好,6月30日,再回测多两个月就大回撤了哦。
今天就是随便搓一个。感兴趣的可以自己试试。
"""import jqdata# 1. 标的池security_list = [# 8只 A股宽基ETF"510050.XSHG", # 上证50ETF"510300.XSHG", # 沪深300ETF"510500.XSHG", # 中证500ETF"510600.XSHG", # 中证1000ETF"159915.XSHE", # 创业板ETF"588000.XSHG", # 科创50ETF"159361.XSHE", # 中证A500ETF"159845.XSHE", # 科创创业50ETF# 4只 跨境ETF"513600.XSHG", # 恒生指数ETF"513130.XSHG", # 恒生科技ETF"513100.XSHG", # 纳指100ETF"513500.XSHG" # 标普500ETF]# 指标参数MA_period = 20macd_fast = 12macd_slow = 26macd_signal = 9def initialize(context):set_benchmark('000300.XSHG')set_option('use_real_price', True)# ETF交易费率set_order_cost(OrderCost(open_tax=0, close_tax=0,open_commission=0.0001, close_commission=0.0001,close_today_commission=0, min_commission=5), type='stock')g.buy_candidates = []g.sell_candidates = []# 收盘计算信号run_daily(generate_signal, time='15:20', reference_security='000001.XSHE')# 次日开盘交易run_daily(execute_trade, time='9:31', reference_security='000001.XSHE')def generate_signal(context):# 先清空昨日信号g.buy_candidates = []g.sell_candidates = []for stock in security_list:# 获取日线数据df = get_price(stock, end_date=context.current_dt, frequency='daily', count=80, fields=['close'])# 数据长度不足直接跳过if len(df) < 40:log.warn(f"{stock} 历史K线数量不足,跳过计算")continueclose = df['close']ma20 = close.rolling(window=MA_period).mean()price_now = close.iloc[-1]ma20_now = ma20.iloc[-1]# MACD计算ema_fast = close.ewm(span=macd_fast, adjust=False).mean()ema_slow = close.ewm(span=macd_slow, adjust=False).mean()dif = ema_fast - ema_slowdea = dif.ewm(span=macd_signal, adjust=False).mean()dif_now = dif.iloc[-1]dif_pre = dif.iloc[-2]dea_now = dea.iloc[-1]dea_pre = dea.iloc[-2]# 买入条件:站上20日线 + MACD金叉cond_buy = (price_now >= ma20_now) and (dif_pre <= dea_pre) and (dif_now > dea_now)if cond_buy:g.buy_candidates.append(stock)# 卖出条件:跌破20日线cond_sell = price_now < ma20_nowif cond_sell:g.sell_candidates.append(stock)log.info("===== 收盘信号 =====")log.info("待买入标的:", g.buy_candidates)log.info("待卖出标的:", g.sell_candidates)def execute_trade(context):positions = context.portfolio.positions# 卖出持仓中满足条件标的for stock in g.sell_candidates:if stock in positions and positions[stock].total_amount > 0:order_target(stock, 0)log.info(f"【开盘卖出】{stock} 收盘价跌破MA20")# 均分资金买入候选标的buy_list = g.buy_candidatesbuy_count = len(buy_list)if buy_count <= 0:returnavailable_cash = context.portfolio.available_casheach_target_value = available_cash / buy_countfor stock in buy_list:order_target_value(stock, each_target_value)log.info(f"【开盘买入】{stock} MA20之上 + MACD金叉")
夜雨聆风