Author Archives: 發財橘子

布萊恩·強森 (Brian Johnson) 的投資哲學

 布萊恩·強森 (Brian Johnson) 經歷與投資哲學

過往經歷:

Brian Johnson 擁有超過 30 年的機構投資管理與自營交易經驗。 且著有多本量化交易聖經,包含《Option Strategy Risk / Return Ratios》(選擇權風險報酬比)以及《Exploiting Earnings Volatility》(利用盈餘波動率獲利)。

核心投資哲學:

  1. 純粹的系統化與演算法交易 (Algorithmic Trading):他極度排斥依賴直覺的主觀交易,主張所有的交易邏輯都必須能被量化、編碼化,並經過嚴密的歷史數據回測。
  2. 利用「盈餘與波動率」的定價異常 (Exploiting Pricing Anomalies):他特別擅長在企業發布財報(Earnings)前後,尋找市場因為過度恐慌或貪婪所造成的「波動率錯價」。在股票操作上,這轉化為尋找「基本面極佳,但短線遭市場情緒錯殺」的均值回歸機會。
  3. 極致的風險/報酬優化 (Risk/Return Optimization):在進場前必定先計算風險。他習慣透過加入嚴格的流動性過濾器(Trade Filters)與趨勢保護,來避免極端的回撤(Drawdown)。

⚙️ XScript 邏輯解構 (Type A: 選股腳本)

為了貼合 Brian Johnson 的投資哲學,我們將從知識庫中提取對應的正規欄位,建立一個 「盈餘動能 + 短線波動均值回歸 的量化選股模型:

  1. 盈餘基本面濾網 (Earnings Filter)
    • 確保企業真的很 賺錢:使用 每股稅後淨利(元) >N元 。這裡是用每季賺超過五元。
    • 確保營收具備成長動能:使用 營收年增率 (月頻率) > 15%。
  2. 定價異常與均值回歸 (Volatility Anomaly)
    • 趨勢保護:股價必須在季線之上(長期趨勢向上,具備大資金保護)。
    • 短線錯殺:股價跌破月線(利用短線市場恐慌的波動,進行均值回歸套利)。
  3. 流動性與防呆風險控管 (Risk Management)
    • 排除成交量過低的殭屍股以控制滑價風險,限制 成交量 > 1000。
// 腳本類型:Type A 選股腳本 (Screener)
// 策略名稱:Brian Johnson 量化盈餘與波動率回歸策略 (修正版)
// 策略邏輯:結合強勢盈餘動能與短線波動錯殺的均值回歸模型

// 確保長天期歷史資料讀取足夠 (計算 60 日均線需要)
SetTotalBar(60);

// 變數宣告鐵律:無底線、無系統保留字 daily、預設給定初始值
var: revYoy(0), epsNum(0), volToday(0);
var: isLongTrend(false), isShortPullback(false);

// 修正:直接使用 "月營收年增率" 來抓取營收動能
revYoy = GetField("月營收年增率", "M"); 
epsNum = GetField("每股稅後淨利(元)", "Q"); // 必須包含(元)
volToday = GetField("成交量", "D"); // 確保流動性

// 條件一:長線趨勢保護 (確保大趨勢為多頭,Brian Johnson 強調的風險控管)
if Close > Average(Close, 60) then 
isLongTrend = true 
else 
isLongTrend = false;

// 條件二:短線波動率異常/均值回歸 (短線跌破月線,尋找錯殺點)
if Close < Average(Close, 20) then 
isShortPullback = true 
else 
isShortPullback = false;

// 核心量化綜合判斷:單一等號、完整邏輯包覆、加上防呆
if revYoy > 15.0 and epsNum > 2.0 and isLongTrend = true and isShortPullback = true and volToday > 1000 then begin
// 觸發條件成立
ret = 1;

// 輸出九宮格檢驗欄位 (警示腳本禁用,但選股腳本可使用)
OutputField1(revYoy, "月營收年增率(%)");
OutputField2(epsNum, "每股稅後淨利(元)");
OutputField3(volToday, "今日成交量");
end;

回測過去一年台股,持有20天,回測報告如下

 

這種策略在大多頭且很多好公司在大賺錢時特別有用,空頭市場就千萬別用

馬斯登·帕克(Marsten Parker)的均值回歸模型

馬斯登·帕克(Marsten Parker)是傑克·史瓦格(Jack Schwager)在《無名金融怪傑》(Unknown Market Wizards)中採訪的一位極度特別的操盤手。

為什麼說他特別?因為他那個年代的大師,無論是價值、成長還是逆勢,多半帶有「主觀判斷」的成分;但 Marsten Parker 是一位100% 的純系統化交易員(Purely Systematic Trader)。他是一位程式設計師,自己開發了強大的回測軟體(RealTest),將所有的交易規則寫成程式碼,由電腦自動執行。他在長達 20 年的期間,創造了年化報酬率超過 20% 的驚人績效,且完全不看任何財報或基本面故事。

Marsten Parker 原本是一位古典小提琴手,後來轉行成為軟體工程師。當他接觸到交易後,一開始的「主觀交易」讓他吃盡苦頭,甚至經歷了 45% 的嚴重資金回撤。隨後,他痛定思痛,決定發揮自己的寫程式專長,把所有的情緒與主觀判斷徹底剔除,轉型為完全依賴統計學與演算法的系統化交易者。

核心投資哲學:

  1. 100% 系統化與排除情緒 (Emotionless Execution)
    他認為人類的情緒(恐懼與貪婪)是交易虧損的元兇。他不看新聞、不看財報、不聽故事。他的進出場完全依賴價格與成交量的數學運算,只要電腦訊號一亮,就機械化地執行。
  2. 多頭趨勢中的均值回歸 (Mean Reversion in Uptrends)
    他最喜歡的演算法模型之一是「均值回歸」。他會在股票長期處於多頭趨勢(確保大方向向上)時,尋找短線上發生「極度超賣、乖離過大」的恐慌買點。買進後,只要價格反彈回歸均值,他就會在幾天內迅速獲利了結。
  3. 不斷淘汰失效的策略 (Adaptability)
    他深知市場的結構會改變,沒有任何一套策略可以永遠有效。因此他透過軟體持續監控自己策略的健康度,一旦發現某個策略的統計優勢消失(Broken Strategy),他會立刻停止使用。
  4. 極致的風險控管與分散 (Portfolio-Level Risk Control)
    他不押注單一股票,而是讓系統同時買進一籃子符合條件的標的來分散非系統性風險。

我請Gemini依據他的投資哲學寫的選股腳本如下

// 腳本類型:Type A 選股腳本 (Screener)
// 策略名稱:Marsten Parker 純量化均值回歸策略
// 策略邏輯:100% 捨棄基本面,純粹依賴統計學,尋找長線位於 200 日均線之上,但短線 RSI 極度超賣的均值回歸買點

// 確保長天期歷史資料讀取足夠 (計算 200 日均線需要)
SetTotalBar(260);

// 變數宣告鐵律:無底線、無系統保留字 daily、預設給定初始值
var: volToday(0), ma200(0), rsiShort(0);
var: isTrendUp(false), isOversold(false);

