我下载了 GFS 从 2025-11-14 到 2025-11-21 的 1 分钟级别数据,用于计算 120 周期与 250 周期的移动平均线。策略的买入信号设定为:两条均线均呈现上升趋势,且短期均线(120)位于长期均线(250)之上;卖出信号则为价格回落至 120 均线时触发。
该策略最初在 moomoo 平台上运行,但由于缺少 2025-11-21 的完整数据,后续改用 Python 结合 yfinance 进行回测。目前回测范围仅覆盖 11 月 21 日当天的交易情况,初步结果显示买卖点的捕捉效果较为理想。
尽管已有一定成效,但策略仍具备优化潜力。例如,可加入逻辑避免在卖出后立即重新买入的情况,提升整体执行效率和信号质量。
GFS 原本是 AMD 分拆出来的芯片代工企业,其股价波动特性适合短线量化策略测试。以下是实现该策略的部分代码逻辑,欢迎交流指正。
尽管已有一定成效,但策略仍具备优化潜力。例如,可加入逻辑避免在卖出后立即重新买入的情况,提升整体执行效率和信号质量。
GFS 原本是 AMD 分拆出来的芯片代工企业,其股价波动特性适合短线量化策略测试。以下是实现该策略的部分代码逻辑,欢迎交流指正。
import yfinance as yf
import pandas as pd
import os
def get_data():
filepath = 'GFS_20251121_1m.xlsx'
if os.path.exists(filepath):
df = pd.read_excel(filepath)
df['datetime'] = pd.to_datetime(df['datetime'])
else:
df = yf.download(tickers='GFS', period='1d', interval='1m', progress=False, start='2025-11-21')
if isinstance(df.columns, pd.MultiIndex):
df.columns = df.columns.droplevel(1)
df = df[['Open', 'High', 'Low', 'Close', 'Volume']]
df.columns = ['open', 'high', 'low', 'close', 'volume']
for col in ['open', 'high', 'low', 'close']:
df[col] = df[col].round(3)
df.index.name = 'datetime'
df.reset_index(inplace=True)
df['datetime'] = pd.to_datetime(df['datetime'], format="%Y-%m-%d").dt.tz_localize(None)
df.to_excel(filepath, index=False)
return df
df = get_data()
df.head()
df['ma120'] = df['close'].rolling(window=120).mean()
df['ma250'] = df['close'].rolling(window=250).mean()
df['ma120_prev'] = df['ma120'].shift(1)
df['ma250_prev'] = df['ma250'].shift(1)
df['trend_long'] = (
(df['ma120_prev'] < df['ma120']) &
(df['ma250_prev'] < df['ma250']) &
(df['close'] > df['ma120']) &
(df['ma120'] > df['ma250'])
)
position = 0
buy_price = 0
qty = 100
commission = 2
equity = 4000
trade_log = []
for i in range(len(df)):
row = df.iloc[i]
price = row['close']
ma120 = row['ma120']
ma120_prev = row['ma120_prev']
ma250 = row['ma250']
ma250_prev = row['ma250_prev']
# Skip until MAs exist
if pd.isna(ma120) or pd.isna(ma250):
continue
if row['datetime'] < pd.Timestamp('2025-11-20'):
continue
# BUY CONDITION (same as your strategy)
if position == 0:
if (ma120_prev < ma120) and (ma250_prev < ma250) and (price > ma120) and (ma120 > ma250):
position = qty
buy_price = price
equity -= price * qty + commission
trade_log.append({
'datetime': row['datetime'],
'type': 'BUY',
'price': price
})
# SELL CONDITION
if position > 0:
profit = (price - buy_price) * qty - commission
if price < ma120 and profit > 0:
equity += price * qty - commission
position = 0
trade_log.append({
'datetime': row['datetime'],
'type': 'SELL',
'price': price,
'profit': round(profit, 2)
})
# Close any open position at the end
if position > 0:
final_price = df['close'].iloc[-1]
equity += final_price * qty - commission
profit = (final_price - buy_price) * qty
trade_log.append({
'datetime': df['datetime'].iloc[-1],
'type': 'FORCED EXIT',
'price': final_price,
'profit': round(profit, 2)
})
position = 0
# -------------------------------------------------------
# 4. Results
# -------------------------------------------------------
trades = pd.DataFrame(trade_log)
print("Final Equity:", equity)
print("Net Profit:", equity - 4000)
print("\nTrade Log:")
print(trades)
trades.to_csv("GFS_20251121_trades.csv", index=False)
import mplfinance as mpf
import numpy as np
df_plot = df.copy()
df_plot.set_index("datetime", inplace=True)
df_plot['buy'] = np.nan
df_plot['sell'] = np.nan
for t in trade_log:
dt = t['datetime']
if t['type'] == 'BUY':
df_plot.loc[dt, 'buy'] = df_plot.loc[dt, 'close']
elif t['type'] == 'SELL':
df_plot.loc[dt, 'sell'] = df_plot.loc[dt, 'close']
apds = [
mpf.make_addplot(df_plot['ma120'], color='blue'),
mpf.make_addplot(df_plot['ma250'], color='red'),
mpf.make_addplot(df_plot['buy'], type='scatter', markersize=80, marker='^', color='green'),
mpf.make_addplot(df_plot['sell'], type='scatter', markersize=80, marker='v', color='red'),
]
mpf.plot(
df_plot,
type='candle',
addplot=apds,
volume=False,
title='GFS Backtest with MA120/MA250 and Trade Points',
style='yahoo',
figsize=(18, 9)
)

雷达卡


京公网安备 11010802022788号







