,掌握MT4指標與EA開發(fā)基礎(chǔ))
簡介面向外匯交易者及編程入門用戶的MQL4開發(fā)教程系統(tǒng)梳理MetaTrader 4平臺中自定義指標與EA智能交易程序的編寫方法。內(nèi)容圍繞編程基礎(chǔ)四大模塊展開自定義變量的類型定義、extern附加變量在策略參數(shù)調(diào)優(yōu)中的應用、自定義函數(shù)的構(gòu)造與調(diào)用、數(shù)組的創(chuàng)建與元素引用并講解開盤價、收盤價等預定義數(shù)組的歷史數(shù)據(jù)取值方式幫助讀者構(gòu)建完整的腳本開發(fā)知識鏈。資源為單個doc格式教程文檔壓縮包僅197KB內(nèi)容精煉、章節(jié)緊湊適合快速通讀后直接對照練習。目前已獲得389人次瀏覽學習屬于入門輕量型資料。教程源自外匯程序化交易實戰(zhàn)系列每章均配有可運行的代碼范例并對變量生命周期、函數(shù)返回值、數(shù)組索引邊界等易錯點做了專門說明能夠引導零基礎(chǔ)用戶逐步書寫規(guī)范的自定義指標與EA框架是進入MT4量化交易開發(fā)領(lǐng)域的低成本入門材料。1. 先搞懂一個概念MQL4 到底是什么很多人在MT4上看盤久了都會冒出一個念頭那些均線、MACD是怎么畫出來的能不能按自己的規(guī)則來一條這就是MT4 MQL4編程入門最常見的起點。簡單說MQL4是MT4平臺自帶的編程語言全稱MetaQuotes Language 4。可以寫三類東西自定義指標、腳本小程序、EA自動交易程序讓代碼自動判斷、自動下單。它語法接近C語言又比C簡單MT4自帶編輯器就能寫。這份教程的目標是讓你從沒寫過代碼到能讀懂并寫出自己的第一行MQL4代碼。不用先學編程把變量、數(shù)組、判斷、循環(huán)過一遍那些看起來玄學的指標就能變成你能控制的代碼。2. 從變量開始寫 MQL4 的第一塊積木現(xiàn)在正式開始寫代碼。如果你完全沒接觸過編程可以把程序理解成一條處理數(shù)據(jù)的流水線。數(shù)據(jù)從哪兒來要么來自行情要么來自你寫死在代碼里的數(shù)值要么來自使用者的輸入。而變量就是這條流水線上用來暫時存放數(shù)據(jù)的小盒子。為什么一上來就要先學變量因為在MQL4里任何程序——不管是指標、腳本還是EA——本質(zhì)上都是在操作數(shù)據(jù)。你得先知道數(shù)據(jù)怎么存、怎么取才能談到怎么判斷、怎么循環(huán)。這一章我們把變量和函數(shù)這兩個最基礎(chǔ)的概念講透它們是你之后所有代碼的積木。2.1 四種變量類型先認識 int、double、string、bool初學者最常見的困惑是為什么不能直接寫一個a3就完事非要寫成int a3因為在MQL4里每個變量在第一次使用時都必須明確告訴程序兩件事它是什么類型、它叫什么名字。類型決定這個盒子能裝什么數(shù)據(jù)名字決定你以后怎么找到它。MQL4里最基本的變量類型有四種先把這四個記住后面所有程序都夠用類型定義符干什么用的舉例整型int存整數(shù)正數(shù)負數(shù)都行int 數(shù)量5;雙精度小數(shù)double存帶小數(shù)的數(shù)字價格就用它double 現(xiàn)價1.0850;字符串string存文字比如品種名、報錯信息string 名稱EURUSD;邏輯型bool只能存 true 或 false真/假bool 是否報警true;定義變量的標準寫法是類型 變量名 初始值。初始值可以暫時不寫。舉個例子int mark; // 定義一個整型變量名字叫 mark沒賦值 bool 觸發(fā)開關(guān) true; // 定義邏輯型變量名字是觸發(fā)開關(guān)初值為 true這段代碼里第一行只創(chuàng)建了 mark 這個變量沒給任何初值第二行創(chuàng)建變量觸發(fā)開關(guān)的同時把初值設(shè)為 true。有一點很關(guān)鍵類型定義詞只在創(chuàng)建變量時用一次。創(chuàng)建之后再用到這個變量直接寫名字就行不能再加 int、bool 這類詞否則就變成重復定義編譯時會報錯。需要提醒的是MQL4 允許變量名使用中文這一點對中文使用者很友好。我第一次學的時候把周期、均線、報警開關(guān)這些名字直接寫成中文代碼讀起來比滿屏的英文好理解得多。不過要注意名稱取完之后從頭到尾拼寫必須完全一致尤其不要一會兒寫周期一會兒寫周其這種錯誤最隱形。2.2 extern 附加變量把參數(shù)交到使用者手里看MT4自帶的MACD指標時你應該注意過它的參數(shù)設(shè)置框里有三個數(shù)字12、26、9。這三個數(shù)字能直接在圖表屬性里改改完指標線馬上變。這種使用者能修改的參數(shù)在MQL4里叫附加變量。附加變量的定義方式很簡單在普通變量定義前面加一個 extern 關(guān)鍵字extern int 周期 9; // 外部可修改的整型變量默認值 9當程序里出現(xiàn) extern 變量時MT4 圖表加載指標后你可以在輸入?yún)?shù)選項卡里看到并修改它的值不用去碰代碼本身。這就是 MACD 那個 12、26、9 背后的實現(xiàn)原理。所以凡是希望使用者能自由調(diào)整的參數(shù)都建議設(shè)計成 extern 變量。這里有個使用習慣建議把那些你自己都可能反復調(diào)的數(shù)據(jù)比如均線周期、報警價位、判斷閾值盡量都做成 extern。否則每次想調(diào)參數(shù)都要改代碼重新編譯不僅麻煩還容易改出新錯誤。附加變量本質(zhì)也是變量規(guī)則和普通變量一樣類型、名稱、初值三者都要齊全。2.3 自定義函數(shù)把邏輯裝進小盒子如果你有一段計算邏輯要在程序里用很多次比如算3*x2*y最笨的辦法是每次用到都重寫一遍。MQL4 提供了函數(shù)這個機制相當于把這段邏輯裝進一個帶名字的小盒子想用的時候只需要喊名字。先看一個最經(jīng)典的數(shù)學例子。數(shù)學函數(shù) ft(x,y)3x2y寫成 MQL4 的代碼就是int ft(int x, int y) // 函數(shù)頭部返回類型 int函數(shù)名 ft兩個參數(shù) x 和 y { int temp; // 函數(shù)體內(nèi)部定義一個臨時變量 temp 3*x 2*y; // 算出結(jié)果存入 temp return(temp); // 結(jié)束函數(shù)把 temp 的值返回給調(diào)用處 }函數(shù)定義分兩個部分。頭部第一行聲明了返回類型、函數(shù)名和參數(shù)列表大括號里是函數(shù)體也就是實際執(zhí)行的運算語句。return 語句表示函數(shù)到此結(jié)束并把括號里的值作為運算結(jié)果送出去。上面這個函數(shù)也能簡寫成一行int ft(int x, int y) { return(3*x2*y); }效果完全一樣。用起來更簡單只要函數(shù)名寫對、參數(shù)個數(shù)和類型一致就能直接調(diào)用int 結(jié)果 ft(4, 5); // 程序把 4 傳給 x把 5 傳給 y返回 23 給結(jié)果函數(shù)還有一種特殊情況有的函數(shù)只執(zhí)行一系列動作不需要送回任何結(jié)果這時返回類型就寫成 void。比如void 更新界面() { // 這里執(zhí)行更新界面的一系列語句不需要 return 值 }void 函數(shù)運行完就結(jié)束不留返回值適合那些做了就是成功的操作。再強調(diào)一下作用域函數(shù)內(nèi)部定義的變量比如例子里的 x、y、temp只在函數(shù)運行的那段時間里存在。函數(shù)一結(jié)束這些變量就自動注銷函數(shù)外部完全看不到它們。這也意味著你在不同函數(shù)里可以放心使用同名的變量互不干擾。2.4 容易出錯的習慣先定義再使用這一章的最后說一個MQL4新手最容易犯的習慣錯誤在還沒有創(chuàng)建變量的情況下就直接拿它來賦值或判斷。MQL4的原則非常明確——所有變量、數(shù)組、函數(shù)都必須先定義創(chuàng)建后使用沒有任何例外。比如有人想記錄一個計數(shù)變量直接寫i i 1;但前面根本沒有定義過 i編譯時就會報錯變量未聲明。正確做法是在這一句之前先加上類型定義int i 0;。類似的還有一個高發(fā)問題運行到某個函數(shù)時才發(fā)現(xiàn)里面用到的一個變量根本沒傳進來。遇到這種情況不要急著一行行找錯先回到變量定義區(qū)檢查一次名稱、類型和定義位置大多數(shù)報錯都能在這里找到答案。還有一個很容易被忽視的細節(jié)MQL4 對大小寫敏感Close和close會被當成兩個不同的名字。很多指標代碼里系統(tǒng)預定義數(shù)組用的是大寫開頭自己寫的變量用什么命名習慣都可以但必須前后一致。把這些習慣在起步階段固定下來后面寫代碼會少走很多彎路。3. 數(shù)組與行情數(shù)據(jù)讓程序讀懂K線第2章學完你已經(jīng)能讓程序存儲單個數(shù)值了。但現(xiàn)實世界的行情數(shù)據(jù)遠不止一個數(shù)圖表上幾千根K線每根都有自己的開盤價、最高價、最低價、收盤價和成交量。如果你打算用變量把這些數(shù)據(jù)都存下來——Open1、Open2、Open3、Open4……寫幾百行變量名代碼會立刻失控而且根本沒法用循環(huán)去遍歷。這一章解決的就是大量同類型數(shù)據(jù)的問題。你將學會用數(shù)組來組織數(shù)據(jù)并且直接調(diào)用MT4預定義好的行情數(shù)組和指標函數(shù)。3.1 數(shù)組一列同類型變量的集合先看一個最簡單的例子int aa[4] {4,3,2,1}; // 一個叫 aa 的整型數(shù)組長度 4同時賦初值這樣寫等于一次創(chuàng)建了 4 個整型變量分別用 aa[0]、aa[1]、aa[2]、aa[3] 來訪問。注意編號是從 0 開始的不是從 1 開始aa[0] 的值是 4aa[1] 是 3aa[2] 是 2aa[3] 是 1。這個從0數(shù)起的規(guī)則是數(shù)組最反直覺、也最容易出錯的點。數(shù)組的定義同樣遵循先建后用而且創(chuàng)建時比較靈活可以只定名稱不定個數(shù)可以先規(guī)定長度不賦初值也可以規(guī)定長度并賦一部分初值。下面幾種寫法都是合法的int bb[]; // 創(chuàng)建數(shù)組 bb不設(shè)定元素個數(shù)后面再處理 int cc[8]; // 創(chuàng)建數(shù)組 cc8 個元素不賦初值 int dd[3] {9,8,7}; // 創(chuàng)建數(shù)組 dd3 個元素賦初值 int ee[9] {0,1,2,3}; // 創(chuàng)建數(shù)組 ee9 個元素只給前 4 個賦初值使用數(shù)組時有兩條硬規(guī)矩。第一除了新建時能整體賦初值之外之后給數(shù)組賦值必須一個一個來必須精確到具體元素。第二引用數(shù)組時一次也只能引用一個元素。所以如果你想把一個數(shù)組整列都用上就得配合循環(huán)逐個處理這也正是下一章循環(huán)的基礎(chǔ)。動手試一個假設(shè) dd[3]{9,8,7}執(zhí)行dd[2]1;之后數(shù)組變成 {9,8,1}。這一句把第 3 個元素下標 2的值從 7 改成了 1前兩個元素完全沒動。理解了這種按下標定位的方式你就能明白為什么后面所有指標腳本都在用數(shù)組和下標去訪問歷史行情。3.2 預定義數(shù)組Open、High、Low、Close 直接拿來用數(shù)組這么好用MT4 干脆幫你把K線數(shù)據(jù)都裝成了現(xiàn)成的數(shù)組這就是預定義數(shù)組。常見的有開盤價 Open[]、最高價 High[]、最低價 Low[]、收盤價 Close[]、成交量 Volume[]、時間 Time[]。它們不需要你創(chuàng)建啟動就能用。這些數(shù)組存的是雙精度小數(shù)Time[] 是日期時間型你必須知道的是它們的編號規(guī)則MT4 把圖表從右往左數(shù)最右邊第一根K線編號為 0往左第二根編號為 1第三根編號為 2以此類推。注意方向和大家習慣的從左往右看正好相反。下面幾個例子說明這套編號double latest Close[0]; // 這一根最新一根K線的收盤價 double prev Close[1]; // 上一根K線的收盤價 double prev2 Close[2]; // 再往前一根K線的收盤價 double now High[0]; // 最新一根K線的最高價所以寫指標報警時如果你看到代碼里出現(xiàn)Close[0]它代表的永遠是當前最新K線的收盤價不是昨天那根。補充一句這些是數(shù)組訪問時一定要用方括號[]別寫成圓括號。除了K線數(shù)組MT4 還預定義了幾個直接可用的變量Ask 和 Bid 是當前的實時賣出價和買入價都是 double 類型Bars 是當前圖表上的K線總數(shù)int 類型Digits 是當前貨幣對的小數(shù)位數(shù)不含日元的一般是 4 位含日元的是 2 位Point 是當前品種一個點的大小不含日元的是 0.0001含日元的是 0.01。這幾個在你寫報警、寫止損的時候會經(jīng)常用到。3.3 指標函數(shù)任意品種、任意周期都能取值如果只在自己的圖表上取數(shù)據(jù)用 Open[]、Close[] 就夠了。但很多時候你想取別的品種、別的周期的價格比如想在 EURUSD 的 1 小時圖上同時讀取 GBPUSD 的 4 小時圖第 3 根K線的收盤價。這時候預定義數(shù)組就不夠用了得請出功能更全的指標函數(shù)。先看最基礎(chǔ)的一組iOpen(symbol, timeframe, shift) // 開盤價 iClose(symbol, timeframe, shift) // 收盤價 iHigh(symbol, timeframe, shift) // 最高價 iLow(symbol, timeframe, shift) // 最低價 iVolume(symbol, timeframe, shift) // 成交量 iTime(symbol, timeframe, shift) // 所屬時間它們統(tǒng)一有三個參數(shù)第一個寫貨幣對名稱比如 EURUSD、GBPUSD第二個寫K線周期第三個寫位置序號就是我們剛學的下標0 是最新一根。周期有很多預定義常量可以直接用PERIOD_M1 是 1 分鐘PERIOD_M5 是 5 分鐘PERIOD_M15 是 15 分鐘PERIOD_M30 是 30 分鐘PERIOD_H1 是 1 小時PERIOD_H4 是 4 小時PERIOD_D1 是日線PERIOD_W1 是周線再往上還有月線 PERIOD_MN1。結(jié)合參數(shù)試讀幾個例子iOpen(USDJPY, PERIOD_H1, 0) // 美元兌日元 1 小時圖最新K線的開盤價 iClose(EURUSD, PERIOD_H4, 2) // 歐元兌美元 4 小時圖第 3 根K線的收盤價 iClose(GBPUSD, PERIOD_H1, i) // 英鎊兌美元 1 小時圖第 i1 根K線的收盤價 iHigh(NULL, 0, 0) // 不指定品種和周期當前圖表當前周期最新K線的最高價最后一行里的 NULL 和 0 是個偷懶寫法NULL 表示當前圖表正在用的品種0 表示當前圖表正在用的周期。換句話說這句代碼在哪個圖表上運行就用哪個圖表的數(shù)據(jù)。這也是很多自定義指標默認寫法因為指標本來就是在自己圖表上畫的。再進階一點移動平均線這類指標也有現(xiàn)成函數(shù)最常用的是 iMA它參數(shù)最多一共 7 個iMA(symbol, timeframe, period, ma_shift, ma_method, applied_price, shift)從左到右分別是品種、周期、均線周期數(shù)、均線偏移、平均模式、價格種類、位置。平均模式用常量表示MODE_SMA 是簡單平均MODE_EMA 是指數(shù)平均MODE_SMMA 是平滑平均MODE_LWMA 是線性加權(quán)平均。價格種類常用 PRICE_CLOSE收盤價、PRICE_OPEN開盤價、PRICE_HIGH最高價、PRICE_LOW最低價。舉個例子iMA(EURUSD, PERIOD_H1, 20, 0, MODE_SMA, PRICE_CLOSE, 0)這表示歐元 1 小時圖上以收盤價計算的 20 期簡單移動平均線取最新K線位置的值。如果碰巧要取自己編的指標還有 iCustom 函數(shù)括號里依次填品種、周期、指標名稱、指標參數(shù)、指標線編號和位置??吹竭@里你應該明白了MT4 里幾乎所有指標都能當函數(shù)調(diào)用規(guī)則都是品種、周期、位置三件套記熟了就不再怕黑匣子。4. 判斷與循環(huán)讓程序會思考、會重復前面幾章的內(nèi)容相當于你有了原材料變量、數(shù)組、行情數(shù)據(jù)和加工工具函數(shù)。但程序還不會動——它并不知道什么時候該報警也不知道怎么把幾千根K線逐個算一遍。這一章補上最核心的兩塊能力條件判斷和循環(huán)。判斷讓程序在面對不同的行情狀態(tài)時做出不同的決定循環(huán)讓程序用同樣的計算規(guī)則去處理成千上萬根K線。這兩樣加在一起指標和報警腳本的骨架就立起來了。4.1 if 判斷滿足條件才執(zhí)行if 語句是程序最基礎(chǔ)的決策器官規(guī)則一句話就能講完如果小括號里的條件成立就執(zhí)行大括號里的語句如果不成立就跳過這一整塊。它的標準格式如下if (條件) { // 條件成立時要執(zhí)行的語句 }在指標報警里我們常要判斷價格是否向上穿越某個價位。比如想判斷價格從低于 1.0000 變成上穿 1.0000需要同時滿足兩個條件上一根K線的最高價低于 1.0000并且當前K線的最高價已經(jīng)大于或等于 1.0000。寫成代碼就是這樣if (High[1] 1.0000 High[0] 1.0000) { Alert(Symbol(), 價格向上觸及 1.0000); }這段代碼里表示并且兩個條件必須同時為真括號里的整段判斷才算成立。Symbol() 返回當前品種名Alert() 是彈出提示框。整個程序的邏輯就是上一根還沒到 1.0000這根到了說明價格發(fā)生了向上穿越此時報警一次。判斷條件里經(jīng)常用到的比較符號需要記一下是等于注意是兩個等號!是不等于、、、分別是大于、小于、大于等于、小于等于。4.2 if...else 分支不成立時走另一條路很多時候我們不能只處理成立那一側(cè)的情況價格下穿也要處理。這就需要 if...else條件成立執(zhí)行第一段不成立則執(zhí)行 else 后面第二段??聪旅孢@個同時處理上穿和下穿報警的完整例子int mark 0; // 報警標記0 為沒有報過警1 為已上穿報警2 為已下穿報警 if (High[1] 1.0000 High[0] 1.0000 mark ! 1) { Alert(Symbol(), 價格向上觸及 1.0000); mark 1; // 上穿報警后標記改為 1 } else if (Low[1] 1.0000 Low[0] 1.0000 mark ! 2) { Alert(Symbol(), 價格向下觸及 1.0000); mark 2; }這個例子建議初學者反復看幾遍里面有個非常典型的技巧用 mark 變量當報警記憶。它的初值是 0表示兩個方向都還沒報過警一旦上穿報警發(fā)生mark 改成 1之后即使再次滿足上穿條件因為 mark ! 1 不成立就不會重復報警。同樣的道理下穿報警后 mark 改成 2。這個狀態(tài)標記思路在交易程序里極其常用。寫 if 語句時還要注意一個細節(jié)只有語句后面才需要打語句結(jié)束符;條件、大括號、小括號后面都不能加。如果你覺得整個函數(shù)體只有一句要執(zhí)行大括號可以省略比如if (條件) 報警;。但剛?cè)腴T時我建議寧可多寫大括號也不要省養(yǎng)成習慣后可以降低很多低級錯誤。4.3 while 與 for 循環(huán)處理幾千根K線一根K線有開盤、最高、最低、收盤、成交量這些值加上各種移動平均線、MACD計算結(jié)果圖表上還有幾千根K線。如果讓你把這幾千個數(shù)據(jù)都手動寫出來沒人做得到。循環(huán)就是為這種海量重復處理而生的。先看 while 循環(huán)它的結(jié)構(gòu)是while (條件) { // 只要條件成立就一直執(zhí)行的循環(huán)體 }執(zhí)行過程是先看條件成立就執(zhí)行大括號里的語句執(zhí)行完再看一次條件還成立就再執(zhí)行直到條件不成立才停下來。這里要看清楚它和 if 的區(qū)別if 只執(zhí)行一次while 只要條件為真就會反復執(zhí)行這也是它名字里循環(huán)二字的由來。下面用一個真實任務(wù)演示循環(huán)的價值——給數(shù)組 buffer[] 的前 1000 個元素依次存入快線均線值減去慢線均線值extern int 快線 12; // 快線周期 extern int 慢線 26; // 慢線周期 double buffer[]; // 用來存計算結(jié)果的數(shù)組 int i 0; // 循環(huán)計數(shù)變量 while (i 1000) { buffer[i] iMA(NULL, 0, 快線, 0, MODE_EMA, PRICE_CLOSE, i) - iMA(NULL, 0, 慢線, 0, MODE_EMA, PRICE_CLOSE, i); i; // 每循環(huán)一次i 增加 1 }循環(huán)體里做了兩件事第一句把兩條指數(shù)均線在當前下標的差值存入 buffer[i]第二句i;讓 i 在原有基礎(chǔ)上加 1。隨著循環(huán)一輪輪執(zhí)行i 從 0 漲到 999再執(zhí)行完最后一次循環(huán)后 i 等于 1000此時i 1000不再成立循環(huán)結(jié)束。1000 個位置的值就這樣全部算完了。如果不寫 ii 永遠停在 0循環(huán)就變成死循環(huán)程序卡死。4.4 for 循環(huán)更緊湊的寫法while 方案已經(jīng)能干活了但 MQL4 里更常見的是 for 循環(huán)它的原理和 while 完全一致只是把三部分壓縮進了一行小括號。把上面的例子改寫extern int 快線 12; extern int 慢線 26; double buffer[]; for (int i 0; i 1000; i) { buffer[i] iMA(NULL, 0, 快線, 0, MODE_EMA, PRICE_CLOSE, i) - iMA(NULL, 0, 慢線, 0, MODE_EMA, PRICE_CLOSE, i); }對比 while 的寫法能看到兩處移動int i 0;被移到了 for 括號的第一格里i;被移到了條件后面。for 循環(huán)的執(zhí)行順序嚴格分成四步。第一步先執(zhí)行小括號里的第一格也就是初值語句int i 0;這一句在整個循環(huán)里只執(zhí)行一次第二步判斷第二格i 1000是否成立不成立就跳出循環(huán)成立則繼續(xù)到第三步第三步執(zhí)行大括號里的循環(huán)體第四步執(zhí)行第三格i讓 i 增加 1然后回到第二步繼續(xù)判斷。這就是 for 循環(huán)完整的生命周期。每次訪問K線數(shù)據(jù)時循環(huán)體里那個 i最終會成為你訪問數(shù)組和指標函數(shù)位置參數(shù)的依據(jù)。入門階段有一個強烈建議所有循環(huán)都從i0或i1開始并確保循環(huán)內(nèi)部每一輪都會推進 i 的值i這樣就不會踩到死循環(huán)這個經(jīng)典大坑。5. 新手避坑指南五個我替你踩過的坑我剛開始學MQL4那陣子幾乎把初學者能犯的錯誤全犯了一遍。后來我養(yǎng)成了一個習慣看到報錯先不慌先看報錯信息指在編輯器的哪一行再對照常見原因去排。MetaEditor 的編譯日志其實給得很直白雙擊日志里的報錯行光標會自動跳到出錯的那一行代碼。初次看到一大串英文不要慌你先看最前面的關(guān)鍵字undeclared identifier 是變量未聲明unbalanced 是括號不配對; expected 是分號丟了或多了left side of assignment 是賦值左側(cè)寫了一個不能賦值的東西。把錯誤分好類再往下面這五條里對應排查就快了。下面這五條每條按現(xiàn)象、原因、解決的順序?qū)懩憧梢园阉敵梢环菖挪榍鍐斡龅綄Y狀時直接回來對照。5.1 編譯報錯變量沒有定義就這么用現(xiàn)象寫完代碼點編譯編輯器在某個變量名下面報錯說它是 undeclared identifier未聲明的標識符。原因九成是變量沒定義就使用或者變量名字前后寫得不一致。比如函數(shù)開頭寫的是int mark 0;到函數(shù)中間卻寫if (markk 0)只是多敲了一個字母MQL4 就會把 markk 當成一個從未出現(xiàn)的新名字。解決看到這個報錯先回到變量定義區(qū)確認三件事有沒有定義這個變量名字拼寫是否完全一致類型定義詞是否符合創(chuàng)建規(guī)則。中文變量名也容易在這里翻車比如一會兒寫周期一會兒寫周其建議定義一個就復制一個不要手打。5.2 翻車現(xiàn)場中文符號惹的禍現(xiàn)象代碼看來看去邏輯都對但編譯器就是報錯有時整行標紅甚至中文注釋都顯示異常。原因輸入法沒切換回英文半角模式。MQL4 的編輯器只認英文標點小括號、大括號、分號必須是半角狀態(tài)下的(){};。中文輸入法敲出來的逗號和分號是全角字符編譯器根本不認。解決寫代碼時把輸入法切到英文模式養(yǎng)成習慣。如果是在中文輸入法狀態(tài)下連打了一整段代碼先整體檢查有沒有混進全角逗號、全角分號。比較快的排查辦法是把報錯那一行刪掉重新輸入一遍很多時候問題就出在一個看不見的中文標點上。5.3 指標線全平數(shù)組忘了賦值現(xiàn)象寫了一個自定義指標加載到圖表上不報錯可指標線就是一條水平的直線數(shù)值永遠是 0。原因多數(shù)情況是聲明了指標緩沖區(qū)數(shù)組但在 start() 函數(shù)里忘了給它循環(huán)賦值或者 SetIndexBuffer 綁定數(shù)組時寫錯了對應編號。我的排查經(jīng)驗是先看數(shù)組有沒有綁定再看循環(huán)有沒有跑最后看計算式里的數(shù)據(jù)源是不是空的。比如想算均線差值卻引用了兩個根本沒定義過的函數(shù)參數(shù)結(jié)果自然是 0。解決在 start() 函數(shù)里補上對 buffer[i] 的賦值語句并且確認循環(huán)次數(shù)正確覆蓋了所有K線。建議每寫完一個自定義指標先在圖表上把指標線數(shù)值調(diào)出來看是不是每個位置都有值從第一個元素開始逐個核對這樣定位很快。5.4 參數(shù)改了沒反應忘了重新編譯現(xiàn)象把 extern 變量的默認值從 12 改成 20點編譯沒報錯圖表上的線紋絲不動。原因第一修改源代碼之后沒有重新編譯。extern 是編譯期參數(shù)改了代碼必須重新編譯才生效第二圖表上加載的指標仍然是舊版本沒有把新編譯生成的指標重新拖入或者 MT4 還停留在舊的加載狀態(tài)。解決改完 extern 之后在 MetaEditor 里點編譯按鈕確認編譯日志顯示成功再回到圖表把原來的指標刪掉重新拖入一次。如果還不行就把圖表切換一下周期或點一下刷新讓它重新加載指標。5.5 位置搞反Close[0] 是最近這一根現(xiàn)象寫完報警邏輯發(fā)現(xiàn)報警時機總比預期晚一根K線比如明明這根已經(jīng)超過 1.0000卻等下一根才觸發(fā)。原因這是對 MT4 編號規(guī)則的理解偏差。MT4 的K線編號是從右往左數(shù)的最右邊最新一根的編號是 0Close[0] 是當前這根K線的收盤價而 Close[1] 才是它左邊那一根。初學者按從最開始數(shù)的直覺來用會把所有下標都錯位一根。解決在正式開始寫報警或 EA 之前先在圖表上打印幾個關(guān)鍵值驗證。比如在代碼里把 Close[0]、Close[1] 的值顯示出來和圖表上的K線收盤價逐一對照。把0 是最新這條規(guī)則刻進腦子后面所有指標函數(shù)的位置參數(shù) shift 也都遵循同樣規(guī)則通用的規(guī)律記熟了就不會再錯。把這幾條保存下來等于有了一份輕量的坑位地圖。以后遇到編譯錯誤或指標異常按未聲明→符號→賦值→編譯→編號這個順序排查一遍大部分問題都能自己解決。6. 下一步學什么從指標線到完整報警程序到這里MQL4 的入門基礎(chǔ)你已經(jīng)完整過了一遍變量、函數(shù)、數(shù)組、行情數(shù)據(jù)、判斷、循環(huán)。每個概念單獨看都不大但組合起來已經(jīng)能完成很多實用功能。接下來怎么走給你三條具體的路徑。第一件事把畫一條指標線的完整例子親手跑通。代碼量不大卻用到了指標文件結(jié)構(gòu)、數(shù)組綁定、循環(huán)賦值、iMA 取值值得你敲一遍、編譯一遍、加載一遍。跑通后試著把兩條均線的周期從固定值改成 extern再試著給它加第二根不同顏色的線改動不大但對理解指標線是怎么來的幫助非常大。第二件事做一個會報警的小程序。有個經(jīng)典思路用 SendMail 把行情發(fā)送到郵箱實現(xiàn)遠程接收行情提醒。用到的知識全在基礎(chǔ)范圍內(nèi)TimeLocal() 取當前時間Symbol() 取當前品種Close[0] 取最新收盤價自己設(shè)定發(fā)信間隔。把它當一個正式項目來做能學會怎么把前面的知識點串起來。第三件事再往后才是 EA 自動交易。自動交易的本質(zhì)是指標判斷 下單函數(shù) 風險控制核心難點已經(jīng)不在語法而在策略邏輯的保護上。建議先用模擬賬戶反復測試再考慮真實環(huán)境這一點無論如何強調(diào)都不過分。學習階段核心內(nèi)容練手目標第一階段變量、數(shù)組、判斷、循環(huán)能讀懂別人寫的指標代碼第二階段指標函數(shù)、自定義指標結(jié)構(gòu)畫出自己想要的指標線第三階段報警、郵件、訂單函數(shù)做一個能用的報警小工具第四階段EA 框架、下單邏輯、風控跑通一個模擬 EA最后說個我自己吃的教訓。我剛學會寫循環(huán)那幾天急著寫一個遍歷所有K線找最高點的程序沒有限制循環(huán)次數(shù)也沒有在任何地方打印中間結(jié)果結(jié)果程序跑起來后界面卡死只能強退。從那以后我每次寫帶循環(huán)的程序都會強制自己走一遍檢查循環(huán)條件有沒有可能在某個時刻不成立循環(huán)體里能不能保證至少一個變量在推進關(guān)鍵的中間值有沒有打印出來確認。這三點花不了多少時間卻幫我避免了一大半程序不動了的麻煩。希望幫到你。本文還有配套的精品資源點擊獲取