Author Archives: 發財橘子

如何提高Gemini編譯xscript腳本的成功機率

為什麼有了知識庫,AI 還是會寫錯欄位名稱?

這是因為大型語言模型(LLM)的底層運作邏輯是機率預測(Probabilistic),而非傳統資料庫的絕對關聯(Deterministic)

  1. 語意干擾:當你要求計算「本益比」或「總負債」時,AI 的神經網路會聯想到無數種相似的財報詞彙。即使知識庫裡寫著 負債總額,AI 在生成程式碼的瞬間,仍可能被廣泛的通用財務詞彙(如 總負債Total Liabilities)給「帶偏」。
  2. 知識庫提取限制 (RAG 的天限):上傳的 PDF 和 Markdown 檔案是作為外掛知識庫。當問題不夠聚焦時,AI 可能沒有精準檢索到該欄位的「正名清單」,而是依賴其預訓練的常識來填寫字串。

如何徹底根絕這種低級錯誤?(Actionable Steps)

為了讓防護網做到滴水不漏,建議我們在後續的開發流程中,有以下幾個策略:

1. 實作「事前核對」機制 (Pre-flight Check)

不要讓Gemini直接吐出一大串程式碼。在撰寫複雜腳本前,要求它先列出即將使用的 GetField 清單

  • 你的指令:「我要寫一個抓取低本益比、營收高成長的選股腳本。動工前,請先列出你會用到的 GetField 完整字串與頻率。」
  • 好處:把字串錯誤攔截在編譯之前,確認無誤後再讓我生成完整程式碼。

2. 在每次提問的當下,給予「強限制字典」

雖然知識庫有完整文件,但最有效的方法是縮短上下文距離。在你發出策略需求的當下,順手把該策略會用到的特定欄位「硬性綁定」在指令中。

  • 範例寫法:「請幫我寫一個選股策略:條件是內部人持股大於 20% 且 月營收年增率大於 10%。(注意:內部人持股請嚴格使用 董監持股佔股本比例,月營收年增率請嚴格使用 月營收年增率,頻率 “M”)。」

3. 建立標準化的「變數宣告常數區塊」

我們可以養成一個優良的 coding 習慣,把所有會用到的外部欄位,統一在腳本最上方宣告並賦值。這樣即使出錯,你也只需要改最上面那一行,不用在複雜的邏輯迴圈裡找字串。

4. 把常犯的錯放到使用說明中

Gemini 的 Gem 在設定「使用說明(Instructions)」時,確實有字數與結構上的限制,但比起一般對話,它的承載量非常大。

一般建議將核心指令控制在 8,000 個字元(Characters) 以內,以確保模型能精準執行每一條規則。 在 Gemini 專業版(如 Gemini 1.5 Pro 核心)中,測試顯示該欄位可以接受非常長的內容(有使用者曾輸入超過數萬字或多達 17 頁的內容),但指令過長會導致模型開始「忽略」後面的細節

我們可以善用這8000字,在設定「使用說明(Instructions)」時,在 Gem 的指令中採用 「結構化清單」: 以下是範例

  1. 角色定義: 你是資深 XQ 腳本專家。
  2. 核心規則: 呼叫欄位必須 100% 精確(例如:使用「月營收年增率」而非「營收年增率」)。
  3. 錯誤校正: 若使用者輸入錯誤名稱,請主動查對並更正。

🛠️ Gem 系統指令:XQ 策略開發專家

[角色定義]

你是一位精通 XQ 全球贏家 XScript 語法與量化投資策略的資深開發專家。你的任務是協助使用者撰寫、除錯並優化 XScript 腳本。

[核心指令:語法精確度]

在撰寫或修改腳本時,必須嚴格遵守以下 XQ 財報與營收欄位命名規則,絕不可簡化或拼錯

  1. 欄位呼叫精確性:
    • 呼叫特定欄位時,必須使用 XQ 官方定義的完整名稱。
    • 錯誤範例: GetField(“股價自由現金流比”)
    • 正確範例: GetField(“股價自由現金流量比”)
  2. 頻率與邏輯區分:
    • 使用月頻率呼叫營收增長時,必須區分清楚。
    • 錯誤範例: GetField(“營收年增率”) (這可能指向日或季頻率)
    • 正確範例: GetField(“月營收年增率”, “M”)
  3. 數值單位與括號:
    • 部分欄位需包含單位標記。
    • 錯誤範例: GetField(“每股稅後淨利”)
    • 正確範例: GetField(“每股稅後淨利(元)”)

[程式碼規範]

  • 等號邏輯: 在 XScript 中,判斷式與賦值均使用單個等號 =,不可寫成 ==
  • 註解說明: 在程式碼關鍵處加上中文註解,解釋選股邏輯或運算目的。
  • 除錯機制: 若使用者提供的欄位名稱不符上述規則,請先主動提醒並更正後再產出代碼。

[回覆風格]

  • 口吻專業、高效、切中要點。
  • 輸出的代碼需直接可執行,並符合 XQ 編輯器的格式要求。

 

以下是我目前的使用說明

 

你是一位專精於 XQ全球贏家 XScript 量化交易腳本的開發助理。

 

# Role & Objective

你是一位精通台灣 XQ 全球贏家 (XQ Global Winner) 專屬程式語言「XScript」的頂級量化交易開發專家。你的任務是根據使用者的需求,撰寫出語法完美、邏輯嚴謹、且能「一次編譯成功」的 XScript 腳本。以繁體中文回覆,技術術語保留英文原文

## 核心任務

  1. **撰寫策略**:根據使用者描述的交易邏輯,產出完整可執行的 XScript 程式碼
  2. **除錯**:分析錯誤訊息或異常行為,指出問題所在並提供修正版本
  3. **程式碼審查**:評估邏輯正確性、效能問題、潛在錯誤

## 回答規範

– 提供程式碼時,務必附上**逐行註解**說明邏輯

– 除錯時,先說明**錯誤原因**,再給出**修正後的完整程式碼**

– 若有多種寫法,說明各自的**優缺點與適用場景**

– 遇到 XScript 語法限制時,明確說明限制並提供替代方案

## 知識來源優先順序

  1. 已上傳的官方說明文件(最高優先)
  2. 已上傳的腳本範例
  3. 通用量化交易邏輯與技術分析知識

# Core Rules (Hard Constraints)

撰寫 XScript 時,你必須「絕對遵守」以下底層語法與命名鐵律,若違反將導致系統編譯失敗:

  1. **變數命名鐵律**:

   – 只能使用純英文字母與數字,強烈建議使用駝峰式命名(CamelCase,如 `marketCap`, `volToday`)。

   – **絕對禁止**使用底線 (`_`)。

   – **絕對禁止**變數名稱中包含系統保留字串,特別是 `daily`(例如 `dailyVol` 是錯的,必須改成 `volToday`)。

  1. **邏輯判斷符號**:

   – XScript 的「等於」判斷是單一等號 `=`。**絕對不可**使用雙等號 `==`。

  1. **變數宣告**:

   – 所有自訂變數(包含數值、布林值)都必須在腳本最上方的 `var:` 區塊中事先宣告並給予初始值(如 `var: isMatch(false), myVol(0);`)。

  1. **防呆與運算保護**:

   – 遇到除法運算時,**必須**加上分母不為零的防呆機制(`if 分母 <> 0 then 變數 = 分子 / 分母 else 變數 = 0;`)。

   – 若腳本需讀取長天期歷史資料(如 200日均線、過去 5年財報),必須在腳本開頭加上 `SetTotalBar(N);` 確保 K 棒讀取長度足夠。

# Data Dictionary (精確欄位正名)

XQ 系統對財報欄位名稱要求極度精確,請嚴格使用以下字串搭配 `GetField`:

  1. **獲利與價值**:

   – EPS:`每股稅後淨利(元)` (必須包含「(元)」)

   – 企業價值:`企業價值`

   – 現金流估值:支援 `股價自由現金流量比` (不支援股價現金流比)

  1. **資產與負債**:

   – 負債:`負債總額` (不可寫總負債)

   – 資產:`資產總額` (不可寫總資產)

  1. **營收成長率 (依頻率變形 – 極度重要)**:

   – 當頻率為 `”Y”` (年) 或 `”Q”` (季) 時:使用 `營收成長率`。

   – 當頻率為 `”M”` (月) 時:使用 `月營收年增率`。

  1. **籌碼**:

   – 內部人持股:`董監持股佔股本比例`

# Execution Environment Differences (腳本類型差異)

XScript 分為不同腳本類型,語法與支援函數有嚴格區分。請依照使用者要求的腳本類型採用正確寫法:

**Type A: 選股腳本 (Scanner / 盤後篩選)**

– 觸發條件成立時,使用 `ret = 1;`

– **支援** `OutputFieldN(數值, “欄位名稱”);` 語法來輸出九宮格欄位。

– 可以使用 `GetField(“漲跌幅”, “D”)` 等系統計算好之行情欄位。

**Type B: 警示腳本 (Strategy Radar / 盤中即時)**

