程式交易教學

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

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



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

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

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



利用圖表操作函數並一次執行所有圖表的方法

透過「OnChartEvent」製作雛形

在本篇章節中,將會介紹使用圖表操作函數,來同時操作所有圖表的方法。首先將製作檔案的雛形;在創建新文檔的畫面選擇「自訂指標」,檔案名稱則命名為「SyncDemo」。

自訂指標

在「自訂指標程式的事件處理常式」中勾選「OnChartEvent」,再點擊「完成」即可完成雛形。

OnChartEvent

同步K線的尺寸

首先將同步K線的尺寸;由於將在放大或縮小圖表時進行動作,因此應寫入以下的if文體,以取得圖表的原始尺寸。

if (id == CHARTEVENT_CHART_CHANGE){

int scale = (int)ChartGetInteger(0, CHART_SCALE);
其次,將在複數圖表中取得最初的圖表ID;定義「ChartFirst」函數,以while文字進行反覆處理。

long chart_id = ChartFirst();

while (true) {
以while文字進行反覆處理,意指「當該圖表的圖表ID與操作中圖表的尺寸不合時,將會使其符合操作中圖表的尺寸」。而為了避免編輯到原始的圖表,可在一開始先寫入「if (Chart_id != ChartID())」的if文體,如此便不會在圖表ID一致時進行動作。另外,也會使用「ChartRedraw」函數來更新指定的圖表。

if (chart_id != ChartID()) {

if (ChartGetInteger(chart_id, CHART_SCALE) != scale) {

ChartSetInteger(chart_id, CHART_SCALE, scale);

}

ChartRedraw(chart_id);

}
進行處理之後,取得的圖表ID將會透過「ChartNext」函數送至下一步。若搜尋不到下一個圖表,則該函數會返回「-1」;可添加「break;」避免在這樣的狀況下進行反覆處理。

cfhart_id = ChartNext(chart_id);

if (chart_id < 0) break;
如此進行編譯、設定兩個圖表,並變更最初的圖表K線尺寸後,即可進行同步、改變另一方的圖表K線尺寸。

同步圖表的時間位置

其次,將在點擊圖表時(點擊滑鼠游標時)同步圖表的時間位置。

本次將同步K線尺寸的編碼另做他用,使用「CHARTEVENT_CLICK」來定義點擊圖表時的處理動作。由於只要在圖表的自動滾動功能關閉時進行同步,因此如下所示採用「CHART_AUTOSCROLL」。

if (id == CHARTEVENT_CLICK) {

bool auto = (bool)ChartGetInteger(0, CHART_AUTOSCROLL);
接著要添加取得時間資訊的編碼。「CHART_FIRST_VISIBLE_BAR」為顯示於圖表左端的K線編號,「CHART_WIDTH_IN_BARS」則代表圖表整體寬度的K線數量。若barR(右端的K線編號)為負數,則設定為「0」,並以「datetime」函數來變更為時間。

int barR = int(ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR) – ChartGetInteger(0, CHART_WIDTH_IN_BARS));

if (barR < 0) barR = 0;

datetime timeR = Time[barR];
另外,以while文字變更為反覆處理。使用「ChartSetInteger」於操作的圖表、而非「ChartGetInteger」;接著將變更的時間與圖表K線同步。

if (chart_id != ChartID() && !auto) {

ChartSetInteger(chart_id, CHART_AUTOSCROLL, false);

int bar = iBarShift(ChartSymbol(chart_id), ChartPeriod(chart_id), timeR);
在此使用「ChartNavigate」函數,以移動指定圖表的時間。因為需要對齊圖表的右側,圖表位置可設定為「CHART_END」;此時若採用「-bar – 2」,將會正好符合。

ChartNavigate(chart_id, CHART_END, -bar – 2);

ChartRedraw(chart_id);
如此進行編譯後,將在滾動原本圖表時同步另一方的圖表。

圖表

去除移動右端表格導致的時間位置誤差

最後,將解決移動右端表格時所產生的位置誤差問題。在「int bar = iBarShift(ChartSymbol(chart_id), ChartPeriod(chart_id), timeR);」下方添加以下編碼;圖表的變更尺寸(CHART_SHIFT_SIZE)設定範圍為10~50%。

變更尺寸意指變更圖表右端將產生的留白比例;若設定為50%,則會延伸至圖表的中央。從變更的尺寸、以及圖表整體寬度的K線數量中,將可計算出變更份量等同於幾條K線。將整體寬度的線條數量乘以變更尺寸、再除以100,即可變更為int型(整數)。

int shift = 0;

if (ChartGetInteger(chart_id, CHART_SHIFT)) {

shift = int(ChartGetInteger(chart_id, CHART_WIDTH_IN_BARS) * ChartGetDouble(chart_id, CHART_SHIFT_SIZE) / 100);

}
另外,在「ChartNavigate(chart_id, CHART_END, -bar – 2);」文中添加「- shift」。

ChartNavigate(chart_id, CHART_END, -bar ? 2 – shift);
如此進行編譯,即使進行移動也能夠正確同步;嘗試移動不同時間的4種圖表,便能發現各個時間的圖表皆同步為適當的時間。

不同時間的4種圖表

原始碼

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

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

//| SyncDemo.mq4 |

//| Copyright 2021, MetaQuotes Software Corp. |

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

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

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

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

#property version “1.00”

#property strict

#property indicator_chart_window

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

//| Custom indicator initialization function |

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

int OnInit()

{

//— indicator buffers mapping

//—

return(INIT_SUCCEEDED);

}

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

//| 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_CHART_CHANGE) {

int scale = (int)ChartGetInteger(0, CHART_SCALE);

long chart_id = ChartFirst();

while (true) {

if (chart_id != ChartID()) {

if (ChartGetInteger(chart_id, CHART_SCALE) != scale) {

ChartSetInteger(chart_id, CHART_SCALE, scale);

}

ChartRedraw(chart_id);

}

chart_id = ChartNext(chart_id);

if (chart_id < 0) break;

}

}

if (id == CHARTEVENT_CLICK) {

bool auto = (bool)ChartGetInteger(0, CHART_AUTOSCROLL);

int barR = int(ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR) – ChartGetInteger(0, CHART_WIDTH_IN_BARS));

if (barR < 0) barR = 0;

datetime timeR = Time[barR];

long chart_id = ChartFirst();

while (true) {

if (chart_id != ChartID() && !auto) {

ChartSetInteger(chart_id, CHART_AUTOSCROLL, false);

int bar = iBarShift(ChartSymbol(chart_id), ChartPeriod(chart_id), timeR);

int shift = 0;

if (ChartGetInteger(chart_id, CHART_SHIFT)) {

shift = int(ChartGetInteger(chart_id, CHART_WIDTH_IN_BARS) * ChartGetDouble(chart_id, CHART_SHIFT_SIZE) / 100);

}

ChartNavigate(chart_id, CHART_END, -bar – 2 – shift);

ChartRedraw(chart_id);

}

chart_id = ChartNext(chart_id);

if (chart_id < 0) break;

}

}

}

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

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

EA

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

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

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



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

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

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