English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
다양한 대륙과 시간대에 맞춘 거래 전략의 예시

다양한 대륙과 시간대에 맞춘 거래 전략의 예시

MetaTrader 5 | 5 7월 2021, 13:42
270 0
Vasily
Vasily


들어가며

약간 여유로웠기에 이번에는 시장을 연구하고 경제 사이클과 기술적 지표의 차이를 조사하는 데 소비할 예정이었습니다. 다음 문서 Graphical Control Options을 가지고 인디케이터 만들기에서 연구 결과를 볼 수 있습니다. 하지만 이것 외에도 알아낸 게 있습니다! 훨씬 더 큰 규모의 현상을 발견했지만, 그것을 이해하기 위해서는 먼저 시간대의 관점에서 우리의 세계를 살펴보아야합니다(1번 그림).

1번 그림. 시간대

우리가 볼 수 있듯이, 하루는 나라마다 다르게 시작되고 우리 나라같이 큰 나라의 경우는 10개의 시간대가 있을 정도지만, 대서양엔 고작 6개의 시간대가 있을 뿐입니다.

패턴이 느껴지십니까? 일본, 호주, 중국, 러시아 등 여러 나라의 시장 개방 순서를 살펴봅시다. 러시아 사무원들이 처음 사무실에 도착해 무역 업무를 시작할 때쯤이면 아시아는 벌써 저녁이고, 유럽 회의가 열리면 이미 문을 닫습니다.

이쯤이 흥미로운데요. 일단 시장이 열리면, 유럽의 중개인과 헤지펀드 매니저들은 그들의 자산을 시장에 내놓고, 투자자들의 이익, 행동을 관망하거나 같이 들어갑니다. 이게 끝이 아닙니다. 아직 시카고에 새벽이 오면 시작되는 가장 재미있는 부분을 다루지 않았습니다. 대서양의 작은 범위와 관련해서요. 시카고 주식 시장의 관리자들이 무역 단말기를 열고 자본 관리에 착수하는 시기가 왔습니다.

대서양에서 조금 떨어진 곳과 관련하여 잠시 멈춰보겠습니다. 유럽 세션은 아직 종료되지 않았습니다(1번 그림). 만약 규정 근무시간이 8시간이고 여기에 더해 담배피러 쉬는 시간이 45분, 1시간정도 대충하면 실제로는 1시간 30분에서-2시간 추가로 연장됩니다 (사무실에서 일해본 사람은 압니다).  

이때가 바로 유럽과 미국 경영자들의 시장 자산을 확보하는 시점입니다. 이 시점에서 자산이 얼마나 될지 확실히 알긴 어렵지만, 유럽과 미국의 경영자들은 주식거래 가격을 놓고 고군분투하기 시작하고 있으며, 이 시점에서 2번 그림에서와 같이 하나의 현상이 됩니다.  

2번 그림. 시장의 고동

쩐의 전쟁이 시장을 가득 채우고 자산은 매초마다 주인이 바뀌지만, 이걸로 시장이 끝나는 것이 아닙니다! 이 기간이 끝나면 조용한 움직임이 시작되고 현재 추세 방향으로 이동합니다. 이때 범위는 경계를 확장한 후 다시 한 번 좁히고나서 주요 추세 방향으로 계속 이동합니다.

시장 가격이 오르거나 내릴 수도 있다는 것을 눈치채셨을 거라고 생각하지만, 항상 오른쪽으로 움직입니다.


2. 알고리즘 개발의 핵심, 플로우차트

"Start-Stop" 프로그램의 첫 블록은 3번 그림에서 볼 수 있습니다:


3번 그림. "Start-Stop" 블록

이 블록은 프로그램의 시작, 함수의 시작 및 끝을 나타내거나 초기화 및 초기화 해제와 같은 다른 절차를 나타내기 위해 사용됩니다. 다음 블록에는 "Data"라는 레이블이 붙어 있으며 4번 그림으로 확인할 수 있습니다.


4번 그림. "Data" 블록

"Data" 블록은 프로그램 기동시에 특정 패러미터나 MQL5 출력 변수를 판단하는데에 쓰입니다. 이 단위는 또한 전역 변수의 대상 기능을 제공합니다.

