Trong bài này chúng ta sẽ áp dụng Stop Loss/ Take Profit (SL/TP) trong EA mà chúng ta đã phát triển trong bài Viết chương trình Simple Buy EA. SL/TP là biện pháp thường được sử dụng trong trading nhằm hạn chế rủi ro cũng như thu về lợi nhuận mong muốn. Ví dụ khi ta mở một vị thế Long, mục tiêu lãi của chúng ta là 50 pips và trong trường hợp rủi ro chúng ta không muốn lỗ quá 20 pips thì ta sẽ đặt SL= 20 pips và TP= 50 pips.
Với Stop loss, chúng ta có thể chia thành hai loại chính là Hard-SL và Rule based SL. Hard-SL là SL mà ta thiết lập giá trị SL cố định, không thay đổi theo thời gian còn Rule based SL là giá trị SL có thể thay đổi tùy theo tiêu chuẩn của chúng ta (ví dụ như SL thay đổi theo đường SMA, ATR,..). Một dạng Rule based SL phổ biến thường dùng là Trailing Stop (giá trị SL di chuyển theo giá thực tế ở một khoảng cách nhất định).
Để viết chương trình EA sử dụng SL/TP, chúng ta sẽ sử dụng lại code đã được trình bày trong bài Viết chương trình Simple Buy EA và bổ sung thêm SL/TP cũng như Trailing Stop. Trong phần Setting, ta định nghĩa thêm một số biến cần thiết như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | //+------------------------------------------------------------------+ //|SLTP_EA.mq5 | //|Copyright 2020, MetaQuotes Software Corp. | //| //www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link"//www.mql5.com" #property version "1.00" #include<Trade\Trade.mqh> // Define variables CTrade tradeController; double currentAsk; input int short_sma=10, medium_sma=51; int short_smaHandle, medium_smaHandle; double short_smaData[], medium_smaData[]; input int fixed_SL=50, fixed_TP=80, trailing_ST=30; // The value in pips input bool useTrailingSL=true; // True if we want to use Trailing stop double SL_price, TP_price, TrailingST_price; // The real price |
Lưu ý:
Ở đây ta thiết lập giá trị fixed_SL, fixed_TP và trailing_ST ở đơn vị pip và ta sẽ tiến hành đổi sang giá trị giao dịch thực trong phần OnTick
Giá trị short_sma và medium_sma được thay đổi là 10 và 51 theo như kết quả testing trình bày trong bài Tối ưu hóa Expert Advisors
Đối với phần OnInit và DeInit thì ta vẫn giữ nguyên code như trong bài bài Viết chương trình Simple Buy EA.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //---Get handle for sma indicators short_smaHandle= iMA(_Symbol,_Period, short_sma,0,MODE_SMA, PRICE_CLOSE); medium_smaHandle= iMA(_Symbol,_Period,medium_sma,0,MODE_SMA, PRICE_CLOSE); if(short_smaHandle<0 || medium_smaHandle<0) { Alert("Error creating SMA indicators: ", GetLastError()); } //Set SMA data as timeseries ArraySetAsSeries(short_smaData,true); ArraySetAsSeries(medium_smaData,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //---Release sma handles IndicatorRelease(short_smaHandle); IndicatorRelease(medium_smaHandle); } |
Đối với phần OnTick, ta sẽ bổ sung thêm SL/TP khi đặt lệnh mua và thực hiện kích hoạt Trailing Stop khi có một vị thế đang mở. Cụ thể, khi đặt lệnh mua ta sử dụng đoạn code sau:
1 2 3 4 5 6 | // Calculate the SL/TP price from SL/TP pips SL_price=currentAsk-fixed_SL*10*_Point; TP_price=currentAsk+fixed_TP*10*_Point; //Place a buy order tradeController.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.10,currentAsk,SL_price,TP_price,"Open Long position"); |
Lưu ý: trước khi sử dụng hàm PositionOpen(), ta cần phải quy đổi giá trị SL/TP từ đơn vị pips sang giá trị giao dịch thực.
Với Trailing Stop thì ta sử dụng đoạn code sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | //If the position still open, trigger the trailing stop if(useTrailingSL) { //Calculate trailing stop price TrailingST_price=SymbolInfoDouble(_Symbol,SYMBOL_BID)-trailing_ST*10*_Point; //Round TrailingST_price to the same digit as broker TrailingST_price=NormalizeDouble(TrailingST_price,_Digits); //Only Trigger Trailing stop when TrailingST_price is more thanf the price we buy //to make sure we earn some profit if(TrailingST_price> PositionGetDouble(POSITION_PRICE_OPEN)) { // Only modify stop loss if the trailing stop price > current SL if(TrailingST_price>PositionGetDouble(POSITION_SL)) { tradeController.PositionModify(_Symbol,TrailingST_price,0); Print("Trailing Stop moved from ",PositionGetDouble(POSITION_SL)," to ", TrailingST_price); } } } |
Ở đây, ta chỉ kích hoạt Trailing Stop khi giá trị của Trailing Stop cao hơn giá trị mà chúng ta đã đặt mua để đảm bảo khi đóng lệnh với Trailing Stop ta vẫn sẽ thu được một khoản lợi nhuận nhất định. Ngoài ra, khi ta đã kích hoạt Trailing Stop thì không sử dụng Hard TP, do đó ta thiết lập giá trị này bằng 0.
Như vậy, full code của chương trình EA sử dụng SL/TP và Trailing Stop như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | //+------------------------------------------------------------------+ //|SLTP_EA.mq5 | //|Copyright 2020, MetaQuotes Software Corp. | //| //www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link"//www.mql5.com" #property version "1.00" #include<Trade\Trade.mqh> // Define variables CTrade tradeController; double currentAsk; input int short_sma=10, medium_sma=51; int short_smaHandle, medium_smaHandle; double short_smaData[], medium_smaData[]; input int fixed_SL=50, fixed_TP=80, trailing_ST=30; // The value in pips input bool useTrailingSL=true; // True if we want to use Trailing stop double SL_price, TP_price, TrailingST_price; // The real price //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //---Get handle for sma indicators short_smaHandle= iMA(_Symbol,_Period, short_sma,0,MODE_SMA, PRICE_CLOSE); medium_smaHandle= iMA(_Symbol,_Period,medium_sma,0,MODE_SMA, PRICE_CLOSE); if(short_smaHandle<0 || medium_smaHandle<0) { Alert("Error creating SMA indicators: ", GetLastError()); } //Set SMA data as timeseries ArraySetAsSeries(short_smaData,true); ArraySetAsSeries(medium_smaData,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //---Release sma handles IndicatorRelease(short_smaHandle); IndicatorRelease(medium_smaHandle); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //---Get Ask Price, SMA20 and SMA50 currentAsk=SymbolInfoDouble(_Symbol,SYMBOL_ASK); CopyBuffer(short_smaHandle,0,0,3,short_smaData); CopyBuffer(medium_smaHandle,0,0,3,medium_smaData); //Check if we have a open position and close it if(PositionSelect(_Symbol)==true) { // We will close the Long position when SMA20 cut SMA50 from above if(short_smaData[0]<medium_smaData[0] && short_smaData[1]>medium_smaData[1]) { tradeController.PositionClose(_Symbol); if(tradeController.ResultRetcode()==10008 || tradeController.ResultRetcode()==10009) { Print("Close long position succesfully: ", tradeController.ResultOrder()); } else { Print("Error closing long position: ",GetLastError()); ResetLastError(); return; } } //If the position still open, trigger the trailing stop if(useTrailingSL) { //Calculate trailing stop price TrailingST_price=SymbolInfoDouble(_Symbol,SYMBOL_BID)-trailing_ST*10*_Point; //Round TrailingST_price to the same digit as broker TrailingST_price=NormalizeDouble(TrailingST_price,_Digits); //Only Trigger Trailing stop when TrailingST_price is more thanf the price we buy //to make sure we earn some profit if(TrailingST_price> PositionGetDouble(POSITION_PRICE_OPEN)) { // Only modify stop loss if the trailing stop price > current SL if(TrailingST_price>PositionGetDouble(POSITION_SL)) { tradeController.PositionModify(_Symbol,TrailingST_price,0); Print("Trailing Stop moved from ",PositionGetDouble(POSITION_SL)," to ", TrailingST_price); } } } } // Only open a new position if there is no existing position if(PositionSelect(_Symbol)==false) { // Open long position if SMA20 cut SMA 50 from below if(short_smaData[0]>medium_smaData[0] && short_smaData[1]<medium_smaData[1]) { // Calculate the SL/TP price from SL/TP pips SL_price=currentAsk-fixed_SL*10*_Point; TP_price=currentAsk+fixed_TP*10*_Point; //Place a buy order tradeController.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.10,currentAsk,SL_price,TP_price,"Open Long position"); if(tradeController.ResultRetcode()==10008 || tradeController.ResultRetcode()==10009) { Print("Open long position succesfully: ", tradeController.ResultOrder()); } else { Print("Error opening long position: ",GetLastError()); ResetLastError(); return; } } } } //+------------------------------------------------------------------+ |
Sau khi hoàn thành phần coding, ta sử dụng Strategy Tester để kiểm tra độ hiệu quả của EA trên (xem thêm về Strategy Tester tại bài Đánh giá Expert Advisors với Strategy Tester). Ta thu được kết quả như sau:
Như vậy, với các tham số đã thiết lập chúng ta chỉ thu được lợi nhuận là 77.98$ (so với 692.33$ khi không sử dụng SL/TP). Tiếp tục ta vào phần Inputs và thay đổi useTrailingSL thành false để không kích hoạt Trailing Stop. Chạy lại phần Testing ta được kết quả sau:
Như vậy, trong trường hợp không sử dụng Trailing Stop ta thu được lợi nhuận là 234.17 $ (cao hơn so với 77.98$ khi sử dụng Trailing Stop).
Kết luận: Qua việc Testing ta thấy rằng SL/TP là biện pháp cần được sử dụng trong Trading. Tuy nhiên hiệu quả mà nó mang lại phụ thuộc vào chiến lược Trading của chúng ta và chúng ta cũng cần phải thực hiện Optimization để tìm ra giá trị tham số tốt nhất cho EA mà chúng ta phát triển.