以下是用AI寫的一個小工具,計算每月定期定額投資1萬元在指定的標的上,所能夠得到的年化報酬率結果。對於想要參與「金雞計劃」的朋友,就可以用這個工具來實測投資標的以往的績效,作為未來的參考。
我用的是TradingView pine script v6,有興趣的朋友可以複製以下的程式碼測試看看(若有疏漏謬誤之處也歡迎指教)
//@version=6
strategy("定期定額 DCA", overlay=true, initial_capital=0, currency=currency.USD, calc_on_order_fills=true, calc_on_every_tick=true)
//------------------------------------------------------------------
// 使用者輸入:設定投資的開始與結束日期
// 請依 ISO-8601 格式輸入 (例如 "2020-01-01T00:00:00")
//
// 注意:本策略僅於 startDate ~ endDate 區間內進行定期定額投資
//------------------------------------------------------------------
startDate = input.time(timestamp("2010-01-01T00:00:00"), "Start Date")
endDate = input.time(timestamp("2024-12-31T23:59:59"), "End Date")
//------------------------------------------------------------------
// 定義 XIRR 函數:根據現金流及其發生時間,利用二分法求解 IRR
// XIRR 公式: Σ[ CF[i] / (1 + r)^((t[i]-t0)/365) ] = 0
//------------------------------------------------------------------
f_xirr(_flows, _times) =>
n = array.size(_flows)
if n < 2
na
else
rLow = -0.99
rHigh = 10.0
// 以 50 次迭代達到足夠精度
for i = 0 to 50
rMid = (rLow + rHigh) / 2.0
npv = 0.0
t0 = array.get(_times, 0)
for j = 0 to n - 1
cf = array.get(_flows, j)
t = array.get(_times, j)
// 將毫秒轉換為天數 (1 天 = 86,400,000 毫秒)
days = (t - t0) / 86400000.0
npv += cf / math.pow(1 + rMid, days / 365.0)
if npv > 0
rLow := rMid
else
rHigh := rMid
(rLow + rHigh) / 2.0
//------------------------------------------------------------------
// 宣告全域變數:用來記錄每次投資的現金流與時間、累計買進的股數以及總投入金額
//------------------------------------------------------------------
var float[] cashFlows = array.new_float()
var int[] cashFlowTimes = array.new_int()
var float totalShares = 0.0
var float totalInvested = 0.0
// 用來確保僅在設定期間結束後首次計算 XIRR 與累積報酬率
var bool computedResults = false
//------------------------------------------------------------------
// 判斷是否為新月份的第一根 K 線(month open)
// ta.change(time("M")) 回傳數值,需與 0 比較取得布林值
//------------------------------------------------------------------
is_new_month = ta.change(time("M")) != 0
//------------------------------------------------------------------
// 每月定期定額投資 10000 元:僅在使用者設定的期間內進行
//------------------------------------------------------------------
if is_new_month and time >= startDate and time <= endDate
shares_to_buy = 10000 / open
totalShares += shares_to_buy
totalInvested += 10000
// 記錄投入的現金流(支出以負值表示)
array.push(cashFlows, -10000)
array.push(cashFlowTimes, time)
// 下單買入(strategy.entry 便於在策略測試器中觀察交易)
strategy.entry("Buy", strategy.long, qty = shares_to_buy)
//------------------------------------------------------------------
// 當 bar 的時間大於或等於使用者設定的結束日期,且尚未計算結果時:
// 1. 計算最終組合價值 (持有股數 * 當前收盤價)
// 2. 加入正向現金流並計算 XIRR
// 3. 計算總累積報酬率 = (最終組合價值 - 總投入金額) / 總投入金額 * 100%
// 4. 利用 label 顯示結果
//------------------------------------------------------------------
if not computedResults and time >= endDate
finalValue = totalShares * close
array.push(cashFlows, finalValue)
array.push(cashFlowTimes, time)
irr = f_xirr(cashFlows, cashFlowTimes)
computedResults := true
// 總累積報酬率 (%)
cumulativeReturn = (finalValue - totalInvested) / totalInvested * 100.0
// 顯示 XIRR,轉換為百分比格式
label.new(bar_index, high, text="XIRR: " + str.format("{0,number,#.##}%", irr * 100), style=label.style_label_up, color=color.green, textcolor=color.white)
// 顯示總累積報酬率
label.new(bar_index, high * 0.95, text="累積報酬率: " + str.format("{0,number,#.##}%", cumulativeReturn), style=label.style_label_up, color=color.blue, textcolor=color.white)
留言