工法 判準 · 績效揭露
怎麼判斷一份交易紀錄是不是真的:八道檢查,第一個被量的是這個站
3,575 字 · 約 10 分鐘
一份交易紀錄不會自己宣告它是不是真的。這一篇是八道你可以自己跑的檢查:模擬還是真錢、是不是全部的帳戶、淨額還是毛額、樣本數夠不夠、資料斷過沒有、能不能回頭改、沒揭露的是不揭露還是藏起來、誰驗的。八道我先量這個站,兩道不及格。
先講最難看的:下面八道檢查,這個站兩道不及格,一道只有一半。
前兩篇寫的是我自己搞砸的事。這一篇換個方向:同樣的判準拿去量別人給你看的紀錄。 一份交易紀錄不會自己宣告它是不是真的,它只給你一張圖和一個數字。
八道裡四道(第一、二、三、八)出自監理機關與業界標準,一道是統計,三道是這個站每天在跑的工程。
| # | 這一道問什麼 | 這個站 | 證據 |
|---|---|---|---|
| 1 | 模擬還是真錢 | 過 | 績效頁左右分區 |
| 2 | 全部的帳戶,還是只有好的那個 | 過 | 首頁八條線含判死四條 |
| 3 | 淨額還是毛額 | 過 | 回測稽核是反例 |
| 4 | 樣本數夠不夠 | 不及格 | 最高 t=1.88,零條過門檻 |
| 5 | 資料斷過沒有 | 過 | 26 天斷線 |
| 6 | 能不能被回頭改 | 一半 | 擋意外,擋不了故意 |
| 7 | 不揭露還是藏起來 | 過 | 方法論寫死界線 |
| 8 | 誰驗的 | 不及格 | 只有我自己寫的閘門 |
每一道下面有兩段:你可以怎麼問對方,以及這個站的成績。
一、模擬還是真錢:這條線是法規自己畫的
美國商品期貨交易委員會的廣告規則把這條線寫死了。17 CFR 4.41(b)(1)(i) 要求呈現模擬績效時附上指定文字,其中兩句就是判準:模擬結果「並不代表實際交易」,模擬交易「是在後見之明的助益下設計出來的」(designed with the benefit of hindsight)(17 CFR 4.41,查證日期 2026-08-27)。
你可以怎麼問:曲線上的每個點,是對帳單算出來的還是程式重播歷史算出來的?兩種點不該畫在同一條線上。答不出這題,後面七道不用問。
這個站:績效頁左右分區。左邊真錢三條線,本金 $3,300、目前值 $3,499.44(資料時點 2026-08-27T05:10:29Z)。右邊一個評測帳戶顯示 $50,620.24,它不計入左邊的合計。
$50,620.24 ÷ $3,499.44 = 14.5 倍(這是我拿站上兩個數字相除算出來的,不是站上記錄的數字)—— 把兩邊加起來的績效頁,會讓這個帳戶看起來大十四倍。所以資料層有一條不變量:標記為評測的線不得進入總計,違反就拋錯、不寫檔。
二、是全部的帳戶,還是只有好的那個
這一道有現成的答案。CFA Institute 的 GIPS 績效揭露標準第 3.A.2 條要求,所有實際的、收費的、有裁量權的獨立管理帳戶都必須被納入至少一個組合(must be included in at least one composite),而合規以整個公司為單位,不能只挑一個帳戶。
出處:GIPS Standards for Firms, 2020,查證日期 2026-08-27。該站對一般命令列工具回 403,要帶瀏覽器 User-Agent 才取得得到。
白話:挑帳戶跟改數字一樣是造假,而它不留痕跡。 十個帳戶跑同一套邏輯,只展示最好的那一個,每個數字都還是真的。
你可以怎麼問:你總共開過幾條線、幾個帳戶?沒出現在這張表上的那幾個,為什麼不在?
這個站(現況以 2026-08-27 的資料為準):首頁第一張表列八條線,四條判死、四條未證實。包含投入 $0 的 Solana 迷因幣階梯(六天期望值 −13% 到 −18%)、從未下過真錢的運動賽事背離(紙上 15 注),以及一條營收 $0 的商業線。
賠掉的與沒開始的都留著:拿掉它們之後剩下那幾條會變好看,而好看的來源是「拿掉」不是「表現」。
三、淨額還是毛額
NFA 的宣傳品規則 2-29 第 (b)(5) 款訂了兩個條件:績效必須淨於全部佣金、費用與支出(net of all commissions, fees and expenses),而且必須能證明它足以代表同期間所有合理可比帳戶的實際績效(all reasonably comparable accounts)(NFA Compliance Rule 2-29,查證日期 2026-08-27)。
第二個條件是第二道的法規版本,寫在同一條規則裡不是巧合:挑帳戶與扣不扣成本,是同一種修圖的兩種筆刷。
你可以怎麼問:一筆進出的總成本多少?乘上交易次數後佔報酬幾成?講不出成本,那個報酬率就是毛的。
這個站:真錢三條的數字是帳戶層級的餘額與淨值,成本已經在裡面 —— 那不是重算的值,是帳戶本身。反例在我自己站上:一份跑六年的回測原始輸出 13.25 倍,我自己稽核完剩 2.26 倍,而三處高估沒有一處是成本,全部是不會拋例外的 bug(回測說 13.25 倍,稽核完剩 2.26 倍)。所以這一道真正要問的比字面更寬:那個數字被誰算過,算的人有沒有理由懷疑它。
四、樣本數夠不夠讓那個數字有意義
前三道問紀錄的成分,這一道問它的重量。沒有 n 的報酬率不能用,因為它沒有大小。
Harvey、Liu 與 Zhu 在 2016 年的《Review of Financial Studies》給了更狠的門檻:金融文獻已經試過太多因子,考慮多重檢定之後,新因子的 t 值應該拉到 3.0 而不是慣用的 2.0(Harvey, Liu & Zhu, 2016)。
你可以怎麼問:n 是多少?試過幾個版本才留下這一個?後面那個數字是多重檢定的分母,幾乎沒有人主動報。
這個站:這一道不及格,而不及格就是這個站的結論。 事前寫死的門檻是 t*=2.0,八條線最高 t=1.88,零條通過。用上面那個 3.0 的標準看,我自己那把還偏鬆。
更難看的是方向。期貨 fade 那條 n=30 時 t=1.52,多五個交易日、n=53 之後掉到 0.79。樣本數變大,數字變壞。
運動賽事那條的算法寫在背離那篇:統計上要區分 60% 與 50% 的命中率需要 n≈152 注,目前 15 注。在拿到那 137 注之前,那條線的任何報酬率都是它自己的雜訊。
五、資料斷過沒有,斷掉的那一段怎麼標
這一道排在「能不能被改」前面:先知道紀錄有沒有洞,才會在意洞能不能被事後補平。
這個站踩過:一條線的資料收集在 2026-08-01 停掉,到 08-27 為止 26 天沒有新資料,沒有人發現,是我一個月後想起這條線才去看的。根因與我第一份錯掉的根因分析寫在〈兩個都錯的環節〉。
處置是一張存活面板:八條線各自最後一次產生資料是什麼時候,斷線與已結案分開標 —— 已結案的線不再有新資料是正常的,畫成告警就是假警報。新鮮度判準寫死在收集器裡,三十六小時:
STALE_H = 36
def stale(fetched_at, now):
return (now - dt.datetime.fromisoformat(fetched_at)).total_seconds() > STALE_H * 3600
寫這一篇的當下,這個站有一條線正紅著:美股 fade 的淨值資料截止在 2026-08-19,資料時點是 08-27,stale 為真,頁面顯示紅字的「資料截止」而不是靜靜沿用舊值。那條線的數字也不做滾動動畫 —— 會動的數字暗示它是活的。
你可以怎麼問:曲線最後一個點是什麼時候「寫進去」的?不是問最後一天是哪一天。停止更新與持續更新的紀錄,在圖上長得一樣。
六、這份紀錄能不能被回頭改
歷史不可竄改在程式裡就是兩條不變量:時間不倒退、已平倉筆數只增不減。違反就拋錯,不寫檔。
# prev 預設是 sentinel,只有正式跑才去讀磁碟上的前一版;測試一律顯式傳入
if prev:
if payload['as_of'] < prev['as_of']:
errs.append('as_of 倒退:%s < %s' % (payload['as_of'], prev['as_of']))
for name, ln in payload['lines'].items():
pn = len(prev['lines'].get(name, {}).get('closed_trades', []))
if len(ln['closed_trades']) < pn:
errs.append('%s: 已平倉筆數從 %d 掉到 %d' % (name, pn, len(ln['closed_trades'])))
if errs:
raise AssertionError('不變量違反:
- ' + '
- '.join(errs))
筆數少一筆有兩種可能:資料源壞了,或有人不喜歡那一筆。檢查不需要分辨是哪一種,它只要拒絕寫檔然後讓人來看。分辨動機是人的工作,拒絕寫檔是程式的工作。
那個哨兵值有來歷。檢查原本無條件讀磁碟上的前一版,成敗於是取決於磁碟上剛好累積幾筆真交易:一開始會過,累積出三筆平倉紀錄就必然失敗(2026-08-27 修掉)。一個因為環境狀態而通過的檢查,正是這個站在記錄的那一類 bug(怎麼寫一個不會因為錯誤理由通過的檢查)。
這個站:這一道只有一半。 那兩條擋的是意外 —— 手滑、資料源改格式、少抓一筆。它擋不了故意:我有這個倉庫的寫入權,紀錄沒有第三方時間戳。
你可以怎麼問:歷史是只增不改的嗎?誰有權改?改了誰會知道?對方拿得出券商對帳單或交易所 API 的原始輸出,那比任何自訂檢查都強,因為簽名的人不是他。
七、沒揭露的,是「不揭露」還是「藏起來」
所有紀錄都有沒公開的部分。判準不是「有沒有藏」,是你看不看得到那個空位。
這個站永遠不公開進出場的參數與門檻、持有時間、停損位置與容量上限,理由寫在方法論:四條線裡三條是逆勢,跟單的人會墊高我自己的進場成本。逐筆交易走白名單,不是黑名單 —— 原始檔另有四個進場特徵欄位,逐筆公開它們等於逐筆公開進場條件,所以不在這一行上:
# 白名單而非黑名單:新增欄位預設不外流
TRADE_FIELDS = ['sym', 'opened', 'closed', 'entry', 'exit', 'ret', 'days', 'why', 'withheld']
寫這一段的時候我被自己的閘門擋下來。 原始檔那一行上方的註解寫得比較具體,具體到它自己命中了防洩漏閘門的兩條規則,我改寫成上面這個版本才貼得上來。決定什麼可以公開的那份程式碼,自己也要過同一道閘門。 被擋下來這件事可以寫,被擋下來的內容不能寫 —— 包括不能用「原文是這樣所以被擋」的方式繞回去。
最後那個欄位 withheld 是這一道的實作。一筆交易可以同時是「歷史平倉紀錄」與「尚未平倉的部位」—— 同一個標的平掉之後再進一次就是這個形狀。這時標的名稱要遮蔽,但整列不刪:
if t['withheld'] and t['sym'] is not None:
errs.append('%s: 標記 withheld 卻仍帶著標的名稱 %s' % (name, t['sym']))
if not t['withheld'] and t['sym'] is None:
errs.append('%s: sym 為 None 卻沒標記 withheld' % name)
為什麼不刪整列:刪掉會讓第六道那條「筆數只增不減」被自己觸發(三筆變兩筆再變三筆)。遮蔽讓筆數穩定、日期與報酬照留,平倉之後名稱自己回來。
你可以怎麼問:不公開的部分有沒有欄位、有沒有筆數、有沒有標記?看得到空位的紀錄,比看不到空位的紀錄可信。
八、誰驗的:這一道我不及格,而且不打算補
回到 GIPS:宣稱合規至少要有五年的合規績效(第 1.A.3 條),而驗證由外部單位對整個公司做,不是自己對自己說。
這個站:沒有第三方稽核、沒有公開的券商對帳單、沒有任何形式的外部驗證。 運轉時間以月計,離五年很遠。手上只有兩樣:七道建置閘門,全部我自己寫的;以及一個獨立的驗收流程,而它仍然在同一個專案裡面。
那七道閘門的可信度也有紀錄可查:其中五道在寫下的當天就出問題,而且全部沒有報錯。自己寫的檢查會壞,而且會安靜地壞。
這一格不打算補:補的方法是花錢請外部單位驗,而對一個本金 $3,300 的帳戶那不成比例。它會一直紅著,讀到這裡的人應該把上面的數字乘上這個折扣。
你可以怎麼問:誰驗的?他跟你什麼關係?他驗的是「這些交易發生過」,還是「這些是你全部的交易」?
八道加起來:這個站五過、一半、兩不及格
這一行原本寫「四過、兩半」,而上面那張表是五過、一半。 兩組數字都加得到八,所以七道閘門一道都沒響 —— 是驗收方逐列讀表才看出來的(2026-08-27)。
改的是這一行不是表格:表格每一列帶得出證據連結,這一行只是對表格的轉述,而轉述應該從被轉述的東西生成。
這個更正把自評調高了一級,四過變五過。不是有人事後把分數改好看 ——表格從第一版就是這樣,錯的一直是這一行。
現在有一道閘門在比這兩組數,比的是「過/半/不及格」三個數各自相等,不是總和相等。
這個成績不算好,而它是這個站唯一能給的東西:一把用在自己身上會割傷自己的尺。 拿去量下一份有人給你看的紀錄,八道裡它答得出幾道,你就知道要相信到什麼程度。
常見問題
為什麼不直接看報酬率就好? 報酬率是這八道的輸出,不是輸入。前七道都通過的 12%,跟一道都答不出來的 300%,性質不同。
第三方「已驗證」的績效平台算不算通過第八道? 算一半。那類平台驗的通常是「這些交易發生在這個帳戶裡」,而第二道問的是「這是不是你全部的帳戶」。同一個人可以有五個已驗證的帳戶而只給你看一個。
為什麼要把自己的不及格寫出來? 因為一把只割別人的尺沒有人會信。這個站零條通過門檻寫在首頁最上面,跟這裡寫第四道與第八道不及格,是同一個決定。
上面四個來源都在 2026-08-27 當天取得並讀過原文。原本還有第五個,一份量化過存活者偏誤與回填偏誤的對沖基金研究:網址回應正常,但取回來的不是論文本身,我沒讀到原文,所以沒有引用。這是「取得失敗所以不引用」,不是「不重要所以不引用」—— 缺的那塊就在第二道旁邊:挑帳戶之外,資料庫本身也會挑帳戶。
真金額與存活面板在績效頁,界線與理由在方法論,同一種病的完整清單在〈檢查因為錯誤的理由而通過〉。