程式交易教學

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

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



全面升級——更多功能、更大靈活性!
優化了“固定最大虧損”,“每日虧損限制”等。查看詳情全新「Boost」計劃

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

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



運用MQL程式語言來製作顯示3條RCI的方式

改寫為3條顯示

本章的內容雖然並不是MT4的預設指標、但被交易人所廣泛使用的RCI。

此處將使用免費公開的「HT_RCI」指標作為模板,並說明其修改的重點。

其本的檔案只會顯示1條RCI,而此處將修改為顯示3條RCI。首先,由於尚未設定緩衝區數量,因此需新增至「3」,並設定其各自的公式、顏色、寬度以及線條種類。寬度以及線條種類可維持不變,顏色則設定為白色、黃色及紅色。

#property indicator_buffers 3

#property indicator_plots 3

#property indicator_color1 clrWhite

#property indicator_color2 clrYellow

#property indicator_color3 clrRed

#property indicator_width1 1

#property indicator_width2 1

#property indicator_width3 1

#property indicator_style1 STYLE_SOLID

#property indicator_style2 STYLE_SOLID

#property indicator_style3 STYLE_SOLID
RCI週期設定為為短期「10」、中期「20」、長期「50」。

input int PERIOD_S = 10; // 短期

input int PERIOD_M = 20; // 中期

input int PERIOD_L = 50; // 長期
緩衝區也新增至可供其個別使用,設定為「0」「1」「2」。

double RCI0[], RCI1[], RCI2[];
針對這些緩衝區,需新增其各自的設定。「Label」將改寫為可分別顯示週期的方式,「string name」則以逗號來連接各個週期。

SetIndexBuffer(0, RCI0, INDICATOR_DATA);

SetIndexBuffer(1, RCI1, INDICATOR_DATA);

SetIndexBuffer(2, RCI2, INDICATOR_DATA);

SetIndexLabel(0, “RCI(” + (string)PERIOD_S + “)”);

SetIndexLabel(1, “RCI(” + (string)PERIOD_M + “)”);

SetIndexLabel(2, “RCI(” + (string)PERIOD_L + “)”);

string name = “RCI(” + (string)PERIOD_S + “,” + (string)PERIOD_M + “,” + (string)PERIOD_L + “)”;
計算內容也將分別設定3個種類。

for(int i = limit; i >= 0; i–) {

RCI0[i] = iRCI(NULL, 0, PERIOD_S, i);

RCI1[i] = iRCI(NULL, 0, PERIOD_M, i);

RCI2[i] = iRCI(NULL, 0, PERIOD_L, i);
計算的BARS則應避免設定過多的數量。

input int BARS = 500; // 計算條列數量

計算「BARS」的條列數量將暫定為500條列,意指最多不會計算超過500條列。

int limit = MathMin(Bars – 1, BARS);
針對設定的參數、以及整體「BARS」的條列數量,此處將只計算其中較小的一項;透過以上的修改,將可顯示3條RCI。

3條RCI

設定箭頭顯示的條件

接下來,將在3條RCI依照短期、中期、長期依序並列時,製作顯示符號的條件公式。

首先將從上方開始,照著短期>中期>長期的並列狀態設定為「up」。製作「短期大於中期」、以及「中期大於長期」的條件。

此處是為了定義「bool」的條件成立與否,其亦可自前1條列 (i+1)中加以判斷。另外,針對與「up」對立排列的「dn」,將以反向符號進行相同的步驟。

bool upNow = RCI0[i] > RCI1[i] && RCI1[i] > RCI2[i];

bool upPre = RCI0[i + 1] > RCI1[i + 1] && RCI1[i + 1] > RCI2[i + 1];

bool dnNow = RCI0[i] < RCI1[i] && RCI1[i] < RCI2[i];

bool dnPre = RCI0[i + 1] < RCI1[i + 1] && RCI1[i + 1] < RCI2[i + 1];
此處使用if文法製作,設定為「目前的並列狀態成立,前1根K線則不成立」的條件。若添加「!」記號,則將使條件反轉,在此處及代表條件不成立。透過如此步驟,將會在並列成立時顯示箭頭訊號。另外,可在選單的「插入」→「符號類」中,使用箭頭物件(Arrow物件)作為顯示的箭頭。

if (upNow && !upPre)

顯示箭頭

將名稱暫定為「3RCI_Sign」,並預先寫入這是第「i」根K線的資訊。ObjectCreate函數設定為0號(目前顯示的圖表),物件種類則為「OBJ_ARROW」。由於顯示視窗為主要視窗,因此設定為「0」;此處設定「1」將代表第一個視窗分頁、「2」則代表第二個視窗分頁。雖然亦可設定時間與價格,但本次將先設定為「0」「0」。

string name = “3RCI_Sign_” + (string)i;

ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);
接下來將使用ObjectSetInteger函數來設定時間。

與前述的步驟相同,並選擇「OBJPROP_TIME」、將時間資訊設定為「i」。

ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);
ObjectSetDouble函數也同樣將買進訊號顯示為低價方;而「ANCHOR」亦可設定物件基準點的位置。若使用Arrow物件,則可選擇「TOP」或「BOTTOM」;由於本次將顯示在下方,因此選擇TOP。大小設定為「2」、顏色為紅色、箭頭編碼則為「233」。

ObjectSetDouble(0, name, OBJPROP_PRICE, 0, Low[i]);

ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP);

ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

