이 코드 블록은 손절매를 사용하든 사용하지 않든 작동합니다.
필요 사항
- Trade.mqh 파일을 포함해야 CTrade 클래스를 사용할 수 있습니다. 이 클래스를 통해 포지션과 주문을 다룰 수 있습니다.
#include <Trade\Trade.mqh> // <<------------------------------------------ 이 "Trade.mqh"를 포함하여 CTrade 클래스를 사용하세요.
- 트레일링 거리 조정을 위한 입력 파라미터를 설정해야 합니다. 이 설정은 필수는 아니지만 편리합니다.
input double Traling_Step = 3.0;
- CTrade 클래스의 인스턴스를 정의해야 합니다. 이름은 원하는 대로 설정할 수 있습니다. OnInit 이벤트 핸들러 다음에 정의하는 것이 좋습니다.
- 현재 실행 중인 포지션이 있는지 확인하는 if 문을 생성해야 합니다. 이 문장은 매 틱마다 Check_TrailingStop(); 함수를 호출합니다. 이는 EA가 트레일링을 부드럽고 정확하게 진행하도록 하기 위해 중요합니다. 이 문장을 OnTick 이벤트 핸들러의 맨 위에 배치해야 제대로 작동합니다.
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//--- create timer
EventSetTimer(60);
//---
return(INIT_SUCCEEDED);
}
CTrade trade; // <<------------------------------------------ "CTrade" 클래스를 선언합니다. 원하는 이름으로 변경할 수 있습니다.
void OnTick() {
if(PositionsTotal() > 0) // 현재 포지션이 있을 경우 매 틱마다 트레일링 스탑 함수를 호출합니다.
{
Check_TralingStop();
}
}
- 나머지를 수행하기 위해 Check_TrailingStop();이라는 사용자 정의 함수를 선언해야 합니다. 원하는 이름으로 사용할 수 있습니다.
- 이 사용자 정의 함수는 모든 열린 포지션을 반복하며 설정한 거리만큼 트레일링합니다.
void Check_TralingStop() {
int totalPositions = PositionsTotal();
for(int count = 0; count < totalPositions; count++) {
ulong TicketNo = PositionGetTicket(count); // 포지션의 티켓 번호를 가져옵니다.
if(PositionSelectByTicket(TicketNo)) {
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double stopLoss = PositionGetDouble(POSITION_SL); // 현재 손절매를 가져옵니다.
double takeProfit = PositionGetDouble(POSITION_TP);
double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
ulong ticket = PositionGetTicket(count);
double trailingLevel = NormalizeDouble(bidPrice - (Traling_Step * Point()), _Digits);
if(stopLoss < openPrice) { // 손절매가 설정되지 않은 경우.
if(bidPrice > openPrice && trailingLevel > openPrice) { // 포지션당 한 번만 실행됩니다. 첫 번째 SL을 설정합니다.
trade.PositionModify(ticket, trailingLevel, takeProfit); // "CTrade.trade"를 사용하여 트레일링 스탑 수정
}
}
if(bidPrice > openPrice && trailingLevel > stopLoss) { // 트레일링 레벨이 이전 레벨보다 위에 있는지 확인합니다.
trade.PositionModify(ticket, trailingLevel, takeProfit); // "CTrade.trade"를 사용하여 트레일링 스탑 수정
}
}
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) {
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double stopLoss = PositionGetDouble(POSITION_SL);
double takeProfit = PositionGetDouble(POSITION_TP);
double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
ulong ticket = PositionGetTicket(count);
double trailingLevel = NormalizeDouble(askPrice + (Traling_Step * Point()), _Digits);
if(stopLoss < openPrice) { // 손절매가 설정되지 않은 경우.
if(askPrice < openPrice && trailingLevel < openPrice) { // 포지션당 한 번만 실행됩니다. 첫 번째 SL을 설정합니다.
trade.PositionModify(ticket, trailingLevel, takeProfit); // "CTrade.trade"를 사용하여 트레일링 스탑 수정
}
if(askPrice < openPrice && trailingLevel < stopLoss) { // 트레일링 레벨이 이전 레벨보다 위에 있는지 확인합니다.
trade.PositionModify(ticket, trailingLevel, takeProfit); // "CTrade.trade"를 사용하여 트레일링 스탑 수정
}
}
}
}
}