這篇使用針對 MT5 外匯商品 交易策略開發 [01] 內容作一些說明 有助於了解部落格後續文章內相關的 MT5 語法及架構
#include
這行指的是引入 MQL5 提供的交易類別庫,包含一系列預定義的功能,用於執行交易操作(如下單、修改訂單和平倉)。這使得交易邏輯的實現更加高效和簡潔。
#include
這行代表引入一個命名為 MagicMT5_函數庫V1.mqh 的自定義函數庫。此函數庫可能包含自定義的輔助工具或功能,專門用來加強交易策略、數據處理或特殊操作。如果這是您自己設計的函數庫,則可能已經加入了獨特的邏輯來支持您的算法需求。
ENUM_TIMEFRAMES 時間週期 = PERIOD_M20;
這行代碼創建一個 ENUM_TIMEFRAMES 類型的變數,名稱為 時間週期,並將其初始值設定為 PERIOD_M20。
ENUM_TIMEFRAMES 是 MQL5 中的一個列舉類型,用來表示不同的時間週期(例如,1分鐘、5分鐘或小時級別的時間框架)。
PERIOD_M20 代表 20 分鐘的時間框架,這通常用於技術分析、指標計算或交易策略中的決策邏輯。
int OnInit()
OnInit() 是 MQL5 中的初始化事件函數,專門用來處理當程式(例如 Expert Advisor)被加載到圖表上時的初始化工作。
它的回傳型態為整數(int),通常表示初始化結果。
LoadEA = TimeCurrent();
此行將伺服器的當前時間(TimeCurrent())賦值給變數 LoadEA。
TimeCurrent() 是 MQL5 的內建函數,提供以秒數表示的伺服器時間。
此操作常用於記錄 EA 啟動的時間,例如方便在後續的邏輯中進行時間相關的分析或操作。
return(INIT_SUCCEEDED);
INIT_SUCCEEDED 是 MQL5 定義的常數,用來表示初始化成功。
回傳值告訴系統 EA 已成功完成初始化,可進行正常運行。
若遇到初始化失敗的情況,您可以使用 return(INIT_FAILED) 等選項來反映問題。
OnTick 函數邏輯,主要用於處理每次市場資料更新(即每個新 Tick 到達時)執行的操作。
if(AccountInfoDouble(ACCOUNT_BALANCE) <= 資金風控)
此條件用於檢查帳戶的餘額是否低於「資金風控」的設定值。
若餘額不足,則觸發警報提示,並透過 return 終止後續操作。
使用 AccountInfoDouble(ACCOUNT_BALANCE) 函數,可以獲取帳戶目前的可用資金。
BarNumber = iBarShift(Symbol(),時間週期,LoadEA);
透過 iBarShift() 函數,獲得指定商品(Symbol())、指定時間週期(時間週期)自某一點時間(LoadEA)以來的 K 棒數量。
此變數主要用於回測區間內的 K 棒數分析。
BarSinceExit = BarNumber - CloseOrderNo;
計算自前一次交易平倉(CloseOrderNo)後至當前的 K 棒數量。
此變數可用於控制交易頻率或設置間隔限制。
if((BarNumber == 1 && BarNumber != JudgeNo))
判斷當前是否為第 1 根 K 棒(BarNumber == 1),且與上次判斷的 K 棒不同(BarNumber != JudgeNo)。
此條件可能是策略中判斷進場的觸發條件。
多單進場單號 =
Buy_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber);
呼叫自定義函數 Buy_at_MARKET(),進行多單進場操作。
輸入參數包括商品名稱(Symbol())、手數(Lots)、止損、止盈以及其他附加設定。
MagicNumber 是用於識別該交易的唯一標記。
LX_CloseByTicket(多單進場單號, Lots);
呼叫自定義函數 LX_CloseByTicket(),用來平倉指定單號(多單進場單號)的部分或全部倉位。
此處執行的是根據手數(Lots)進行平倉。
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA);
更新平倉的 K 棒編號,用於後續的交易條件判斷。
FastSma = MathMin(LenA1, LenB1);
使用 MathMin() 函數,計算較短的均線周期,用於生成快速均線(FastSma)。
可能代表短期趨勢。
SlowSma = MathMax(LenA1, LenB1);
使用 MathMax() 函數,計算較長的均線周期,用於生成慢速均線(SlowSma)。
可能用於判斷長期趨勢。
if(BarNumber != JudgeNo)
條件判斷:檢查當前的 K 棒編號(BarNumber)是否與最後一次判斷的 K 棒(JudgeNo)不同。
若條件成立,執行以下操作:
換K棒();:呼叫自定義函數,可能用來更新或切換 K 棒狀態。
允許交易時段 設定:透過 getTM_hour(TimeCurrent()) 函數,檢查當前時間是否在交易允許的範圍內(例如:早上 10 點至凌晨 2 點)。
Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
獲取商品的最新買價(Ask)。
使用內建函數 SymbolInfoDouble() 來獲取指定商品的價格資訊。
Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
獲取商品的最新賣價(Bid)。
同樣使用 SymbolInfoDouble(),針對商品的交易價格。
AccountBalance=AccountInfoDouble(ACCOUNT_BALANCE);
獲取帳戶的當前資金餘額。
此資訊通常用於進一步的風控或計算。
Tickvalue=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE);
獲取商品的每 Tick 的價值(即價格波動最小單位的價值)。
此變數可能用於手數或風險計算。
SP = NormalizeDouble(MathAbs(Ask-Bid),Digits());
計算買賣價差(Spread),使用 MathAbs() 取得絕對值,並透過 NormalizeDouble() 格式化至商品的價格小數位數(Digits())。
這通常是用來判斷市場流動性或交易成本。
動態計算交易手數:
if(Lots_AutoCal == true)
檢查是否啟用自動計算手數(Lots_AutoCal)。
若啟用,執行以下操作:
呼叫自定義函數 get_dynamic_lot_size(),根據以下參數動態計算手數:
Lots_Even:基準手數。
Symbol():商品符號。
RiskPercent:每筆交易的風險百分比。
AccountBalance:帳戶資金餘額。
SL:止損距離。
Lots = MathMin(0.3,MathMax(0.01,Lots));
限制計算出來的手數範圍:最低 0.01 手,最高 0.3 手。
使用 MathMin() 和 MathMax() 控制手數範圍。
if(允許交易時段 == true)
檢查是否處於允許的交易時段。只有在交易時段內,此區塊的邏輯才會被執行。
這是防止非交易時段內的自動交易操作。
多單進場邏輯
LE_Cond = (_3GreatThanBBUp());
這是一個自定義條件(可能是技術指標),用於檢查是否滿足進場多單的條件。
假設 _3GreatThanBBUp() 是布林帶上軌突破等條件的檢查邏輯。
清倉空單:sell_order_close_all()
如果目前有空單(空單部位() > 0),並且 K 棒編號不等於上次交易的 K 棒(BarNumber != OrderBarNo),則將所有空單平倉。
多單建立:
買入價格 計算
透過 Highest_OHLC() 函數計算當日最高價格,加上一定的範圍偏移量(Range[1]*0.5),並格式化為指定小數位數(Digits())。
市價單進場:Buy_at_MARKET()
如果無持有多單(多單部位() == 0)且距離上次平倉超過 1 根 K 棒(BarSinceExit > 1),則執行市價多單進場。
使用自定義函數 Buy_at_MARKET(),進行市價買入操作,並保存該單的編號(多單進場單號)。
更新交易 K 棒編號:OrderBarNo
進場後,將交易的 K 棒編號更新,用於避免重複交易。
空單進場邏輯
SE_Cond = (DayBlack3Bar_LClose() && a_RSIA[1]
> 50);
檢查是否滿足進場空單的條件:
DayBlack3Bar_LClose() 可能表示「日線三根黑棒」的條件檢查。
a_RSIA[1] > 50 表示 RSI 指標的某個值大於 50。
清倉多單:buy_order_close_all()
如果目前有多單(多單部位() > 0),並且 K 棒編號不等於上次交易的 K 棒(BarNumber != OrderBarNo),則將所有多單平倉。
空單建立:
賣出價格 計算
透過 Lowest_OHLC() 函數計算當日最低價格,減去一定的範圍偏移量(Range[1]*0.5),並格式化為指定小數位數。
掛單空單進場:Short_at_STOP()
如果無持有空單(空單部位() == 0),且距離上次平倉超過 1 根 K 棒(BarSinceExit > 1),並且上一根收盤價大於計算的賣出價格(Close[1]
> 賣出價格),則執行掛單賣出操作。
使用自定義函數 Short_at_STOP(),設定 Stop 掛單進行賣出。
更新交易 K 棒編號:OrderBarNo
掛單成功後,將交易的 K 棒編號更新。
功能概述:
進場條件檢查:
根據布林帶或技術指標等條件判斷多單或空單進場。
僅在允許的交易時段內執行邏輯。
多單與空單的動作互斥:
清倉對沖的倉位(如進多單前平空單,進空單前平多單)。
動態計算價格:
根據當日最高/最低價格,結合一定範圍偏移量計算進場價格。
交易限制:
通過 BarNumber 和 OrderBarNo 避免同一根 K 棒內重複交易。
通過 BarSinceExit 控制平倉後的進場間隔。
多單平倉邏輯
條件檢查
if(多單部位() > 0)
確保目前有多單部位(倉位數量大於零)時才執行平倉邏輯。
停利與停損的計算
多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號);
使用自定義函數 LE_EntryPrice(),根據進場單號(多單進場單號)和魔術號(MagicNumber)獲取多單的進場價格。
多單停利價格 = 多單進場價格
+ TP * Point();
計算多單的停利價格(TP),即在進場價格的基礎上加上目標點數(TP)。
多單停損價格 = 多單進場價格
- SL * Point();
計算多單的停損價格(SL),即在進場價格的基礎上減去止損點數(SL)。
判斷平倉條件
LX_Cond 定義:
LX_Cond = ((Close[1] <= 多單停利價格 && Bid > 多單停利價格) || (Close[1] >= 多單停損價格 && Bid
< 多單停損價格));
檢查多單是否達到停利或停損條件:
停利條件:上一根 K 棒收盤價低於或等於停利價格,且當前買價(Bid)超過停利價格。
停損條件:上一根收盤價高於或等於停損價格,且當前買價低於停損價格。
執行平倉
if(LX_Cond == true && BarNumber !=
CloseOrderNo)
確保符合平倉條件,且 K 棒編號不同於上次平倉時的 K 棒(避免重複執行)。
LX_CloseByTicket(多單進場單號, Lots);
呼叫自定義函數,將指定單號的多單進行平倉。
更新平倉 K 棒編號:
if(多單部位() == 0) { CloseOrderNo =
iBarShift(Symbol(), 時間週期, LoadEA); }
平倉成功後,更新平倉時的 K 棒編號,避免重複執行平倉邏輯。
空單平倉邏輯
條件檢查
if(空單部位() > 0)
確保目前有空單部位時才執行平倉邏輯。
停利與停損的計算
空單進場價格 = SE_EntryPrice(MagicNumber, 空單進場單號);
使用自定義函數 SE_EntryPrice() 獲取空單進場價格。
空單停利價格 與 空單停損價格 計算:
空單停利價格 = MathMin(a_ICHI_SA[1],
a_ICHI_SB[1]) - Range[1] * 2;
空單停損價格 = MathMax(a_ICHI_SA[1],
a_ICHI_SB[1]) + Range[1] * 2;
a_ICHI_SA[1] 和 a_ICHI_SB[1] 可能是 Ichimoku 指標(基準線和轉換線)的值。
空單停利價格:取這些指標的較小值減去偏移範圍。
空單停損價格:取這些指標的較大值加上偏移範圍。
判斷平倉條件
SX_Cond 定義:
SXcond51 = (空單進場價格 > 空單停利價格 && Close[1] >= 空單停利價格 &&
Ask < 空單停利價格);
SXcond52 = (空單進場價格 < 空單停損價格 && Close[1] <= 空單停損價格 &&
Ask > 空單停損價格);
SX_Cond = (SXcond51 == true ||
SXcond52 == true);
判斷空單是否達到停利或停損條件:
停利條件:進場價格高於停利價格,且上一根收盤價大於或等於停利價格,並且賣價低於停利價格。
停損條件:進場價格低於停損價格,且上一根收盤價小於或等於停損價格,並且賣價高於停損價格。
執行平倉
if(SX_Cond == true && BarNumber !=
CloseOrderNo)
確保符合平倉條件,並避免重複執行。
SX_CloseByTicket(空單進場單號, Lots);
呼叫自定義函數,將指定單號的空單平倉。
更新平倉 K 棒編號:
if(空單部位() == 0) { CloseOrderNo =
iBarShift(Symbol(), 時間週期, LoadEA); }
更新判斷編號
JudgeNo = iBarShift(Symbol(), 時間週期, LoadEA);
更新最後的判斷 K 棒編號,確保進場和平倉的邏輯同步。
多單部位
函數定義
int 多單部位()
{
int count;
count = get_TradeCounts(Symbol(), MagicNumber,
POSITION_TYPE_BUY);
return count;
}
功能: 計算當前多單的部位數量。
邏輯:
使用自定義函數 get_TradeCounts(),傳遞當前交易商品(Symbol())、專屬識別碼(MagicNumber)及多單類型(POSITION_TYPE_BUY)。
該函數返回多單部位的數量,並存入 count,最後回傳此值。
用途: 確認是否有持倉多單,供進場/平倉邏輯使用。
2. 空單部位
函數定義
int 空單部位()
{ int count;
count = get_TradeCounts(Symbol(), MagicNumber,
POSITION_TYPE_SELL);
return count;
}
功能: 計算當前空單的部位數量。
邏輯:
與 多單部位() 類似,不同點在於這裡判斷的是空單部位數量(POSITION_TYPE_SELL)。
用途: 確認是否有持倉空單,用於進場或平倉操作。
3. 換K棒
函數定義
void 換K棒()
{ // 新K棒刪除所有掛單
if(total_pending_order_count(Symbol(), MagicNumber,
-1) != 0)
{
delete_pending_orders_all(Symbol(), MagicNumber, -1,
0x0000ff);
}
Set_OHLC_Bar_Series();
Set_OHLC_Day_Series();
Get_OHLC_Bar(10);
Get_OHLC_Day(10);
set_BarInfo();
set_BBAND();
set_RSI();
set_ICHIMOKU();
}
功能解釋
刪除所有掛單
total_pending_order_count(Symbol(), MagicNumber, -1)
計算當前所有掛單的數量。
delete_pending_orders_all()
如果有掛單,則刪除所有掛單。
使用 MagicNumber 和商品符號(Symbol())進行過濾,確保只刪除與特定識別碼相關的掛單。
OHLC 資料更新
Set_OHLC_Bar_Series() 與 Set_OHLC_Day_Series()
更新當前 K 棒和日線的開高低收(OHLC)數據序列。
取得 OHLC 值
Get_OHLC_Bar(10) 與 Get_OHLC_Day(10)
抓取最近 10 根 K
棒及最近 10 天的 OHLC 值,用於後續邏輯。
技術指標設定
set_BarInfo():可能設定當前 K 棒的其他資訊。
set_BBAND():設定布林通道指標。
set_RSI():設定 RSI 指標。
set_ICHIMOKU():設定一目均衡表。
用途
此函數用於每當新 K 棒生成時,更新 OHLC 資料與技術指標,並清除舊掛單,確保交易環境整潔且邏輯一致。
沒有留言:
張貼留言