目錄
1. 為什麼要用 AI 輔助編程?
2024 年以來,AI 編程助手(如 ChatGPT、Claude、GitHub Copilot)已經成為程序員的標配工具。對於量化交易開發來說,AI 可以幫你:
- 快速生成模板代碼:策略框架、數據處理、回測邏輯
- 解釋複雜概念:不懂的函數、庫的用法
- 調試錯誤:報錯信息扔給 AI,秒出解決方案
- 優化代碼:讓 AI 幫你重構、提升性能
Claude 3.5 / ChatGPT-4o 都可以完成本教程。推薦使用 Claude,代碼質量更高。
接下來,我會展示完整的對話過程,你可以直接複製這些 Prompt 來復現整個開發流程。
2. 雙均線策略原理
在開始編程之前,先快速了解我們要實現的策略:
什麼是雙均線策略?
雙均線策略(Dual Moving Average)是最經典的趨勢跟蹤策略之一,使用兩條移動平均線:
- 快線(Short MA):較短周期,如 10 日均線,反應靈敏
- 慢線(Long MA):較長周期,如 30 日均線,反應遲鈍
交易信號
| 信號 | 條件 | 操作 |
|---|---|---|
| 🟢 金叉(Golden Cross) | 快線從下方穿越慢線 | 買入 |
| 🔴 死叉(Death Cross) | 快線從上方穿越慢線 | 賣出 |
好了,原理就這麼簡單。現在讓我們開始和 AI 對話!
3. 第一步:讓 AI 獲取數據
Prompt #1:獲取 SPY 歷史數據
AI 生成的代碼
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta
def download_spy_data():
"""下載 SPY 最近 10 年的日 K 線數據"""
# 計算日期範圍
end_date = datetime.now()
start_date = end_date - timedelta(days=365*10)
print(f"正在下載 SPY 數據...")
print(f"日期範圍: {start_date.strftime('%Y-%m-%d')} 至 {end_date.strftime('%Y-%m-%d')}")
# 使用 yfinance 下載數據
spy = yf.Ticker("SPY")
df = spy.history(start=start_date, end=end_date, interval="1d")
# 重置索引,讓 date 成為一列
df = df.reset_index()
# 重命名列
df = df.rename(columns={
'Date': 'date',
'Open': 'open',
'High': 'high',
'Low': 'low',
'Close': 'close',
'Volume': 'volume'
})
# 只保留需要的列
df = df[['date', 'open', 'high', 'low', 'close', 'volume']]
# 保存為 CSV
filename = 'spy_daily_10years.csv'
df.to_csv(filename, index=False)
print(f"\n✅ 數據下載完成!共 {len(df)} 條記錄")
print(f"已保存至: {filename}")
print(f"\n數據預覽:")
print(df.head(10))
print(f"\n...\n")
print(df.tail(5))
return df
if __name__ == "__main__":
df = download_spy_data()
成功獲取約 2500 條數據,保存在 spy_daily_10years.csv
4. 第二步:讓 AI 編寫策略邏輯
Prompt #2:實現雙均線策略
AI 生成的代碼
import backtrader as bt
import pandas as pd
from datetime import datetime
class DualSMAStrategy(bt.Strategy):
"""雙均線策略"""
params = (
('fast_period', 10), # 快線周期
('slow_period', 30), # 慢線周期
)
def __init__(self):
# 計算均線
self.fast_sma = bt.indicators.SMA(
self.data.close,
period=self.params.fast_period
)
self.slow_sma = bt.indicators.SMA(
self.data.close,
period=self.params.slow_period
)
# 交叉信號
self.crossover = bt.indicators.CrossOver(self.fast_sma, self.slow_sma)
# 記錄訂單
self.order = None
def log(self, txt, dt=None):
"""日誌輸出"""
dt = dt or self.datas[0].datetime.date(0)
print(f'{dt.isoformat()} {txt}')
def notify_order(self, order):
"""訂單狀態通知"""
if order.status in [order.Completed]:
if order.isbuy():
self.log(f'🟢 買入執行: 價格={order.executed.price:.2f}, '
f'成本={order.executed.value:.2f}, '
f'手續費={order.executed.comm:.2f}')
else:
self.log(f'🔴 賣出執行: 價格={order.executed.price:.2f}, '
f'成本={order.executed.value:.2f}, '
f'手續費={order.executed.comm:.2f}')
self.order = None
def next(self):
"""每個 bar 執行的邏輯"""
# 如果有未完成訂單,不操作
if self.order:
return
# 沒有持倉
if not self.position:
# 金叉買入
if self.crossover > 0:
self.log(f'📈 金叉信號! 快線={self.fast_sma[0]:.2f}, 慢線={self.slow_sma[0]:.2f}')
self.order = self.buy()
else:
# 死叉賣出
if self.crossover < 0:
self.log(f'📉 死叉信號! 快線={self.fast_sma[0]:.2f}, 慢線={self.slow_sma[0]:.2f}')
self.order = self.sell()
def run_backtest():
"""運行回測"""
# 創建回測引擎
cerebro = bt.Cerebro()
# 添加策略
cerebro.addstrategy(DualSMAStrategy)
# 加載數據
data = bt.feeds.GenericCSVData(
dataname='spy_daily_10years.csv',
datetime=0,
open=1,
high=2,
low=3,
close=4,
volume=5,
dtformat='%Y-%m-%d',
fromdate=datetime(2016, 1, 1),
todate=datetime(2026, 1, 1)
)
cerebro.adddata(data)
# 設置初始資金
cerebro.broker.setcash(100000.0)
# 設置手續費
cerebro.broker.setcommission(commission=0.001) # 0.1%
# 設置全倉交易
cerebro.addsizer(bt.sizers.AllInSizer, percents=95)
# 添加分析器
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')
# 運行回測
print('=' * 60)
print('SPY 雙均線策略回測')
print('=' * 60)
print(f'初始資金: ${cerebro.broker.getvalue():,.2f}')
print('=' * 60)
results = cerebro.run()
strat = results[0]
# 輸出結果
print('=' * 60)
print('回測結果')
print('=' * 60)
final_value = cerebro.broker.getvalue()
print(f'最終資金: ${final_value:,.2f}')
print(f'總收益率: {(final_value/100000 - 1)*100:.2f}%')
# 年化收益率
returns = strat.analyzers.returns.get_analysis()
print(f'年化收益率: {returns["rnorm100"]:.2f}%')
# 最大回撤
drawdown = strat.analyzers.drawdown.get_analysis()
print(f'最大回撤: {drawdown["max"]["drawdown"]:.2f}%')
# 交易統計
trades = strat.analyzers.trades.get_analysis()
if trades.total.total > 0:
print(f'總交易次數: {trades.total.total}')
print(f'盈利次數: {trades.won.total}')
print(f'虧損次數: {trades.lost.total}')
print(f'勝率: {trades.won.total/trades.total.total*100:.1f}%')
return cerebro, results
if __name__ == "__main__":
cerebro, results = run_backtest()
運行結果示例
============================================================
SPY 雙均線策略回測
============================================================
初始資金: $100,000.00
============================================================
2016-02-16 📈 金叉信號! 快線=187.23, 慢線=186.95
2016-02-16 🟢 買入執行: 價格=187.50, 成本=99,750.00, 手續費=99.75
2016-06-27 📉 死叉信號! 快線=202.15, 慢線=202.48
2016-06-27 🔴 賣出執行: 價格=201.85, 成本=107,382.50, 手續費=107.38
...
============================================================
回測結果
============================================================
最終資金: $215,832.50
總收益率: 115.83%
年化收益率: 8.12%
最大回撤: 23.45%
總交易次數: 42
盈利次數: 18
虧損次數: 24
勝率: 42.9%
5. 第三步:讓 AI 完善回測框架
基礎版跑通了,但我們想要更多功能。繼續向 AI 提需求:
Prompt #3:添加參數優化
AI 補充的優化代碼
def optimize_parameters():
"""參數優化"""
results_list = []
fast_periods = [5, 10, 15, 20]
slow_periods = [20, 30, 40, 50, 60]
total = len(fast_periods) * len(slow_periods)
count = 0
print("開始參數優化...")
print(f"共 {total} 種組合\n")
for fast in fast_periods:
for slow in slow_periods:
# 快線必須小於慢線
if fast >= slow:
continue
count += 1
# 創建回測引擎
cerebro = bt.Cerebro()
cerebro.addstrategy(DualSMAStrategy,
fast_period=fast,
slow_period=slow)
# 加載數據
data = bt.feeds.GenericCSVData(
dataname='spy_daily_10years.csv',
datetime=0, open=1, high=2, low=3, close=4, volume=5,
dtformat='%Y-%m-%d',
fromdate=datetime(2016, 1, 1),
todate=datetime(2026, 1, 1)
)
cerebro.adddata(data)
cerebro.broker.setcash(100000.0)
cerebro.broker.setcommission(commission=0.001)
cerebro.addsizer(bt.sizers.AllInSizer, percents=95)
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
# 運行
result = cerebro.run()[0]
final_value = cerebro.broker.getvalue()
returns = result.analyzers.returns.get_analysis()
drawdown = result.analyzers.drawdown.get_analysis()
results_list.append({
'fast': fast,
'slow': slow,
'return': (final_value/100000 - 1) * 100,
'annual_return': returns.get('rnorm100', 0),
'max_drawdown': drawdown['max']['drawdown']
})
print(f"[{count}/{total}] SMA({fast},{slow}): "
f"收益={results_list[-1]['return']:.1f}%, "
f"回撤={results_list[-1]['max_drawdown']:.1f}%")
# 轉為 DataFrame 並排序
df = pd.DataFrame(results_list)
df = df.sort_values('return', ascending=False)
print("\n" + "=" * 60)
print("參數優化結果(按收益率排序)")
print("=" * 60)
print(df.to_string(index=False))
# 最優參數
best = df.iloc[0]
print(f"\n🏆 最優參數: SMA({int(best['fast'])}, {int(best['slow'])})")
print(f" 收益率: {best['return']:.2f}%")
print(f" 年化收益: {best['annual_return']:.2f}%")
print(f" 最大回撤: {best['max_drawdown']:.2f}%")
return df
# 運行優化
optimize_parameters()
6. 第四步:讓 AI 添加可視化
Prompt #4:繪製策略圖表
AI 生成的可視化代碼
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
def plot_strategy_result(cerebro, results):
"""繪製策略結果圖表"""
# 設置中文字體
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 創建圖表
fig, axes = plt.subplots(3, 1, figsize=(14, 10),
gridspec_kw={'height_ratios': [3, 1, 1]})
# 圖1: K線 + 均線 + 買賣點
ax1 = axes[0]
# 獲取數據
strat = results[0]
data = strat.data
dates = [bt.num2date(x) for x in data.datetime.array]
closes = data.close.array
fast_sma = strat.fast_sma.array
slow_sma = strat.slow_sma.array
ax1.plot(dates, closes, label='SPY', color='#1f77b4', linewidth=1)
ax1.plot(dates, fast_sma, label=f'SMA{strat.params.fast_period}',
color='#ff7f0e', linewidth=1.5)
ax1.plot(dates, slow_sma, label=f'SMA{strat.params.slow_period}',
color='#2ca02c', linewidth=1.5)
ax1.set_title('SPY 雙均線策略回測', fontsize=14, fontweight='bold')
ax1.set_ylabel('價格 ($)')
ax1.legend(loc='upper left')
ax1.grid(True, alpha=0.3)
# 圖2: 資金曲線
ax2 = axes[1]
# ... 資金曲線繪製代碼
ax2.set_ylabel('資金 ($)')
ax2.set_title('資金曲線', fontsize=12)
ax2.grid(True, alpha=0.3)
# 圖3: 回撤曲線
ax3 = axes[2]
# ... 回撤曲線繪製代碼
ax3.fill_between(dates, drawdown_pct, 0, color='red', alpha=0.3)
ax3.set_ylabel('回撤 (%)')
ax3.set_title('回撤曲線', fontsize=12)
ax3.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('spy_dual_sma_backtest.png', dpi=150, bbox_inches='tight')
plt.show()
print("\\n📊 圖表已保存至: spy_dual_sma_backtest.png")
將以上所有代碼整合,運行後會生成專業的回測報告和圖表。完整代碼已上傳至 GitHub。
7. 與 AI 交互的技巧總結
7.1 如何寫好 Prompt
| 技巧 | 說明 | 示例 |
|---|---|---|
| 明確目標 | 告訴 AI 你要做什麼 | 「實現一個雙均線策略回測」 |
| 指定技術棧 | 告訴 AI 用什麼庫/框架 | 「使用 Backtrader 框架」 |
| 列出要求 | 用列表說明具體需求 | 「1. 輸出交易記錄 2. 計算最大回撤」 |
| 給出示例 | 如果有具體格式要求 | 「輸出格式:日期 | 信號 | 價格」 |
| 迭代改進 | 逐步添加功能 | 「很好,現在請添加參數優化」 |
7.2 常見問題處理
直接把錯誤信息複製給 AI:「運行報錯:[粘貼錯誤信息],請修復」
更具體地描述:「不是這樣,我的意思是 [更詳細的說明]」
7.3 完整工作流程
- 第一輪:讓 AI 生成基礎框架代碼
- 運行測試:先跑起來看看效果
- 第二輪:針對問題讓 AI 修改/優化
- 第三輪:添加新功能(可視化、參數優化等)
- 最終:整理代碼,添加註釋
通過 4 輪對話,我們完成了一個完整的 SPY 雙均線策略回測程序,包括:數據獲取 → 策略實現 → 參數優化 → 可視化。這就是 AI 輔助編程的威力!
想要更系統地學習量化交易?在我的課程中,你將學會更多策略和實戰技巧。課程中也會大量使用 AI 輔助編程,讓你快速上手。