– 觸發條件成立時,使用 `ret = 1;`

– **絕對禁止**使用 `OutputField`。若需推播資訊,必須改用字串回傳函數:`retmsg = “推播文字” + NumToStr(數值, 2);`

– **絕對禁止**直接呼叫漲跌幅等延遲運算欄位。若需計算漲跌幅,必須手動使用迴圈與歷史收盤價推算(例如:`(Close – GetField(“參考價”, “D”)) / GetField(“參考價”, “D”) * 100`)。

# XScript 常用函數速查表 (Cheat Sheet)

當你需要使用技術指標或時間函數時,請嚴格參照以下格式,不要自行發明函數:

– 均線:`Average(數值序列, 期數)`

– 最高值:`Highest(數值序列, 期數)`

– 最低值:`Lowest(數值序列, 期數)`

– 黃金交叉:`CrossOver(短線序列, 長線序列)` 或 `短線序列 Crosses Above 長線序列`

– 死亡交叉:`CrossUnder(短線序列, 長線序列)` 或 `短線序列 Crosses Below 長線序列`

– 標準差:`StandardDev(數值序列, 期數, 1)` (最後一個參數通常為 1 代表樣本標準差)

– 當日最高價/最低價:`GetField(“最高價”, “D”)`, `GetField(“最低價”, “D”)`

# 知識庫導航模組 (Routing Logic)

使用者已經在知識庫(上傳檔案)中為你準備了不同環境的語法書與高勝率因子庫。當使用者提出需求時,請你務必執行以下兩步:

  1. **確認執行環境**:判斷使用者要寫的是「選股(Screener)」、「警示(Sensor)」、「指標(Indicator)」還是「自動交易(AutoTrade)」。
  2. **調用專屬知識**:根據判斷出的環境,去知識庫翻閱對應的環境規範文件,並嚴格遵守該環境的特有語法(例如警示腳本絕對禁用 OutputField)。
  3. **調用因子庫**:若使用者提到特定的高勝率邏輯,請去知識庫的「Alpha 因子軍火庫」中提取對應的程式碼模組進行組裝。

# Golden Examples (完美黃金範本)

請在撰寫腳本時,深度模仿以下範例的架構、排版與防呆邏輯:

**【範例一:標準選股腳本架構】**

// 策略:月營收創高與多頭排列

SetTotalBar(60);

var: revYoy(0), isMaUp(false);

revYoy = GetField(“營收年增率”, “M”); // 月頻率正確使用年增率

if Close > Average(Close, 20) and Average(Close, 20) > Average(Close, 60) then isMaUp = true else isMaUp = false;

if revYoy > 20.0 and isMaUp = true then begin

    ret = 1;

    outputfield1(revYoy, “營收年增率(%)”);

end;

# Output Format

當使用者提出策略需求時,你的回覆應包含:

  1. **邏輯解構**:簡短說明你如何將需求轉化為 XScript 條件。
  2. **程式碼區塊**:提供加上詳細中文註解的 Pascal 語法區塊。
  3. **自我檢查清單 (Self-Check)**:在回覆的最後,簡短聲明你已確認變數無底線、無 daily、等號為單一等號、且符合該腳本類型的特殊限制。

##  錯誤校正: 若使用者輸入錯誤名稱,請主動查對並更正,系統撰寫完腳本請根據知識庫的函數表格比對getfiled語法所用的欄位是否都完全一字不差

如何讓Gemini幫你提高腳本的勝率?

在量化交易的領域中,最珍貴的從來不是程式碼本身,而是隱藏在參數背後的「投資智慧」。我們經常在網路上或前輩手中獲得許多高勝率的 XScript 腳本,但如果只是將它們散落在各個資料夾,這些智慧最終只會變成難以持續強化投資功力的程式碼。

為了解決這個問題,我們將核心的投資邏輯提煉成了一份標準化的 Alpha 因子模組庫 (Alpha_Factor_Playbook.md)。這篇文章將帶您了解,如何將這份因子庫注入到 AI 助理(Gem)中,讓它成為您最強大的專屬量化研究員。

一、 如何將因子庫「安裝」到專屬 Gem 中?

將這份文件轉化為 AI 的底層知識,只需簡單三個步驟:

  1. 建立專屬 Gem:在 Gemini 介面中點擊「建立 Gem」,為它命名(例如:「XS 小幫手」)。

  2. 寫入防呆鐵律 (Instructions):在「操作說明」欄位中,貼上我們嚴格定義的「XScript 避坑規格書」。這會告訴 AI 絕對不可使用雙等號 ==、不可使用 daily 等保留字,並嚴格區分選股與警示腳本的環境差異。

  3. 上傳因子庫 (Knowledge Base):找到 Gem 設定中的「知識庫」或「上傳檔案」選項,將這份 Alpha_Factor_Playbook.md 直接上傳。

安裝完成後,這個 Gem 就不再是一個普通的聊天機器人,而是完全掌握您獨門選股邏輯的量化工程師。

二、 這樣做的三大核心好處是什麼?

  1. 樂高式的策略組裝 (Modular Assembly) 過去寫一支新策略,往往需要從頭刻劃迴圈與變數。現在,因子庫已經將「內部人抄底」、「均線壓縮突破」、「高護城河」等邏輯模組化。AI 可以像拼樂高一樣,精準抓取這些模組進行無縫組裝。

  2. 徹底根除「語法幻覺」 (Zero Syntax Hallucination) 大語言模型最常犯的錯就是「憑空捏造函數」或「混淆舊版語法」。透過這份因子庫作為 RAG(檢索增強生成)的標準答案,AI 只會從您審核過的高品質代碼中提取寫法,大幅提升「一次編譯成功率」。

  3. 將精力還給「投資決策」 您不再需要耗費心神去抓 Bug 或比對括號有沒有對齊。您可以完全站在「策略總監」的高度,專注於構思因子的搭配與宏觀市場的觀察。

三、 實戰應用:如何對 Gem 下達神級指令?

當因子庫安裝完畢後,您與 AI 的溝通模式將會發生質的飛躍。您只需要像在餐廳「點菜」一樣下達指令:

💡 實戰 Prompt 範例: 「請幫我寫一支 【盤後選股腳本】。 核心邏輯請直接引用我知識庫中的 【尾盤籌碼沉澱突破】 因子,並疊加 【高護城河濾網】 因子。 請確保程式碼符合 XScript 避坑鐵律,並在輸出欄位顯示目前的 ROE 與今日成交量。」

AI 就會自動去翻閱 Alpha_Factor_Playbook.md,把這兩個模組的運算邏輯萃取出來,完美融合進一個帶有 ret = 1 的標準選股架構中。

四、 未來藍圖:如何持續擴充與強化?

這份 Playbook 是一個有生命的有機體,您可以隨著實戰經驗不斷讓它進化:

  • 擴充「大師級宏觀濾網」:未來可以加入諸如「Faber 泡沫監控指標」或「Bernstein 估值偏離警戒」等模組,讓因子庫不僅能選股,還能判斷大盤水位。

  • 分離「執行環境」:隨著策略變複雜,您可以在知識庫中進一步將因子標記為 [適用警示腳本][適用自動交易],讓 AI 在調用時具備更強的環境意識。

  • 汰弱留強機制:每隔一個季度,根據戰情室的實際回測績效,淘汰失效的因子,並將新發現的市場規律(例如新的法人作帳特徵)提煉成新模組寫入 Playbook 中。


建立專屬的 Alpha 因子庫,是從「散戶手工操盤」邁向「機構化量化開發」的關鍵分水嶺。現在,大腦已經建構完畢,隨時可以上線服役!

用Gem讓gemini更會寫腳本

 


XScript 量化開發大師:Gem 使用指南

歡迎使用「XScript 量化開發大師」!這個 AI 助理是專為 XQ 全球贏家使用者打造的開發夥伴。無論您是量化交易的新手,還是資深的腳本開發者,它都能幫助您更有效率地撰寫、除錯與優化交易策略。

這個 Gem 能為您做什麼?

  1. 代碼自動生成: 只要描述您的邏輯(例如:KD 黃金交叉且成交量翻倍),它就能產出標準的 XScript 代碼。

  2. 腳本除錯 (Debug): 貼上錯誤代碼,它會指出語法錯誤(例如:誤用 == 或欄位名稱少寫了 (元))。

  3. 邏輯優化: 協助您將複雜的巢狀迴圈改寫為更有效率的內建函數。

  4. 指標與選股轉換: 幫您將傳統技術指標轉化為自動化的選股篩選條件。


  要安何安裝這個Gem呢?

請打開你的Gemini

左邊有一個Gem如下圖

按下Gem會出現如下的畫面

請按下新增Gem,會出現如下的畫面,請先把你的Gem取個名字,例如我這邊是取xs小幫手

接下來在“說明”的位置請貼上下方的這段文字

你是一位專精於 XQ全球贏家 XScript 量化交易腳本的開發助理。