다음으로, 우리는 일반적으로 사용되는 블록(MQL 프로그램의 99%가 이 방법을 사용함)을 고려합니다. 이 블록은 두 부분으로 설명되며, 이는 사이클의 경계를 표시합니다. 5번 그림을 보아주세요:

사이클 블록

5번 그림. 사이클 블록

귀책이나 회계와 같은 프로세스는 대개 이러한 주기 내에서 이루어지며, 6번 그림에서 볼 수 있습니다.

액션

6번 그림. 액션

그리고 우리는 논리적 블록에 대해 잊어서는 안 됩니다 - 7번 그림에서 "solution" 블록을 볼 수 있습니다.


7번 그림. "솔루션" 블록

"solution" 블록이 만약 "위치 수에 따라 달라지는 스위치" 유형의 오퍼레이터 내부에 위치할 경우엔 출력이 세 개 이상 있을 수 있습니다. 이 장치에는 해당하는 출력 수가 있습니다.

다음 블록은 iMACD iRSA 같은 사전정의된 함수나, 프로그램 혹은 라이브러리 어딘가에서 정의된 커스텀 함수를 가져옵니다 (8번 그림).


8번 그림. 함수

마지막 두 블록은 코멘트나 브리치 같은 서비스 기능만 구현합니다(9번 그림).

서비스 블록

9번 그림. 서비스 블록

이러한 블록 유형은 모두 기계에 대해 작성된 프로그램을 설명하는 데 사용할 수 있는 블록 유형입니다. 모두 명확하고 간단하며 사용하기 쉽습니다. 개발의 주요 단계에서 시스템의 취약점을 드러내고 이를 제거하는 방법을 고안하기도 합니다.

이제 이 방법에 대해 잘 아시겠지만, 저는 여러분이 이 스킴에 따라 정확하게 행동하라는 것이 아니라 플로우차트의 첫 값을 아는 것만으로 어떤 종류의 계산법을 이해하는 것은 충분히 쉽다는 것입니다. 이 방법을 통해 저는 아이디어를 뇌의 우반구에서 탈출시켜 좌반구로 빠르게 날려보냈습니다.

3. 알고리즘 생성

이제 플로우차트 전략에 따라 Expert Advisor를 마련해보겠습니다.

첫 번째 블록은 입력 패러미터를 요청합니다. 결정한 대로, 주요 전투의 순간, 즉 미국 개장으로부터 2시간째에 유럽 폐장까지 기다리는 것이 매우 중요합니다. 우리는 이것을 세계시계로 볼 것입니다. 즉, 터미널 시간에 말이죠. 그래서 우리는 스스로 개장시간을 계산할 것입니다.

그런 다음 우리는 포지션의 규모와 손익 수준을 결정하는데, 이 포지션 정보에 미래에 최적화할 수 있는 잠재력이 있습니다. Expert Advisor가 주문을 결정하고 거래를 개시하는 데 사용할 것이기 때문에 Magic number 패러미터에는 각별히 주의를 기울일 것입니다. 또한, 우리는 우리의 위치, 우리의 관찰에 대한 위험을 제한하기 위해 후행적인 정지를 할 것입니다.

우리에게 필요하고, 재미있는 패러미터가 하나 더 있습니다 - 안전 레벨. 이를 통해 매 순간 의미있는 경제 뉴스가 있는지 체크하고 이 때문에 경제적 타격을 입을 것인지 체크합니다. 보통은 터지고 나서 2시간 내에 영향이 시장에 반영됩니다.


10번 그림. 입력 패러미터

//--- input parameters
input int      America=16;
input double   Lots=0.1;
input int      TakeProfit=500;
input long     MagicNumber=665;
input int      Limited=600;
input int      TrailingStop=100;

전략 수립의 다음 부분으로 넘어가도록 하겠습니다.

우리는 세션이 엇갈렸는지, 그리고 주문이 진행됐는지, 진행되고 있는지 판단해야 합니다. (11번 그림).

거래 시작

11번 그림. 거래 시작

