組到自定義指標(biāo)的核心避坑指南)
簡介《MT4的MQL4編程入門》是一份面向外匯交易初學(xué)者和編程零基礎(chǔ)用戶的MQL4語言入門教程基于韜客外匯論壇經(jīng)典入門系列整理而成。教程系統(tǒng)講解從自定義變量到函數(shù)的完整語法包括int、double、string、bool四種基本類型extern附加變量用于設(shè)置可調(diào)參數(shù)自定義函數(shù)支持有返回值類型與void無返回值類型數(shù)組則用于批量處理同類數(shù)據(jù)同時結(jié)合MT4平臺演示如何編寫交易策略、自定義指標(biāo)和EA自動化程序覆蓋市場數(shù)據(jù)取值等后續(xù)進階內(nèi)容。資源為DOC文檔共1個文件壓縮包約197KB內(nèi)容精煉、結(jié)構(gòu)清晰適合隨時翻閱。目前已有389人瀏覽學(xué)習(xí)。通過該教程零基礎(chǔ)讀者可快速掌握MQL4的核心編程邏輯理解變量作用域、函數(shù)調(diào)用與數(shù)組引用規(guī)則并逐步構(gòu)建個人交易策略的自動執(zhí)行腳本提升交易效率與自動化水平。1. MT4 MQL4 編程入門先看懂語言再談策略落地很多人拿到 MT4 之后的第一反應(yīng)是找現(xiàn)成的 EA 和指標(biāo)源碼復(fù)制進去編譯然后面對一堆紅色報錯只能干瞪眼。這套《MT4 的 MQL4 編程入門》教程不教你預(yù)測行情也不承諾一鍵生成策略它做的事情很樸素把 MQL4 這門語言的骨架拆開——變量與類型、extern 參數(shù)、函數(shù)與數(shù)組、市場數(shù)據(jù)取值、指標(biāo)結(jié)構(gòu)與循環(huán)判斷每一節(jié)都帶著能直接編譯的小例子。它適合剛?cè)腴T的交易者也適合會一點 C 但沒碰過 MQL4 的程序員??赐昴隳茏x懂別人指標(biāo)源碼的八成邏輯能改參數(shù)、能畫第一條指標(biāo)線也知道出了問題該去哪里查而不是把 MT4 當(dāng)黑匣子瞎猜。2. 變量、extern 與函數(shù)先立起 MQL4 的語法骨架2.1 四種基礎(chǔ)類型與“先定義后使用”規(guī)則MQL4 不是腳本語言它和 C 很像所有要用的數(shù)據(jù)都必須在使用前聲明類型和名稱。教程里那句“自定義變量在使用前必須創(chuàng)建”翻譯過來就是編譯器要提前知道這個變量占多大空間、用什么方式解釋它。拿int mark;舉例int 是類型定義詞mark 是變量名這條語句告訴編譯器“給我一個用來存整數(shù)的盒子名字叫 mark”。四種基本類型我列了一張表方便對照類型含義典型用途int整型包括負整數(shù)循環(huán)計數(shù)、指標(biāo)周期參數(shù)double雙精度小數(shù)價格、指標(biāo)計算值string字符串指標(biāo)名、郵件內(nèi)容、注釋bool邏輯型 true/false開關(guān)參數(shù)、報警狀態(tài)標(biāo)記聲明時可以直接賦初值比如bool 是否報警 true;、string 說明 測試;。這里有一個 MQL4 的特別之處變量名可以用中文這在老牌編程語言里不多見。不過中文變量名參與字符串拼接時要注意編碼教程示例本身沒毛病但如果源碼從網(wǎng)頁直接復(fù)制粘貼偶爾會出現(xiàn)中文名亂碼導(dǎo)致編譯失敗。我一般遇到這種現(xiàn)象先把源碼另存為 UTF-8 編碼再重新編譯大多數(shù)情況下就過去了。類型定義詞只在創(chuàng)建變量時用一次。創(chuàng)建之后給變量賦值直接寫變量名mark 5;。新手最常見的編譯錯誤就是賦值時順手又寫了一遍int mark 5;這在 MQL4 里屬于重復(fù)定義直接報錯。記住這個原則int、double 這類關(guān)鍵字只在變量第一次出現(xiàn)的時候?qū)懞竺嬖俪霈F(xiàn)就是錯的。2.2 extern 附加變量把參數(shù)交到用戶手里的入口extern 是 MQL4 里最值得先記住的關(guān)鍵字。一個變量聲明前面加上 extern它就會出現(xiàn)在 MT4 加載指標(biāo)或 EA 時的“輸入?yún)?shù)”面板里用戶不用打開源碼就能改數(shù)值。MACD(12,26,9) 這種括號參數(shù)本質(zhì)就是三個 extern 變量的默認值。extern int 周期 9; extern double 止損點數(shù) 30.0; extern bool 是否開啟報警 true;第一個 extern 聲明了整型變量 周期默認 9用戶在輸入?yún)?shù)面板里把它改成 20指標(biāo)內(nèi)部所有用 周期 的地方就自動換成 20。第二個是雙精度型適合放點數(shù)、金額這類帶小數(shù)參數(shù)。第三個是邏輯型適合做開關(guān)。這里要提一個默認值的坑extern 變量的默認值直接影響用戶第一次加載時的行為很多人策略翻車不是邏輯寫錯而是默認參數(shù)本身不合理。我一般會把默認值設(shè)置成能在當(dāng)前周期畫出正常圖形的值而不是隨手寫一個整數(shù)。extern 還有兩個使用邊界它只能修飾全局變量不能放在 start() 函數(shù)或自定義函數(shù)內(nèi)部否則編譯不通過命名不要用 MQL4 保留字比如 int、double、start 這些都不能作為變量名。另外extern 變量在程序運行中改動后不會立即生效需要重新加載指標(biāo)或 EA 才會按新參數(shù)計算調(diào)試時要記得這一步。2.3 自定義函數(shù)參數(shù)傳遞、返回值和局部變量的生命周期函數(shù)的意義是把一段反復(fù)用到的運算打包。教程里那個 ft(x,y)3x2y 的例子非常典型寫成 MQL4 就是int ft(int x, int y) { int temp; temp 3 * x 2 * y; return(temp); } void 顯示提示(string 文本) { Comment(文本); }邏輯說明函數(shù)頭的 int 是函數(shù)類型表示這個函數(shù)返回整數(shù)函數(shù)名后面的括號里是參數(shù)表x 和 y 在使用前也必須聲明類型所以寫成 int x, int y大括號里是函數(shù)體temp 是函數(shù)內(nèi)部定義的局部變量return(temp) 把 temp 的值帶回調(diào)用處。調(diào)用時寫 ft(4,5)程序按順序把 4 傳給 x、5 傳給 y函數(shù)計算返回 23調(diào)用點拿到這個值繼續(xù)往下執(zhí)行。void 類型是 MQL4 里第二常見的函數(shù)類型它沒有 return 值函數(shù)體執(zhí)行完就結(jié)束。像 顯示提示 這種只負責(zé)在圖表左上角輸出文本的函數(shù)用 void 最合適。判斷什么時候用 int、double 還是 void核心看調(diào)用方是否需要這個函數(shù)算出一個結(jié)果來參與后續(xù)計算。局部變量的生命周期值得多說一句ft 函數(shù)里的 x、y、temp 都在函數(shù)被調(diào)用時才創(chuàng)建函數(shù)執(zhí)行結(jié)束立刻注銷。這就帶來一個實際問題——如果你需要一個變量記錄“上一次報警發(fā)生在什么時候”放在函數(shù)內(nèi)部每次調(diào)用都會重置。解決方法是把這種狀態(tài)變量放到函數(shù)外面定義成全局變量或者在聲明時加 static 關(guān)鍵字讓它在多次調(diào)用之間保留值。這算是 MQL4 新手從函數(shù)語法過渡到實際指標(biāo)編程的一道小坎。2.4 數(shù)組與下標(biāo)一次只能操作一個元素數(shù)組在 MQL4 里是一組同類型變量的集合。int aa[4] {4,3,2,1};聲明了一個長度 4 的整型數(shù)組方括號里的數(shù)字是下標(biāo)。數(shù)組下標(biāo)從 0 開始也就是說 aa[0] 的值是 4aa[1] 是 3aa[2] 是 2aa[3] 是 1。這個“第 0 個元素”的規(guī)則和日常計數(shù)習(xí)慣沖突新手第一次遍歷數(shù)組時經(jīng)常越界下標(biāo)寫成 4 去訪問 aa[4] 就直接報 array out of range。int aa[4] {4,3,2,1}; // 長度為 4aa[0]4 ... aa[3]1 double buf[]; // 不定長數(shù)組后面綁定指標(biāo)緩沖 int cc[8]; // 定長數(shù)組8 個元素未賦初值數(shù)組最容易被忽略的一點定義之后一次只能通過下標(biāo)訪問一個元素不能像某些語言那樣整體賦值或整體比較。要處理整列數(shù)據(jù)就寫循環(huán)逐個操作。MQL4 里的動態(tài)數(shù)組不定長數(shù)組有一個常見陷阱int bb[];這種聲明在普通場景下直接寫 bb[0]1 會在運行時越界報錯因為編譯器沒有給這個數(shù)組分配實際容量。我常用的做法是先用ArrayResize(bb, 數(shù)量)明確容量再按下標(biāo)寫入。指標(biāo)緩沖數(shù)組是例外它由 SetIndexBuffer 在初始化函數(shù)里綁定容量由 MT4 內(nèi)部管理這個后面會講到。3. 市場數(shù)據(jù)與指標(biāo)取值搞懂 Open[] 和 iMA 的參數(shù)習(xí)慣3.1 預(yù)定義數(shù)組記住 0 是最新一根 K 線MT4 把每根 K 線的開、高、低、收、成交量、時間分別做成了可以直接使用的數(shù)組Open[]、High[]、Low[]、Close[]、Volume[]、Time[]。這些數(shù)組的下標(biāo)代表 K 線位置方向跟多數(shù)人的直覺相反0 是當(dāng)前最新一根1 是它左邊那一根2 再往左i 表示第 i1 根。我之前帶人寫第一個指標(biāo)時十個人里有八個把方向?qū)懛醋詈螽嫵鰜淼木€整體平移了一根 K 線。double 最新收盤 Close[0]; double 前一根最高 High[1]; double 倒數(shù)第三根開盤 Open[2]; int 柱總數(shù) Bars;Close[0] 是最新收盤價High[1] 是前一根最高價Bars 是當(dāng)前圖表的總柱數(shù)。這些預(yù)定義數(shù)組只屬于當(dāng)前圖表——也就是說它們在哪個貨幣對、哪個周期加載取的就是那個圖表的數(shù)據(jù)。想要讀別的周期就得用帶 i 前綴的函數(shù)見 3.2。除了這些數(shù)組還有幾個預(yù)定義變量要順手記住Ask 和 Bid 是當(dāng)前實時賣價和買價double 型Digits 是當(dāng)前品種的小數(shù)位數(shù)無日元幣對一般是 4有日元的是 2Point 是點值和 Digits 對應(yīng)寫止損止盈計算時離不開它們。有一個使用上的陷阱當(dāng)軟件剛連接行情、歷史數(shù)據(jù)還沒有完全加載時Close[0] 這類值可能是 0 或者無效數(shù)據(jù)。如果在指標(biāo)初始化階段就讀取這些數(shù)組做判斷偶爾會得到錯誤結(jié)論。我的習(xí)慣是在 start() 里先檢查 Bars等柱數(shù)足夠后再開始計算避免把無效值寫進指標(biāo)線。3.2 跨周期取數(shù)iOpen、iClose 系列與周期常量預(yù)定義數(shù)組只能看當(dāng)前圖表數(shù)據(jù)但實際策略經(jīng)常需要“大周期定方向、小周期找進場”。這時候要用 iOpen(symbol, timeframe, shift) 這一系列函數(shù)。它們的參數(shù)結(jié)構(gòu)完全一致第一個參數(shù)是品種字符串第二個是 K 線周期常量第三個是位置序號。周期常量對應(yīng)關(guān)系如下常量周期PERIOD_M11 分鐘PERIOD_M55 分鐘PERIOD_M1515 分鐘PERIOD_M3030 分鐘PERIOD_H11 小時PERIOD_H44 小時PERIOD_D1日線PERIOD_W1周線PERIOD_MN1月線double 指定品種小時最新開盤 iOpen(USDJPY, PERIOD_H1, 0); double 當(dāng)前周期最新收盤 iClose(NULL, 0, 0); double 當(dāng)前圖表第3根收盤 iClose(NULL, 0, 2);第一行表示某貨幣對 1 小時圖最新一根開盤價。第二行是“不指定品種也不指定周期”NULL 表示跟隨當(dāng)前圖表品種0 表示當(dāng)前圖表周期常用于寫通用指標(biāo)。第三行的 2 是位置序號注意這里 2 表示從右往左第 3 根。位置序號和預(yù)定義數(shù)組的下標(biāo)是同一個坐標(biāo)系這樣設(shè)計的好處是一個指標(biāo)里混用 Close[0] 和 iClose(NULL,0,0)結(jié)果完全一致不會出現(xiàn)偏移。用 NULL 有個副作用要心里有數(shù)它跟隨當(dāng)前圖表圖表切到別的品種或周期取值跟著變。寫通用指標(biāo)是優(yōu)點寫固定品種策略時反而要小心最好顯式指定品種字符串。iHigh、iLow、iVolume、iTime 系列與 iOpen 完全同構(gòu)參數(shù)含義一致區(qū)別只在 iTime 返回的是 datetime 類型其他返回 double。3.3 iMA 移動平均線七個參數(shù)錯一個就不是你想要的線均線是 MQL4 里調(diào)用頻率最高的指標(biāo)函數(shù)iMA 一共有七個參數(shù)也是新手最容易記混的一組。完整形式是double maValue iMA(symbol, timeframe, period, ma_shift, ma_method, applied_price, shift);參數(shù)依次是品種、周期、均線周期、均線偏移、平均模式、價格種類、位置。舉例double ma20 iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0); double ema20_3根前 iMA(NULL, 0, 20, 0, MODE_EMA, PRICE_CLOSE, 2);第一行取當(dāng)前圖表 20 周期簡單移動平均線在最新位置的值。第二行取 20 周期指數(shù)移動平均線在第 3 根 K 線位置的值。第五個參數(shù)平均模式有四個常量MODE_SMA 簡單移動平均、MODE_EMA 指數(shù)移動平均、MODE_SMMA 平滑移動平均、MODE_LWMA 線性加權(quán)。第六個參數(shù)價格種類最常用 PRICE_CLOSE 收盤價此外還有 PRICE_OPEN、PRICE_HIGH、PRICE_LOW、PRICE_MEDIAN 等。第七個 shift 是 K 線位置0 是當(dāng)前坐標(biāo)系和 3.1 一致。注意第五、第六個參數(shù)位置經(jīng)常被寫反。MODE_EMA 和 PRICE_CLOSE 一個是模式、一個是價格寫反了編譯不報錯但計算出來的線完全不是預(yù)期中的均線回測時才發(fā)現(xiàn)數(shù)值對不上。這種錯誤在代碼里非常隱蔽。ma_shift 參數(shù)大多數(shù)時候填 0它表示均線整體左右平移的柱數(shù)。需要提醒的是如果你在循環(huán)里從 i0 一直取值到 1000每次 iMA 調(diào)用都會重新計算一次均線性能開銷比較大。對于已經(jīng)算好的數(shù)組可以使用 iMAOnArray 來自定義數(shù)據(jù)源的移動平均值它參數(shù)更短適合做二次計算。3.4 iCustom 讀取自定義指標(biāo)參數(shù)的坑在看不見的地方當(dāng)指標(biāo)是別人寫的、沒有內(nèi)置取數(shù)函數(shù)時用 iCustom 可以拿到自定義指標(biāo)的指標(biāo)線值。標(biāo)準(zhǔn)形式double val iCustom(NULL, 0, mymacd, 12, 26, 9, 2, 0);這段的意思是在當(dāng)前圖表當(dāng)前周期加載自定義指標(biāo) mymacd把 12、26、9 三個參數(shù)傳給它取它的第 3 條指標(biāo)線編號從 0 開始所以 2 是第 3 條在最新位置的值。為什么說坑在看不見的地方——iCustom 的參數(shù)個數(shù)必須和自定義指標(biāo)源碼里的 extern 聲明完全一致多一個少一個通常在編譯階段不報錯運行日志里才有提示參數(shù)順序也必須和源碼聲明順序一致否則取到的是另一個參數(shù)組合算出的結(jié)果。我一般拿到陌生指標(biāo)第一步先打開它的源碼數(shù)清楚有幾個 extern 變量按順序把值填進 iCustom。如果指標(biāo)有多根指標(biāo)線編號規(guī)則是第一條為 0、第二條為 1最后一個 shift 參數(shù)仍然是 K 線位置。另外 iCustom 每次調(diào)用都會讓 MT4 去重新計算那個自定義指標(biāo)在 for 循環(huán)里頻繁調(diào)用性能很差合理的做法是把 iCustom 的結(jié)果先存進數(shù)組再使用而不是每根 K 線都調(diào)好幾遍。4. 自定義指標(biāo)避坑四段結(jié)構(gòu)、畫線流程與四類報錯4.1 先理解指標(biāo)的四段結(jié)構(gòu)與 #property 指令MT4 自定義指標(biāo)文件由四部分組成文件頭部的 #property 預(yù)處理指令、全局變量定義區(qū)、init() 初始化函數(shù)、start() 主函數(shù)另外還有一個可選的 deinit() 在指標(biāo)卸載時執(zhí)行。#property 指令不寫分號它負責(zé)告訴編譯器“這個指標(biāo)要在哪個窗口顯示、有幾條線、什么顏色”。新手第一道坎就在這里常見組合如下#property indicator_chart_window // 顯示在主圖如均線類 #property indicator_separate_window // 顯示在副圖如 MACD、RSI 類 #property indicator_buffers 2 // 聲明 2 條指標(biāo)緩沖線 #property indicator_color1 Red // 第 1 條線紅色 #property indicator_width1 1 // 第 1 條線粗細為 1 #property indicator_level1 0.0 // 在 0 值處畫一條水平虛線第一個和第二個是一組互斥指令一個指標(biāo)只能選其一。indicator_buffers 的數(shù)量必須不小于你實際綁定的指標(biāo)線數(shù)量少寫會導(dǎo)致高編號的線丟失。indicator_color1、indicator_color2 按編號對應(yīng)第 1、2 條線indicator_level1 常用于 MACD 這類在 0 軸上下擺動的指標(biāo)固定畫一條零值參考線。這些指令全部放在文件最頂部位置靠后會影響編譯階段的緩沖區(qū)分配所以務(wù)必保持在第一條語句之前。4.2 init() 里綁定緩沖區(qū)start() 里逐根畫線MACD 白線示例一個指標(biāo)至少要有三件事一個存儲數(shù)值的數(shù)組、一次緩沖區(qū)綁定、一段給數(shù)組賦值的循環(huán)。教程里那個只畫 MACD 白線的示例很干凈我把它完整貼出來逐段拆#property indicator_separate_window #property indicator_color1 White #property indicator_level1 0 extern int FMA 12; extern int SMA 26; double buf[]; int init() { SetIndexBuffer(0, buf); SetIndexStyle(0, DRAW_LINE); return(0); } int start() { int limit Bars - IndicatorCounted(); for(int i 0; i limit; i) { buf[i] iMA(NULL, 0, FMA, 0, MODE_EMA, PRICE_CLOSE, i) - iMA(NULL, 0, SMA, 0, MODE_EMA, PRICE_CLOSE, i); } return(0); }邏輯說明文件頭部聲明這是一條副圖白線并在 0 位置畫水平參考線。FMA 和 SMA 兩個 extern 變量是快慢均線周期默認 12 和 26。double buf[] 是數(shù)據(jù)緩沖區(qū)它本身沒有長度真正的容量在 SetIndexBuffer 完成時由 MT4 內(nèi)部分配。init() 在指標(biāo)加載時只運行一次SetIndexBuffer(0, buf) 把 buf 綁定為第 1 條指標(biāo)線SetIndexStyle(0, DRAW_LINE) 把它畫成連續(xù)曲線。start() 在有新數(shù)據(jù)變動時被觸發(fā)關(guān)鍵在 limit Bars - IndicatorCounted()Bars 是當(dāng)前圖表總柱數(shù)IndicatorCounted() 返回已經(jīng)計算過的柱數(shù)兩者相減就是“還沒算過的柱數(shù)”。循環(huán)從 i0 跑到 limit逐根取兩條 iMA 在相同位置的差值寫入 buf[i]已經(jīng)算過的部分不再重復(fù)計算。這就是 MQL4 的增量計算機制指標(biāo)加載在幾千根 K 線的圖表上也不會卡。循環(huán)部分如果習(xí)慣用 while 也是一回事int i 0; while(i limit) { buf[i] iMA(NULL, 0, FMA, 0, MODE_EMA, PRICE_CLOSE, i) - iMA(NULL, 0, SMA, 0, MODE_EMA, PRICE_CLOSE, i); i; }兩者執(zhí)行邏輯完全一樣先判斷條件成立就執(zhí)行循環(huán)體再回到判斷。for 只是把初始化變量、判斷條件、遞增語句壓縮到一行。4.3 坑一報警條件永遠不觸發(fā)或每次都觸發(fā)寫價格穿越報警時條件判斷看起來簡單實際最容易翻車??催@段典型的上下穿 1.0000 報警邏輯int mark 0; if(High[1] 1.0000 High[0] 1.0000 mark ! 1) { Alert(Symbol(), 價格向上觸及 1.0000); mark 1; } if(Low[1] 1.0000 Low[0] 1.0000 mark ! 2) { Alert(Symbol(), 價格向下觸及 1.0000); mark 2; }現(xiàn)象報警條件寫好后要么一根 K 線觸發(fā)十幾次要么一次都不觸發(fā)。原因第一沒有用 mark 標(biāo)記去重上穿條件在同一根 K 線持續(xù)成立start() 每來一個報價都會 Alert 一次第二判斷上穿用的是當(dāng)前 K 線和前一根 K 線的最高價如果當(dāng)前 K 線開盤價已經(jīng)在 1.0000 上方High[0] 從一開始就大于等于 1.0000條件被誤判成“剛剛上穿”。解決用 mark 記錄上次報警類型0 表示從未報警1 表示已上穿報警2 表示已下穿報警。上穿后 mark 置 1只有 mark 不等于 1 時才允許再次觸發(fā)同時把穿越判斷寫成 High[1] 1.0000 High[0] 1.0000用前一根 K 線的價格狀態(tài)和當(dāng)前 K 線做比較保證這是真正發(fā)生過的一次穿越而不是狀態(tài)一直滿足。這是我個人的調(diào)試經(jīng)驗先把 Alert 換成 Print 輸出 mark 和兩個 High 值看日志確認條件每一步都符合預(yù)期再加回 Alert。4.4 坑二數(shù)組越界導(dǎo)致指標(biāo)線中斷現(xiàn)象指標(biāo)編譯通過加載后前半段正常后半段空白日志窗口反復(fù)出現(xiàn) array out of range。原因start() 里循環(huán)上限寫成了 Bars而不是 Bars - IndicatorCounted()。當(dāng) MT4 給指標(biāo)緩沖數(shù)組分配的容量小于你要訪問的最大下標(biāo)時就會越界。動態(tài)數(shù)組沒分配容量直接寫入也是同樣的報錯。解決循環(huán)上限一律用 Bars - IndicatorCounted()并且在計算前加一個空值保護int limit Bars - IndicatorCounted(); if(limit 0) return(0); for(int i 0; i limit; i) { // 計算邏輯 }如果你的數(shù)據(jù)不是指標(biāo)緩沖區(qū)而是普通動態(tài)數(shù)組記得先用 ArrayResize 分配容量ArrayResize(tmp, Bars);。注意 ArrayResize 的第二個參數(shù)是元素個數(shù)不是字節(jié)數(shù)這里寫成 Bars 就是和當(dāng)前圖表柱數(shù)一致。4.5 坑三iCustom 參數(shù)對不上取到錯誤數(shù)值卻不報錯現(xiàn)象用 iCustom 引用別人寫好的指標(biāo)圖形加載正常但取到的指標(biāo)值跟原指標(biāo)顯示的值對不上。原因參數(shù)順序和源碼 extern 聲明順序不一致或者指標(biāo)線編號選錯。自定義指標(biāo)的 extern 參數(shù)順序是硬規(guī)則iCustom 按位置傳參跟參數(shù)名無關(guān)。解決打開自定義指標(biāo)源碼把 extern 聲明順序抄下來依次填進 iCustom。如果原指標(biāo)有 3 個 extern 參數(shù)形如 extern int A12; extern int B26; extern int C9;那調(diào)用就是 iCustom(NULL,0,指標(biāo)名,12,26,9,線編號,位置)。線編號從 0 開始第一根線是 0第二根是 1。這個錯誤最迷惑人的地方在于參數(shù)個數(shù)一致時編譯器不報任何警告只有把取到的值和圖上疊加的原指標(biāo)對比才能發(fā)現(xiàn)。提示調(diào)用 iCustom 前先打開自定義指標(biāo)源碼數(shù)清 extern 個數(shù)并按順序填參數(shù)這是減少排查時間最有效的一步。5. 把行情提醒和驗證變成習(xí)慣SendMail 與數(shù)據(jù)窗口抽查5.1 用 SendMail 把行情推到手機一個很實用的落地小技巧利用 MT4 的郵件發(fā)送函數(shù)每間隔固定分鐘數(shù)就把最新價格發(fā)到你的郵箱配合郵箱服務(wù)商的短信提醒功能手機就變成了行情接收機。完整指標(biāo)如下#property indicator_chart_window extern int 間隔分鐘 10; datetime NextTime 0; int start() { if(TimeLocal() NextTime) { SendMail(Symbol() DoubleToStr(Close[0], Digits), ); NextTime TimeLocal() 間隔分鐘 * 60; } return(0); }邏輯說明這個指標(biāo)加載到主圖后每次報價到來都會觸發(fā) start()。TimeLocal() 返回本機當(dāng)前時間NextTime 是預(yù)定的下次發(fā)送時間初始為 0所以第一次觸發(fā)立即發(fā)送。發(fā)送完成后把 NextTime 更新為當(dāng)前時間加上間隔分鐘乘以 60 秒。datetime 類型在 MQL4 里本質(zhì)是自 1970 年起的秒數(shù)所以分鐘要乘 60。SendMail 的第一個參數(shù)是郵件主題第二個參數(shù)是正文這里我把品種和最新價格都拼進主題里正文留空手機短信一般直接展示主題內(nèi)容一眼就能看到行情。把 間隔分鐘 改成 30就是半小時一封。這里有一個親身踩過的坑MT4 的郵件功能需要在工具選項里預(yù)先配置好發(fā)件郵箱、收件郵箱和 SMTP 服務(wù)器否則 SendMail 什么也不做。我第一次測試時日志里全是錯誤一度以為是代碼問題后來發(fā)現(xiàn)是 SMTP 連接沒有建立重啟 MT4 再測一次才收到測試郵件。所以寫完這個指標(biāo)第一件事是先在工具選項里發(fā)一封測試郵件確認通道通了再掛到圖表上。5.2 用數(shù)據(jù)窗口抽查指標(biāo)線數(shù)值寫完指標(biāo)不要急著上實盤驗證數(shù)值比寫代碼更要緊。MT4 圖表頂部工具欄有數(shù)據(jù)窗口開關(guān)打開后鼠標(biāo)移到任意一根 K 線上就能看到該 K 線位置指標(biāo)線的具體數(shù)值。我每次都在最早的幾根 K 線、中間某一根、最新一根分別讀數(shù)和手工計算或另一周期的同指標(biāo)做個交叉對比數(shù)值連續(xù)沒有跳變才敢說這條線畫對了。從那以后我每次把指標(biāo)掛到圖表上都強制走一遍這個流程先看編譯警告再核對 #property 窗口屬性最后用數(shù)據(jù)窗口抽查三根 K 線的值。這套流程擋住過不少低級錯誤也讓我后來寫 EA 時少走很多彎路。希望幫到你。本文還有配套的精品資源點擊獲取