程式交易教學

誠邀您參加全球知名外匯經紀商OANDA的自營交易(Prop Trader)

報名OANDA自營交易(Prop Trader),並通過我們的考核,您就可以使用OANDA提供的資金進行交易,獲得高達80%的交易利潤分成。



限時優惠代碼
在購買鈦金挑戰賽時輸入“TITANIUM30”,即獲得30%的折扣(優惠截止日期為2024年4月30日)。

優化了挑戰塞交易規則
無最低交易天數限制等優化了挑戰賽的交易規則。

500,000美元交易資金
您可以使用最高500,000美元的資金進行交易。

豐富的交易商品
您可以交易包括外匯、黃金、原油、股票指數等多種商品。



【MQL編程基礎】|從ZigZag軌跡中確認價格波動特性的方法

1.在圖表上設定ZigZag並製作新檔案

在本篇文章中,將介紹從ZigZag的軌跡中確認價格波動特性的方法。ZigZag是以直線連結指定高價與低價的指標,為MT4的標準配備。其能夠以目測掌握大型趨勢,受到許多人的愛用。

首先要在圖表上設定ZigZag。在此處將線條的寬度加粗至「3」以便判別,並為了在頂點進行多方觀測,將Depth數值變更為「5」以增加頂底數量。本次製作的工具,能將此ZigZag的頂點資訊留作軌跡。

ZigZag

以下來製作檔案的雛形。在製作新檔案處選擇「自訂指標」,檔案名稱設定為「ZigZagPoint」。參數為結合標準配備ZigZag的三個設定。第一個的名稱為「Depth」、預設值為「5」、第二個的名稱為「Deviation」、預設值為「5」、第三個的名稱為「Backstep」、預設值為「3」。

自訂指標

在「自訂指標的事件處理常式」中,無需勾選「OnTimer」或「OnChartEvent」即可進入下一步,點擊「完成」便是雛形。

2.尋找ZigZag的兩個頂點

可以顯示出ZigZag頂端的最新點和前一個點的軌跡。首先為了讀取調出的ZigZag數值,將利用iCustom函數。在OnCalculate函數內寫入以下編碼。貨幣對與時間週期皆為圖表中所顯示的,名稱為「ZigZag」、輸入參數則填入先前設定的「Depth」「Deviation」「Backstep」,由於緩衝器編號只有一個,因此為「0」。如此即可取得ZigZag的資訊。

for (int i = 0; i < Bars -1; i++) {

double zz = iCustom(NULL, 0, “ZigZag”, Depth, Deviation, Backstep, 0, i);

}
只要取得最早的點以及第二個點即可,故找到頂點時即可進入下一輪計算,當計算至「2」以上時,便能在該處除去for文體。從最早的條列依序往回搜尋,當找到兩個頂點時便可結束。

int count = 0;

for (int i = 0; i < Bars -1; i++) {

double zz = iCustom(NULL, 0, “ZigZag”, Depth, Deviation, Backstep, 0, i);

if (zz != 0) {

count++;

}

if (count >= 2) break;

}

3.設定Text物件

在上述文章中,說明了如何在圖表上設定ZigZag、以及搜尋最新點與前一點之間的兩點。接下來,將在找到的兩處頂點上顯示Text物件。

可從MQL4幫助檔中,複製使用Text物件的範例編碼。於MQL4幫助檔目錄中點選「Constants, Enumerations and Structures」→「Objects Constants」→「Object Types」,便會顯示物件一覽表。從中選擇「OBJ_TEXT」,並將預先準備的「Creating Text object」編碼複製貼上於檔案的下方。

首先來變更初始設定。由於希望在頂點正中央顯示Text物件,故須將「// anchor type」的「anchor=ANCHOR_LEFT_UPPER」設定為「anchor=ANCHOR_CENTER」。本次將使用〇以及×符號,因此將「// font」的「font=”Arial”」變更為「font=“Mayo”」的字體。另外,將「// font size」的「font_size=10」變更為「font_size=16」、並為了指定文字顏色,將「// color」行列移動至「// the text itself」下方。

其次需刪除不需要的部分。從「//— set anchor point coordinates if they are not set」至「ResetLastError();」的4行、以及「Print(__FUNCTION__,」「”: failed to create \”Text\” object! Error code = “,GetLastError());」兩行都應刪除。為了進一步反映出價格資訊,在「return(false);」上方添加「ObjectSetDouble(chart_ID, name, OBJPROP_PRICE, 0, price);」。若無加上此行,處理步驟便會在製作一次物件後立即結束,故須特別留意。如此即可完成Text物件的設定。