보시다시피, 주어진 알고리즘은 입력 패러미터, 완료된 계산 및 출력 결과를 가진 닫힌 프로그램입니다. 이러한 미니 프로그램은 함수라고 불리며 캡슐화를 통해 메인 프로그램으로부터 보호됩니다.

캡슐화는 프로그램 또는 프로그램 부분 사이의 장벽으로, 다른 Get들과 Set들의 사이의 영역을 통과하지 못하도록 Get 및 Set(Get and Set)와 같은 메소드로 구분됩니다. 이 프로세스의 본질은 변수의 이름이 함수 내 및 메인 프로그램 내에서 동일할 수 있다는 사실에 있지만 Get 방법이 변수 이름을 가진 셀에서 가져오려고 할 때, 그것은 캡슐화에 직면하게 될 것이며. 본 함수 혹은 프로그램에 할당된 메모리 셀의 특정 섹터에만 접근할 수 있게 할 것이라는 점입니다.

Set 메소드도 동일하지만 Get과는 다르게 적용됩니다. 셀 메모리에 있는 값을 변수의 이름으로 설정하며, 프로그램 내 변수 이름과 함수 내 변수의 이름이 일치하면 캡슐화는 Set 메소드가 다른 프로그램이나 함수 내부에 변수의 값을 할당하는 것을 허용하지 않습니다.

bool time2trade(int TradeHour,int Number)
  {
   MqlDateTime time2trade;
   TimeTradeServer(time2trade);
   if(time2trade.hour!=TradeHour) return(false);
   time2trade.hour= 0;
   time2trade.min = 0;
   time2trade.sec = 1;
   for(int ii=OrdersTotal()-1;ii>=0;ii--)
     {
      OrderGetTicket(ii);
      long ordmagic=OrderGetInteger(ORDER_MAGIC);
      if(Number==ordmagic) return(false);
     }
   HistorySelect(StructToTime(time2trade),TimeTradeServer());
   for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--)
     {
      long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC);
      if(Number==HistMagic) return(false);
     }
   return(true);
  }

우리는 필요한 세션을 식별하고 주문 설정 여부를 판단했습니다. 다음에 무엇을 해야 할지 생각해 보겠습니다.

앞서 우리는 주요 변화가 미국 개장 2시간 후에 발생한다는 것을 알게 되었습니다. 미국 장이 시작된 뒤 15분짜리 바 9개를 준비합니다. 우리는 이 기간에 대한 최대 범위를 찾고 신중하게 고려합니다. 만약 이 변동이 충분히 크다면, 아마도 시장에 광범위한 공황이 있을 것이고, 미래의 추세는 예측하기 어렵습니다. 따라서, 우리는 여기에 약간의 제한이 필요할 것입니다.

시장이 진정되면, 세션이 변동성을 증가시킬 것입니다. 이를 통해 주 트렌드로부터의 최대 편차를 결정하고, 안전한 거리에 주문 트랩을 배치하는 기회를 얻게 되며, 주 트렌드가 계속될 것이기 때문에 효과가 있을 것입니다. 앞서 말씀드린 것처럼 가격이 오르거나 내리거나 할 수 있지만, 항상 오른쪽으로 움직입니다. (12번 그림).

주문 알고리즘

12번 그림 주문 완료 알고리즘

프로그램 코드를 짤 때에, MetaTrader 5 거래 터미널이 가장 최근 거래가에 가까운 주문 설정을 허용하지 않는다는 사실에 주목하십시오. 지금 이 시점에서 가격이 새로운 최저 또는 최대치를 끌어낸다면, 우리는 신뢰할 수 있는 주문 결정을 위해 최신 거래가에서 최소 거리만큼 물러나 포지션을 지킬 것입니다. 그리고 주문 기한은 오늘로 세팅하여 유효기간이 오늘을 넘기지 않도록 할 것입니다.

