程式交易教學

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

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



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

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

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



在早盤頭皮EA中加入追蹤停損功能【複製源碼就可以使用】


本篇文章並不是確認「最大持倉數量」,而是測試加入「追蹤停損」功能後會有什麼樣的結果。

追蹤停損的優點與缺點

首先介紹一下追蹤停損的優點與缺點。

<優點>

優點是即可以控制風險還可以擴大收益

由於追蹤停損被執行時停損點就會被提高,所以,與簡單的停損停利的結算方式相比,獲利的機會更大。

<缺點>

其缺點就是,在產生小幅盈利時就會結算,從而錯失本可以獲得更大利潤

為了防止小幅盈利,需要緊密調整追蹤停損的幅度。

如果追蹤停損的幅度設置不正確的話,有可能會出現「輕微反彈就馬上結算」或「追蹤停損本身不會被執行」。

    追蹤停損的種類

    加入追蹤停損時有多種方法。

    例如,「當達到一定收益幅度時上移停損點」、「產生一點收益就上移停損點」、「根據行情趨勢修改幅度」等方法。

    追蹤停損如果與EA邏輯相匹配的話,將會成為擴大收益的有力武器。

說明

首先介紹上次製作的EA。

・下單

時間在台灣時間清晨,並且RSI低於超賣線時下多單

時間在台灣時間清晨,並且RSI高於超買線時下空單

・平倉

根據停利價格和停損價格平倉

・其他

Copyright設置為「OANDA」

透過滑點和點差限制下單數量

設置為只能持有1個部位

可以修改Magic Number和手數

以上內容是上次製作的EA。

這次將會用追蹤停損來控制停損,所以要把平倉邏輯「根據停損價格平倉」修改為「根據追蹤停損來停損平倉」。

製作EA

本程式是以上次的「製作早盤頭皮EA」為基礎製作,所以跳過上次內容,本篇文章至介紹加入的功能。

領域

input int MAGICMA = 23498721; // Magic Number
input double Lots =0.01; // 1手為10萬貨幣
input int Slippage = 4; // 限制下單滑點
input double MaxSpread = 5; // 限制下單點差
input double TakeProfit = 30.0; // 停利點數(pips)
input int RSIPeriod=6; // 週期
input ENUM_APPLIED_PRICE RSIAppliedPrice = PRICE_CLOSE; // 價格來源
input int UpLine = 85; // 上線
input int DownLine = 25; // 下線
input int TradeTime = 0; // 交易時間
input int TrailWidth = 10; // 追蹤幅度(pips)

double dSpread;
在上次程式中,刪除了「停損點數(pips)」,新添加了「追蹤幅度(pips)」參數。

OnTick函數

void OnTick()
{
dSpread = (Ask - Bid) / (Point * 10);
if(CalculateCurrentOrders()==0 && dSpread < MaxSpread) CheckForOpen(); 上次
TrailingStop(); //這次

}
這是OnTick函數。

這次準備了一個簡單易懂的TrailingStop函數,只需在OnTick函數中調用該函數就可以執行追蹤停損。

CheckForOpen函數

void CheckForOpen()
{
int res;
double RSI = iRSI(Symbol(), 0, RSIPeriod, RSIAppliedPrice, 1);
if(TradeTime == TimeHour(Time[1]))
{
if(RSI < DownLine)
{
res=OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Bid - TrailWidth * Point * 10, Ask + TakeProfit * Point * 10,"", MAGICMA, 0, Red);
}
if(RSI > UpLine)
{
res=OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, Ask + TrailWidth * Point * 10, Bid - TakeProfit * Point * 10, "", MAGICMA, 0, Blue);
}
}
}
把OrderSend函數的停損價格修改為TrailWidth參數。

這樣,TrailWidth數值就會成為持有部位時停損幅度。

TrailingStop函數

for (int i = OrdersTotal() - 1; i >= 0; i--){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderType() == OP_BUY){
if ((Bid - OrderStopLoss()) / (Point * 10) > TrailWidth * 2){ //①
int om = OrderModify(OrderTicket(), //②
OrderOpenPrice(),
OrderStopLoss() + TrailWidth * (Point * 10),
OrderTakeProfit(),
OrderExpiration());
}
}
if (OrderType() == OP_SELL){
if ((OrderStopLoss() - Ask) / (Point * 10) > TrailWidth * 2){ //①
int om = OrderModify(OrderTicket(), //②
OrderOpenPrice(),
OrderStopLoss() - TrailWidth * (Point * 10),
OrderTakeProfit(),
OrderExpiration());
}
}
}
操作很簡單,對持有的部位執行2個處理,「①確認是否滿足追蹤停損的條件」、「②如果滿足追蹤停損條件,使用OrderModify函數上移停損點」。