// 嚴格依照 Data Dictionary 規範讀取資料 (純技術面與價量)
volToday = GetField("成交量", "D"); // 流動性指標

// 條件一:大趨勢保護 (確認長線格局仍為多頭,股價位於 200 日均線之上)
ma200 = Average(Close, 200);
if Close > ma200 then 
isTrendUp = true 
else 
isTrendUp = false;

// 條件二:短線極度超賣 (使用極短天期的 3 日 RSI 尋找均值回歸的恐慌買點)
rsiShort = RSI(Close, 3);
if rsiShort < 15.0 then 
isOversold = true 
else 
isOversold = false;

// 核心量化綜合判斷:單一等號、完整邏輯包覆
// 條件說明:
// 1. isTrendUp = true (大趨勢為多頭,確保不是買在長線崩盤的股票)
// 2. isOversold = true (短線出現極端非理性拋售,勝率極高的反彈買點)
// 3. volToday > 2000 (確保程式自動下單時不會遇到流動性枯竭的問題)
if isTrendUp = true 
and isOversold = true 
and volToday > 2000 then begin

// 觸發條件成立
ret = 1;

// Type A 選股腳本專屬:輸出九宮格檢驗欄位 (警示腳本絕對禁用)
OutputField1(rsiShort, "3日RSI(超賣指標)");
OutputField2(Close, "今日收盤價");
OutputField3(ma200, "200日均線");
OutputField4(volToday, "今日成交量");
end;

回測報告如下

AI無法完全闡釋其思維,但均值回歸的確是一個好的概念,可以據此再進一步優化

柯姆奧謝的投資哲學

 柯姆·奧謝(Colm O’Shea)是全球宏觀避險基金(Global Macro Hedge Fund)領域的頂尖大師,曾被收錄在傑克·史瓦格(Jack Schwager)的經典名著《對沖基金市場巫師》(Hedge Fund Market Wizards)中。

與傳統只看財報的價值投資者不同,O’Shea 的思維橫跨了總體經濟、流動性與技術面。以下為您整理他的過往經歷、核心投資哲學,並將其轉化為符合 XQ 系統限制與知識庫欄位規範的 XScript 量化選股腳本。

💡 柯姆·奧謝 (Colm O’Shea) 經歷與投資哲學

過往經歷:

Colm O’Shea 曾在索羅斯基金管理公司(Soros Fund Management)擔任宏觀交易員,後來創立了 COMAC Capital 避險基金。他在 2008 年金融海嘯期間,憑藉著對總體經濟與流動性的敏銳嗅覺,不僅毫髮無傷,還創造了驚人的正報酬,確立了他在全球宏觀交易界的傳奇地位。

核心投資哲學:

  1. 基本面決定「買什麼」,技術面決定「何時買」 (Fundamentals for WHAT, Price Action for WHEN)
    O’Shea 強調,他絕對不會只因為「某個東西很便宜」就買進。他會先透過基本面確認這是一家好公司或好資產,然後耐心等待市場趨勢(價格行為)與他的基本面觀點一致時,才會真正出手。他不當接刀子的英雄。
  2. 尋找不對稱的風險報酬比 (Asymmetric Risk/Reward)
    他極度看重下檔風險的保護。如果一筆交易看錯的代價是賠 1 塊,但看對可以賺 5 塊或 10 塊,且趨勢已經啟動,他就會重倉參與。
  3. 跟隨流動性與大資金 (Liquidity and Flows)
    在宏觀交易中,他緊盯央行的流動性;在股市中,這可以轉化為緊盯「聰明錢」與「法人大戶」的資金流向。

⚙️ XScript 邏輯解構 (Type A: 選股腳本)

為了將 Colm O’Shea 的「基本面+技術面順勢+大資金流向」宏觀哲學程式化,我們建立一個 高質量基本面 + 多頭趨勢確認 + 法人資金點火」 的選股模型:

  1. 基本面 (The “What”) – 確保公司具備成長與高品質底氣
    • 實質獲利底線:每股稅後淨利(元) > 0。
    • 資本效率高:股東權益報酬率 (ROE) > 10%。
    • 營收具備成長動能:使用 月營收年增率 > 10%。
  2. 技術面/價格行為 (The “When”) – 不摸底,順勢而為
    • 確認市場已經認同基本面:短天期均線(20日)必須大於長天期均線(60日),且股價在均線之上,呈現標準的「多頭排列」。
  3. 流動性與聰明錢 (Liquidity & Flow)
    • 籌碼面:要求 法人買賣超張數 > 0(代表機構大資金開始順勢推升)。
    • 流動性防禦:限制 成交量 > 2000 張(O’Shea 絕不碰缺乏流動性的市場,方便隨時停損撤退)。

 

// 腳本類型:Type A 選股腳本 (Screener)
// 策略名稱:Colm O'Shea 宏觀順勢與高質量選股策略
// 策略邏輯:基本面過濾標的質量,結合均線多頭排列抓準進場時機,並跟隨法人資金流向

// 確保長天期歷史資料讀取足夠 (計算 60 日均線需要)
SetTotalBar(60);

// 變數宣告鐵律:無底線、無系統保留字 daily、預設給定初始值
var: epsNum(0), roeNum(0), revYoy(0), instNetBuy(0), volToday(0);
var: isTrendUp(false);

// 嚴格依照 Data Dictionary 與知識庫規範讀取資料
epsNum = GetField("每股稅後淨利(元)", "Q"); // 基本面:必須包含(元)
roeNum = GetField("股東權益報酬率", "Q"); // 基本面:ROE
revYoy = GetField("月營收年增率", "M"); // 基本面:營收動能
instNetBuy = GetField("法人買賣超張數", "D"); // 籌碼面:大資金流向
volToday = GetField("成交量", "D"); // 流動性防呆

// 核心技術面判斷 (The "When"):確認均線多頭排列 (股價 > 月線 > 季線)
if Close > Average(Close, 20) and Average(Close, 20) > Average(Close, 60) then 
isTrendUp = true 
else 
isTrendUp = false;

// 核心量化綜合判斷:單一等號、完整邏輯包覆
// 條件說明:
// 1. EPS > 0 且 ROE > 10% (高質量獲利)
// 2. 月營收年增率 > 10% (具備成長動能)
// 3. isTrendUp = true (技術面趨勢確認,市場價格行為與基本面方向一致)
// 4. 法人買賣超張數 > 0 (機構資金點火)
// 5. 成交量 > 2000 (確保進出場流動性)
if epsNum > 0.0 
and roeNum > 10.0 
and revYoy > 10.0 
and isTrendUp = true 
and instNetBuy > 0.0 
and volToday > 2000 then begin

// 觸發條件成立
ret = 1;

// Type A 選股腳本專屬:輸出九宮格檢驗欄位 (警示腳本絕對禁用)
OutputField1(revYoy, "月營收年增率(%)");
OutputField2(roeNum, "股東權益報酬率(%)");
OutputField3(instNetBuy, "法人買賣超張數");
end;

 

回測報告如下圖

德伍.卻斯 (Derwood S. Chase Jr.) 的投資哲學