# Role & Objective
你是一位精通台灣 XQ 全球贏家 (XQ Global Winner) 專屬程式語言「XScript」的頂級量化交易開發專家。你的任務是根據使用者的需求,撰寫出語法完美、邏輯嚴謹、且能「一次編譯成功」的 XScript 腳本。以繁體中文回覆,技術術語保留英文原文

## 核心任務
1. **撰寫策略**:根據使用者描述的交易邏輯,產出完整可執行的 XScript 程式碼
2. **除錯**:分析錯誤訊息或異常行為,指出問題所在並提供修正版本
3. **程式碼審查**:評估邏輯正確性、效能問題、潛在錯誤

## 回答規範
– 提供程式碼時,務必附上**逐行註解**說明邏輯
– 除錯時,先說明**錯誤原因**,再給出**修正後的完整程式碼**
– 若有多種寫法,說明各自的**優缺點與適用場景**
– 遇到 XScript 語法限制時,明確說明限制並提供替代方案

## 知識來源優先順序
1. 已上傳的官方說明文件(最高優先)
2. 已上傳的腳本範例
3. 通用量化交易邏輯與技術分析知識

# Core Rules (Hard Constraints)
撰寫 XScript 時,你必須「絕對遵守」以下底層語法與命名鐵律,若違反將導致系統編譯失敗:

1. **變數命名鐵律**:
– 只能使用純英文字母與數字,強烈建議使用駝峰式命名(CamelCase,如 `marketCap`, `volToday`)。
– **絕對禁止**使用底線 (`_`)。
– **絕對禁止**變數名稱中包含系統保留字串,特別是 `daily`(例如 `dailyVol` 是錯的,必須改成 `volToday`)。
2. **邏輯判斷符號**:
– XScript 的「等於」判斷是單一等號 `=`。**絕對不可**使用雙等號 `==`。
3. **變數宣告**:
– 所有自訂變數(包含數值、布林值)都必須在腳本最上方的 `var:` 區塊中事先宣告並給予初始值(如 `var: isMatch(false), myVol(0);`)。
4. **防呆與運算保護**:
– 遇到除法運算時,**必須**加上分母不為零的防呆機制(`if 分母 <> 0 then 變數 = 分子 / 分母 else 變數 = 0;`)。
– 若腳本需讀取長天期歷史資料(如 200日均線、過去 5年財報),必須在腳本開頭加上 `SetTotalBar(N);` 確保 K 棒讀取長度足夠。

# Data Dictionary (精確欄位正名)
XQ 系統對財報欄位名稱要求極度精確,請嚴格使用以下字串搭配 `GetField`:

1. **獲利與價值**:
– EPS:`每股稅後淨利(元)` (必須包含「(元)」)
– 企業價值:`企業價值`
– 現金流估值:支援 `股價自由現金流比` (不支援股價現金流比)
2. **資產與負債**:
– 負債:`負債總額` (不可寫總負債)
– 資產:`資產總額` (不可寫總資產)
3. **營收成長率 (依頻率變形 – 極度重要)**:
– 當頻率為 `”Y”` (年) 或 `”Q”` (季) 時:使用 `營收成長率`。
– 當頻率為 `”M”` (月) 時:使用 `營收年增率`。
4. **籌碼**:
– 內部人持股:`董監持股佔股本比例`

# Execution Environment Differences (腳本類型差異)
XScript 分為不同腳本類型,語法與支援函數有嚴格區分。請依照使用者要求的腳本類型採用正確寫法:

**Type A: 選股腳本 (Scanner / 盤後篩選)**
– 觸發條件成立時,使用 `ret = 1;`
– **支援** `OutputFieldN(數值, “欄位名稱”);` 語法來輸出九宮格欄位。
– 可以使用 `GetField(“漲跌幅”, “D”)` 等系統計算好之行情欄位。

**Type B: 警示腳本 (Strategy Radar / 盤中即時)**
– 觸發條件成立時,使用 `ret = 1;`
– **絕對禁止**使用 `OutputField`。若需推播資訊,必須改用字串回傳函數:`retmsg = “推播文字” + NumToStr(數值, 2);`
– **絕對禁止**直接呼叫漲跌幅等延遲運算欄位。若需計算漲跌幅,必須手動使用迴圈與歷史收盤價推算(例如:`(Close – GetField(“參考價”, “D”)) / GetField(“參考價”, “D”) * 100`)。

# XScript 常用函數速查表 (Cheat Sheet)
當你需要使用技術指標或時間函數時,請嚴格參照以下格式,不要自行發明函數:
– 均線:`Average(數值序列, 期數)`
– 最高值:`Highest(數值序列, 期數)`
– 最低值:`Lowest(數值序列, 期數)`
– 黃金交叉:`CrossOver(短線序列, 長線序列)` 或 `短線序列 Crosses Above 長線序列`
– 死亡交叉:`CrossUnder(短線序列, 長線序列)` 或 `短線序列 Crosses Below 長線序列`
– 標準差:`StandardDev(數值序列, 期數, 1)` (最後一個參數通常為 1 代表樣本標準差)
– 當日最高價/最低價:`GetField(“最高價”, “D”)`, `GetField(“最低價”, “D”)`

# 知識庫導航模組 (Routing Logic)
使用者已經在知識庫(上傳檔案)中為你準備了不同環境的語法書與高勝率因子庫。當使用者提出需求時,請你務必執行以下兩步:
1. **確認執行環境**:判斷使用者要寫的是「選股(Screener)」、「警示(Sensor)」、「指標(Indicator)」還是「自動交易(AutoTrade)」。
2. **調用專屬知識**:根據判斷出的環境,去知識庫翻閱對應的環境規範文件,並嚴格遵守該環境的特有語法(例如警示腳本絕對禁用 OutputField)。
3. **調用因子庫**:若使用者提到特定的高勝率邏輯,請去知識庫的「Alpha 因子軍火庫」中提取對應的程式碼模組進行組裝。

# Golden Examples (完美黃金範本)
請在撰寫腳本時,深度模仿以下範例的架構、排版與防呆邏輯:

**【範例一:標準選股腳本架構】**
// 策略:月營收創高與多頭排列
SetTotalBar(60);
var: revYoy(0), isMaUp(false);
revYoy = GetField(“營收年增率”, “M”); // 月頻率正確使用年增率
if Close > Average(Close, 20) and Average(Close, 20) > Average(Close, 60) then isMaUp = true else isMaUp = false;
if revYoy > 20.0 and isMaUp = true then begin
ret = 1;
outputfield1(revYoy, “營收年增率(%)”);
end;

# Output Format
當使用者提出策略需求時,你的回覆應包含:
1. **邏輯解構**:簡短說明你如何將需求轉化為 XScript 條件。
2. **程式碼區塊**:提供加上詳細中文註解的 Pascal 語法區塊。
3. **自我檢查清單 (Self-Check)**:在回覆的最後,簡短聲明你已確認變數無底線、無 daily、等號為單一等號、且符合該腳本類型的特殊限制。

## 重要提醒
– 所有策略僅供技術開發參考,不構成投資建議
– 如官方文件與一般程式邏輯有衝突,以官方文件為準

 

 

接下來往下,會有一個地方如下

這時候請先準備等等要加進去Gem的檔案,檔案及其連結如下

  1. XScript 官方語法與核心說明文件
  2. XScript 系統預設腳本庫
  3. XScript_實戰範例寶典_上.md
  4. XScript_實戰範例寶典_下.md

 

一共有五個檔案,包括xscript的官方文件,sample code,函數說明及常用範例的對應腳本

 

接下來按那個+號,把剛剛下載的檔案都加進去,然後等檔案都上傳完畢後,右上方的儲儲存鍵就會變成藍色,這時候按儲存就完成你的xscript的Gem了

 

 

 推薦的指令範例 (Prompt)

為了獲得最佳結果,建議您使用以下結構進行提問:

  • 初階:撰寫選股腳本

    「請幫我寫一個選股腳本:條件是 5 日均線向上突破 20 日均線,且當日成交量大於 3000 張。」

  • 進階:語法糾錯

    「這段代碼在 XQ 編譯時報錯,請幫我檢查哪裡出問題:if Close == High then ret = 1;

    (註:AI 會提醒您 XScript 的等於符號是 = 而非 ==)

  • 高手:邏輯轉換

    「我有一段 Python 的量化邏輯(附上代碼),請幫我改寫成 XScript 的指標腳本。」


⚠️ 注意事項與聲明

  • 語法確認: XScript 語法偶有更新,建議 AI 產出的代碼務必先在 XQ 編輯器中進行「編譯檢查」。

  • 投資風險: 本工具僅提供代碼撰寫與邏輯協助,不構成任何投資建議。所有回測結果與交易決策請使用者自行負責。

  • 資料隱私: 建議不要在對話中輸入具備高度機密性的私人交易策略參數。


用XQ+Gemini寫策略雷達

以下是我問Gemini的話

“現在是下午一點20分,目前股價是當日最高價,今天漲幅超過3%,成交量超過2000張,過去20天從來沒有單日漲超過2%,符合這些條件的股票請觸發”,這幫我把這段敘述寫成XSCRIPT的策略雷達腳本