//+——————————————————————+

//| Creating Text object |

//+——————————————————————+

bool TextCreate(const long chart_ID = 0, // chart’s ID

const string name = “Text”, // object name

const int sub_window = 0, // subwindow index

datetime time = 0, // anchor point time

double price = 0, // anchor point price

const string text = “Text”, // the text itself

const color clr = clrRed, // color

const string font = “Mayo”, // font

const int font_size = 16, // font size

const double angle = 0.0, // text slope

const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type

const bool back = false, // in the background

const bool selection = false, // highlight to move

const bool hidden = true, // hidden in the object list

const long z_order = 0) // priority for mouse click

{

//— create Text object

if(!ObjectCreate(chart_ID, name, OBJ_TEXT, sub_window, time, price)) {

ObjectSetDouble(chart_ID, name, OBJPROP_PRICE, 0, price);

return(false);

}

//— set the text

ObjectSetString(chart_ID, name, OBJPROP_TEXT, text);

//— set text font

ObjectSetString(chart_ID, name, OBJPROP_FONT, font);

//— set font size

ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size);

//— set the slope angle of the text

ObjectSetDouble(chart_ID, name, OBJPROP_ANGLE, angle);

//— set anchor type

ObjectSetInteger(chart_ID, name, OBJPROP_ANCHOR, anchor);

//— set color

ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);

//— display in the foreground (false) or background (true)

ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);

//— enable (true) or disable (false) the mode of moving the object by mouse

ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);

ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);

//— hide (true) or display (false) graphical object name in the object list

ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);

//— set the priority for receiving the event of a mouse click in the chart

ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);

//— successful execution

return(true);

}

4.以Text物件顯示「×」與「〇」

以下將使用設定的TextCreate來顯示Text物件。首先,為了能一次刪除物件,需要在檔案上方的屬性「property indicator_chart_window」下,將「PREFIX」定義為前綴。

#define PREFIX “ZigZagPoint_”
其次,在「Custom indicator initialization function」之下設置「Custom indicator deinitialization function」,並寫入使用OnDeinit函數的下列編碼。如此一來,當指標自圖表上消失時,物件也會一併刪去。

void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, PREFIX);

}
至於顯示Text物件的TextCreate,則需在OnCalculate函數內的「count++;」下方進行定義。為了使每一根K線只有一個元件,需以「TimeToString」作為條列時間資訊的名稱。此外,也要另外定義顯示的文字,第一個點為「×」、第二個點則是「〇」。×的顏色為白色、〇則是橘色。

string name = PREFIX + (string)i + “_” + TimeToString(Time[i], TIME_DATE | TIME_MINUTES);

string text = count == 1 ? “✕” : “〇”;

color clr = count == 1 ? clrWhite : clrOrange;

TextCreate(0, name, 0, Time[i], zz, text, clr);
如此進行編譯,並設定顯示有 ZigZag的圖表,ZigZag頂端的最新點便會呈現白色的「×」、下一個點則會是橘色的「〇」。即使重新繪製線條,〇×標記也會作為軌跡留下,因此可確認ZigZag線條的變化特性。

ZigZag的圖表

5.經過一定時間之後刪除物件

在上述內容中,已在ZigZag的最新點上顯示白色「×」、前一點則是橘色的「〇」。但是,由於目前的圖表會無限顯示Text物件,因此需使其在經過一定時間後予以刪除。

ZigZag

此作法需使用for文體,一邊確認所有的物件名稱一邊搜尋,只要名稱中包含前綴「PREFIX」,便能取得該時間點的時間資訊。得知時間資訊之後,即可取得物件位置的K線編碼,故此為關鍵重點。若本次的K線編號大於「1000」,就能將物件刪除。如此避免物件無限積存。