我是一個土法煉鋼型的投資人,後來按觸了一些華爾街高手的訪談記錄,才找到自己的投資盲點,例如剛開始入行時,一直都用本益比在作為選股的標準,因此錯過了很多高本益比但也高成長的股票,後來看過德伍.卻斯(Derwood S. Chase Jr.)受訪的內容,他提到不用本益比,用PEG來作標準,我才改變了作法,現在大家耳熟能詳的概念,我當年可是跌跌撞撞摸索了好多年。。

我請Gemini整理德伍.卻斯(Derwood S. Chase Jr.)的投資哲學及對應的選股腳本如下

德伍.卻斯(Derwood S. Chase Jr.),是卻斯投資顧問公司(Chase Investment Counsel)的創辦人。他在華爾街的輩分極高(公司創立於 1957 年),而且他的選股模型被美國散戶協會(AAII)收錄為最經典的長期獲利模型之一。

Chase 是一位將「高品質、高成長、合理價格(GARP)與價格動能」完美融合的集大成者。他既不買便宜的爛公司,也不買昂貴的好公司,更不買正在下跌的股票。

核心投資哲學:

  1. 持續且穩健的雙引擎成長 (Consistent Growth)
    他要求公司的營收與盈餘必須「同步」成長,且年增率通常要求在 15% 以上。他不喜歡那種靠砍成本來擠出 EPS 的公司,必須是本業真實擴張。
  2. 頂級的本業獲利能力 (High Profitability)
    他認為好公司必須擁有寬廣的護城河。這反映在財務數據上,就是股東權益報酬率(ROE)必須大於 15%,且營業利益率必須大於 10%(本業利潤豐厚)。
  3. 無懼經濟寒冬的財務體質 (Financial Strength)
    他非常保守,要求企業的負債比率必須低於 50%。只有低負債的高成長,才是真實的成長。
  4. 合理價格成長法則 (GARP & PEG)
    他願意為好公司支付比大盤稍微高一點的本益比(P/E),但他有一道死命令:本益比絕對不能超過其盈餘成長率的 1.5 倍(即 PEG < 1.5)
  5. 價格動能的確認 (Price Momentum)
    他極度看重「相對強度(Relative Strength)」。在基本面完美的情況下,他要求股價必須處於中長期的多頭趨勢中,證明市場大資金正在為這份財報買單。

為了在台股的 XQ 系統中完美還原 Derwood Chase 的 AAII 經典模型,我們建立一個**「高 ROE + 雙引擎高成長 + PEG<1.5 + 低負債 + 均線多頭」**的全方位防護網:

  1. 頂級的獲利與體質濾網 (Quality & Health)
    • 資本效率:股東權益報酬率 > 15.0%。
    • 本業利潤:營業利益率 > 10.0%。
    • 財務安全:負債比率 < 50.0%。
  2. 雙引擎成長動能 (Double-Digit Growth Engine)
    • 營收擴張:月營收年增率 > 15.0%。
    • 盈餘爆發:當季 每股稅後淨利(元) 大於去年同期,且經過程式碼精算,EPS 年增率 > 15.0%
  3. 估值天花板:PEG 法則 (Valuation Guardrail)
    • 程式碼邏輯:要求 本益比 大於 0,且必須小於 (EPS 年增率 * 1.5)。這精準落實了 Chase 拒絕過度溢價的 GARP 精神。
  4. 價格動能印證 (Momentum Trend)
    • 確保股價處於中長線多頭:今日 收盤價 > 60 日均線(季線),且 60 日均線 > 120 日均線(半年線)。
  5. 規模與流動性 (Liquidity)
    • 限制中大型股:總市值(億) > 50.0 億。
    • 限制 成交量 > 1000 張。
// 腳本類型:Type A 選股腳本 (Screener)
// 策略名稱:Derwood Chase 高品質成長與動能策略
// 策略邏輯:尋找 ROE>15%、負債低、營收盈餘皆成長 15% 以上,且估值合理 (PEG<1.5) 並處於多頭排列的穩健飆股

// 確保長天期歷史資料讀取足夠 (計算 120 日均線與去年同期 EPS 需要)
SetTotalBar(130);

// 變數宣告鐵律:無底線、無系統保留字 daily、預設給定初始值
var: roeNum(0), opMargin(0), debtRatio(0), revYoy(0), epsCurrent(0), epsLastYear(0);
var: peRatio(0), marketCap(0), volToday(0), epsGrowthRate(0);
var: ma60(0), ma120(0), isTrendUp(false), isReasonablePrice(false);

// 嚴格依照 Data Dictionary 與知識庫規範讀取資料
roeNum = GetField("股東權益報酬率", "Q"); // 品質指標:優異的資本效率
opMargin = GetField("營業利益率", "Q"); // 品質指標:強大的本業獲利能力
debtRatio = GetField("負債比率", "Q"); // 體質指標:低於 50% 的健康負債
revYoy = GetField("月營收年增率", "M"); // 成長指標:營收雙位數成長
epsCurrent = GetField("每股稅後淨利(元)", "Q"); // 成長指標:當季 EPS
epsLastYear = GetField("每股稅後淨利(元)", "Q")[4]; // 成長指標:去年同期 EPS
peRatio = GetField("本益比", "D"); // 估值指標:本益比
marketCap = GetField("總市值(億)", "D"); // 規模指標:中大型股
volToday = GetField("成交量", "D"); // 流動性指標

// 計算 EPS 年成長率 (%),加入防呆機制避免去年 EPS 為 0 或負數導致計算失真
if epsLastYear > 0.0 then 
epsGrowthRate = ((epsCurrent - epsLastYear) / epsLastYear) * 100.0 
else 
epsGrowthRate = 0.0;

// 計算中長線均線 (季線與半年線),確認大趨勢動能
ma60 = Average(Close, 60);
ma120 = Average(Close, 120);

// 條件一:多頭動能排列 (股價大於季線,季線大於半年線)
if Close > ma60 and ma60 > ma120 then 
isTrendUp = true 
else 
isTrendUp = false;

// 條件二:PEG 合理估值 (本益比必須小於 EPS 成長率的 1.5 倍)
// 例如:EPS 成長 20%,則本益比最高只能接受到 30 倍
if peRatio > 0.0 and peRatio < (epsGrowthRate * 1.5) then 
isReasonablePrice = true 
else 
isReasonablePrice = false;

// 核心量化綜合判斷:單一等號、完整邏輯包覆
// 條件說明:
// 1. marketCap > 50.0 (鎖定具備一定規模的中大型股)
// 2. roeNum > 15.0 and opMargin > 10.0 (本業獲利極佳,護城河深厚)
// 3. debtRatio < 50.0 (無懼升息與衰退的強健財務)
// 4. revYoy > 15.0 and epsGrowthRate > 15.0 (營收與盈餘同步爆發,雙引擎驅動)
// 5. isReasonablePrice = true (貫徹 Chase 的 GARP 精神,拒絕天價)
// 6. isTrendUp = true (技術面資金認同)
// 7. volToday > 1000 (確保進出流動性)
if marketCap > 50.0 
and roeNum > 15.0 and opMargin > 10.0 
and debtRatio < 50.0 
and revYoy > 15.0 and epsGrowthRate > 15.0 
and isReasonablePrice = true 
and isTrendUp = true 
and volToday > 1000 then begin

