程式交易教學

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

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



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

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

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

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



【MQL編程基礎】|擴展Comment函數的方法

1.製作新檔案並定義前綴

在本篇文章中,將說明如何擴展Comment函數。Comment函數是MT4標準配備的函數,能夠將指定的文字縮小顯示於圖表的左上方。

但是,其無法改變文字的尺寸或字體。有鑒於此,為了透過參數來指定文字尺寸,本次便將製作顯示文字用的函數。

首先,在製作新檔案處選擇「自訂指標」,檔案名稱設定為「CommentEx」。在「自訂指標程式的事件處理常式」中,無需勾選「OnTimer」或「OnChartEvent」即可進入下一步,再點擊「完成」即是雛形。

自訂指標

由於本次將使用物件,因此要在檔案上方的屬性「#property indicator_chart_window」之下定義接頭詞「PREFIX」。此動作是為了能夠一次刪除製作的元件。

「MQLInfoString(MQL_PROGRAM_NAME)」將顯示指標的檔案名稱。

#define PREFIX MQLInfoString(MQL_PROGRAM_NAME) + “_”
其後,在「Custom indicator initialization function」下方設定「Custom indicator deinitialization function」,寫入使用OnDeinit函數的下列編碼。如此一來,當指標自圖表上刪除時,相關的元件或備註便會一併消失。

void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, PREFIX);

Comment(“”);

}

2.利用Comment函數顯示文字

在一開始,將示範如何利用一般的Comment函數顯示文字。以string定義「text」的文字,並試著將其指定於Comment函數的括弧內加以顯示。

string text = “123\n345\nabc\ndef\nあいうえお\nかきくけこ”;

Comment(text);
如此進行編譯並設定圖表,換行的文字就會顯示於圖表的左上方。透過一般的Comment函數所顯示的文字,缺點在於字體小而難以判讀。

Comment函數

3.製作顯示文字用的函數

在前文當中,使用的是一般的Comment函數,並說明了如何將文字顯示於圖表上。接下來,將客製化指定該文字的顯示位置、尺寸以及顏色。

在檔案「Custom indicator iteration function」的下方設定「Comment function」,於該處製作顯示文字用的函數。本次將能夠指定文字、字體、位置、行距、尺寸、顏色並執行處理。首先,在接收到文字時,因希望透過換行來判斷文字並置於行列中,故需要先定義行列。

void CommentEx(string text, string font, int x, int y, int gap, int size, color clr)

{

string comment[];

}
其次,使用while文體進行反覆處理。While文體與for文體不同,只要處於括弧中的條件成立期間,便會持續重複執行處理動作。在此處的括弧中置入「true」作為無限迴圈,並在if文體的條件成立時,以「break」來強制中斷該無限迴圈。

定義「pos」與「pre」,在文字列中尋找換行的位置寫入pos。當pos並非-1時(找到換行的時候),便會擷取前一次位置至換行位置之間的文字,納入於comment序列當中。其後,如欲從換行之後的位置開始搜尋,便須在該位置先代入pre。由於comment序列最初並無尺寸設定,因此可使用「ArrayResize」來依次放大。

int pos = 0, pre = 0;

while (true) {

int n = ArraySize(comment);

ArrayResize(comment, n + 1);

pos = StringFind(text, “\n”, pre);

if (pos != -1) {

comment[n] = StringSubstr(text, pre, pos – pre);

pre = pos + 1;


另外,當pos為-1時(找不到換行的時候),便會就此結束反覆處理的動作。

} else {

comment[n] = StringSubstr(text, pre);

break;

}

4.複製Label物件的範例編碼

由於本次利用Label元件來顯示文字,因此可從MQL4幫助檔中,複製Label物件的範例編碼。於MQL4相關參考目錄中點選「Constants, Enumerations and Structures」→「Objects Constants」→「Object Types」,便會顯示物件一覽表。從中選擇「OBJ_LABEL」,並將預先準備的「Create a text label」編碼複製貼上於檔案的下方。

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

//| Create a text label |

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

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

const string name = “Label”, // label name

const int sub_window = 0, // subwindow index

const int x = 0, // X coordinate

const int y = 0, // Y coordinate

const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring

const string text = “Label”, // text

const string font = “Arial”, // font

const int font_size = 10, // font size

const color clr = clrRed, // color

const double angle = 0.0, // text slope

const ENUM_ANCHOR_POINT anchor = ANCHOR_LEFT_UPPER, // 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

{

//— reset the error value

ResetLastError();

//— create a text label

if(!ObjectCreate(chart_ID, name, OBJ_LABEL, sub_window, 0, 0)) {

Print(__FUNCTION__,

“: failed to create text label! Error code = “, GetLastError());

return(false);

}

//— set label coordinates

ObjectSetInteger(chart_ID, name, OBJPROP_XDISTANCE, x);

ObjectSetInteger(chart_ID, name, OBJPROP_YDISTANCE, y);

//— set the chart’s corner, relative to which point coordinates are defined

ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, corner);

//— 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 label 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);

}