void OnTick()
  {
//---
   if(time2trade(America+2,MagicNumber))
     {
      int i;
      double Highest = 0;
      double Lowest = 0;
      MqlRates Range[];
      CopyRates(Symbol(),15,0,9,Range);
      Lowest=Range[1].low;
      for(i=0; i<9;i++)
        {
         if(Highest<Range[i].high) Highest=Range[i].high;//MathMax(,Highest);
         if(Lowest>Range[i].low)  Lowest=Range[i].low;
        }
      long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL);
      Highest=Highest+StopLevel*Point();
      // add to the current prices parameters of the minimum distance possible for the setting of orders
      Lowest=Lowest-StopLevel*Point();
      // to ensure the maximum probability of the acceptance of our order 30>

      if((Higest-Lowest)/Point()<Limited)
        {
         MqlTradeRequest BigDogBuy;
         MqlTradeRequest BigDogSell;
         BigDogBuy.action=TRADE_ACTION_PENDING;
         // Set the pending order
         BigDogBuy.magic = MagicNumber;
         BigDogBuy.symbol=Symbol();
         BigDogBuy.price=Highest;
         //Price by which the order will be set
         BigDogBuy.volume=Lots;
         BigDogBuy.sl=Lowest;
         //if the stop loss is not set, then set by the strategy /s39>
         BigDogBuy.tp=Highest+TakeProfit*Point();
         //set the take profit/s41>
         BigDogBuy.deviation=dev;
         //minimum deviation from the requested price, 
         //in other words, by how much the executed price can differ from the specified price
         BigDogBuy.type=ORDER_TYPE_BUY_STOP;
         //order type, which is executed based on the specified price or by a higher than specified price
         //in this case the order is set to a higher or equal amount to the specified price 
         //if the order type was buy_limit, then it would be executed 
         //by the specified price, or prices lower than the specified price
         BigDogBuy.type_filling=ORDER_FILLING_AON;
         //the given parameter demonstrates how the order acts 
         //with partial execution of the scope 
         BigDogBuy.expiration=TimeTradeServer()+6*60*60;
         //by the strategy text the order life span only for the current work day
         //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6
         BigDogSell.action=TRADE_ACTION_PENDING;

         // Set the pending order
         BigDogSell.magic = MagicNumber;
         BigDogSell.symbol=Symbol();
         BigDogSell.price=Lowest;
         //Price, by which the order will be set
         BigDogSell.volume=Lots;
         BigDogSell.sl=Highest;
         //Stop loss set by the strategy
         BigDogSell.tp=Lowest-TakeProfit*Point();
         //set the take profit
         BigDogSell.deviation=dev;
         //Minimum deviation from the requested price, 
         //in other words, by how much the executed price can differ from the specified price
         BigDogSell.type=ORDER_TYPE_SELL_STOP;
         //order type, which is executed based on the specified price or by a higher than specified price
         //in this case the order is set to a higher or equal amount to the specified price  
         //if the order type was buy_limit, then it would be executed
         //by the specified price, or prices lower than the specified price
         BigDogSell.type_filling=ORDER_FILLING_AON;
         //the given parameter demonstrates how the order acts 
         ///with partial execution of the scope  
         BigDogSell.expiration=TimeTradeServer()+6*60*60;
         //by the strategy text the order life span only for the current work day
         //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6
         MqlTradeResult ResultBuy,ResultSell;
         OrderSend(BigDogBuy,ResultBuy);
         OrderSend(BigDogSell,ResultSell);
        }
     }

주문이 접수되고 함정이 설정되었습니다. 이제 포지션 리스크를 줄일 차례입니다. 트레일링 스톱(trailing stop) 기술을 적용합시다.

현 포지션을 파악하기 위해 매직넘버(MagicNumber)를 사용하고, 가격변동을 최소화하면서 일정 수준의 이익에 도달했을 때, 손절레벨을 바꿀 것입니다(13번 그림).

트레일링 스톱 구현

13번 그림 트레일링 스톱의 구현

다른 전략의 경우, 트레일링 스탑은 가장 단순한 방법을 사용하여 구현되지만, 일부 전략에서는 가격이 목표를 달성하는 것을 방지하지 않기 위해 트레일링 스탑을 사용하지 않는 것이 권장되거나, 그러한 메커니즘을 무손실 위치로 이동하기 위해서만 사용하는 것이 권장됩니다. 그러나 이 전략에서, 우리는 가격 변동의 경우, 우리의 방향으로 일정 수의 최소 가격 변동에 대한 보호 중지를 이동하기 위한 고전적인 메커니즘을 적용합니다