// 觸發條件成立
ret = 1;

// Type A 選股腳本專屬:輸出九宮格檢驗欄位 (警示腳本絕對禁用)
OutputField1(epsGrowthRate, "EPS年增率(%)");
OutputField2(peRatio, "本益比");
OutputField3(roeNum, "股東權益報酬率(%)");
OutputField4(opMargin, "營業利益率(%)");
OutputField5(debtRatio, "負債比率(%)");
end;


請AI幫我寫腳本的最大好處,最大的收穫,不見得只是節省時間,更大的價值在於,AI可以寫出我原本寫不出來的腳本。

例如我想要 盤中找到漲幅超過2%的細產業指數,其成交量成長超過三成的成份股。

這我之前試了好幾次,都沒能成功寫出來,現在有了Gemini,我就直接請它寫

Gemini一開始不會用Group這個函數,跟我說寫不出來

我就回它

Group是用來宣告清單的語法,接著可以在腳本內透過使用 GetSymbolGroup 來取得和執行商品相關的清單。

詳細說明可參考商品清單功能。

以下範例:宣告一個名為 myGroup 的清單並讓其取得執行商品的成分股。

 

Group: myGroup();myGroup = GetSymbolGroup(“成分股”)  

 

 然後問它:可以用group來宣告 細產業及其成份股的關係嗎?

Gemini回我如下:

太棒了!您非常敏銳,找到了 XScript 較為進階的 Group (清單) 宣告語法。這確實是跨出單一商品限制的重要一步。

針對您的問題:「可以用 Group 來宣告細產業及其成份股的關係嗎?」 答案是:可以的! 如果您將腳本執行在「細產業指數」上,使用 GetSymbolGroup(“成分股”) 確實能成功抓出該指數底下的所有成份股代碼,並將其存入陣列清單中。

然後他就寫了一個腳本給我

 

但我拿去編譯時出了一些錯誤訊息,我直接把訊息貼給它

 

Gemini看完後直接就給我正確的腳本了

 

// 策略名稱:細產業成份股量增偵測 (完美修正版)
// 腳本類型:警示腳本 (Sensor)

SetTotalBar(30);

var: 
idx(0), jdx(0), 
compCode(""), // 僅供字串串接使用
volSum(0), 
volAvg(0), 
volToday(0), 
triggerList("");

// 宣告清單:用來存放取得的成份股
Group: myGroup();
myGroup = GetSymbolGroup("成分股");

// 初始化觸發清單
triggerList = "";

// ==========================================
// 第一層迴圈:使用 GroupSize 來取得清單長度
// ==========================================
for idx = 1 to GroupSize(myGroup) 
begin
// 將代碼存入字串變數,專門留給最後的字串串接使用
compCode = myGroup[idx]; 
volSum = 0;

// ==========================================
// 第二層迴圈:手動計算該成份股的 20 日均量
// 修正點:直接將 myGroup[idx] 傳入 GetSymbolField 滿足系統型態要求
// ==========================================
for jdx = 0 to 19 
begin
volSum = volSum + GetSymbolField(myGroup[idx], "成交量", "D")[jdx];
end;

// 計算均量(防呆:分母不為零)
if 20 <> 0 then volAvg = volSum / 20 else volAvg = 0;

// 取得該股今日目前的總成交量
volToday = GetSymbolField(myGroup[idx], "成交量", "D");

// ==========================================
// 邏輯判斷:今日成交量 > 20日均量 * 1.3
// ==========================================
if volAvg <> 0 and volToday > volAvg * 1.3 then 
begin
// 修正點:移除無效函數,直接串接 compCode (字串型態)
triggerList = triggerList + compCode + " ";
end;
end;

// ==========================================
// 最終觸發輸出
// ==========================================
if triggerList <> "" then 
begin
ret = 1;
retmsg = SymbolName + " 異常量增股代碼: " + triggerList;
end;

用這個腳本去跑,昨天盤中出來的訊號長這樣

Gemini只要給它相關的函數,的確可以擴展它的能力圈,寫出我們原本寫不出來的腳本,不過你貼error message 給它時,它的反應還蠻中二的

 

下面是它這次回我的時候,順帶也把xscript罵了一頓

 

非常抱歉讓你遇到這些編譯錯誤!這絕對不是你的邏輯有問題,而是 XScript 編譯器在處理「跨商品群組 (Group)」與「字串串接」時,有著極度嚴格甚至有些龜毛的底層型態限制。你提供的錯誤訊息非常精準,我們來逐一擊破這些語法盲區!

💡 錯誤原因解構與修正對策

  1. ArraySizeGroup 型態不相容 (錯誤 2616)
    • 原因:在 XScript 中,透過 GetSymbolGroup 取得的清單屬於特殊的 Group 型態,而不是一般的陣列 (Array)。因此系統不認得 ArraySize
    • 修正:必須改用專屬函數 GroupSize(myGroup)
  2. GetSymbolField 拒絕變數傳入 (錯誤 3842, 4531)
    • 原因:錯誤訊息提示第一參數必須是 String/Input/Group。這代表 XScript 編譯器不允許你把群組裡的代碼先存成一個 var 字串變數(如 compCode),再傳入函數中。它強硬要求必須「直接傳入 Group 的元素」。
    • 修正:將原本的 GetSymbolField(compCode, …) 直接替換為 GetSymbolField(myGroup[idx], …)
  3. GetSymbolName 不存在與字串型態衝突 (錯誤 5337, 5363)
    • 原因:XScript 警示腳本中沒有內建 GetSymbolName 這種可以跨商品查名稱的函數。當系統認不得這個函數時,它回傳了未知的型態,導致你無法用 + 號將它與 triggerList (字串) 串接,進而引發「左右兩邊型態不同」的錯誤。
    • 修正:移除 GetSymbolName,我們直接將存放商品代碼的字串變數 compCode 串接進結果中即可。

經過這次的除錯,你應該對 XScript 處理 Group 的龜毛脾氣有很深的體會了

 

AI會罵Xscript龜毛,真是我的媽啊的媽啊

麥克普萊斯

麥克·普萊斯(Michael Price)是華爾街最具攻擊性、也最傳奇的價值投資大師之一。 他完美示範了如何將傳統的價值投資,進化為極具破壞力與主動性的獲利武器。以下為您梳理他的傳奇生平與核心投資哲學:

一、 在投資領域的主要成就

  1. 師承大師並青出於藍

普萊斯的職業生涯起步於 1970 年代,他師從價值投資先驅麥克斯·海恩(Max Heine),並加入了「共同系列基金」(Mutual Series Fund)。他從海恩身上學會了如何在華爾街不屑一顧的「廢墟」中挖掘被嚴重低估的資產。

  1. 開創「主動型價值投資」(Activist Value Investing)的先河

不同於傳統葛拉漢(Ben Graham)信徒「買進便宜股票然後死抱等待」的被動策略,普萊斯是早期「行動派」的代表。當他發現一家公司擁有極高價值的資產,但管理層卻無所作為或正在摧毀價值時,他會大舉買入成為大股東,直接向董事會施壓,要求撤換 CEO、進行企業分拆或出售公司,強行將「隱藏價值」變現。

  1. 驚人的長期績效與天價併購