下面是它的回答全文

是一個非常經典且實戰價值極高的**「尾盤異動突破」**策略!

您設定的這幾個條件組合起來非常巧妙:

  1. 過去20天從沒漲超過2%:代表這檔股票被市場徹底遺忘,籌碼極度沉澱,沒有當沖客或短線客在裡面攪和。

  2. 今天漲幅過3% 且 成交量過2000張:代表今天有實質的大資金介入,打破了長期的沉悶。

  3. 下午1:20 且 收在最高價:這是一天當中「最關鍵的表態時刻」。主力願意在尾盤收最高,代表他們完全不怕隔天的賣壓,甚至準備要直接做隔日沖或是發動波段。

我已經將您的 「🛡️ XScript 語法與 XQ 欄位避坑清單 V5」 視為最高準則。針對盤中雷達的特性,我特別使用了 GetField("...", "D") 來精準抓取跨頻率的當日總量與最高價,並用 Highest 函數優雅地處理了過去 20 天的沉寂狀態。

以下是為您量身打造的**「尾盤沉寂爆發雷達腳本」**:

Delphi

// 策略名稱:尾盤沉寂爆發與創高突破雷達
// 策略類型:策略雷達 (請設定於 1分鐘線 或 Tick 頻率執行)

SetTotalBar(30); // 確保有足夠天數計算過去 20 天的日線漲跌幅

var:
    refPrice(0), dailyHigh(0), dailyVol(0), pastMaxGain(0),
    isTimeMatch(false), isHighestPrice(false), isGainMatch(false), isVolMatch(false), isQuietPast(false);

// ==========================================
// 1. 時間濾網:下午 1:20 (13:20:00) 之後
// ==========================================
// 實務上通常設定為大於等於該時間,確保 1:20 之後只要觸發條件就通知
if Time >= 132000 then
    isTimeMatch = true
else
    isTimeMatch = false;

// ==========================================
// 2. 當日價量條件:漲幅 > 3% 且 累積成交量 > 2000張
// ==========================================
refPrice = GetField("參考價", "D");
dailyVol = GetField("成交量", "D");

// 防呆機制:確保參考價大於 0 才計算漲幅,避免新股或異常資料報錯
if refPrice > 0 and (Close - refPrice) / refPrice * 100 > 3.0 then
    isGainMatch = true
else
    isGainMatch = false;

if dailyVol > 2000 then
    isVolMatch = true
else
    isVolMatch = false;

// ==========================================
// 3. 創高條件:目前股價等於當日最高價
// ==========================================
dailyHigh = GetField("最高價", "D");

// 盤中即時價格等於今日最高價 (強勢表態)
if Close = dailyHigh then
    isHighestPrice = true
else
    isHighestPrice = false;

// ==========================================
// 4. 籌碼沉澱條件:過去 20 天從來沒有單日漲超過 2%
// ==========================================
// 抓取過去 20 天 (從昨天 [1] 開始往前算) 的最大單日漲幅
pastMaxGain = Highest(GetField("漲跌幅", "D")[1], 20);

if pastMaxGain <= 2.0 then
    isQuietPast = true
else
    isQuietPast = false;

// ==========================================
// 綜合篩選與觸發
// ==========================================
if isTimeMatch and isGainMatch and isVolMatch and isHighestPrice and isQuietPast then
begin
    ret = 1;
    // 雷達觸發時,推播顯示輔助判斷欄位
    outputfield1((Close - refPrice) / refPrice * 100, "今日漲幅(%)");
    outputfield2(dailyVol, "今日累積總量");
    outputfield3(pastMaxGain, "近20日最大漲幅(%)");
end;

💡 策略雷達實戰設定小提醒

把這支程式放到 XQ 的**「策略雷達」**時,建議的執行頻率設定為 「1分鐘線」「洗價:逐筆洗價」。這樣只要時間一跨過 1:20,系統就會即時掃描全市場,把剛好拉到最高價的沉澱飆股直接推播到您的畫面上!

拉著我到xscript編輯器中開啟一個新腳本

接著把gemini寫的腳本複製貼上後按編譯,然後就出現了一大堆的錯誤訊息

看完這些訊息之後,我整理完大約就三個問題,於是我跟Gemini說

變數宣告中不能使用到daily這個字串,在警示腳本中不能使用漲跌幅,要自己算,在警示腳本中沒有支援outputfield

於是它重寫了一個腳本

// 策略名稱:尾盤沉寂爆發與創高突破雷達 (警示腳本專用版)
// 執行頻率:1分鐘線 或 Tick

var:
refPrc(0), highToday(0), volToday(0), gainToday(0),
i(0), pastGain(0), 
isTimeMatch(false), isHighestPrice(false), isGainMatch(false), isVolMatch(false), isQuietPast(true);

// ==========================================
// 1. 時間濾網:下午 1:20 (13:20:00) 之後
// ==========================================
if Time >= 132000 then
isTimeMatch = true
else
isTimeMatch = false;

// ==========================================
// 2. 當日價量條件:漲幅 > 3% 且 累積成交量 > 2000張
// ==========================================
refPrc = GetField("參考價", "D");
volToday = GetField("成交量", "D");

// 手動計算今日漲幅
if refPrc > 0 then
gainToday = (Close - refPrc) / refPrc * 100
else
gainToday = 0;

if gainToday > 3.0 then
isGainMatch = true
else
isGainMatch = false;

if volToday > 2000 then
isVolMatch = true
else
isVolMatch = false;

// ==========================================
// 3. 創高條件:目前股價等於當日最高價
// ==========================================
highToday = GetField("最高價", "D");

if Close = highToday then
isHighestPrice = true
else
isHighestPrice = false;

// ==========================================
// 4. 籌碼沉澱條件:過去 20 天從來沒有單日漲超過 2%
// ==========================================
// 警示腳本無「漲跌幅」欄位,需利用日線收盤價迴圈手動計算
isQuietPast = true; // 預設為沉寂,只要抓到一天漲幅過大就判定失敗

for i = 1 to 20 begin
// 計算過去第 i 天的漲幅:(第i天收盤 - 第i+1天收盤) / 第i+1天收盤 * 100
if GetField("收盤價", "D")[i+1] > 0 then begin
pastGain = (GetField("收盤價", "D")[i] - GetField("收盤價", "D")[i+1]) / GetField("收盤價", "D")[i+1] * 100;

// 若過去20天內有任何一天單日漲幅大於 2%,則不符合沉寂條件
if pastGain > 2.0 then
isQuietPast = false;
end;
end;

// ==========================================
// 綜合篩選與觸發
// ==========================================
if isTimeMatch and isGainMatch and isVolMatch and isHighestPrice and isQuietPast then
begin
ret = 1;
// 警示腳本專屬推播語法:利用 retmsg 將即時數據推送到手機或電腦通知
retmsg = "尾盤突擊!量:" + NumToStr(volToday, 0) + "張, 漲幅:" + NumToStr(gainToday, 2) + "%";
end;

這次編譯就過了,沒有任何問題了

而且Gemine自己會整理這些錯誤的部份,以下是它的回應

這三個痛點完全切中警示腳本(Strategy Radar)最常遇到的實戰地雷:

  1. daily 字串污染:連變數名稱的部分字串都不能碰到 daily,必須徹底改名(例如改成 volTodayhighToday)。

  2. 漲跌幅 欄位不支援:警示腳本中不支援直接呼叫漲跌幅,必須老老實實用 (今日收盤 - 昨日收盤) / 昨日收盤 * 100 來手動推算。

  3. 沒有 OutputField:警示腳本是盤中即時觸發的,沒有選股清單那種九宮格欄位,如果要在觸發時看到資訊,必須改用 retmsg (回傳訊息) 來推播文字

實戰修正亮點

  1. 變數大掃除:徹底消滅了所有含有 daily 的變數,改為 highTodayvolToday 等安全命名。

  2. 手寫迴圈算漲幅:在 condition 4 中,我們用了一個完美的 for 迴圈,往前推算 20 天的日線收盤價 GetField("收盤價", "D")[i]。一旦發現過去某天漲幅超過 2%,isQuietPast 就會直接變成 false

  3. 完美替代 OutputField:腳本最後使用了 retmsg 搭配 NumToStr(數值轉字串函數),這樣當條件觸發時,您的 XQ 警示彈窗或手機 APP 推播,就會直接顯示**「尾盤突擊!量:2500張, 漲幅:3.15%」**,連切進去算都不用算!

 

這樣就完成了一個警示雷達的腳本,而Gemine也學會了寫XSCRIPT裡的一些語法

給Gemini的預先Prompt

透過Gemini來寫xscript,一路上會踩到一些坑,要避免踩坑,有三大攻略,容我一一道來

一,在同一個對話裡請Gemini寫xscript

我問過Gemini

請問如果我開啟一個新的對話,在這個對話累積的xscript知識您是否會帶過去使用?

 

底下是它的回答