ObjectSetInteger(0, name, OBJPROP_COLOR, clrRed);

ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 233);
此處也將設定賣出訊號。賣出的部分可選擇「BOTTOM」來顯示高價方,顏色為藍色、箭頭編碼則為「234」。如此一來,RCI便會依照短期>中期>長期的順序來顯示紅色箭頭(買進訊號),並依照短期<中期<長期的順序來顯示藍色箭頭(賣出訊號)。

3條RCI

重設顯示箭頭

顯示符號的外觀已經完成;但由於顯示的箭頭將延續下去,因此每次切換時間週期便會持續增加。

為了重設顯示方式,可使用ObjectsDeleteAll函數;其可在目前的圖表中,全部刪除已設定的文字序列等物件。透過輸入此參數,將能夠切換圖表、刪除舊箭頭、顯示新箭頭。

ObjectsDeleteAll(0, “3RCI_Sign_”);
最後刪除此指標時,將不會留下任何物件。OnDeinit函數將在切換時間軸、改變參數、結束指標時執行一次。

void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, “3RCI_Sign_”);

}
透過此步驟在圖表上刪除指標時,箭頭將會一併消失。

原始碼

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

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

//| 3RCI_Sign |

//| HT FX |

//| http://htfx.blog.fc2.com/ |

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

#property copyright “HT FX”

#property link “http://htfx.blog.fc2.com/”

#property description “Copyright (C) 2020 HT FX All Rights Reserved.\n”

#property description “http://htfx.blog.fc2.com/\n”

#property description “htfxjp@gmail.com”

#property version “1.00”

#property strict

#property indicator_separate_window

#property indicator_maximum 1

#property indicator_minimum -1

#property indicator_buffers 3

#property indicator_plots 3

#property indicator_color1 clrWhite

#property indicator_color2 clrYellow

#property indicator_color3 clrRed

#property indicator_width1 1

#property indicator_width2 1

#property indicator_width3 1

#property indicator_style1 STYLE_SOLID

#property indicator_style2 STYLE_SOLID

#property indicator_style3 STYLE_SOLID

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

//| Input parameters |

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

input int BARS = 500; // 計算條列數量

input int PERIOD_S = 10; // 短期

input int PERIOD_M = 20; // 中期

input int PERIOD_L = 50; // 長期

//— indicator buff

double RCI0[], RCI1[], RCI2[];

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

//| Custom indicator initialization function |

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

int init()

{

IndicatorSetInteger(INDICATOR_DIGITS, 6);

SetIndexStyle(0, DRAW_LINE);

SetIndexStyle(1, DRAW_LINE);

SetIndexStyle(2, DRAW_LINE);

SetIndexBuffer(0, RCI0, INDICATOR_DATA);

SetIndexBuffer(1, RCI1, INDICATOR_DATA);

SetIndexBuffer(2, RCI2, INDICATOR_DATA);

SetIndexLabel(0, “RCI(” + (string)PERIOD_S + “)”);

SetIndexLabel(1, “RCI(” + (string)PERIOD_M + “)”);

SetIndexLabel(2, “RCI(” + (string)PERIOD_L + “)”);

string name = “RCI(” + (string)PERIOD_S + “,” + (string)PERIOD_M + “,” + (string)PERIOD_L + “)”;

IndicatorSetString(INDICATOR_SHORTNAME, name);

return 0;

}

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

//| Custom indicator deinitialization function |

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

void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, “3RCI_Sign_”);

}

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

//| Custom indicator iteration function |

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

int start()

{

int counted_bars = IndicatorCounted();

//—- check for possible errors

if(counted_bars < 0) return -1;

//—- last counted bar will be recounted

if(counted_bars > 0) counted_bars–;

int limit = MathMin(Bars – 1, BARS);

// if (limit < 1) limit = 1;

ObjectsDeleteAll(0, “3RCI_Sign_”);

for(int i = limit; i >= 0; i–) {

RCI0[i] = iRCI(NULL, 0, PERIOD_S, i);

RCI1[i] = iRCI(NULL, 0, PERIOD_M, i);

RCI2[i] = iRCI(NULL, 0, PERIOD_L, i);

bool upNow = RCI0[i] > RCI1[i] && RCI1[i] > RCI2[i];

bool upPre = RCI0[i + 1] > RCI1[i + 1] && RCI1[i + 1] > RCI2[i + 1];

bool dnNow = RCI0[i] < RCI1[i] && RCI1[i] < RCI2[i];

bool dnPre = RCI0[i + 1] < RCI1[i + 1] && RCI1[i + 1] < RCI2[i + 1];

if (upNow && !upPre) {

string name = “3RCI_Sign_” + (string)i;

ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);

ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);

ObjectSetDouble(0, name, OBJPROP_PRICE, 0, Low[i]);

ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP);

ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

ObjectSetInteger(0, name, OBJPROP_COLOR, clrRed);

ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 233);

}

if (dnNow && !dnPre) {

string name = “3RCI_Sign_” + (string)i;

ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);

ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);

ObjectSetDouble(0, name, OBJPROP_PRICE, 0, High[i]);

ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_BOTTOM);

ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

ObjectSetInteger(0, name, OBJPROP_COLOR, clrDodgerBlue);

ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 234);

}

}

return 0;

}

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

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

EA

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

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

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



全面升級——更多功能、更大靈活性!
優化了“固定最大虧損”,“每日虧損限制”等。查看詳情全新「Boost」計劃

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

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