//--- trailing implementation
   int PosTotal=PositionsTotal();
   for(int i=PosTotal-1; i>=0; i--)
     {
      //--- go through open positions and see if there are positions created by this Expert Advisor.
      if(PositionGetSymbol(i)==Symbol())
        {
         if(MagicNumber==PositionGetInteger(POSITION_MAGIC))
           {
            MqlTick lasttick;
            SymbolInfoTick(Symbol(),lasttick);
            if(PositionGetInteger(POSITION_TYPE)==0)
              { //--- buy
               if(TrailingStop>0
                  &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop)
                  && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop)
                 {
                  MqlTradeRequest BigDogModif;
                  ZeroMemory(BigDogModif);
                  BigDogModif.action= TRADE_ACTION_SLTP;
                  BigDogModif.symbol= Symbol();
                  BigDogModif.sl = lasttick.bid - TrailingStop*Point();
                  BigDogModif.tp = PositionGetDouble(POSITION_TP);
                  BigDogModif.deviation=3;
                  MqlTradeResult BigDogModifResult;
                  ZeroMemory(BigDogModifResult);
                  OrderSend(BigDogModif,BigDogModifResult);
                 }
              }
            if(PositionGetInteger(POSITION_TYPE)==1)
              {//--- sell
               if(TrailingStop>0
                  && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop)
                  && (PositionGetDouble(POSITION_SL)==0
                  || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop))
                 {
                  MqlTradeRequest BigDogModif;
                  ZeroMemory(BigDogModif);
                  BigDogModif.action= TRADE_ACTION_SLTP;
                  BigDogModif.symbol= Symbol();
                  BigDogModif.sl = lasttick.ask + TrailingStop*Point();
                  BigDogModif.tp = PositionGetDouble(POSITION_TP);
                  BigDogModif.deviation=3;
                  MqlTradeResult BigDogModifResult;
                  ZeroMemory(BigDogModifResult);
                  OrderSend(BigDogModif,BigDogModifResult);
                 }
              }
           }
        }
     }
  }

다음으로 알고리즘을 종합해봅니다 (14번 그림).





14번 그림 알고리즘 완성하기