for (int i = ObjectsTotal(0, -1) – 1; i >= 0; i–) {

string name = ObjectName(0, i);

if (StringFind(name, PREFIX) != -1) {

datetime timeText = (datetime)ObjectGetInteger(0, name, OBJPROP_TIME, 0);

if (iBarShift(NULL, 0, timeText) > 1000) ObjectDelete(0, name);

}

6.原始碼

本次製作的原始碼如以下所示。

//+——————————————————————+

//| ZigZagPoint.mq4 |

//| Copyright 2022, MetaQuotes Software Corp. |

//| https://www.mql5.com |

//+——————————————————————+

#property copyright “Copyright 2022, MetaQuotes Software Corp.”

#property link “https://www.mql5.com”

#property version “1.00”

#property strict

#property indicator_chart_window

#define PREFIX “ZigZagPoint_”

//— input parameters

input int Depth = 5;

input int Deviation = 5;

input int Backstep = 3;

//+——————————————————————+

//| Custom indicator initialization function |

//+——————————————————————+

int OnInit()

{

//— indicator buffers mapping

//—

return(INIT_SUCCEEDED);

}

//+——————————————————————+

//| Custom indicator deinitialization function |

//+——————————————————————+

void OnDeinit(const int reason)

{ ObjectsDeleteAll(0, PREFIX);

}

//+——————————————————————+

//| Custom indicator iteration function |

//+——————————————————————+

int OnCalculate(const int rates_total,

const int prev_calculated,

const datetime &time[],

const double &open[],

const double &high[],

const double &low[],

const double &close[],

const long &tick_volume[],

const long &volume[],

const int &spread[])

{

//—

int count = 0;

for (int i = 0; i < Bars - 1; i++) {

double zz = iCustom(NULL, 0, “ZigZag”, Depth, Deviation, Backstep, 0, i);

if (zz != 0) {

count++;

string name = PREFIX + (string)i + “_” + TimeToString(Time[i], TIME_DATE | TIME_MINUTES);

string text = count == 1 ? “×” : “〇”;

color clr = count == 1 ? clrWhite : clrOrange;

TextCreate(0, name, 0, Time[i], zz, text, clr);

}

if (count >= 2) break;

}

for (int i = ObjectsTotal(0, -1) – 1; i >= 0; i–) {

string name = ObjectName(0, i);

if (StringFind(name, PREFIX) != -1) {

datetime timeText = (datetime)ObjectGetInteger(0, name, OBJPROP_TIME, 0);

if (iBarShift(NULL, 0, timeText) > 1000) ObjectDelete(0, name);

}

}

//— return value of prev_calculated for next call

return(rates_total);

}

//+——————————————————————+

//| Creating Text object |

//+——————————————————————+

bool TextCreate(const long chart_ID = 0, // chart’s ID

const string name = “Text”, // object name

const int sub_window = 0, // subwindow index

datetime time = 0, // anchor point time

double price = 0, // anchor point price

const string text = “Text”, // the text itself

const color clr = clrRed, // color

const string font = “メイリオ”, // font

const int font_size = 16, // font size

const double angle = 0.0, // text slope

const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type

const bool back = false, // in the background

const bool selection = false, // highlight to move

const bool hidden = true, // hidden in the object list

const long z_order = 0) // priority for mouse click

{

//— create Text object

if(!ObjectCreate(chart_ID, name, OBJ_TEXT, sub_window, time, price)) {

ObjectSetDouble(chart_ID, name, OBJPROP_PRICE, 0, price);

return(false);

}

//— set the text

ObjectSetString(chart_ID, name, OBJPROP_TEXT, text);

//— set text font

ObjectSetString(chart_ID, name, OBJPROP_FONT, font);

//— set font size

ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size);

//— set the slope angle of the text

ObjectSetDouble(chart_ID, name, OBJPROP_ANGLE, angle);

//— set anchor type

ObjectSetInteger(chart_ID, name, OBJPROP_ANCHOR, anchor);

//— set color

ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);

//— display in the foreground (false) or background (true)

ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);

//— enable (true) or disable (false) the mode of moving the object by mouse

ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);

ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);

//— hide (true) or display (false) graphical object name in the object list

ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);

//— set the priority for receiving the event of a mouse click in the chart

ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);

//— successful execution

return(true);

}

將EA自動程式交易應用於外匯與差價合約交易中

EA

我們以圖文形式詳細介紹有關EA自動程式交易的基本知識,以及在MT4/MT5平台上的安裝、參數設定方法、編碼等等內容。另外,對持有OANDA帳戶的客戶,還可以免費使用我們的獨有EA與指標工具。

誠邀您參加全球知名外匯經紀商OANDA的自營交易(Prop Trader)

報名OANDA自營交易(Prop Trader),並通過我們的考核,您就可以使用OANDA提供的資金進行交易,獲得高達80%的交易利潤分成。



限時優惠代碼
在購買鈦金挑戰賽時輸入“TITANIUM30”,即獲得30%的折扣(優惠截止日期為2024年4月30日)。

優化了挑戰塞交易規則
無最低交易天數限制等優化了挑戰賽的交易規則。

500,000美元交易資金
您可以使用最高500,000美元的資金進行交易。

豐富的交易商品
您可以交易包括外匯、黃金、原油、股票指數等多種商品。