在掌舵 Mutual Series Fund 的期間,他憑藉優異的績效讓基金規模暴增。1996 年,他將這家投資公司以超過 8 億美元的天價賣給了富蘭克林·坦伯頓(Franklin Templeton)集團,寫下資產管理界的傳奇,隨後他急流勇退,成立了自己的私人基金 MFP Investors 繼續操盤。

  1. 參與史詩級的複雜交易

他無懼極度複雜的財務泥淖,曾主導或參與大通銀行(Chase)與華友銀行(Chemical)的世紀合併、梅西百貨(Macy’s)的破產重整等。他擅長買進破產公司的優先債券,透過重整程序將債權轉換為股權,最終獲取暴利。

二、 投資哲學與策略核心

 

 策略核心

普萊斯的投資流派屬於 「深層價值與特殊事件驅動」(Deep Value & Special Situations) :

  1. 尋找「死角」裡的資產折價 (Asset Value Discount)

他對華爾街熱捧的藍籌股或高成長股毫無興趣。他評估一家公司的唯一標準是:「如果今天有人要把這整家公司買下來,它值多少錢?」他極度看重資產負債表上的硬資產(如房地產、未受重視的子公司),並要求買進價格必須比他估算的「內在價值」低 30% 到 40%,以此建立堅不可摧的安全邊際

  1. 特殊事件作為「催化劑」 (Special Situations Catalyst)

便宜的股票如果不具備上漲的動力,就會變成「價值陷阱」。因此,普萊斯的投資組合中有極大比例是處於「特殊事件」中的公司。這些事件包括:

  • 企業分拆(Spin-offs)
  • 併購與私有化
  • 破產清算與重組
    這些事件能打破市場的僵局,迫使這家公司的真實資產價值被重新定價。
  1. 遠離華爾街共識 (Eliminate Wall Street Consensus)

普萊斯曾直言:「華爾街的研究報告是為了讓華爾街賺錢,而不是為了產生好的投資結果。」他要求團隊絕對不能看券商的二手報告,而是要親自翻閱厚重的法律文件、破產法庭記錄與財報附註。他透過研究「別人懶得看」的枯燥資料,創造出極大的資訊落差優勢(Information Arbitrage)。


  1. 先問「整家公司值多少」,不是先問「本益比低不低」

普萊斯最具代表性的觀念,是 private market value,也就是「私有市場價值」或「控制權價值」。他看公司時,不先從市場情緒出發,而是先問:如果今天由一個懂行的產業買家把整家公司買下來,合理價格會是多少?
因此,他特別重視可變現資產、部門拆分價值、現金、房地產、投資部位、 正常化獲利能力,而不是只看表面的低本益比。

 

  1. 保本至上與靈活的現金配置 (Preservation of Capital)

儘管他的攻擊性很強,但他的底層思維依然是「風險控管」。他曾說:「我的任務不是在多頭市場裡賺大錢,而是保住本金。」當市場過熱、找不到符合嚴苛折價標準的標的時,他毫不介意持有高比例的現金(有時高達 20% 以上),耐心等待市場崩盤帶來的跳樓大拍賣。

  1. 賣出很務實:接近估值就賣

普萊斯不是那種把每一家公司都當成終身持股的人。當股價接近他估計的私有市場價值,或催化劑已經實現、折價消失,他就傾向賣出,把資金轉到新的折價標的。
這種做法很像一個精明的資產買家,而不是浪漫的長期信仰型投資人。重點不是和公司談戀愛,而是在折價消失前後,有紀律地完成一筆交易。 

7. 他買的未必是偉大企業,而是「下檔受保護、上檔可實現」的企業

這一點很重要。普萊斯和巴菲特後期強調高品質企業長期複利的路線,不完全相同。
普萊斯更接近葛拉漢—Heine 一脈:公司品質可以普通,但價格一定要夠低,資產一定要有保護,價值釋放的路徑一定要看得見。
所以他不是在追求「最好的公司」,而是在追求風險報酬比最划算的公司

 

 

 

根據他的精神,Gemini寫了一個具備深度折價與強健財報,且必須是冷門股或近期有董監加碼跡象的腳本

// 策略名稱:Michael Price 深度價值與事件驅動選股
// 策略類型:深度價值/資產保護/冷門轉機股

SetTotalBar(100); // 確保有足夠的 K 棒計算近三個月的籌碼變動

var:
pb_ratio(0),
debt_to_eq(0),
current_ratio(0),
insider_buy(false),
neglected(false);

// ==========================================
// 1. 深度折價 (Deep Discount to Asset Value)
// ==========================================
pb_ratio = GetField("股價淨值比", "D");

// ==========================================
// 2. 資產負債表強健 (Strong Balance Sheet)
// ==========================================
// 計算負債權益比 (總負債 / 股東權益)
if GetField("股東權益總額", "Q") > 0 then
debt_to_eq = GetField("負債總額", "Q") / GetField("股東權益總額", "Q")
else
debt_to_eq = 999;

// 計算流動比率 (流動資產 / 流動負債)
if GetField("流動負債", "Q") > 0 then
current_ratio = GetField("流動資產", "Q") / GetField("流動負債", "Q")
else
current_ratio = 0;

// ==========================================
// 3. 事件驅動與催化劑 (Catalysts & Neglected)
// ==========================================
// 內部人買入 (Proxy:董監事持股比例近 60 日/約三個月 增加)
if GetField("董監持股佔股本比例", "D") > GetField("董監持股佔股本比例", "D")[60] then
insider_buy = true
else
insider_buy = false;

// 被忽視的冷門股 (Proxy:三大法人合計持股小於 10%)
if (GetField("外資持股比例", "D") + GetField("投信持股比例", "D") + GetField("自營商持股比例", "D")) < 10.0 then
neglected = true
else
neglected = false;

// ==========================================
// 核心篩選條件 (Conditions)
// ==========================================
condition1 = pb_ratio > 0 and pb_ratio <= 0.8; // P/B <= 0.8 (若設 0.6 台股標的極少,先以 0.8 作為折價門檻)
condition2 = debt_to_eq < 0.5; // 嚴格的低槓桿要求 (D/E < 0.5)
condition3 = current_ratio > 2.0; // 極高的短期流動性 (流動資產是流動負債的兩倍)

// 綜合判斷:具備深度折價與強健財報,且必須是冷門股或近期有董監加碼跡象
if condition1 and condition2 and condition3 and insider_buy or neglected then
begin
ret = 1;
// 輸出欄位供選股後檢視與排序
outputfield1(pb_ratio, "股價淨值比");
outputfield2(debt_to_eq, "負債權益比");
outputfield3(current_ratio, "流動比率");
outputfield4(GetField("董監持股佔股本比例", "D") - GetField("董監持股佔股本比例", "D")[60], "董監近3月增減(%)");
end;

拿這個腳本去回測,停損停利都設為20%,回測的結果如下

 

勝率七成

康納相對強弱指數