//+------------------------------------------------------------------+
//|                                          BigDog_By_CoreWinTT.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//--- input parameters
input int      America=16;
input double   Lots=0.1;
input int      TakeProfit=500;
input long     MagicNumber=665;
input int      Limited=600;
input int      TrailingStop=100;
int dev=30;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
bool time2trade(int TradeHour,int Number)
  {
   MqlDateTime time2trade;
   TimeTradeServer(time2trade);
   if(time2trade.hour!=TradeHour) return(false);
   time2trade.hour= 0;
   time2trade.min = 0;
   time2trade.sec = 1;
   for(int ii=OrdersTotal()-1;ii>=0;ii--)
     {
      OrderGetTicket(ii);
      long ordmagic=OrderGetInteger(ORDER_MAGIC);
      if(Number==ordmagic) return(false);
     }
   HistorySelect(StructToTime(time2trade),TimeTradeServer());
   for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--)
     {
      long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC);
      if(Number==HistMagic) return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(time2trade(America+2,int(MagicNumber)))
     {
      int i;
      double Highest= 0;
      double Lowest = 0;
      MqlRates Range[];
      CopyRates(Symbol(),15,0,9,Range);
      Lowest=Range[1].low;
      for(i=0; i<9;i++)
        {
         if(Highest<Range[i].high) Highest=Range[i].high;
         if(Lowest>Range[i].low) Lowest=Range[i].low;
        }
      long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL);
      Highest=Highest+StopLevel*Point();
      //--- add to the current prices the parameters of a minimum possible distance for the order set.
      Lowest=Lowest-StopLevel*Point();
      //--- to ensure the maximum probability of the acceptance of our order.

      if((Highest-Lowest)/Point()<Limited)
        {
         MqlTradeRequest BigDogBuy;
         MqlTradeRequest BigDogSell;
         ZeroMemory(BigDogBuy);
         ZeroMemory(BigDogSell);
         BigDogBuy.action=TRADE_ACTION_PENDING;
         //--- set the pending order
         BigDogBuy.magic = MagicNumber;
         BigDogBuy.symbol=Symbol();
         BigDogBuy.price=Highest;
         //--- Price by which the order will be set
         BigDogBuy.volume=Lots;
         BigDogBuy.sl=Lowest;
         //--- if the stop loss is not established, then we set by the strategy
         BigDogBuy.tp=Highest+TakeProfit*Point();
         //--- set the take profit
         BigDogBuy.deviation=dev;
         //--- Minimum deviation from the requested price, 
         //--- in other words, by how much the executed price can differ from the specified price
         BigDogBuy.type=ORDER_TYPE_BUY_STOP;
         //--- order type, which is executed based on the specified price or by a higher than specified price
         //--- in this case the order is set to a higher or equal amount to the specified price 
         //--- if the order type was buy_limit, then it would be executed 
         //--- by the specified price, or prices lower than the specified price
         BigDogBuy.type_filling=ORDER_FILLING_FOK;
         //--- the given parameter demonstrates how the order acts  
         //--- with partial execution of the scope   
         BigDogBuy.expiration=TimeTradeServer()+6*60*60;
         //--- by the strategy text the order life span only for the current work day
         //--- since it has been 2 hours since the opening of the American market, 
         //--- and the work day is 8 hours, we have 8-2 = 6
         BigDogSell.action=TRADE_ACTION_PENDING;

         //-- Set the pending order
         BigDogSell.magic = MagicNumber;
         BigDogSell.symbol=Symbol();
         BigDogSell.price=Lowest;
         //--- Price by which the order will be set
         BigDogSell.volume=Lots;
         BigDogSell.sl=Highest;
         //-- Stop loss set by the strategy
         BigDogSell.tp=Lowest-TakeProfit*Point();
         //--- Set take profit
         BigDogSell.deviation=dev;
         //--- Minimum deviation from the requested price, 
         //--- in other words, by how much the executed price can differ from the specified price
         BigDogSell.type=ORDER_TYPE_SELL_STOP;
         //--- order type, which is executed based on the specified price or by a higher than specified price
         //--- in this case the order is set to a higher or equal amount to the specified price  
         //--- if the order type was buy_limit, then it would be executed
         //--- by the specified price, or prices lower than the specified price
         BigDogSell.type_filling=ORDER_FILLING_FOK;
         //--- the given parameter demonstrates how the order acts  
         //--- with partial execution of the scope 
         BigDogSell.expiration=TimeTradeServer()+6*60*60;
         //-- by the strategy text the order life span only for the current work day
         //--- since it has been 2 hours since the opening of the American market, 
         //--- and the work day is 8 hours, we have 8-2 = 6
         MqlTradeResult ResultBuy,ResultSell;
         ZeroMemory(ResultBuy);
         ZeroMemory(ResultSell);
         OrderSend(BigDogBuy,ResultBuy);
         OrderSend(BigDogSell,ResultSell);
        }
     }