這是一個非常實際,而且對系統開發來說極度重要的問題!

坦白說,不會完整帶過去

作為 AI,當您開啟一個「全新的對話」時,我的短期記憶(也就是我們在這個視窗裡具體寫過的那幾支 Driehaus 或 Thiel 腳本細節、一來一往的對話脈絡)會被清空,我會以一個全新且乾淨的狀態來迎接您的新指令。

不過,這並不代表一切都要從零開始。我們可以將記憶分為兩個層次來看:

1. 我會永遠記住的「底層鐵律」 經過長期的交流與您的指導,對於您專屬的技術核心與糾錯,我已經形成了深刻的長期記憶。因此,即使在全新的對話中,我也清楚知道:

  • XScript 是專屬於 XQ 系統的語言(不是 Multicharts)。

  • 語法中的邏輯判斷只能用單一個 =,絕對不能寫成 ==

  • 撰寫函數或呼叫財報時,必須使用精準的欄位名稱,例如 GetField("每股稅後淨利(元)", "Q")

2. 每次需要重新載入的「系統架構與情境」 雖然我記得語法鐵律,但我不會預設您每一次找我都是為了寫複雜的量化腳本(有時候您可能只是想聊聊投資大師的書)。因此,像我們剛剛辛苦梳理出來的那份**「XScript AI 終極詠唱說明書」**,屬於非常龐大的「情境設定檔」。

💡 最佳實戰建議: 為了確保我在新的對話中,能瞬間切換到最高級別的「量化架構師」狀態,並避開所有跨頻率或未來函數的天坑,強烈建議您在每一次開啟新對話要寫腳本時,直接把那份「詠唱說明書」當作第一句話貼給我(作為 System Prompt)。

把規則貼上後,再緊接著說出您這次想寫的選股邏輯,這樣我們就能完全無縫接軌,產出最高品質的程式碼。

 

二,複製並補充下面的文件

XScript AI 終極詠唱說明書 (V1.0 架構師完全版)

【核心任務】 你是一位精通台灣股市與 XQ 全球贏家系統「XScript」的頂尖量化工程師。請嚴格遵守以下所有語法規範、防呆機制與系統底層限制來撰寫程式碼。

▋ 一、變數宣告與基礎語法鐵律

  1. 單一等號原則: XScript 的邏輯等於判斷是單一等號 =,絕對不可使用雙等號 ==

  2. 變數命名規範: 嚴格使用純英文字母與數字(建議駝峰式命名,如 marketCap),絕對不可包含底線 (_) 或其他特殊符號。

  3. 強制事前宣告: 所有自訂變數(包含數值與布林值,如 isUndervalued)都必須在最前方的 var: 區塊中事先宣告並賦予初始值。

  4. 嚴禁污染內建變數: 絕對禁止使用系統預設的 Value1 ~ Value99Condition1 ~ Condition99 作為暫存變數。所有運算節點必須賦予具備商業意義的自訂名稱(如 var: grossMargin(0);),以確保模組化安全。

  5. 避開系統保留字: 變數名稱絕對不可包含 daily, open, high, low, close, volume, date, time 等保留字(請改用 volDay, openPrice 等替代詞)。

▋ 二、財報欄位正名與單位對齊

  1. 精準欄位名稱: 請嚴格使用以下 XQ 系統欄位名稱,不可擅自替換為相似詞:

    • EPS:每股稅後淨利(元) (務必包含「(元)」)

    • 負債:負債總額 (不可寫成總負債)

    • 資產:資產總額 (不可寫成總資產)

    • 內部人籌碼:董監持股佔股本比例 (不可寫成董監持股比例)

  2. 單位數量級防呆: XQ 的 總市值總市值(元) 單位與財報數據的底層單位經常不同。若進行跨欄位運算(如計算股價營收比 P/S 或市值研發比 PRR),務必在運算式中做好單位的數量級對齊(例如除以 100000000 換算為億)。

▋ 三、資料頻率與時間軸陷阱

  1. 營收欄位的頻率變形:

    • 頻率設為 “Y”(年) 或 “Q”(季) 時,必須使用 營收成長率

    • 頻率設為 “M”(月) 時,必須使用 營收年增率

  2. 強制填寫頻率參數: 呼叫財報數據時,務必強制填寫頻率參數,例如 GetField("本益比", "D")。若省略頻率,系統預設會抓日線資料,導致季報/年報讀取崩潰。

  3. 相對時間 [n] 的真實意義: [n] 代表「該頻率的前 n 筆」。GetField("每股稅後淨利(元)", "Y")[1] 代表「去年的年報」,而非昨天的資料。

  4. 跨頻率呼叫方向性限制: 只能由小看大,不能由大看小。腳本的「執行頻率」必須設定為所需的最短時間單位(通常為「日」),再透過頻率參數向上呼叫週/月/季報,不可在季線腳本中呼叫日線籌碼。

  5. K 棒讀取長度陷阱: 若用到 200MA 或「過去 5 年平均 EPS」,腳本開頭必須宣告 SetTotalBar(1250);(5 年約 1260 個交易日)。未宣告足夠長度將導致歷史指標失效且不報錯。

▋ 四、防呆防錯與跨商品機制

  1. 分母為零的致命崩潰 (Divide by Zero): 計算 PEG、利潤率或任何自訂比率時,絕對不可直接相除。必須強制加上防呆邏輯:if 分母 <> 0 then ... else 變數 = 0 (或 999);

  2. 未來函數陷阱 (Look-ahead Bias): 若策略包含回測邏輯,必須確保財報數據已公開。判斷最新財報或營收時,需加入 if Date >= GetFieldDate("月營收", "M") then ... 避免回測績效失真。

  3. 跨商品報價格式: 抓取加權指數或特定商品數據作大盤濾網時,必須使用 GetSymbolField("TSE.TW", "Close", "D"),代碼必須包含交易所後綴 .TW

▋ 五、系統特性與輸出限制

  1. 選股觸發開關: 選股腳本的最後一定要包含 ret = 1;,這是將股票加入選股清單的唯一觸發機制。

  2. 輸出欄位上限: 在選股腳本 (Scanner) 中,介面極限最多只能使用到 OutputField9。若需輸出的指標超過 9 個,請合併相近指標或僅輸出核心分數。

 

由於要寫指標,雷達,選股及自動交易用的語法有些不一樣,也可以分別根據不同目的,在不同的對話裡,準備不同的說明書

 

三,不斷補充這份說明書

請記得如果Gemini寫的程式碼編譯沒有過,記得把正確的寫法告訴它,叫它整理出一份新的避坑大全,這樣您這份文件就會愈來愈完整,未來Gemini也不會犯同樣的錯

 

以上是我使用Gemini寫xscript的初步心得。

XQ+Gemini Text to Code 流程說明

在 AI 狂飆的時代,對投資人來說,最有感、CP 值最高的黑科技是什麼?絕對是 Text to Code(自然語言轉程式碼) 啦!最近收到超多熱情 User 敲碗,想知道怎麼把 AI 腦變成自己的專屬量化工程師。今天就來大解密,手把手帶大家走一遍「XQ + Gemini」的實戰打怪流程!

step1 靈感爆發,召喚 Gemini

有了超棒的選股點子?別悶在心裡!直接對著 Gemini 許願,把你的選股邏輯用白話文說清楚,然後霸氣地下達指令:「請幫我寫成 XScript 選股腳本!」

Step 2:一鍵複製,魔法打包

看著 Gemini 劈哩啪啦生成出熱騰騰的程式碼,是不是很有成就感?這時候只要優雅地按下右上方的「複製」按鈕,把魔法打包帶走。

Step 3:進入 XQ ,貼上神作

打開我們最熟悉的 XQ 操盤軟體,進入 XScript 編輯器,勇敢地開啟一個「新選股檔案」,然後大膽地把剛剛複製的程式碼「貼上」!

Step 4:按下「編譯」,迎接審判!

點擊上方的「編譯」鍵,心跳加速地看一下下方的訊息欄,祈禱它一次過關,顯示「編譯成功」。

Step 5:除錯抓蟲 (Debug) 大作戰

嘿!就算失敗了也別灰心。Gemini 的邏輯通常都是神級的,如果報錯,十之八九是卡在「語法小細節」或「欄位名稱水土不服」上。這時候請點擊右上方的「函數搜尋」,在左邊輸入關鍵字,右邊就會跳出 XQ 的標準用法!

在左方的關鍵字搜尋欄打入欄位的名稱,右邊會有正確的用法,到編輯器去修改成正確的字句,例如這個例子裡,董監持股比例%應該改成董監持股佔股本比例

【老司機踩坑經驗談】: 有時候 Gemini 會自己發明名詞,我們就要動手把「董監持股比例%」改成標準的「董監持股佔股本比例」。 另外還有幾個超級經典的除錯必考題:在 XScript 的世界裡,判斷相等的等號只用單一個 =,絕對不能寫成程式語言常用的 ==!而且財報欄位必須一字不差,例如看到 GetField("每股稅後淨利", "Q"),記得要精準修正為 GetField("每股稅後淨利(元)", "Q")。把這些小毛病改完後再按一次編譯,看到成功的畫面那瞬間,真的會想歡呼!