接下來逐一介紹關於2個處理的內容。

①確認是否滿足追蹤停損的條件

if ((Bid - OrderStopLoss()) / (Point * 10) > TrailWidth * 2){
以買入部位為例。

左邊是在求當前價格和停損價格的幅度(pips),然後判斷其數字是否大約TrailWidth參數的2倍數值。這裡設置為TrailWidth 的2倍是一個重要的點。

因為左邊不是「當前價格和下單價格的幅度」,而是「當前價格和停損價格的幅度」,所以需要設置為2倍。

②使用OrderModify函數上移停損點

int om = OrderModify(OrderTicket(),
OrderOpenPrice(),
OrderStopLoss() - TrailWidth * (Point * 10),
OrderTakeProfit(),
OrderExpiration());
第3個參數是指定停損價格的參數。

如果滿足追蹤停損的條件的話,停損點將會按照TrailWidth參數的數值上移。

回測結果

這次製作的追蹤停損EA與上次製作的只開一部位EA的回測結果進行比較。
貨幣對:GBPUSD 時間週期:5分鐘 時間:從2018年1月1日至2023年1月1日的5年時間 點差:固定為15
    貨幣對:GBPUSD
    時間週期:5分鐘
    時間:從2018年1月1日至2023年1月1日的5年時間
    點差:固定為15

・一部位EA

一部位EA

・追蹤停損EA

追蹤停損EA

「交易次數」從511次上升至714次。

這是因為追蹤停損把停損點上移,與平常的停損邏輯相比會提前平倉。

另外,從曲線圖中也可以看出,一部位EA有很多波折,而追蹤停損EA會更加平滑。

這種曲線圖的形狀也是追蹤停損EA的特徵之一。

但是,「勝率」且大幅下降到35.29%。

這也是因為追蹤停損EA的會提前停損,反而證明了可以穩定盈利。

關於勝率,如果對參數進行優化的話還有可能會提升。

注意事項

這次回測是在固定點差中進行。

台灣時間早盤的特徵是,市場波動相對較小,點差容易擴大

在實際操作中需要充分注意點差,對點差設置限制等措施。

完整源碼

#property copyright "Copyright(C) 2023, OANDA"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict

input int MAGICMA = 23498721; // Magic Number
input double Lots =0.01; // 1手為10萬貨幣
input int Slippage = 4; // 限制下單滑點
input double MaxSpread = 5; // 限制下單點差
input double TakeProfit = 30.0; // 停利點數(pips)
input int RSIPeriod=6; // 週期
input ENUM_APPLIED_PRICE RSIAppliedPrice = PRICE_CLOSE; // 價格來源
input int UpLine = 85; // 上線
input int DownLine = 25; // 下線
input int TradeTime = 0; // 交易時間
input int TrailWidth = 10; // 追蹤幅度(pips)

double dSpread;

int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnTick()
{
dSpread = (Ask - Bid) / (Point * 10);
if(CalculateCurrentOrders()==0 && dSpread < MaxSpread) CheckForOpen();
TrailingStop();
}
void CheckForOpen()
{
int res;
double RSI = iRSI(Symbol(), 0, RSIPeriod, RSIAppliedPrice, 1);
if(TradeTime == TimeHour(Time[1]))
{
if(RSI < DownLine)
{
res=OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Bid - TrailWidth * Point * 10, Ask + TakeProfit * Point * 10,"", MAGICMA, 0, Red);
}
if(RSI > UpLine)
{
res=OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, Ask + TrailWidth * Point * 10, Bid - TakeProfit * Point * 10, "", MAGICMA, 0, Blue);
}
}
}

int CalculateCurrentOrders()
{
int positions = 0;
for(int i=0;i= 0; i--){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if (OrderType() == OP_BUY){
if ((Bid - OrderStopLoss()) / (Point * 10) > TrailWidth * 2){
int om = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss() + TrailWidth * (Point * 10), OrderTakeProfit(), OrderExpiration());
}
}
if (OrderType() == OP_SELL){
if ((OrderStopLoss() - Ask) / (Point * 10) > TrailWidth * 2){
int om = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss() - TrailWidth * (Point * 10), OrderTakeProfit(), OrderExpiration());
}
}
}
}

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

EA

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

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

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



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

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

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