//--- trailing implementation
   int PosTotal=PositionsTotal();
   for(int i=PosTotal-1; i>=0; i--)
     {
      //--- go through open positions and see if there are positions created by this Expert Advisor.
      if(PositionGetSymbol(i)==Symbol())
        {
         if(MagicNumber==PositionGetInteger(POSITION_MAGIC))
           {
            MqlTick lasttick;
            SymbolInfoTick(Symbol(),lasttick);
            if(PositionGetInteger(POSITION_TYPE)==0)
              { //--- buy
               if(TrailingStop>0
                  &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop)
                  && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop)
                 {
                  MqlTradeRequest BigDogModif;
                  ZeroMemory(BigDogModif);
                  BigDogModif.action= TRADE_ACTION_SLTP;
                  BigDogModif.symbol= Symbol();
                  BigDogModif.sl = lasttick.bid - TrailingStop*Point();
                  BigDogModif.tp = PositionGetDouble(POSITION_TP);
                  BigDogModif.deviation=3;
                  MqlTradeResult BigDogModifResult;
                  ZeroMemory(BigDogModifResult);
                  OrderSend(BigDogModif,BigDogModifResult);
                 }
              }
            if(PositionGetInteger(POSITION_TYPE)==1)
              {//--- sell
               if(TrailingStop>0
                  && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop)
                  && (PositionGetDouble(POSITION_SL)==0
                  || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop))
                 {
                  MqlTradeRequest BigDogModif;
                  ZeroMemory(BigDogModif);
                  BigDogModif.action= TRADE_ACTION_SLTP;
                  BigDogModif.symbol= Symbol();
                  BigDogModif.sl = lasttick.ask + TrailingStop*Point();
                  BigDogModif.tp = PositionGetDouble(POSITION_TP);
                  BigDogModif.deviation=3;
                  MqlTradeResult BigDogModifResult;
                  ZeroMemory(BigDogModifResult);
                  OrderSend(BigDogModif,BigDogModifResult);
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+


마치며

주기적으로, 정기적으로 발생하는 많은 시장 현상들이 있으며, 그걸 들여다보면 어느 정도 이점을 얻을 수 있습니다. 또한, 아마도 경험이 많은 트레이더들은 잘 알려진 "BigDog" 전략과 일부 겹치는 것을 눈치채셨을겁니다. 이 문서에는 이런 내용이 언급되어 있지 않는데, 이는 독자들이 얼마나 준비되어있나 스스로 판단해보게 하려는 의도였습니다.

인터넷에서는 이 전략의 다양한 변형을 알 수 있습니다. 이 기사는 이 전략이 기반이 되는 현상만을 다루고 있습니다.


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/59

문자 알림과 트레이드 리포트 생성 및 발간 문자 알림과 트레이드 리포트 생성 및 발간
트레이더라고해도 터미널 앞에서 수 시간씩 계속 앉아서 일할 능력이나 동기가 항상 유지되는 것은 아닙니다. 특히나 트레이딩 시스템의 적게건 많게건 표준화되었거나 시장 현황을 자동으로 판별할 수 있을때면 더더욱이죠. 본 문서는 매매 결과 리포트를 (Expert Advisor, 인디케이터 혹은 스크립트를 사용하여) HTML 파일로 생성하여 FTP를 통해 WWW 서버에 업로드하는 법을 다룹니다. 또한 문자를 통해 핸드폰에 매매 알림을 보내는 것 또한 다루겠습니다.
유전 알고리즘-쉬워요 유전 알고리즘-쉬워요
이 글에서는 저자가 직접 개발한 유전 알고리즘을 이용한 진화 연산에 대해 이야기합니다. 예제를 이용해 알고리즘의 기능을 설명하고, 실제 적용 가능한 경우를 설명합니다.
MQL5으로 거래용 능동 제어판 만들기 MQL5으로 거래용 능동 제어판 만들기
이 문서는 MQL5의 활성 제어 패널 개발 문제를 다룹니다. 인터페이스 요소는 이벤트 처리 메커니즘에 의해 관리됩니다. 또한 제어 요소 속성의 범용적인 설정 옵션을 사용할 수 있습니다. 활성 제어판을 사용하면 포지션을 다루거나, 시장 혹은 보류 중인 주문을 설정, 수정 및 삭제할 수 있습니다.
바보도 할 수 있는 MQL: 객체 클래스 디자인 및 생성 방법 바보도 할 수 있는 MQL: 객체 클래스 디자인 및 생성 방법
그래픽 디자인 샘플 프로그램을 생성해 보면 MQL5로는 어떻게 클래스를 고안하고 생성하는지 알 수 있습니다. 이 글은 MT5 애플리케이션을 이용하는 초보 프로그래머들을 위해 작성되었습니다. 객체 지향 프로그래밍 이론을 깊이 파고들지 않아도 클래스를 생성할 수 있도록 간단하고 쉬운 방법을 알려드리겠습니다.