之後再按編譯,成功了會出現下面的畫面

Step 6:加入選股,準備收網!

在編輯器上方有個加入選股的按鈕,按下去就會看到如下方的畫面

 

大功告成!專屬於你的選股策略正式上線啦!接下來不管是想每日自動執行,還是先跑個深度回測驗證勝率,通通任你差遣。趕快打開 XQ,跟著 Gemini 一起把投資點子變成超強大的量化武器吧!

威廉·歐尼爾

威廉·歐尼爾(William J. O’Neil,1933年3月25日-2023年5月28日)是美國著名的投資大師、證券經紀人與財經作家,被譽為「成長股投資的一代宗師」。他最廣為人知的成就是開發了「CAN SLIM」選股系統,並創辦了全球知名的財經報紙《投資者商報》(Investor’s Business Daily, IBD)。歐尼爾是首位將大數據與電腦分析引入股票研究的先驅,其投資哲學結合了基本面分析與技術面動能,對後世動能投資與趨勢交易者產生了深遠影響。

背景與早年經歷

威廉·歐尼爾出生於美國奧克拉荷馬城,在德州長大。他畢業於南方衛理公會大學(Southern Methodist University),取得商學學士學位,並曾於美國空軍服役。

1958 年,歐尼爾進入海登史東公司(Hayden, Stone & Company)擔任證券經紀人,正式開啟了他的金融職涯。在職業生涯初期,他展現出對數據研究的強烈興趣,他開始觀察那些表現最優異的「飆股」在起漲前具備哪些共同特徵。這段時期的研究奠定了他後來「CAN SLIM」法則的基礎。

職涯發展

1962 年至 1963 年間,歐尼爾憑藉著對克萊斯勒(Chrysler)和辛泰克斯(Syntex)等股票的出色操作,在短短 18 個月內將 5,000 美元的原始資金翻倍成長至 200,000 美元。憑藉這筆資本,他在 1963 年創立了威廉·歐尼爾公司(William O’Neil & Co. Inc.),年僅 30 歲便成為當時紐約證券交易所(NYSE)最年輕的席位擁有者。

歐尼爾也是金融科技的先驅,他在 1960 年代初期就投入大量資金建立電腦化的股票資料庫,為專業機構投資者提供詳細的圖表與數據分析服務。1984 年,他為了與《華爾街日報》競爭,創辦了《投資者商報》(Investor’s Daily,後更名為 Investor’s Business Daily),旨在將專業級的數據與「CAN SLIM」研究方法普及給一般散戶投資者。

投資風格概述

歐尼爾的投資風格被歸類為「成長股動能投資」。他並不認同傳統價值投資中「買低賣高」或「尋找低本益比股票」的作法。相反地,他主張「買高賣更高」,尋找那些具備強勁盈餘成長、創新產品或服務,且股價已經突破底部盤整區間的領導股。

其核心理念「CAN SLIM」分別代表了七大選股準則:

  • C (Current Earnings):當季每股盈餘大幅成長。
  • A (Annual Earnings):年度盈餘穩定增長。
  • N (New Product/Management/Highs):新產品、新管理層或股價創下新高。
  • S (Supply and Demand):股票的供給與需求。
  • L (Leader or Laggard):選擇產業領導股而非落後股。
  • I (Institutional Sponsorship):有機構法人支持。
  • M (Market Direction):判斷市場大盤趨勢。

最為人稱道的事蹟

歐尼爾最著名的著作《笑傲股市》(How to Make Money in Stocks)自 1988 年出版以來,在全球銷售超過 200 萬冊,被視為投資界的經典教科書。書中詳細介紹了「杯狀帶柄」(Cup and Handle)形態,這是一種他在研究了數十年飆股走勢後總結出的經典技術分析圖型,至今仍被無數技術分析者沿用。

此外,他對風險管理的堅持也極具代表性。他嚴格執行「7%至8%自動停損」規則,強調投資者應在損失擴大之前果斷認賠,以保護本金並等待下一次重擊的機會。

影響力與地位

威廉·歐尼爾在華爾街被視為將「量化研究」與「技術圖表」結合的奠基者。他打破了散戶與機構投資者之間的資訊不對稱,透過《投資者商報》提供的 RS 評等(相對強度評等)等工具,讓個人投資者也能運用專業級的選股邏輯。

他的弟子與受其影響的投資人無數,其中包括多次奪得美國投資大賽冠軍的大衛·瑞安(David Ryan)以及知名投資家馬克·米奈爾維尼(Mark Minervini)。歐尼爾於 2023 年以 90 歲高齡辭世,但他留下的 CAN SLIM 系統與對成長股的研究方法,依然是現代趨勢跟隨與動能交易的核心支柱。

我把CANSLIM的作法請Gemine寫成一個選股策略,它給的腳本如下

// 策略名稱:William O'Neil CAN SLIM 成長動能選股
// 策略類型:成長股/動能突破/基本面與技術面混合

SetTotalBar(260); // 確保有足夠的 K 棒計算 200 日均線、52 週高點與年度財報

var:
idxClose(0), idxMa50(0), isMarketBullish(false),
epsCurrQ(0), epsPastQ(0), epsYoY(0),
salesCurrQ(0), salesPastQ(0), salesYoY(0),
epsCurrY(0), epsPast3Y(0), epsCagr3Y(0),
roe(0),
high252(0), isNearNewHigh(false),
avgVol50(0), isVolumeSurge(false),
ma10(0), ma50(0), ma200(0), isLeader(false),
instHoldCurr(0), instHoldPast(0), isInstBuying(false);

// ==========================================
// M: 市場方向 (Market Direction)
// ==========================================
// 歐尼爾鐵律:只在確認的上升趨勢中買進股票。以大盤站上 50MA 為基礎濾網。
idxClose = GetSymbolField("TSE.TW", "收盤價", "D");
idxMa50 = Average(idxClose, 50);

if idxClose > idxMa50 then
isMarketBullish = true
else
isMarketBullish = false;

condition1 = isMarketBullish = true;

// ==========================================
// C: 當季盈餘與營收 (Current Earnings)
// ==========================================
// 當季 EPS YoY >= 20%,且營收 YoY >= 25% (確保獲利來自本業高速擴張)
epsCurrQ = GetField("每股稅後淨利(元)", "Q");
epsPastQ = GetField("每股稅後淨利(元)", "Q")[4];

if epsPastQ > 0 then
epsYoY = (epsCurrQ - epsPastQ) / epsPastQ * 100
else
epsYoY = 0;

salesCurrQ = GetField("營業收入淨額", "Q");
salesPastQ = GetField("營業收入淨額", "Q")[4];

if salesPastQ > 0 then
salesYoY = (salesCurrQ - salesPastQ) / salesPastQ * 100
else
salesYoY = 0;

condition2 = epsYoY >= 20.0 and salesYoY >= 25.0;

// ==========================================
// A: 年度盈餘 (Annual Earnings)
// ==========================================
// 過去 3 年 EPS CAGR >= 25% (此處以簡單年化代替),且 ROE >= 17%
epsCurrY = GetField("每股稅後淨利(元)", "Y");
epsPast3Y = GetField("每股稅後淨利(元)", "Y")[3];

if epsPast3Y > 0 then
epsCagr3Y = ((epsCurrY - epsPast3Y) / epsPast3Y) * 100 / 3
else
epsCagr3Y = 0;

roe = GetField("股東權益報酬率", "Y");

condition3 = epsCagr3Y >= 25.0 and roe >= 17.0;

// ==========================================
// N: 新高價 (New Highs)
// ==========================================
// 股價位於 52 週新高的 15% 範圍內 (蓄勢待發的樞紐點附近)
high252 = Highest(High[1], 252);

if Close >= (high252 * 0.85) then
isNearNewHigh = true
else
isNearNewHigh = false;

condition4 = isNearNewHigh = true;

// ==========================================
// S: 供給與需求 (Supply and Demand)
// ==========================================
// 突破時成交量需高於 50 日均量的 40% (即 1.4 倍),並加上基本流動性過濾
avgVol50 = Average(Volume[1], 50);

if Volume > (avgVol50 * 1.4) then
isVolumeSurge = true
else
isVolumeSurge = false;

condition5 = isVolumeSurge = true and avgVol50 > 1000;

// ==========================================
// L: 領導股 (Leader)
// ==========================================
// 股價必須站上 10日、50日及 200日均線,呈現完美的強勢多頭排列
ma10 = Average(Close, 10);
ma50 = Average(Close, 50);
ma200 = Average(Close, 200);

if Close > ma10 and Close > ma50 and Close > ma200 then
isLeader = true
else
isLeader = false;

condition6 = isLeader = true;

// ==========================================
// I: 機構認同度 (Institutional Sponsorship)
// ==========================================
// 投信近 20 日持股比例呈現上升趨勢,確認有 Smart Money 正在進場護航
instHoldCurr = GetField("投信持股比例", "D");
instHoldPast = GetField("投信持股比例", "D")[20];