康納相對強弱指數 (Connors RSI, CRSI) 在量化交易界享有極高的聲譽,被譽為「均值回歸 (Mean Reversion) 的勝率之王」。傳統的 RSI 常常在 30 附近來回洗盤,讓摸底的投資人受盡折磨;而 CRSI 的發明者 Larry Connors 透過疊加三個不同維度的因子,將「超賣」定義的更精細,努力創造出極高勝率的左側買點。

 

一、 核心數學意義與三大動能支柱

CRSI 的數值範圍與傳統 RSI 一樣是 0 到 100,但它的底層公式是由三個完全獨立的動能元件取算術平均而成:

這三個元件分別負責測量市場的短、中、長線極端情緒:

  1. 第一支柱:價格的極短線動能 RSI price
    • 計算方式: 對收盤價取 3 週期的 RSI。
    • 意義: 傳統 RSI 用 14 天,反應太慢。3 天的 RSI 非常神經質,只要股價連續跌個兩三天,數值就會迅速掉到 10 以下,這能第一時間反映極短線的價格恐慌。
  2. 第二支柱:連漲連跌的心理折磨 RSI price
    • 計算方式: 這是 CRSI 最天才的設計。首先,把 K 線轉化為「連勝/連敗」的整數序列。
      • 今天收紅,數值為 +1;明天繼續收紅,數值為 +2。
      • 今天收黑,數值為 -1;明天繼續收黑,數值為 -2。
      • 平盤為 0。
        接著,對這組「整數序列」取 2 週期的 RSI。
    • 意義: 跌 5 天每天跌 1%,跟 1 天暴跌 5%,在心理上的折磨是不同的。連跌 5 天會讓散戶的絕望感達到頂峰。這個元件量化了「連跌天數帶來的恐懼」。
  3. 第三支柱:相對跌幅的歷史位階 PercentRank
    • 計算方式: 將今天的「單日漲跌幅」拿去跟過去 100 天的單日漲跌幅做比較,看看今天的表現贏過過去 100 天裡多少百分比的日子。
    • 意義: 這是一個橫向的相對強弱比較。如果今天跌了 3%,且在過去 100 天內從來沒有單日跌這麼重過,這個數值就會趨近於 0。這代表今天的拋售力道是近期極為罕見的極端事件。

二、 實戰應用指南 (波段操作戰略)

CRSI 不是用來順勢追高的,它是純粹的逆勢抄底(Pullback Trading)」武器。 

  • 大環境濾網 (極重要): 均值回歸的前提是「趨勢向上」。因此,在掃描 CRSI 之前,必須確保股價處於長期多頭(例如:收盤價 > 200 日均線)。不要在空頭市場抄底,那不叫均值回歸,叫接刀。
  • 極端買點觸發: 當股價在 200 日均線之上,且 CRSI < 10(甚至設定嚴格一點為 5)。這代表一檔長期向上的好股票,剛經歷了罕見的短線暴跌與連續收黑。此時進場,隔日或幾日內反彈的機率極高。
  • 靈活停利: 均值回歸的獲利時間極短,通常不超過 5 天。當股價反彈,收盤價突破 5 日均線,或是 CRSI 回升至 70 以上,即刻獲利了結。

 

三、 XScript 完整指標腳本

在 XScript 中實作 CRSI,最複雜的地方在於處理連跌序列與計算百分位排名。以下是 Gemini寫的腳本,我最後為了判讀方便,把CRSI再做了5日平均

// 指標名稱:Connors RSI (CRSI 康納相對強弱指數)
// 理論基礎:Larry Connors
// -----------------------------------------------------------
Input:
RSI_Len(5, "價格 RSI 週期"),
Streak_Len(10, "連勝/連敗 RSI 週期"),
Rank_Len(100, "百分位排名週期");

Variable:
RSI_Price(0),
Streak(0), RSI_Streak(0),
TodayRet(0), HistoryRet(0), RankCount(0), PctRank(0), i(0),
CRSI(0);

// 1. 計算第一支柱:極短線價格 RSI
RSI_Price = RSI(Close, RSI_Len);

// 2. 計算第二支柱:連勝/連敗序列的 RSI
// 記錄連續漲跌天數
if Close > Close[1] then begin
if Streak < 0 then Streak = 1 else Streak = Streak + 1;
end else if Close < Close[1] then begin
if Streak > 0 then Streak = -1 else Streak = Streak - 1;
end else begin
Streak = 0;
end;

// 對連勝連敗序列計算 RSI (XQ 的 RSI 函數可接受數值變數)
RSI_Streak = RSI(Streak, Streak_Len);

// 3. 計算第三支柱:單日漲跌幅的歷史百分位 (PercentRank)
// 確保有足夠的 K 線數據
if CurrentBar > Rank_Len then begin
TodayRet = (Close - Close[1]) / Close[1];
RankCount = 0;

// 迴圈比對過去 N 天的單日報酬率
for i = 1 to Rank_Len - 1 begin
HistoryRet = (Close[i] - Close[i+1]) / Close[i+1];
if HistoryRet < TodayRet then
RankCount = RankCount + 1;
end;

// 算出百分比 (0 ~ 100)
PctRank = (RankCount / Rank_Len) * 100;
end else begin
PctRank = 50; // 數據不足時給予中性值
end;

// 4. 計算最終 CRSI (三者算術平均)
CRSI = (RSI_Price + RSI_Streak + PctRank) / 3;
value1=average(CRSI,5);

// 5. 繪圖輸出
Plot1(value1, "Connors RSI");
Plot2(30, "極度超賣(黃金買點)");

下圖是這個指標對應台積電的圖

麥克金利動態指標 (McGinley Dynamic, MD)

麥克金利動態指標 (McGinley Dynamic, MD) 是由市場技術分析師 John R. McGinley 於 1990 年發明。 它打破了傳統均線「延遲)」的宿命,將流體力學中的「自動變速箱」與「避震器」概念引入了演算法中。傳統的 SMA 或 EMA 在實戰上最大的痛點是:參數固定。當市場盤整時,均線太敏感會導致頻繁假交叉(被雙巴);當市場崩盤時,均線太遲鈍又會讓人逃生不及。

麥克金利動態指標就是為了解決這個痛點 

一、 彈簧與阻尼系統的物理精神:不對稱的自動變速

MD 指標最核心的靈魂,在於它完美契合了股市中最真實的物理法則:「緩漲急跌 (Up by the stairs, down by the elevator)」。也就是說,市場上漲時通常伴隨著緩慢推升,下跌時則伴隨恐懼的急速宣洩。

我們來看看它的核心運算公式:

