- 登入
- 註冊
前幾篇文章中已經有提到 EA 基礎語法的使用,本篇文章用以下的程式直接來說明一支完整交易策略該具備的要素,包含策略邏輯、進出場、停利停損設置、訂單管理等功能。
如果要免費使用 MT4 或進行模擬交易,可以使用 OANDA 安達,進入外匯市場的首選經紀商完整介紹!
(一)限制:
(二) 進場條件:前一根 K棒往下收過當前 MA 即作空、往上收過作多
(三) 出場條件:
這裡使用 #define 來定義 MAGICMA 這個常數,因為魔術碼不會變動。
#define MAGICMA 20131111
這幾行定義了基礎手數(Lots)、最大風險(MaximumRisk)、減少因子(DecreaseFactor)、MA參數(MovingPeriod、MovingShift)、停利停損點數(TP、SL) 。
input double Lots =0.1;
input double MaximumRisk =0.02;
input double DecreaseFactor =3;
input int MovingPeriod =12;
input int MovingShift =6;
input int TP =300;
input int SL =100;
計算目前持倉單量與方向,若有1張多單回傳”1″,有2張空單回傳”-2″ 。
int CalculateCurrentOrders() {
int buys=0,sells=0; // 初始化多空單量
// 走訪所有持倉訂單
for(int i=0;i<OrdersTotal();i++) {
// 使用OrderSelect選取訂單,若選取失敗則使用break語法退出訂單走訪
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
// 判斷選取的訂單貨幣對與魔術碼是否跟該EA一致
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA) {
// 選取的訂單為多單則將buys加一
if(OrderType()==OP_BUY) buys++;
// 選取的訂單為空單則將sells加一
if(OrderType()==OP_SELL) sells++;
}
}
// 判斷持倉多空方向並回傳
if(buys>0) return(buys);
else return(-sells);
}
double LotsOptimized() {
double lot=Lots;
int orders=HistoryTotal(); // 取得歷史訂單數
int losses=0; // 初始化虧損訂單數
// 用最大風險(MaximumRisk)參數取得下單手數
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
// 當減少因子大於0時計算虧損訂單數,用虧損訂單數計算出下單手數
if(DecreaseFactor>0) {
// 走訪歷史訂單
for(int i=orders-1;i>=0;i–) {
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) {
Print(“Error in history!”);
break;
}
// 若選取的訂單不是當前貨幣兌或為掛單則使用continue語法跳過計算
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
continue;
// 當該訂單有盈利時跳出迴圈
if(OrderProfit()>0) break;
// 當該訂單虧損時將losses加一
if(OrderProfit()<0) losses++;
}
// 有虧損訂單則重新計算下單手數
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
// 回傳下單手數,最小值為0.1
if(lot<0.1) lot=0.1;
return(lot);
}
void CheckForOpen() {
double ma;
int res;
double sl;
double tp;
// 當前K棒成交量大於1時代表不是開盤第一個tick所以直接退出函式
if(Volume[0]>1) return;
// 取得最新K棒MA數值
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
// 前一根K棒往下收過當前MA
if(Open[1]>ma && Close[1]<ma) {
// 下單
res=OrderSend(
Symbol(), // 當前EA掛載的商品
OP_SELL, // 市價空單
LotsOptimized(), // 透過LotsOptimized函式取得下單手數
Bid, // 買價
3, // 滑點
0, // 停損,這裡先不設停損,確定成交後再修改訂單設置停損
0, // 停利,這裡先不設停利,確定成交後再修改訂單設置停利
“”, // 備註
MAGICMA, // 魔術碼
0,
Red
);
// 下單回傳值不為-1則表示下單成功,且該值為訂單編號
if(res != -1) {
// 使用訂單編號選取訂單
OrderSelect(res, SELECT_BY_TICKET);
// 用進場價計算停利停損
tp = NormalizeDouble(OrderOpenPrice()-TP*Point, Digits);
sl = NormalizeDouble(OrderOpenPrice()+SL*Point, Digits);
// 修改訂單設置停利停損
OrderModify(res, OrderOpenPrice(), sl, tp, 0);
}
return;
}
// 前一根K棒往上收過當前MA
if(Open[1]<ma && Close[1]>ma) {
res=OrderSend(Symbol(),
OP_BUY, // 市價多單
LotsOptimized(),
Ask, // 賣價
3,0,0,””,MAGICMA,0,Blue);
if(res != -1) {
OrderSelect(res, SELECT_BY_TICKET);
tp = NormalizeDouble(OrderOpenPrice()+TP*Point, Digits);
sl = NormalizeDouble(OrderOpenPrice()-SL*Point, Digits);
OrderModify(res, OrderOpenPrice(), sl, tp, 0);
}
return;
}
}
void CheckForClose() {
double ma;
// 當前K棒成交量大於1時代表不是開盤第一個tick所以直接退出函式
if(Volume[0]>1) return;
// 取得最新K棒MA數值
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
// 走訪持倉訂單
for(int i=0;i<OrdersTotal();i++) {
// 選取訂單
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
// 該訂單並非該EA下的或不是EA掛載的商品則跳過
if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
// 若該訂單為多單
if(OrderType()==OP_BUY) {
// 多單出場條件前一根K棒往下收過當前MA
if(Open[1]>ma && Close[1]<ma) {
// 平倉
if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White))
Print(“OrderClose error “,GetLastError());
}
break;
}
// 若該訂單為空單
if(OrderType()==OP_SELL) {
// 空單出場條件前一根K棒往上收過當前MA
if(Open[1]<ma && Close[1]>ma) {
if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))
Print(“OrderClose error “,GetLastError());
}
break;
}
}
}
//+— — — — — — — — — — — — — — +
// | OnTick function |
//+— — — — — — — — — — — — — — +
void OnTick() {
// 若圖表K棒數量小於100或不允許EA自動交易則退出
if(Bars<100 || IsTradeAllowed()==false)
return;
// 透過呼叫自定義函式CalculateCurrentOrders計算目前持倉單量與方向,為0表示無持倉可以進入下單判斷
if(CalculateCurrentOrders()==0) CheckForOpen();
// 有單則進入出場判斷
else CheckForClose();
}
//+— — — — — — — — — — — — — — +
以上是一個包含各種基礎語法運用的 EA 範例,這其實就是 MT4 內建的「Moving Average」EA,我們在這只是加上了獨立的停利與停損,模仿是學習最好的途徑,去理解他人的做法並從中擷取有用的技巧,祝各位能成功寫出自己覺得滿意的 EA。
這篇文章真棒!
請問這MT4的EA語法教學有出書嗎?哪裡可以買到?
目前我們沒有出相關的書籍,可以參考我們的線上課程
https://quantpass.org/mt4_course_all/