5.以LabelCreate顯示文字

上述文章中,製作了顯示文字用的函數,並複製Label元件的範例編碼加以運用。接下來,將以LabelCreate依序顯示納入comment序列的文字。

圖表ID設定為「0」、名稱為「PREFIX + “Text” + (string)i」,視窗為主視窗,因此是「0」、位置的X座標為「x」、Y座標為「y + i * gap」,因希望置於左上方,故區域採用「CORNER_LEFT_UPPER」,顯示文字則是納入序列的文字「comment[i]」,字體為「font」、尺寸為「size」、顏色為「clr」、角度為「0」、錨定則是「ANCHOR_LEFT_UPPER」。

for (int i = 0; i < ArraySize(comment); i++) {

LabelCreate(0, PREFIX + “Text” + (string)i, 0, x, y + i * gap, CORNER_LEFT_UPPER, comment[i], font, size, clr, 0, ANCHOR_LEFT_UPPER);

}
然後,執行已製作的「CommentEx」函數,作為「Comment(text)」的替代品。在OnCalculate函數內的Comment(text)前端加上「//」作為備註,並在其下添加下列編碼。字體設定為「Meiryo」、顏色為「clrAqua」。

CommentEx(text, “メイリオ”, 0, 15, 25, 14, clrAqua);
如此進行編譯,就會在圖表的左上方看見大型的水藍色文字。透過此方式製作顯示文字用的函數,將能夠指定Comment函數無法處理的文字尺寸等參數。

Comment函數

6.原始碼

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

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

//| CommentEx.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 MQLInfoString(MQL_PROGRAM_NAME) + “_”

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

//| Custom indicator initialization function |

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

int OnInit()

{

//— indicator buffers mapping

//—

return(INIT_SUCCEEDED);

}

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

//| Custom indicator deinitialization function |

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

void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, PREFIX);

Comment(“”);

}

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

//| 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[])

{

//—

string text = “123\n345\nabc\ndef\nあいうえお\nかきくけこ”;

// Comment(text);

CommentEx(text, “メイリオ”, 0, 15, 25, 14, clrAqua);

//— return value of prev_calculated for next call

return(rates_total);

}

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

//| Comment function |

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

void CommentEx(string text, string font, int x, int y, int gap, int size, color clr)

{

string comment[];

int pos = 0, pre = 0;

while (true) {

int n = ArraySize(comment);

ArrayResize(comment, n + 1);

pos = StringFind(text, “\n”, pre);

if (pos != -1) {

comment[n] = StringSubstr(text, pre, pos – pre);

pre = pos + 1;

} else {

comment[n] = StringSubstr(text, pre);

break;

}

}

for (int i = 0; i < ArraySize(comment); i++) {

LabelCreate(0, PREFIX + “Text” + (string)i, 0, x, y + i * gap, CORNER_LEFT_UPPER, comment[i], font, size, clr, 0, ANCHOR_LEFT_UPPER);

}

}

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

//| Create a text label |

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

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

const string name = “Label”, // label name

const int sub_window = 0, // subwindow index

const int x = 0, // X coordinate

const int y = 0, // Y coordinate

const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring

const string text = “Label”, // text

const string font = “Arial”, // font

const int font_size = 10, // font size

const color clr = clrRed, // color

const double angle = 0.0, // text slope

const ENUM_ANCHOR_POINT anchor = ANCHOR_LEFT_UPPER, // 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

{

//— reset the error value

ResetLastError();

//— create a text label

if(!ObjectCreate(chart_ID, name, OBJ_LABEL, sub_window, 0, 0)) {

Print(__FUNCTION__,

“: failed to create text label! Error code = “, GetLastError());

return(false);

}

//— set label coordinates

ObjectSetInteger(chart_ID, name, OBJPROP_XDISTANCE, x);

ObjectSetInteger(chart_ID, name, OBJPROP_YDISTANCE, y);

//— set the chart’s corner, relative to which point coordinates are defined

ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, corner);

//— 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 label 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美元的資金進行交易。

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