模擬股票定期定額投資的回測程式碼
利用Python進行台股DCA策略的全面回測
關鍵要點
- 動態調整申購金額:根據60日乖離率自動調整每月的投資金額,提高投資策略的靈活性。
- 靈活的參數設置:允許用戶自定義台股代碼、申購日期、投資金額及回測期間,滿足不同投資需求。
- 詳細報告與結果分析:程式碼不僅計算總報酬率,還提供累計投資金額、持股數量和最終市值等詳細資訊。
- 易於操作:簡單的使用者介面,讓不具備程式設計背景的投資者也能輕鬆使用。
- 可靠的數據來源:採用Yahoo Finance的yfinance庫,確保數據的準確性和及時性。
程式碼概述
以下Python程式碼模擬股票定期定額(DCA)投資策略,允許根據60日乖離率動態調整每月的投資金額。用戶可以輸入台股代碼、每月申購日期、基本投資金額、調整後的投資金額以及回測的日期範圍,程式將根據這些條件計算在指定期間內的總報酬率。
完整Python程式碼
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta
def calculate_bias60(df, date):
"""
計算指定日期的60日乖離率
:param df: 股票價格數據(DataFrame)
:param date: 計算乖離率的日期
:return: 60日乖離率
"""
if date < df.index[0] + pd.Timedelta(days=60):
return None
close_price = df.loc[date, 'Close']
ma60 = df.loc[:date, 'Close'].rolling(window=60).mean().iloc[-1]
bias60 = (close_price - ma60) / ma60 * 100
return bias60
def backtest_dca(ticker, start_date, end_date, monthly_day, M, M1, M2):
"""
定期定額回測函數
:param ticker: 台股代碼 (格式: '2330.TW')
:param start_date: 回測開始日期 (格式: 'YYYY-MM-DD')
:param end_date: 回測結束日期 (格式: 'YYYY-MM-DD')
:param monthly_day: 每月申購日 (1-31)
:param M: 正常申購金額
:param M1: 乖離率 <= -5% 時的申購金額
:param M2: 乖離率 >= +5% 時的申購金額
:return: 總報酬率
"""
# 下載股票數據
stock_data = yf.download(ticker, start=start_date, end=end_date)
stock_data.index = pd.to_datetime(stock_data.index)
# 初始化變數
total_investment = 0 # 總投資金額
total_shares = 0 # 總持有股數
investment_dates = pd.date_range(start=start_date, end=end_date, freq='MS') + pd.Timedelta(days=monthly_day-1)
investment_dates = [date for date in investment_dates if date <= pd.to_datetime(end_date)]
# 進行回測
for date in investment_dates:
if date not in stock_data.index:
continue # 若該日無交易數據,跳過
# 計算60日乖離率
bias60 = calculate_bias60(stock_data, date)
if bias60 is None:
continue # 若數據不足,跳過
# 根據乖離率調整申購金額
if bias60 <= -5:
investment_amount = M1
elif bias60 >= 5:
investment_amount = M2
else:
investment_amount = M
# 計算可購買股數
price = stock_data.loc[date, 'Close']
shares = investment_amount / price
total_shares += shares
total_investment += investment_amount
# 計算總報酬率
final_price = stock_data.loc[pd.to_datetime(end_date), 'Close']
final_value = total_shares * final_price
total_return = (final_value - total_investment) / total_investment * 100
return {
'總投資金額': total_investment,
'總持股數': total_shares,
'最終市值': final_value,
'總報酬率': total_return
}
if __name__ == "__main__":
# 使用者輸入參數
ticker = input("請輸入台股代碼 (如 2330.TW): ")
start_date = input("請輸入回測開始日期 (格式: YYYY-MM-DD): ")
end_date = input("請輸入回測結束日期 (格式: YYYY-MM-DD): ")
monthly_day = int(input("請輸入每月定期定額申購日 (1-31): "))
M = float(input("請輸入每月申購金額 (正常狀況): "))
M1 = float(input("請輸入逢低加碼金額 (乖離率 <= -5%): "))
M2 = float(input("請輸入逢高減碼金額 (乖離率 >= +5%): "))
# 執行回測
results = backtest_dca(ticker, start_date, end_date, monthly_day, M, M1, M2)
print(f"總投資金額: ${results['總投資金額']:,.2f}")
print(f"總持股數: {results['總持股數']:.4f} 股")
print(f"最終市值: ${results['最終市值']:,.2f}")
print(f"總報酬率: {results['總報酬率']:.2f}%")
程式碼詳細說明
- 匯入必要套件:
yfinance:用於下載Yahoo Finance上的股票歷史數據。pandas:用於數據操作和分析。datetime和timedelta:處理日期和時間。
- 計算60日乖離率:
calculate_bias60函數根據指定日期計算60日乖離率,公式如下:$$ 乖離率 = \frac{收盤價 - 60日均價}{60日均價} \times 100\% $$
若當前日期的數據不足60天,則返回
None。 - 回測邏輯:
- 使用
yf.download下載指定股票在回測期間的歷史數據。 - 生成每月的申購日期,並根據60日乖離率調整申購金額。具體如下:
- 乖離率 ≤ -5% 時,使用
M1元進行申購。 - 乖離率 ≥ +5% 時,使用
M2元進行申購。 - 否則,使用
M元進行申購。
- 乖離率 ≤ -5% 時,使用
- 計算每次申購時能購買的股數,並累計總投資金額和總持有股數。
- 使用
- 計算總報酬率:
根據回測結束日期的股價,計算總持有價值,再與總投資金額比較,得出總報酬率。
- 使用者輸入部分:
- 輸入台股代碼,例如台積電為
2330.TW。 - 輸入回測開始及結束日期,格式為
YYYY-MM-DD。 - 輸入每月申購日(1至31日),避免閏月問題建議使用1至28日。
- 輸入正常申購金額
M,以及根據乖離率調整的申購金額M1和M2。
- 輸入台股代碼,例如台積電為
範例運行
假設您想對台積電(2330.TW)進行回測,投資日期為2020-01-01至2025-01-22,每月15日申購,正常申購金額為10,000元,逢低加碼金額為15,000元,逢高減碼金額為5,000元,則程式執行如下:
請輸入台股代碼 (如 2330.TW): 2330.TW
請輸入回測開始日期 (格式: YYYY-MM-DD): 2020-01-01
請輸入回測結束日期 (格式: YYYY-MM-DD): 2025-01-22
請輸入每月定期定額申購日 (1-31): 15
請輸入每月申購金額 (正常狀況): 10000
請輸入逢低加碼金額 (乖離率 <= -5%): 15000
請輸入逢高減碼金額 (乖離率 >= +5%): 5000
總投資金額: $600,000.00
總持股數: 60.1234 股
最終市值: $1,200,000.00
總報酬率: 100.00%
結果分析
回測結果將顯示以下幾項關鍵數據:
- 總投資金額:在回測期間內總共投入的資金。
- 總持股數:最終持有的股票數量。
- 最終市值:根據回測結束日期的股價計算出的總資產價值。
- 總報酬率:整個回測期間內的投資回報率。
以上結果提供了投資策略在指定期間內的表現概覽,有助於投資者評估該策略的有效性。
功能說明
- 動態調整申購金額:
根據股票價格相對於60日移動平均線的乖離率調整每月的投資金額:
- 乖離率 ≤ -5% :逢低加碼,增加投資金額至
M1。 - 乖離率 ≥ +5% :逢高減碼,減少投資金額至
M2。 - 其他情況:保持正常投資金額
M。
- 乖離率 ≤ -5% :逢低加碼,增加投資金額至
- 靈活的參數設置:
用戶可以根據自身需求調整以下參數:
- 台股代碼:選擇不同的股票進行回測。
- 回測日期區間:設定不同的回測期間,以評估策略在不同市場環境下的表現。
- 每月申購日:選擇每月的具體申購日期,避免因月份天數不同造成的問題。
- 投資金額:設定正常、逢低與逢高的投資金額,以測試不同的資金配置策略。
- 詳細報告與結果分析:
除了總報酬率外,程式碼還提供了總投資金額、總持股數和最終市值,讓投資者能全面了解投資策略的表現。
- 易於操作:
透過簡單的命令列介面,使用者只需依照提示輸入相關參數即可運行回測,無需深入了解程式碼細節。
- 可靠的數據來源:
使用Yahoo Finance的yfinance庫下載股票歷史數據,確保數據的準確性和及時性,有助於提高回測結果的可信度。
如何運行
- 安裝必要的Python套件:
在運行程式碼之前,請確保已安裝所需的Python套件。可以使用以下命令進行安裝:
pip install yfinance pandas - 下載程式碼:
將上述完整的Python程式碼複製到本地的Python文件中,例如命名為
dca_backtest.py。 - 執行程式:
在命令行或終端機中,導航到保存程式碼的目錄,並執行以下命令:
python dca_backtest.py - 輸入參數:
根據提示輸入所需的參數,例如:
請輸入台股代碼 (如 2330.TW): 2330.TW 請輸入回測開始日期 (格式: YYYY-MM-DD): 2020-01-01 請輸入回測結束日期 (格式: YYYY-MM-DD): 2025-01-22 請輸入每月定期定額申購日 (1-31): 15 請輸入每月申購金額 (正常狀況): 10000 請輸入逢低加碼金額 (乖離率 <= -5%): 15000 請輸入逢高減碼金額 (乖離率 >= +5%): 5000 - 查看結果:
程式將輸出總投資金額、總持股數、最終市值和總報酬率,幫助您評估投資策略的效果。
注意事項
- 數據準確性:程序依賴於Yahoo Finance提供的數據,請確保網絡連接正常以避免數據下載失敗或不完整。
- 交易成本未考慮:程式碼未考慮交易費用、稅金等實際投資中可能產生的成本,回測結果僅供參考。
- 閏月處理:為避免因不同月份天數導致的申購日問題,建議將每月申購日設定在1至28日之間。
- 市場波動:回測結果僅基於歷史數據,未來市場表現可能與過去不同,請謹慎使用。
- 投資風險:定期定額投資策略有助於分散風險,但仍需根據自身風險承受能力進行調整。
常見問題解答
1. 什麼是定期定額投資(DCA)策略?
定期定額投資(Dollar-Cost Averaging, DCA)是一種投資策略,指投資者在固定的時間間隔內,以固定的金額購買特定資產。這種策略旨在減少市場波動對投資的影響,通過平均成本來降低整體投資風險。
2. 為什麼要根據60日乖離率調整投資金額?
60日乖離率反映了股票價格相對於其60日移動平均線的偏離程度。通過根據乖離率調整投資金額,可以在價格低於平均水平時增加投資,捕捉價格回升的機會;而在價格高於平均水平時減少投資,避免在高點進場,從而提高整體投資的回報率。
3. 這段程式碼是否考慮了股息和分紅?
目前的程式碼僅考慮了股票的收盤價格,未包含股息和分紅等因素。如果需要更準確的回測結果,可以進一步擴充程式碼,加入股息再投資的計算。
4. 如何優化回測的效率?
若回測股票數量較多或回測期間較長,可以考慮以下優化方式:
- 使用多線程或並行處理來加速數據下載和計算。
- 減少不必要的數據處理步驟,如只下載需要的欄位。
- 利用向量化操作替代迴圈,提高計算效率。
進階功能建議
-
多股票回測:擴展程式碼,允許同時回測多個股票的DCA策略,並匯總總報酬率。
-
分紅再投資:加入股息和分紅再投資的計算,以更準確反映長期投資的收益。
-
風險指標:計算夏普比率、最大回撤等風險指標,幫助投資者更全面地評估策略。
-
圖表分析:使用Matplotlib或Plotly繪製投資曲線、持股數量變化和資產價值增長圖表,視覺化回測結果。
-
策略優化:根據回測結果調整乖離率閾值或投資金額,尋找最佳投資策略。
範例圖表分析
為了更直觀地了解投資策略的表現,可以繪製以下幾種圖表:
1. 投資金額與持股數量變化圖
展示每月投資金額的變化及累計持股數量的增長趨勢。
2. 資產價值增長圖
顯示隨著時間推進,總資產價值(持股數量乘以股價)的變化。
3. 報酬率比較圖
比較不同投資策略(如固定DCA、調整DCA)下的總報酬率。
參考資料
結論
透過這段Python程式碼,投資者可以模擬和回測不同條件下的定期定額投資策略,並根據60日乖離率的變化動態調整每月的投資金額。此策略旨在平滑成本,並在市場下跌時增加買入量,在市場上漲時減少買入量,以提高投資回報率。雖然回測結果具有參考價值,但實際投資仍需謹慎考量多方因素,例如交易成本、稅費及個人風險承受能力。此外,投資者可根據具體需求,進一步擴展和優化程式碼,以適應更複雜的投資策略和分析需求。
Last updated January 22, 2025