這條公式的精髓全在分母那個 4 次方阻尼器  。它創造了絕妙的不對稱變速效果:

  1. 多頭模式 (阻尼增加 = 減速變平滑):
    當股價處於上升趨勢 (Close > MD) 時,這個比例會大於 1。經過 4 次方放大後,分母會急遽變大,導致整體加總的數值變小。

    • 物理意義: 就像汽車在高速公路上巡航,避震器變得柔軟。指標會自動「減速」,與股價保持一段舒服的距離,不會因為盤中的微小回檔就輕易觸發停損,讓使用者的獲利能盡情奔跑。
  2. 空頭崩盤模式 (彈簧收縮 = 加速貼緊):
    當股價跌破指標 (Close < MD) 時,這個比例會小於 1(例如 0.9)。經過 4 次方縮小後( ,分母會急遽變小,導致整體加總的數值變大。

    • 物理意義: 就像汽車遇到緊急煞車,懸吊瞬間變硬。指標會自動 「加速」 向下俯衝,死死咬住暴跌的股價,幫助交易者在第一時間精準停損出場。

二、 實戰應用指南 (VIP 策略模組)

 建議將 MD 指標作為 「智慧移動停利線 (Smart Trailing Stop)」 。

  • 過濾洗盤: 在牛市中,將 MD 設為 14 或 20 週期。只要股價沒有實體跌破 MD 線,就無視任何技術面雜訊,堅定抱牢。
  • 取代傳統均線: 傳統的黃金交叉/死亡交叉極易失效,但如果是 「價格突破 MD 線」 ,因為 MD 已經過濾了大量極端雜訊,其突破訊號的含金量與勝率遠高於一般的 MA 交叉。

三、 XScript 完整指標腳本

 

// 指標名稱:McGinley Dynamic (麥克金利動態指標)
// 理論基礎:John R. McGinley (自動變速的流體均線)
// -----------------------------------------------------------
Input: 
Length(14, "計算週期"); // 建議預設 10 或 14

Variable: 
MD(0), 
K_Const(0.6), // McGinley 建議的平滑常數
Ratio(0), 
DynamicDamper(0);

// 1. 初始化設定 (第一根 K 線)
if CurrentBar = 1 then begin
MD = Close;
end else begin
// 2. 避免除以零的極端防錯機制
if MD[1] <> 0 then begin
// 計算價格與前一期指標的比例
Ratio = Close / MD[1];

// 3. 計算動態阻尼分母: k * N * (Ratio)^4
// 這就是讓指標具備「上漲減速、下跌加速」靈魂的 4 次方引擎
DynamicDamper = K_Const * Length * Power(Ratio, 4);

// 4. 計算麥克金利核心公式
if DynamicDamper <> 0 then
MD = MD[1] + (Close - MD[1]) / DynamicDamper
else
MD = MD[1]; // 若發生極端異常,維持前值

end else begin
// 若歷史值為零,重新定位至當前收盤價
MD = Close; 
end;
end;

// 5. 繪圖輸出
Plot1(MD, "McGinley Dynamic");

 

YT上有一個介紹這個指標的影片,連結如下

Understand the basics of the McGinley Dynamic moving average alternative

This short guide explains the core rationale behind why the McGinley Dynamic adjusts its speed during different market conditions to solve the lagging problem of traditional moving averages.

下面這張圖是台積電與指標的對照圖

跟均線相比,多頭時的確是比較長線穩定的停利指標,但在空頭時,反映似乎沒有它宣稱的那麼靈敏。

 

 

大衛·萊恩(David Ryan)

大衛·萊恩(David Ryan)是華爾街歷史上最傳奇的成長股交易員之一,他完美傳承並發揚了威廉·歐尼爾(William O’Neil)的 CAN SLIM 投資法則 

David Ryan 是威廉·歐尼爾(《笑傲股市》作者)的得意門生。他曾在歐尼爾的公司擔任投資組合經理,並在 1985 年至 1987 年間,連續三年贏得全美投資大賽(U.S. Investing Championship)的冠軍,這三年的總報酬率高達驚人的 1379%。他用實戰成績證明了 CAN SLIM 法則在美股市場的強大威力。

核心投資哲學:

  1. 極致的盈餘與營收動能 (Earnings & Sales Momentum)
    這是 CAN SLIM 法則的核心。Ryan 不買平庸的公司,他要求標的必須具備「爆炸性的當季獲利成長」,通常要求 EPS 年增率達 25% 以上;同時,營收也必須同步出現雙位數以上的強勁擴張。
  2. 強勢股與價格位階 (Relative Strength & Price Action)
    他**「永遠不買」處於下跌趨勢或破底的股票。他只買那些已經處於明確多頭排列,並且價格非常靠近 52 週新高**(歷史高點或波段高點)的強勢股。他認為,真正的超級大飆股在發動前,價格一定會先創下或接近新高。
  3. 底部型態與突破 (Bases and Breakouts)
    他擅長在股票經歷一段時間的橫盤整理(如杯柄型態、平底型態),籌碼沉澱且成交量萎縮後,於帶量突破頸線的那一刻進場。

 

為了將 David Ryan 的「CAN SLIM 高成長 + 52週高點強勢動能」哲學程式化,我們建立一個 「營收盈餘雙飆升 + 長期多頭排列 + 逼近 52 週新高 的強勢成長股模型:

  1. 基本面強大火力 (CAN SLIM 的 C 與 A)
    • 營收爆發:精確使用 月營收年增率 > 25.0%。
    • 盈餘動能加速:每股稅後淨利(元) > 0,且當季 EPS 必須大於去年同期 EPS(確保獲利具備實質成長動能)。
  2. 強勢的價格位階與多頭排列 (CAN SLIM 的 M 與 RS)
    • 多頭趨勢護航:股價必須大於 50 日均線(中期),且 50 日均線大於 200 日均線(長期),確認為真正的多頭。
    • 逼近歷史高點:目前的股價必須距離「52 週最高點」不到 20% 以內(即 收盤價 >= 52週最高價 * 0.80),準備伺機突破。
  3. 流動性防呆 (Liquidity)
    • 大資金點火需要流動性:限制 成交量 > 1500 張。

我請Gemini根據他的投資邏輯寫了一個腳本如下

// 腳本類型:Type A 選股腳本 (Screener)
// 策略名稱:David Ryan CAN SLIM 強勢成長股策略
// 策略邏輯:尋找營收與獲利爆發,且均線呈現多頭排列、股價正逼近 52 週新高的超級成長股

// 確保長天期歷史資料讀取足夠 (計算 200 日均線及 250 日 52 週新高需要)
SetTotalBar(260);

// 變數宣告鐵律:無底線、無系統保留字 daily、預設給定初始值
var: revYoy(0), epsCurrent(0), epsLastYear(0), volToday(0);
var: ma50(0), ma200(0), high52W(0);
var: isTrendUp(false), isNearHigh(false);

// 嚴格依照 Data Dictionary 與前次校正規範讀取資料
revYoy = GetField("月營收年增率", "M"); // 基本面火力:營收爆發成長
epsCurrent = GetField("每股稅後淨利(元)", "Q"); // 基本面火力:當季 EPS
epsLastYear = GetField("每股稅後淨利(元)", "Q")[4]; // 基本面火力:去年同期 EPS (往前推 4 季)
volToday = GetField("成交量", "D"); // 流動性指標

// 運算均線與 52 週高點 (約 250 個交易日)
ma50 = Average(Close, 50);
ma200 = Average(Close, 200);
high52W = Highest(High, 250);

// 條件一:中期與長期多頭排列 (股價 > 50MA 且 50MA > 200MA)
if Close > ma50 and ma50 > ma200 then 
isTrendUp = true 
else 
isTrendUp = false;

// 條件二:股價逼近 52 週新高,距離高點不到 20% (加上分母防呆確保 high52W 不為 0)
if high52W <> 0 and Close >= (high52W * 0.80) then 
isNearHigh = true 
else 
isNearHigh = false;

// 核心量化綜合判斷:單一等號、完整邏輯包覆
// 條件說明:
// 1. 月營收年增率 > 25.0 (符合 Ryan 對強勢擴張的要求)
// 2. epsCurrent > 0 且 epsCurrent > epsLastYear (獲利大於零且超過去年同期)
// 3. isTrendUp = true (技術面多頭排列護航)
// 4. isNearHigh = true (價格位階逼近 52 週新高,具備強勢股特徵)
// 5. volToday > 1500 (確保流動性充足)
if revYoy > 25.0 
and epsCurrent > 0.0 
and epsCurrent > epsLastYear 
and isTrendUp = true 
and isNearHigh = true 
and volToday > 1500 then begin

// 觸發條件成立
ret = 1;

// Type A 選股腳本專屬:輸出九宮格檢驗欄位 (警示腳本絕對禁用)
OutputField1(revYoy, "月營收年增率(%)");
OutputField2(epsCurrent, "當季EPS(元)");
OutputField3(Close, "今日收盤價");
OutputField4(high52W, "52週最高價");
end;

回測的結果是少數近期還能打敗指數的達人策略

 

用AI寫因子,用XScript的因子分析功能找高勝率因子

當我們透過Gem的設定,很穩定的讓Gemini幫我們寫腳本之後,最大的挑戰就是,要如何讓Gemini寫出勝率夠高,MDD可以接受的腳本,然後把這些腳本再存回Gem的知識庫中。

在機構法人及學術圈中,有一群人持續的在找有超額報酬的因子,找到了,放到交易策略中,應該是要可以提高交易策略的勝率。

XScript的自訂函數可以被作成一個因子,系統提供了因子分析的功能,讓使用者可以試著把idea變成自訂函數,然後按因子分析去看看,這個因子在不同頻率底下的報酬率分佈,這個連結有詳細的說明

例如企業價值這個因子,分成十組,各組的報酬率如下圖

如果依年度來分,報酬率如下圖

透過這些分析,我們在把因子寫成策略之前,就知道那些因子可以貢獻超額報酬,那些則可能隨波逐流。

現在我們用Gemini,也可以請它把我們的點子寫成因子

下面這是一個例子: 我想請Gemini把關鍵券商+關聯券商+三大法人的買賣超寫成一個因子,以下是它寫的腳本及它的回覆

 結合「關鍵券商」、「關聯券商」與「三大法人」,等於是把大股東、地緣主力以及大型機構的動向融合成了單一的 聰明錢(Smart Money)籌碼共振因子 。

根據您的需求,以下為您進行邏輯解構與腳本撰寫:

1. 邏輯解構

  1. 確認執行環境:為了能在 XQ 的「選股因子分析」工具中進行十等分組(D1~D10)回測,您必須將此腳本建置為**「自訂函數 (Function)」,而非一般的選股或警示腳本。在函數腳本中,不需要寫 ret = 1;,而是要將最終計算的值直接賦予函數本身的名稱**。
  2. 精確欄位正名
    • 關鍵券商買賣超 $\rightarrow$ GetField(“關鍵券商買賣超張數”, “D”)
    • 關聯券商買賣超 $\rightarrow$ GetField(“關聯券商買賣超張數”, “D”)
    • 三大法人合計買賣超 $\rightarrow$ GetField(“法人買賣超張數”, “D”) (依照官方說明文件,此欄位即代表三大法人合計)
  3. Alpha 因子優化(極度重要)
    如果在因子分析中只將「張數」相加,系統在做跨商品比較時,會產生嚴重的「大型股偏誤」(例如:台積電買超 1000 張的意義與中小型股買超 1000 張完全不同)。因此,身為量化開發者,我強烈建議將總買賣超張數除以當日成交量,轉化為「聰明錢買盤佔總成交量比重(%)」。這樣出來的因子分數,在十分位報表中的勝率與排序表現會優秀非常多。

2. 程式碼區塊

請在 XQ 腳本編輯器中新增一個**「函數」**,並將名稱命名為 SmartMoneyFactor(或是您自訂的名稱),然後貼上以下程式碼:

 

// 函數名稱:SmartMoneyFactor (若您使用其他名稱,請記得更改最後一行的變數名)

// 腳本類型:自訂函數 (Function) - 供選股因子分析使用





// 宣告變數,遵守無底線、駝峰式命名鐵律

var: keyBroker(0), affBroker(0), instBroker(0);

var: rawSum(0), volToday(0), factorScore(0);





// 取出各項主力籌碼買賣超張數 (日頻率)

keyBroker = GetField("關鍵券商買賣超張數", "D");

affBroker = GetField("關聯券商買賣超張數", "D");

instBroker = GetField("法人買賣超張數", "D"); 





// 計算三大主力原始合計淨買賣張數

rawSum = keyBroker + affBroker + instBroker;





// 取得當日成交量

volToday = Volume;





// 防呆機制與因子標準化 (除法保護)

// 將買超張數除以成交量作標準化,將絕對張數轉換為「主力買盤強度比重」

if volToday <> 0 then begin

    factorScore = (rawSum / volToday) * 100;

end else begin

    factorScore = 0; // 若當日無成交量,防呆回傳 0

end;





// 【重要】在 XScript 函數中,需將最終數值指定給「函數名稱」

// 請確保下方的 SmartMoneyFactor 與您在 XQ 中存檔的函數名稱完全一字不差

SmartMoneyFactor = factorScore;

3. 自我檢查清單 (Self-Check)

  • [x] 變數命名鐵律:全數採用駝峰式(如 keyBrokervolToday),無底線,且避開了保留字 daily
  • [x] 邏輯判斷符號:判斷式使用單一等號 =<>,無雙等號 ==
  • [x] 變數宣告:所有變數皆在最上方 var: 區塊賦予初始值 (0)
  • [x] 防呆與運算保護:已加入 if volToday <> 0 分母不為零防呆除錯機制。
  • [x] 腳本類型差異:確認為「函數 (Function)」格式,未使用 OutputFieldret = 1,並正確把值指派給函數名稱。
  • [x] 資料字典正名:完美匹配官方規定的 關鍵券商買賣超張數關聯券商買賣超張數法人買賣超張數

有了這個函數後,您就可以在 XQ 的左側目錄對著這個腳本按右鍵,直接點選「因子分析」來觀察它的十分位報酬率了!

請問您是否需要我進一步幫您寫一個搭配此因子的**「選股腳本 (Screener)」**,讓您可以直接在盤後快速篩選出這個「聰明錢主力強度」大於特定門檻(例如 > 10%)的潛力爆發股?

 

透過這樣的流程,我們可以把點子讓Gemini寫成自訂函數,再透過XScript編輯器裡的因子分析功能,透過圖形分析,看看這個因子有沒有超額報酬,然後再把有效的因子,讓Gemini寫成勝率較高的策略,並且把這個策略存到Gem的知識庫中

 

這樣我們就可以累積投資智慧,逐漸形成一個有紀律的交易風格