模擬交易最常見的失敗,是練兩個星期、看到帳面翻紅或翻黑就下結論。台股 2015~2026 的真實回測給出更清楚的刻度:一個年化 39.7%、贏過 0050 含息(20.4%)的策略,仍然有 88.6% 的交易日淨值低於前一次高點,而且曾經連續 724 天沒有創新高。模擬帳戶真正在訓練的能力,是撐過這段。

執行這個策略
複製提示詞,讓 AI 依照上方證據的資料、條件與風險檢查重跑一次。
告訴你的AI:
幫我用 finlab 跑一個月營收動能選股策略,並列出這個月該持有的股票,請讀:https://finlab.finance/setup?relatedUrl=/blog/cmoney-paper-trading-python-api
圖 1:營收動能分散 20 檔 vs 0050 含息(2015-02~2026-07,對數座標)。紅色區間是策略從 2018-06-15 到 2020-06-08 完全沒有創新高的 724 天。
開始模擬前先看懂的四個數字
下表是本文示範策略(營收動能、分散 20 檔、月換股)與 0050 含息在同一段期間的對照。左邊三欄是回測報表會給你的成績,右邊三欄是你在模擬帳戶裡真正會經歷的東西。
| 項目 | 營收動能分散 20 檔 | 0050 含息買進持有 |
|---|---|---|
| 年化報酬率 | 39.7% | 20.4% |
| 日夏普比率 | 1.37 | 1.03 |
| 月索提諾比率 | 1.92 | 1.70 |
| 最大回撤 | -37.9% | -34.0% |
| 淨值低於前高的交易日比例 | 88.6% | 90.3% |
| 最長沒有創新高 | 724 天 | 758 天 |
| 收黑的月份比例 | 36.5% | 37.2% |
| 任選一天進場、持有 1 個月虧損機率 | 33.9% | 36.1% |
回測區間 2015-02-11 至 2026-07-24,平均持股 19.9 檔。策略在年化報酬、日夏普、月索提諾三項勝出,最大回撤比 0050 深 3.9 個百分點。
右半邊三列才是這篇文章的重點:策略的難熬程度跟大盤幾乎一樣。淨值長期低於前高是持股這件事本身的常態,它本身不構成策略失效的證據。 這正是模擬交易要幫你先經歷一遍的事。
Paper Trading 是什麼,跟回測差在哪
Paper Trading(模擬交易)是用虛擬資金、真實市場報價下單,帳面損益照真實成交價計算,但不動到真錢。它跟回測的差別在時間方向:回測是把策略丟回過去,一次算完十年;模擬交易是從今天開始,一天一天跟著市場走。
兩者要回答的問題不一樣:
- 回測回答「這套規則過去行不行」。它給你年化報酬、最大回撤、夏普比率這些總結性數字。
- 模擬交易回答「這套規則我跟不跟得住」。它給你的是每天打開帳戶的感受、換股當下要不要手癢改單、連續三個月綠字時會不會想停掉。
回測的十年在報表上只佔一張圖,實際跟著跑的人卻要一天一天過。多數策略失敗的原因在執行端:跟著跑的人中途改了規則。
三步驟:用 Python 串接 CMoney 大富翁模擬帳戶
CMoney 的大富翁是台股少數免費、可用程式操控的模擬交易平台。我把操作它的程式碼開源成 CmoneyVirtualAccount,安裝後幾行 Python 就能下單。
1. 安裝
打開終端機(Windows 可用 Anaconda Prompt)輸入:
顯示程式碼
git clone https://github.com/koreal6803/CmoneyVirtualAccount.git
# mac 使用的指令
mv CmoneyVirtualAccount/cmoneyVirtualAccount ./cmoney
# windows 使用的指令
move CmoneyVirtualAccount/cmoneyVirtualAccount ./cmoney2. 申請帳號
到 CMoney 大富翁 申請帳號。假如你用 Facebook 登入,仍然要另外設一組密碼(右上角使用者名稱 → 基本資料),否則 Python 無法登入。
3. 用程式操控帳戶
顯示程式碼
from cmoney.stock import VirtualStockAccount
# 登入
virtual_account = VirtualStockAccount('your_account', 'your_password')
# 切換子帳號
virtual_account.aid = '123456'
# 查看某檔股票的即時報價
virtual_account.get_price('2330')
# 查看目前持股與現有資金
virtual_account.status()
virtual_account.info()
# 買一張台積電、賣一張台積電
virtual_account.buy('2330', 1)
virtual_account.sell('2330', 1)
# 批次買進:一張台積電、一張聯發科
virtual_account.buy({'2330': 1, '2454': 1})
# 出清所有股票
virtual_account.sell_all()
# 把帳戶持股調整成指定的組合(先賣掉不在名單內的,再買進名單內的)
virtual_account.rebalance({'2330': 1, '2454': 1})
# 自動把資金平均分配到這幾檔(實際模擬選股策略時最常用這個)
virtual_account.sync(['1101', '2330'])
# 查看與刪除委託單
virtual_account.get_orders()
virtual_account.cancel_all_orders()把選股策略同步到模擬帳戶
模擬帳戶真正的用途,是接上一個有規則的策略,而不是憑感覺點買賣。下面這段用 finlab 算出當期該持有的股票,再一行同步到大富翁帳戶。第一次執行時 finlab 會自動引導登入,不需要在程式裡填任何金鑰。
顯示程式碼
from finlab import data
from finlab.backtest import sim
close = data.get('price:收盤價')
volume = data.get('price:成交股數')
revenue = data.get('monthly_revenue:當月營收')
# 短期價格動能:近 5 日平均日報酬
momentum = (close / close.shift() - 1).rolling(5).mean()
# 趨勢濾網:站上 20/60/120 日均線
trend = (close > close.average(20)) & (close > close.average(60)) & (close > close.average(120))
# 營收動能:3 個月平均營收高於 12 個月平均
revenue_up = revenue.average(3) > revenue.average(12)
# 流動性濾網:20 日平均成交量 500 張以上
liquid = volume.average(20) > 500 * 1000
position = momentum[trend & revenue_up & liquid].is_largest(20)
report = sim(position, resample='M', resample_offset='11D',
stop_loss=0.1, position_limit=0.08, name='營收動能分散20檔')拿到 position 之後,把最新一期的持股名單丟給模擬帳戶:
顯示程式碼
from cmoney.stock import VirtualStockAccount
virtual_account = VirtualStockAccount('your_account', 'your_password')
latest = position.iloc[-1]
stock_ids = list(latest[latest > 0].index)
# sync 會自動平均分配資金,並賣掉不在名單內的持股
virtual_account.sync(stock_ids)之後每個月換股日執行一次,模擬帳戶就會跟著策略走。這條路徑跟真實下單只差最後一步,想直接接券商的話可以看自動下單的爬蟲與部位串接與 FinLab 全自動下單。
模擬要跑多久才看得出東西:11 年台股數據
這是模擬交易最常被問、也最少人用數據回答的問題。我們把上面那個策略的每日淨值拆開來看,算出三組體感指標。
你有 88.6% 的日子會在「還沒回本」的狀態
圖 2:距離前次淨值高點的百分比。策略有 88.6% 的交易日在水面下,0050 含息是 90.3%。
把每天的淨值跟「歷史最高淨值」相比,只有創新高的那天是 0,其餘都是負的。11 年 2,788 個交易日裡,策略有 2,470 天低於前高,比例 88.6%;0050 含息是 2,512/2,783,比例 90.3%。
換句話說,你打開帳戶看到「離最高點還差一截」的機率接近九成,而且買 0050 也一樣。模擬帳戶最重要的訓練,是讓你在這個狀態下仍然照規則換股。
最長的一段:2018-06-15 到 2020-06-08,整整 724 天沒有再創新高,中間最深跌到 -37.9%。0050 含息的對應紀錄是 2022-01-18 到 2024-02-15 的 758 天。如果你只模擬三個月就下結論,抽到的很可能是這 724 天裡的任意一段。
寫這篇文章的當下就是一個現成的例子:截至 2026-07-24,這個策略距離前次高點還差 -22.3%,同一天 0050 含息是 -7.9%。全期年化 39.7% 與此刻帳戶上的紅字同時成立,模擬帳戶要先讓你習慣的就是這件事。
三分之一的月份會是紅字,連四個月收黑是正常的
圖 3:策略逐月報酬熱圖(2015~2026)。137 個月裡有 36.5% 收黑,最長連續 4 個月收黑發生在 2016 年 9 月至 12 月;最右下角的 2026 年 7 月為統計至 24 日的部分月份。
137 個月份中有 50 個月是虧的,比例 36.5%(0050 含息是 37.2%;最後一個月統計至 2026-07-24)。最差的單月是 2021 年 5 月的 -26.6%,最好的單月是 2020 年 8 月的 +31.9%。連續收黑的最長紀錄是 4 個月,發生在 2016 年 9 月到 12 月,而 2016 年全年策略仍上漲 16.5%。
這組數字給模擬交易一個明確的停損標準:連續三、四個月虧損不足以判定策略失效,因為在一個年化 39.7% 的策略裡它本來就會出現。要判定失效,需要的是規則本身的前提改變(例如流動性條件不再成立),而不是帳面顏色。
任選一天進場,持有一個月有三分之一機率是虧的
圖 4:任選一天進場後,持有不同期間仍為帳面虧損的機率。持有愈久,虧損機率愈低。
把 11 年裡每一個交易日都當成「進場日」,計算持有固定期間後的報酬:
| 持有期間 | 策略虧損機率 | 策略報酬中位數 | 0050 虧損機率 |
|---|---|---|---|
| 1 個月 | 33.9% | +2.8% | 36.1% |
| 3 個月 | 28.4% | +7.9% | 28.7% |
| 6 個月 | 19.6% | +14.9% | 24.9% |
| 1 年 | 12.8% | +36.8% | 19.9% |
模擬一個月,有三分之一的機率你會得到一個誤導性的結論(策略沒問題但你看到紅字),這個機率在 0050 上是 36.1%。模擬期拉到半年以上,虧損機率才明顯低於兩成,策略跟大盤的差距也才開始顯現:持有一年時策略的虧損機率是 12.8%,0050 是 19.9%。
實務上的建議是模擬至少三到六個月、涵蓋至少一次完整的換股循環與一次明顯的回檔,再決定要不要投入真錢。
為什麼帳面數字撐不住人:三份研究
模擬交易在做的事,本質上是先把行為偏誤的成本花在虛擬帳戶上。三份經典研究解釋了這些偏誤從哪來:
- Kahneman & Tversky(1979) 的前景理論指出,人對損失的感受明顯強於對同額獲利的感受(後續 Tversky & Kahneman(1992) 把這個損失趨避係數估在 2.25 附近)。這解釋了為什麼 88.6% 的水下時間會被主觀放大成「這策略不行」。
- Odean(1998) 的處分效果研究分析一萬個券商帳戶,發現投資人明顯傾向賣掉賺錢的部位、抱住虧錢的部位。策略要求月底換股時,這個傾向會直接讓你想跳過某幾檔。
- Barber & Odean(2000) 追蹤 66,465 個家庭帳戶,發現交易最頻繁的族群年化淨報酬 11.4%,比市場的 17.9% 低約 6.5 個百分點,成本主要來自過度交易。模擬帳戶的價值之一,就是讓你看見「多做的那幾筆」對淨值的實際影響。
這三個機制都不需要真錢才會發生,所以模擬交易能練到。它練不到的部分放在下一節。
模擬交易的檢查清單:該記錄什麼
模擬期間光看帳面損益意義不大,建議固定記錄這幾項,結束時才有東西可以檢討:
- 有沒有照規則換股:每次換股日記下「策略給的名單」與「你實際下的單」,兩者不一致的次數就是你的執行落差。
- 手癢紀錄:每次想要改單、加碼、停損卻不在規則裡的念頭都記一行,包含當下的帳面損益。模擬結束後回頭看,這些念頭多半發生在水下最深的時候。
- 成交價落差:模擬平台用的是真實報價,但你的委託價與收盤價會有差距,把它記下來當作滑價的粗估(滑價定義)。
- 持股數與集中度:確認實際持股接近策略設定的檔數。持股過度集中會讓體感波動遠大於回測,這點在分散投資的成本有完整的數據拆解。
- 換股頻率:實際換手率若遠高於回測假設,成本會吃掉報酬(周轉率定義)。
回測方法與限制
本文所有數字都來自 finlab 套件的真實回測,可用文末的 strategy.py 完整重現。
| 項目 | 本文設定 |
|---|---|
| 交易成本 | sim() 預設已內扣手續費 0.1425%(未打折)與賣出證交稅 0.3% |
| 滑價 | 未額外假設滑價,成交價採換股日收盤價 |
| 股票池 | 全上市櫃,未排除金融股、KY 股與 ETF |
| 流動性過濾 | 20 日平均成交量 > 500 張 |
| 生存者偏誤 | finlab 資料庫保留已下市股票,回測期間內下市者仍計入 |
| 前視偏差 | 月營收以公布日對齊,換股日設在每月第 11 天之後(resample_offset='11D'),避開營收尚未公布的期間 |
| 權重 | 等權重、單檔上限 8%(position_limit=0.08) |
| 停損 | 個股 -10% 停損(stop_loss=0.1) |
| 周轉率 | 未估算;月頻換股 20 檔的換手率會顯著高於買進持有 |
| 樣本內外 | 全段樣本內(in-sample),未做樣本外或滾動測試 |
| 基準 | 0050 使用 etl:adj_close 還原價買進持有,含息 |
風險調整指標的口徑統一:夏普與索提諾皆由日/月淨值序列計算,無風險利率取 1%。策略的月索提諾 1.92 高於 0050 的 1.70,日夏普 1.37 高於 1.03(日索提諾 1.84 對 1.41、月夏普 1.23 對 0.97,四種口徑一致勝出),但最大回撤 -37.9% 比 0050 的 -34.0% 更深,追求較低波動的讀者要把這點納入考量。
模擬交易本身也有三件事練不到:
- 胃納量:模擬平台不會因為你的委託而讓價格移動,真實下單在小型股上會有衝擊成本。
- 真實的心理壓力:虛擬資金的痛感遠小於真錢,模擬期表現好不代表真倉能執行相同紀律。
- 滑價與成交失敗:模擬撮合通常比實際寬鬆,漲跌停與零股情境不一定被完整模擬。
這三項加上其他常見的回測失真來源,整理在回測限制與回測陷阱完整指南;回測報酬率本身怎麼計算,可以看 FinLab 回測引擎規則解析。
常見問題
Q1:CMoney 大富翁模擬交易免費嗎? 基本的模擬帳戶免費,註冊後即可使用。用 Facebook 登入的話要另外設定密碼,Python 才能登入。
Q2:模擬交易要跑多久才有參考價值? 以本文數據為準,模擬一個月有 33.9% 的機率得到與策略長期表現相反的結論,建議至少三到六個月,並涵蓋一次完整換股循環與一次回檔。
Q3:Paper Trading 跟回測哪個重要? 回測驗證規則本身,模擬驗證你執行規則的能力。策略沒經過回測就模擬,等於用三個月的樣本判斷一套規則,樣本數遠遠不夠;只有回測沒有模擬,則容易在第一次連續虧損時放棄。
Q4:模擬帳戶賺錢,真實帳戶就會賺錢嗎? 不一定。模擬不含衝擊成本與真實心理壓力,兩者的差距在資金規模大、標的流動性差時特別明顯。
Q5:可以用其他券商的模擬帳戶嗎? 可以。永豐、玉山富果等券商都有模擬或實單 API,差別在申請流程與可用函式;本文的策略同步邏輯(取得當期持股名單 → 呼叫同步函式)不變。
Q6:連續虧損幾個月該停掉策略? 用固定月數當停損門檻並不可靠。本文策略最長連續 4 個月收黑,但當年仍為正報酬。判定失效應該回到規則前提是否改變,或是用回測績效檢討的方法重跑最新資料。
Q7:模擬交易需要自己寫程式嗎? 不需要從零寫。策略部分可以直接跟 AI 助手描述條件,讓它用 finlab 產生程式碼;選股策略工具頁與量化交易總覽有更多可直接使用的範例。
互動式回測報告
下面是本文策略的完整回測報表,可以自行切換指標、拖曳時間軸,觀察每一段水下期間的長度:
下載資源
| 檔案 | 用途 |
|---|---|
| strategy.py | 策略、體感指標計算與模擬帳戶同步的完整程式碼 |
| data.csv | 策略與 0050 含息的逐日淨值與水下曲線 |
| metrics.json | 全部回測與體感指標的機器可讀版本 |
重跑方式:安裝 finlab 套件後直接執行 strategy.py(第一次執行會自動引導登入),或把檔案內容貼給你的 AI 助手,請它換成你自己的選股條件再跑一次。
延伸閱讀
- 月營收動能選股:台股 11 年回測與參數拆解(該文同一變體回測到 2026-06,本文釘在 2026-07-24、含 7 月 -18.0% 的月報酬,因此年化數字略低)
- 程式交易是什麼?完整入門指南
- 低波動選股有效嗎?純低波輸 0050 的台股實測
- FinLab 與 CMoney 的功能比較
投資警語:本文僅供教學參考,不構成投資建議。投資有風險,過去績效不代表未來表現。模擬交易的結果不代表真實交易績效,讀者應自行評估風險承受度,並在做出投資決策前諮詢專業顧問。
最後更新:2026-07|回測區間:2015-02-11~2026-07-24|作者:FinLab 量化研究團隊(經量化研究員審閱)
FinLab AI
想建立自己的策略?
用自然語言描述你的選股想法,AI 自動驗證、回測、給你答案
免費開始


