誠邀您參加全球知名外匯經紀商OANDA的自營交易(Prop Trader)
報名OANDA自營交易(Prop Trader),並通過我們的考核,您就可以使用OANDA提供的資金進行交易,獲得高達90%的交易利潤分成。
優化了挑戰塞交易規則
無最低交易天數限制等優化了挑戰賽的交易規則。
500,000美元交易資金
您可以使用最高500,000美元的資金進行交易。
豐富的交易商品
您可以交易包括外匯、黃金、原油、股票指數等多種商品。
【MQL編程基礎】|製作簡易繪圖工具的方法
1.透過建立新檔案來設定顏色、尺寸的參數
在本篇章節中,將說明製作簡易繪圖工具的方法。 為工具設定以下三項功能。-
①透過鍵盤P鍵,切換工具的ON/OFF開關。
②切換至ON時,能以滑鼠在圖表上拖曳畫線。
③透過鍵盤D鍵,刪除描繪的線條。
2.定義可一次刪除物件的前綴
由於本次將使用物件,因此要在檔案上方的屬性「#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)另外,在檔案上方的尺寸參數「input int SIZE = 5;」之下,寫入確認開關ON/OFF的變數、以及儲存游標位置的變數。
{
if (reason == REASON_REMOVE) ObjectsDeleteAll(0, PREFIX);
}
bool paint = false;
int posX, posY;
3.確認分配給P鍵的編號
接下來,將繼續製作OnChartEvent函數內的開關功能。為了確認鍵盤的操作方式,並在按下P鍵時能夠切換開關的ON/OFF,首先需確認分配給P鍵的編號。利用可得出所按按鍵編號的「CHARTEVENT_KEYDOWN」,並試著取得編號。if (id == CHARTEVENT_KEYDOWN) {如此進行編譯並設定圖表,當按下鍵盤的P鍵時,就會在終端視窗的「Expert」標籤中顯示「25」。此25即為分配給P鍵的編號。
Print(sparam);
}
4.按下鍵盤P鍵切換ON/OFF開關
上述利用了開關的ON/OFF切換,確認完分配給P鍵的編號。接下來,將使用此經過確認的編號,寫入按下P鍵時所執行的處理動作。首先利用if文體,使sparam為「25」時切換開關。開關為OFF時paint為ON,開關為ON時paint則是OFF。
if (id == CHARTEVENT_KEYDOWN) {
if (sparam == “25”) {
if (!paint) {
paint = true;
} else {
paint = false;
}
}
Print(sparam);
}
}
5.以Label物件顯示文字
為了讓開關的狀態一目了然,將以Label物件顯示大型文字。可從MQL4幫助檔中,複製Label物件的範例編碼。於MQL4相關參考目錄中點選「Constants, Enumerations and Structures」→「Objects Constants」→「Object Types」,便會顯示物件一覽表。從中選擇「OBJ_LABEL」,並將預先準備的「Create a text label」編碼複製貼上於檔案的下方。刪除不需要的「//— reset the error value」「ResetLastError();」2行,以及「Print(__FUNCTION__,」「”: failed to create text label! Error code = “,GetLastError());」2行。
另外,上方參數的「// subwindow index」「// chart corner for anchoring」「// text slope」等3行也無需使用,可加上「//」作為備註,將「if(!ObjectCreate(chart_ID, name, OBJ_LABEL, sub_window, 0, 0))」的「sub_window」處以及「ObjectSetDouble(chart_ID, name, OBJPROP_ANGLE, angle);」的「angle」處一併變更為「0」,「ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, corner);」的「corner」處則變更為「CORNER_LEFT_UPPER」。
//+——————————————————————+在此狀態下使用LabelCreate。寫入畫線處理動作的位置,則是方才if文體中的「paint = true;」下方。Id為0、名稱為「PREFIX + “switch”」、X為「5」、Y為「15」、文字為「PAINT」、字體為粗體字的「Arial Black」、尺寸為「20」、顏色為參數指定的顏色、錨定於左上方,其他則維持初始數值。
//| 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
{
//— create a text label
if(!ObjectCreate(chart_ID, name, OBJ_LABEL, 0, 0, 0)) {
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_LEFT_UPPER);
//— 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, 0);
//— 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);
}
LabelCreate(0, PREFIX + “Switch”, 5, 15, “PAINT”, “Arial Black”, 20, CLR, ANCHOR_LEFT_UPPER);另外,因希望在開關切換至OFF時刪除Label物件,故應在「paint = false;」下方寫入下列使用ObjectDelete的編碼。
ObjectDelete(0, PREFIX + “Switch”);如此進行編譯並按下P鍵,就會在圖表左上方看見「PAINT」字樣。在此狀態下,再按一次P鍵即可將其刪去。
6.設定成拖曳也不會移動的圖表
接下來,將在開關切換為ON時,使用「MOUSE_MOVE」來描繪線條。但是,若在圖表上透過拖曳游標來畫線,圖表將會出現移動,因此需避免此狀況發生。舉例來說,因拖曳物件時圖表不會隨之移動,就能夠利用此特性,在開關轉為ON時置入虛擬物件,將圖表設定為不會移動。首先於「posX」置入「lparam」、於「posY」置入「dparam」。if (id == CHARTEVENT_MOUSE_MOVE) {其後在「LabelCreate(0, PREFIX + “Switch”, 5, 15, “PAINT”, “Arial Black”, 20, CLR, ANCHOR_LEFT_UPPER);」下方添加以下編碼。名稱為「Point」,並在文字處以空白表示,讓物件無法被看見。
posX = (int)lparam;
posY = (int)dparam;
LabelCreate(0, PREFIX + “Point”, posX, posY, ” “, “メイリオ”, 10000, clrNONE, ANCHOR_CENTER, false, true);當開關轉為OFF時,若希望刪除此虛擬物件,便須在「ObjectDelete(0, PREFIX + “Switch”);」下方新增以下編碼。
ObjectDelete(0, PREFIX + “Point”);並讓製作的虛擬物件隨著游標位置移動。另外,為了避免在點擊兩下時遭到取消選擇,將OBJPROP_SELECTED設為隨時有效。
if (paint) {接著,為了啟動「MOUSE_MOVE」,於OnInit函數中的「//— indicator buffers mapping」下方寫入以下編碼。
ObjectSetInteger(0, PREFIX + “Point”, OBJPROP_XDISTANCE, posX);
ObjectSetInteger(0, PREFIX + “Point”, OBJPROP_YDISTANCE, posY);
ObjectSetInteger(0, PREFIX + “Point”, OBJPROP_SELECTED, true);
}
ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);如此進行編譯並按下P鍵,圖表便不會因滑鼠拖曳而移動。
另外,亦可配合運用ChartSetInteger()的CHART_MOUSE_SCROLL。
ChartSetInteger(0, CHART_MOUSE_SCROLL, false);依照上方所示設定為false,如此即便在圖表上拖曳,圖表也不會滑動。
7.在圖表上拖曳時繪製線條
上述文章中,實行了透過P鍵來切換ON/OFF開關,並讓圖表不會因滑鼠拖曳而移動。接下來,將寫入游標在圖表上拖曳時(點擊並移動時)繪製線條的處理動作。首先在「posY = (int)dparam;」下方,定義記憶前一個游標座標的函數「preX」「preY」。
static int preX, preY;利用if文體,當點擊滑鼠時,若與儲存的座標相異,便會在該處執行繪圖處理。將繪製的圖案設定為「●」標記。
if (sparam == “1”) {由於希望在paint處理為OFF時重新設定,因此在「if (paint)」新增else。
if (posX != preX || posY != preY) {
string name = PREFIX + “Parint_” + (string)preX + “_” + (string)preY;
LabelCreate(0, name, posX, posY, “●”, “メイリオ”, SIZE, CLR, ANCHOR_CENTER);
}
preX = posX;
preY = posY;
}
} else {如此進行編譯並按下P鍵,就能在拖曳游標時繪製線條與文字。
preX = 0;
preY = 0;
}
8.以D鍵刪除繪製的線條
最後的設定,是當按下D鍵時刪除繪製的線條。分配給D鍵的編號為「32」。運用if文體,當「sparam」為32時刪除元件。將「Print(sparam);」替換為以下內容。if (sparam == “32”) ObjectsDeleteAll(0, PREFIX);如此進行編譯並按下D,方才描繪的物件便會消失。
更甚,若添加將paint的開關也設定為OFF的「paint = false;」,即可完成簡易的繪圖工具。
if (sparam == “32”) {
ObjectsDeleteAll(0, PREFIX);
paint = false;
}
9.原始碼
本次製作的原始碼如以下所示。//+——————————————————————+
//| EasyPaint.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) + “_”
//— input parameters
input color CLR = clrWhite;
input int SIZE = 5;
bool paint = false;
int posX, posY;
//+——————————————————————+
//| Custom indicator initialization function |
//+——————————————————————+
int OnInit()
{
//— indicator buffers mapping
ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
//—
return(INIT_SUCCEEDED);
}
//+——————————————————————+
//| Custom indicator deinitialization function |
//+——————————————————————+
void OnDeinit(const int reason)
{
if (reason == REASON_REMOVE) 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[])
{
//—
//— return value of prev_calculated for next call
return(rates_total);
}
//+——————————————————————+
//| ChartEvent function |
//+——————————————————————+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//—
if (id == CHARTEVENT_KEYDOWN) {
if (sparam == “25”) {
if (!paint) {
paint = true;
LabelCreate(0, PREFIX + “Switch”, 5, 15, “PAINT”, “Arial Black”, 20, CLR, ANCHOR_LEFT_UPPER);
LabelCreate(0, PREFIX + “Point”, posX, posY, ” “, “メイリオ”, 10000, clrNONE, ANCHOR_CENTER, false, true);
} else {
paint = false;
ObjectDelete(0, PREFIX + “Switch”);
ObjectDelete(0, PREFIX + “Point”);
}
}
if (sparam == “32”) {
ObjectsDeleteAll(0, PREFIX);
paint = false;
}
}
if (id == CHARTEVENT_MOUSE_MOVE) {
posX = (int)lparam;
posY = (int)dparam;
static int preX, preY;
if (paint) {
ObjectSetInteger(0, PREFIX + “Point”, OBJPROP_XDISTANCE, posX);
ObjectSetInteger(0, PREFIX + “Point”, OBJPROP_YDISTANCE, posY);
ObjectSetInteger(0, PREFIX + “Point”, OBJPROP_SELECTED, true);
if (sparam == “1”) {
if (posX != preX || posY != preY) {
string name = PREFIX + “Parint_” + (string)preX + “_” + (string)preY;
LabelCreate(0, name, posX, posY, “●”, “メイリオ”, SIZE, CLR, ANCHOR_CENTER);
}
preX = posX;
preY = posY;
}
} else {
preX = 0;
preY = 0;
}
}
}
//+——————————————————————+
//| 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
{
//— create a text label
if(!ObjectCreate(chart_ID, name, OBJ_LABEL, 0, 0, 0)) {
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_LEFT_UPPER);
//— 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, 0);
//— 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自動程式交易的基本知識,以及在MT4/MT5平台上的安裝、參數設定方法、編碼等等內容。另外,對持有OANDA帳戶的客戶,還可以免費使用我們的獨有EA與指標工具。
誠邀您參加全球知名外匯經紀商OANDA的自營交易(Prop Trader)
報名OANDA自營交易(Prop Trader),並通過我們的考核,您就可以使用OANDA提供的資金進行交易,獲得高達90%的交易利潤分成。
優化了挑戰塞交易規則
無最低交易天數限制等優化了挑戰賽的交易規則。
500,000美元交易資金
您可以使用最高500,000美元的資金進行交易。
豐富的交易商品
您可以交易包括外匯、黃金、原油、股票指數等多種商品。