if instHoldCurr > instHoldPast then
isInstBuying = true
else
isInstBuying = false;

condition7 = isInstBuying = true;

// ==========================================
// 綜合篩選與輸出
// ==========================================
if condition1 and condition2 and condition3 and condition4 and condition5 and condition6 and condition7 then
begin
ret = 1;
// 輸出欄位供選股後檢視與排序
outputfield1(epsYoY, "單季EPS YoY(%)");
outputfield2(salesYoY, "單季營收 YoY(%)");
outputfield3(roe, "ROE(%)");
end;

我拿這個腳本去回測,發現績效蠻好的,勝率也蠻高的

缺點是訊號少,如果踩到雷,不停損 ,虧起來還蠻慘的

加了8%停損後,績效依然不錯,但MDD就回到20%以內了

列出去年這個策略符合條件的交易標的如下

理查·德里豪斯的動能投資之道

從芝加哥中產家庭到動能投資之父

理查·德里豪斯(Richard Herman Driehaus,1942-2021),出生於芝加哥一個中產階級家庭,父親從事機械工程。他從小就展現對金融市場的濃厚興趣——13歲起便開始閱讀報紙財經版,並用零用錢購買人生第一支股票。1965年取得德保羅大學商學學士學位,1970年獲得MBA學位。1960年代起在A.G. Becker等券商擔任機構研究員,累積了深厚的產業研究基礎。他在傳統價值投資思維盛行的年代,獨排眾議地發展出一套以股價動能和盈餘驚喜為核心的成長型投資方法論,最終創立德里豪斯資本管理公司,成為動能投資領域的開山鼻祖。

年化30%報酬率的動能投資傳奇

德里豪斯被《巴倫周刊》評選為過去100年對基金業最具影響力的25位人物之一,這一殊榮足以說明他在投資界的崇高地位。他所創立的德里豪斯資本管理公司,在成立後的前12年創造了年化複合報酬率約30%的驚人績效。到2021年他逝世時,公司管理的資產規模已超過130億美元。除了投資領域的卓越成就,德里豪斯還是一位文化藝術的推動者——他在2003年設立了「德里豪斯建築獎」,專門表彰對古典建築有傑出貢獻的人士,該獎項的地位足以與普立茲克建築獎並駕齊驅。

買高賣更高的逆傳統投資思維

德里豪斯的投資理念與傳統價值投資截然不同。他主張:與其買入股價已經跌至低點的公司,不如買入股價正在創新高、盈餘成長強勁的公司。他的核心投資邏輯建立在三個關鍵要素之上:第一,極度看重「盈餘驚喜」(Earnings Surprise),當公司公布的盈餘大幅超越市場預期時,往往是股價加速上漲的起點;第二,不畏懼高本益比,只要成長速度能夠超越估值水平,高本益比就是合理的;第三,追隨市場心理與股價趨勢,相信價格本身包含了豐富的資訊。他的方法被後世稱為「動能投資」的經典範式。

XScript 台股選股策略:盈餘驚喜動能模型

將德里豪斯的動能投資邏輯轉化為台股選股策略,核心在於捕捉「盈餘超預期且股價動能強勁」的個股:

一、盈餘驚喜:最近一季EPS超越前一季或去年同期20%以上,代表公司營運出現顯著改善。
二、營收動能:近三個月營收年增率持續為正且逐月加速,確認成長趨勢正在強化。
三、股價趨勢:股價站上所有短中長期均線(5日、20日、60日均線多頭排列),且近20日曾創下52週新高。
四、相對強度:近三個月股價漲幅排名市場前20%,確認為市場中的領先者。
五、成交量確認:近5日平均成交量較前20日平均成交量放大50%以上,代表市場資金正在積極追捧。
六、停損紀律:設定買入價格下方8%為停損點,嚴格執行風險控管。根據這些邏輯,我試著寫出一個相對應的選股策略腳本

// 腳本名稱:Driehaus 盈餘驚喜動能模型
// 資料頻率:日 (結合季/月財報)

// ================= 第一階段:全市場相對強度排序 =================
// 條件四:近三個月股價漲幅排名市場前20%
rank RS_Rank begin
// 計算近 60 日 (約三個月) 的價格漲幅
retval = RateOfChange(Close, 60);
end;

// ================= 第二階段:個股條件篩選 =================

// --- 條件一:盈餘驚喜 (EPS超越前一季或去年同期20%以上) ---
var: eps_q0(0), eps_q1(0), eps_q4(0);

eps_q0 = GetField("每股稅後淨利(元)", "Q");
eps_q1 = GetField("每股稅後淨利(元)", "Q")[1];
eps_q4 = GetField("每股稅後淨利(元)", "Q")[4];

condition1 = false;
if eps_q0 > 0 then begin
if (eps_q1 > 0 and (eps_q0 - eps_q1) / eps_q1 >= 0.2) or 
(eps_q4 > 0 and (eps_q0 - eps_q4) / eps_q4 >= 0.2) then 
condition1 = true;
end;

// --- 條件二:營收動能 (近三個月營收年增率持續為正且逐月加速) ---
var: rev_yoy_0(0), rev_yoy_1(0), rev_yoy_2(0);
rev_yoy_0 = GetField("月營收年增率", "M");
rev_yoy_1 = GetField("月營收年增率", "M")[1];
rev_yoy_2 = GetField("月營收年增率", "M")[2];

condition2 = (rev_yoy_0 > rev_yoy_1) and (rev_yoy_1 > rev_yoy_2) and (rev_yoy_2 > 0);

// --- 條件三:股價趨勢 (均線多頭排列,且近20日曾創下52週新高) ---
var: ma5(0), ma20(0), ma60(0);
var: is_bull_aligned(false), is_new_high(false);

ma5 = Average(Close, 5);
ma20 = Average(Close, 20);
ma60 = Average(Close, 60);
is_bull_aligned = (Close > ma5) and (ma5 > ma20) and (ma20 > ma60);

// 52週新高約等於 250 個交易日最高價
if Highest(High, 20) = Highest(High, 250) then is_new_high = true;

condition3 = is_bull_aligned and is_new_high;

// --- 條件四:相對強度 (市場前20%) ---
// 假設台股具流動性的上市櫃股票約 1700 檔,前 20% 大約是排名前 340 名
condition4 = RS_Rank.pos <= 340;

// --- 條件五:成交量確認 (近5日均量較前20日放大50%以上) ---
var: vol5(0), vol20(0);
vol5 = Average(Volume, 5);
vol20 = Average(Volume, 20);

condition5 = vol5 >= (vol20 * 1.5) and vol20 > 500; // 加入 >500 張避免冷門股雜訊

// ================= 綜合輸出 =================
if condition1 and condition2 and condition3 and condition4 and condition5 then begin
ret = 1;

// 輸出動能與基本面指標供介面排序觀察
outputField1(RS_Rank.pos, "三個月漲幅排名");
outputField2(eps_q0, "最新單季EPS");
outputField3(rev_yoy_0, "近月營收YoY(%)");
outputField4(vol5, "5日均量");
end;

 

此策略忠實還原德里豪斯「買高賣更高」的動能投資精神,在台股中尋找盈餘成長加速、股價創新高且量能充沛的強勢飆股。把這腳本回測過去12年,持有60天,回測報告如下圖

如果只持有30天,時間加權報酬更高達3031%,顯示追求這種強勢股的報酬率真的是一條可以走的道路

 

德懷特·安德森~景氣循環股之王

德懷特·安德森(Dwight W. Anderson)簡介

德懷特·安德森是一位美國資深的避險基金經理人,以對基礎工業、大宗商品與農業領域的深厚研究而聞名 。他目前擔任 Ospraie Management, LLC 的創辦人暨執行長 。安德森擁有普林斯頓大學歷史學學士學位,隨後取得了北卡羅來納大學教堂山分校的工商管理碩士(MBA)學位 。他的職涯起點極具傳奇色彩,曾在朱利安·羅伯遜的「老虎管理」擔任基礎工業與原物料投資小組負責人,是業界著名的「老虎子弟兵」之一 。離開老虎管理後,他加入了另一位宏觀大師保羅·圖多·瓊斯的圖多投資公司,擔任董事總經理並領導基礎工業團隊

 

投資成績

安德森在圖多投資的支持下,於 1999 年正式創立了 Ospraie Management 。憑藉著對宏觀經濟與原物料週期的敏銳嗅覺,他成功捕捉到了 2000 年代初期的全球大宗商品超級循環 。隨著原物料市場的爆發,Ospraie 的管理規模迅速擴張,在 2008 年的巔峰時期,該基金管理了超過 90 億美元的資產 。這項驚人的成績,使 Ospraie 成為當時全球規模最大的原物料避險基金之一,也確立了安德森在原物料投資領域的大神地位

 

核心投資邏輯與策略

安德森的投資邏輯深受「老虎管理」的影響,強調由宏觀供需失衡驅動的「主題式」投資,並嚴格搭配微觀的企業基本面分析 。他的策略可以拆解為以下幾個核心維度:

資本週期與供應面限制:他偏好尋找過去 3 到 5 年資本支出呈現下降趨勢的產業(如採礦、能源) 。當產業的總資本支出年增率小於 0% 持續兩年以上,或是企業的資本支出小於折舊時,代表產業投資不足,這最終將導致供應短缺並推升商品價格

大宗商品價格動能確認:為了避免買入「價值陷阱」,目標個股底層對應的大宗商品期貨價格必須處於上升趨勢,例如價格站上 200 日移動平均線,或 12 個月動能大於 0

庫存與微觀基本面篩選:在宏觀上看好全球庫存消費比低於歷史平均的商品 。在微觀選股上,只挑選現金成本位於產業前 25%、EV/EBITDA 低於產業中位數,且負債權益比低於產業平均的公司,確保企業財務體質能撐過週期底部

嚴格的出場與風險管理:面對高波動的原物料市場,若商品價格跌破 200 日均線且維持 5 個交易日,或期貨曲線從現貨溢價轉為期貨溢價,即視為趨勢反轉 。此外,單一部位若虧損達 15% 至 20%,或最大回撤超過 3 倍 ATR,便會觸發硬性停損

我用他的邏輯,簡單的寫了一個景氣循環股的篩選腳本

// 策略名稱:安德森資本週期與基本面選股策略
// 說明:專為 XQ 平台設計,篩選資本支出受限、資產負債表強健且具備長線價格動能的標的。

// 條件 1:資本週期與供應面限制 (Capex/Depreciation < 1.0)
// 邏輯:資本支出 愈來愈小,代表企業擴產停滯,長期有助於供給收縮

value1 = GetField("資本支出金額", "Y");

condition1 = GetField("資本支出金額", "Y") <GetField("資本支出金額", "Y")[1]
and GetField("資本支出金額", "Y")[1]<GetField("資本支出金額", "Y")[2];

// 條件 2:微觀基本面防禦力 (負債比率較低)
// 邏輯:確保公司資產負債表強健,能撐過週期底部 (此處以負債比率小於同業或絕對值 50% 為例)
value3 = GetField("負債比率", "Q");
condition2 = value3 < 50;

// 條件 3:價格動能確認 (避免價值陷阱)
// 邏輯:股價需站上 200 日移動平均線,作為商品/個股動能轉強的確認指標
value4 = Average(Close, 200);
condition3 = Close > value4;

// 綜合判斷與選股輸出
if condition1 and condition2 and condition3 then 
begin
ret = 1;
// 輸出輔助資訊,方便後續在選股戰情室或儀表板中進行排序與多因子權重評估

outputField1(value3, "負債比率(%)");
end;

建議在 XQ 平台執行此腳本時,將選股範圍鎖定在「原物料」、「能源」或「塑化」等景氣循環相關產業。

Foster Friess的動態的評分系統(Scoring System)。

佛斯特·史蒂芬·弗里士(Foster Stephen Friess,1940年4月2日-2021年5月27日)是美國著名的投資管理專家、共同基金經理人與慈善家。他以創立 Friess Associates 投資公司及其旗下的旗艦產品「白蘭地基金」(Brandywine Fund)聞名於世。在 1990 年代,弗里士被視為成長股投資(Growth Investing)的領軍人物,1999 年《CNBC》譽其為「世紀偉大投資者」之一。

弗里士最輝煌的紀錄在於白蘭地基金的長期績效。自 1985 年成立至 2000 年代初期,該基金的平均年化報酬率接近 20%。據報導,如果在該基金成立之初投入 1 萬美元,到 2000 年時,該筆資產將成長至超過 27 萬美元,遠遠跑贏同期的標準普爾 500 指數。

他在 2001 年《商業週刊》(BusinessWeek)的採訪中被評為「生存最久的成長股選股大師」,因為他在長達 36 年的投資生涯中(截至當時),成功帶領投資者度過多次市場牛熊轉換,且始終能保持卓越的獲利水準。

 

他最核心的選股邏輯是尋找「盈餘增長速度高於預期」的公司。弗里士深信,股價最終會反映企業的獲利能力,因此他的研究團隊會極致地追蹤企業的每季盈餘。他不僅看本益比(P/E ratio),更重視盈餘成長率與估值的對等關係。

他最有名的操作手法是”Stick with them until you find something better” (替換原則):建立一個動態的評分系統(Scoring System),然後根據這個系統,汰弱留強。

Friess 的核心思想是「永遠保持投資組合處於最強狀態」。他不看絕對估值,而是把持股當作球隊陣容,只要板凳區有表現更好的球員(分數更高的股票),就毫不猶豫地換人。

我根據他的精神,寫了一個適合台股的動態評分系統,分數的比重如下

腳本如下

// 腳本名稱:Friess 動態替換多因子模型 (全市場排行)
// 資料頻率:日

rank FriessScore begin
// ================= 0. 基本流動性過濾 =================
// 排除股價低於10元或近5日均量低於500張的冷門股,避免籌碼分數失真
if Average(Volume, 5) < 500 or Close < 10 then 
retval = 0 
else begin
var: score1(0), score2(0), score3(0), score4(0);

// ================= 因子1:營收驚喜 (權重 40%) =================
// 邏輯:本月營收年增率,減去「過去6個月平均年增率」
var: rev_yoy(0), rev_avg(0), surprise(0);
rev_yoy = GetField("月營收年增率", "M");
rev_avg = Average(GetField("月營收年增率", "M")[1], 6);
surprise = rev_yoy - rev_avg;

// 正規化:大於等於 50% 拿滿分 100,小於等於 0 拿 0 分
if surprise >= 50 then score1 = 100
else if surprise <= 0 then score1 = 0
else score1 = surprise * 2;

// ================= 因子2:盈餘成長 (權重 30%) =================
// 邏輯:單季稅後淨利年增率
var: earn_yoy(0);
earn_yoy = GetField("稅後淨利成長率", "Q");

// 正規化:大於等於 100% 拿滿分 100,小於等於 0 拿 0 分
if earn_yoy >= 100 then score2 = 100
else if earn_yoy <= 0 then score2 = 0
else score2 = earn_yoy;

// ================= 因子3:法人籌碼動能 (權重 20%) =================
// 邏輯:近 5 日 (外資買賣超 + 投信買賣超) 佔總成交量的比例
var: inst_net(0), vol_sum(0), inst_ratio(0);
inst_net = Summation(GetField("外資買賣超", "D") + GetField("投信買賣超", "D"), 5);
vol_sum = Summation(Volume, 5);

if vol_sum > 0 then inst_ratio = (inst_net / vol_sum) * 100 else inst_ratio = 0;

// 正規化:買超佔總量大於等於 10% 拿滿分 100,賣超或沒買拿 0 分
if inst_ratio >= 10 then score3 = 100
else if inst_ratio <= 0 then score3 = 0
else score3 = inst_ratio * 10;

// ================= 因子4:價格動能 (權重 10%) =================
// 邏輯:近 20 日 (約一個月) 漲跌幅
var: mom(0);
mom = RateOfChange(Close, 20);

// 正規化:月漲幅大於等於 30% 拿滿分 100,下跌拿 0 分
if mom >= 30 then score4 = 100
else if mom <= 0 then score4 = 0
else score4 = mom * 3.33;

// ================= 計算加權總分 =================
retval = (score1 * 0.4) + (score2 * 0.3) + (score3 * 0.2) + (score4 * 0.1);
end;
end;

// ================= 主執行區:篩選與輸出 =================
// 找出全市場多因子綜合評分前 50 名的股票 (作為動態替換的「板凳候選人」)
if FriessScore.pos <= 50 and FriessScore.value > 0 then begin
ret = 1;
outputField1(FriessScore.pos, " Friess 排名");
outputField2(FriessScore.value, " 綜合總分");

// 輸出原始數據,方便在 XQ 介面直接肉眼驗證各因子的強度
outputField3(GetField("月營收年增率", "M") - Average(GetField("月營收年增率", "M")[1], 6), "營收驚喜(%)");
outputField4(GetField("稅後淨利成長率", "Q"), "淨利 YoY(%)");

// 計算並輸出法人買超佔比
var: out_inst_net(0), out_vol(0);
out_inst_net = Summation(GetField("外資買賣超", "D") + GetField("投信買賣超", "D"), 5);
out_vol = Summation(Volume, 5);
if out_vol > 0 then 
outputField5((out_inst_net / out_vol) * 100, "法人買佔比(%)") 
else 
outputField5(0, "法人買佔比(%)");
end;

我拿這個腳本去回測所有普通股,因為主要是靠月營收來衡量業績是否超過市場預期,所以持有期間設為22天,然後投資組合設為50檔,這樣回測的結果如下圖

 

雖然組合的勝率不到50%,但整個投資組合過去12年來的時間加權平均報酬率是692%,比大盤的269%要好,也比0050的668%要好