그리드 메이커 1.1

 
다음은 'Grid maker' 버전 1.1입니다... 일련의 균등한 간격의 매수 또는 매도 주문 을 설정하고 유지하는 스크립트 또는 전문가 고문입니다.
이 버전은 전문 고문의 스크립트이거나 업데이트 빈도를 변경하고, long 및/또는 shorts 등을 선택할 수 있습니다. 설명은 매개변수를 참조하십시오.

대부분의 변형을 테스트했지만 모든 경우에 작동한다는 보장은 없다고 생각합니다! 시도해보고 문제가 있으면 알려주십시오.

이것은 아마도 내가 게시하는 마지막 버전일 것입니다. MT4 테스트용으로 개발했습니다. 향후 버전은 지원 및 저항 수준과 같은 외부 데이터가 필요한 더 복잡하므로 게시하는 것이 적절하지 않습니다.



//+------------------------------------------------------------------+
//|                                                     MakeGrid.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"
//#property version      "1.1beta"

extern string GridName = "Grid";       // identifies the grid. allows for several co-existing grids
extern double Lots = 0.1;              // 
extern double GridSize = 6;            // pips between orders - grid or mesh size
extern double GridSteps = 10;          // total number of orders to place
extern double UpdateInterval = 15;     // update orders every x minutes
extern bool   wantLongs = true;        //  do we want long positions
extern bool   wantShorts = true;       //  do we want short positions
extern bool   wantBreakout = true;     // do we want longs above price, shorts below price
extern bool   wantCounter = true;      // do we want longs below price, shorts above price
extern bool   limitEMA34 = false;      // do we want longs above ema only, shorts below ema only
extern double LastUpdate = 0;          // counter used to note time of last update
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
 #property show_inputs              // shows the parameters - thanks Slawa...    
//----
   return(0);
  }
//+------------------------------------------------------------------------+
//| test if there is an open position or order in the region of atRate     |
//|     will check for longs if checkLongs is true, else will check        |
//|     for shorts                                                         |
//+------------------------------------------------------------------------+

bool IsPosition(double atRate, double inRange, bool checkLongs )
  {
  
     int totalorders = OrdersTotal();
     for(int j=0;j<totalorders;j++)                                // scan all orders and positions...
      {
        OrderSelect(j, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && OrderComment() == GridName )  // only look if mygrid and symbol...
         {  int type = OrderType();
            if (MathAbs( OrderOpenPrice() - atRate) < inRange) // dont look for exact price but price proximity (less than gridsize)
              { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT  || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT  || type == OP_SELLSTOP ) ) )
                 { return(true); }
              }
         }
      } 

   return(false);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   int    i, j,k, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, traderate;
 
//----
  if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60)           // we update the first time it is called and every UpdateInterval minutes
   {
   LastUpdate = CurTime();
   Print("Updating");
   point = MarketInfo(Symbol(),MODE_POINT);
   startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
   k = startrate ;
   k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
   
   double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0);
   
   for( i=0;i<GridSteps;i++)
   {
     traderate = startrate + i*point*GridSize;
     if ( wantLongs && (!limitEMA34 || traderate > EMA34))
       {
         if (!IsPosition(traderate,point*GridSize,true) )           // test if i have no open orders close to my price: if so, put one on
          {
             if ( traderate > Ask ) 
              { entermode = OP_BUYSTOP; } 
              else 
              { entermode = OP_BUYLIMIT ; } 
             if ( (traderate > Ask ) && (wantBreakout) || ((traderate < Ask ) && (wantCounter)) ) 
              { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,0,traderate+point*GridSize,GridName,16384,0,Green); }
          }
       }

     if ( wantShorts && (!limitEMA34 || traderate < EMA34))
       {
         if (!IsPosition(traderate,point*GridSize,false) )           // test if i have no open orders close to my price: if so, put one on
          {
             if ( traderate > Bid ) 
              { entermode = OP_SELLLIMIT; } 
              else 
              { entermode = OP_SELLSTOP ; } 
              
              if ( (traderate < Bid ) && (wantBreakout) || ((traderate > Bid ) && (wantCounter)) ) 
                { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,0,traderate-point*GridSize,GridName,16384,0,Red); }
          }
       }

    }
   }
   return(0);
  }
//+------------------------------------------------------------------+
 
안녕하세요 hdb님

저는 MoneyTec(Simspeed), ET(ElectricSavant) 및 Oanda 포럼(MarkVH 및 Sympatico)에서 오랫동안 이 아이디어를 따라왔으며 포럼에 보낸 첫 번째 스크립트를 개선하기 위해 일부 전문가를 개발하는 방법에 대해 생각하고 있습니다. 아마도 우리는 더 빠른 것을 얻기 위해 함께 일할 수 있을 것입니다 :) 관심이 있으시면 알려주세요. 제 이메일은 artefactodigital@gmail.com입니다.

친애하는,
페르난도.

다음은 'Grid maker' 버전 1.1입니다... 일련의 균등한 간격의 매수 또는 매도 주문을 설정하고 유지하는 스크립트 또는 전문 고문입니다.
이 버전은 전문 고문의 스크립트이거나 업데이트 빈도를 변경하고, long 및/또는 shorts 등을 선택할 수 있습니다. 설명은 매개변수를 참조하십시오.

대부분의 변형을 테스트했지만 모든 경우에 작동한다는 보장은 없다고 생각합니다! 시도해보고 문제가 있으면 알려주십시오.

이것은 아마도 내가 게시하는 마지막 버전일 것입니다. MT4를 테스트하기 위해 개발했습니다. 향후 버전은 지원 및 저항 수준과 같은 외부 데이터가 필요한 더 복잡하므로 게시하는 것이 적절하지 않습니다.
 
ok 잘 들린다.. 내 이메일을 참조하십시오 ...
 
그건 그렇고, 당신은 그것을 시도하고, 사용하고, 변경할 수 있지만 판매하지 마십시오!

나는 그것의 효과적인 작업 조건과 당신이 그것으로 할 수 있는 모든 거래에 대해 어떠한 보증도 하지 않습니다.
나는 이 스크립트로 인한 직간접적인 손실에 대해 책임을 지지 않습니다.


사용하는 경우 결과, 설정, 버그, 관찰 등 가끔 피드백을 게시하십시오.

즐겨
 
자, 여기로 갑니다. 나중에 한 가지 주요 시장 움직임이 있을 때 그리드가 살아남습니다!! 2주 전에 50k로 데모 계정 을 시작했습니다.
저는 그리드메이커 테스트에서 1k를 잃었고 유로 폭락 직전에 기본 GridMaker 전문가를 9개의 통화 쌍에 배치했습니다.
EUR/CHF, USD/JPY, GBP/JPY, EUR/GBP, USD/CHF, AUD/USD, GBP/USD, EUR/USD, EUR/JPY.

그리드 간격은 모든 통화에 대해 6틱이고 TP는 6틱입니다. 0.1랏 사이즈를 배치했습니다. 나는 각 통화 쌍에 대해 매 6틱마다 롱/숏했습니다.
새로 고침은 5분에 EUR/USD 및 GBP/USD를 제외하고 15분마다(즉, 그리드가 15분마다 재생성됨) 있었습니다.

잔고는 10,000(20%) 증가, 사용된 마진은 13,000(26%), 무료 마진은 26,000(52%), 미실현 손익은 -19,000입니다.

유로 강타의 최종 결과(지금까지)는 -9k 하락했습니다. 나는 이것보다 훨씬 더 나쁜 것을 기대했다!

그리드는 하루에 600에서 2000의 비율로 균형에 추가되고 있습니다!

다음주에는 어떤 모습일지 기대됩니다.

그리드 만세!!
 
글쎄요, 1주일 후, 그리드는 정말로 두들겨 맞았습니다! 필요한 로트 크기/격자 간격 계산을 하지 않았기 때문에 내 잘못
사용 가능한 자산으로 얼마나 많은 히트를 칠 수 있는지 확인해야 합니다.

어쨌든, 잔액은 꽤 잘 휘젓고 있습니다. 하루에 700에서 1800 증가 - 잔액은 이제 65k입니다(49k에서 시작하므로 +16k).
사용된 마진은 이제 15,000이고 사용 가능한 마진은 21,000입니다. 필요할 때 포지션을 추가할 여지가 여전히 많습니다.
미실현 손익은 -29k로 지난주보다 4나빠진 13k의 순 손실을 기록했습니다.

긍정적인 측면은 카운터 트레이드(CounterTrade 플래그가 false)를 피하기 위해 설정을 변경했고 미실현 손익이 안정화된 것 같습니다.
한 단계에서 -36k였습니다.

이 전방 테스트에 대해 내가 좋아하는 것은 그것이 큰 타격을 입기 시작했다는 것입니다 - 지난 주 유로화 하락 - 그래서 이제 어떻게 그리고 언제 어떻게 보는 것이 흥미로울 것입니다
시스템이 복구됩니다. 그럴 것이라고 믿어 의심치 않습니다.

다음 주에 결과를 보기 위해 기다릴 수 밖에 없습니다!!!

추신. TP를 변경하고 SL을 추가할 수 있는 v1.2가 있습니다. 원한다면 여기에 게시하십시오.
 
나는 이것으로 꽤 많이 놀았다. 모든 쌍에서 기본적으로 모든 것을 실행합니다.
나는 그것이 어떻게 수행되었는지 매우 감명 받았다고 말해야 만합니다.

이것에 하나의 큰 큰 niggle이 있습니다 ..

숏 포지션만 취하자.. 가격이 떨어지면 숏 오더가 활성화된다. 그러나 가격이 반전되기 전에 숏 사이드에서 2개의 주문을 받을 수 있는 경우가 많다.

즉, 이익실현 은 개시될 다음 공매도와 동일한 가격이며 스프레드(예: 매수 및 매도 호가)를 고려하지 않습니다.

따라서 가격이 장측으로 반전되기 전에 2개의 주문이 열리는 것을 방지하려면 다음 공매도 주문과 동시에 TP가 발생해야 합니다.

이것이 가능하다면 현재 내 손실을 절반으로 줄일 수 있다고 생각합니다.

나는 이것에 대한 최근의 당신의 생각이 이 문제를 해결할 것이라고 생각합니다.

게시할 수 있다면 환상적일 것입니다...
 
안녕,

재밌게 봐서 다행이야.. 나도 그래..

내가 동시에 TP = 그리드 크기를 가질 수 있고 반전 시 2개의 열린 위치를 가질 가능성을 제거할 수 있는 방법은 없습니다.
이것은 소프트웨어 문제가 아니라 단순히 스프레드와 관련이 있습니다.

이론적으로 이것을 완전히 제거할 수 있는 유일한 가능성은 매번 스프레드를 잃는 것입니다.
즉, 4틱 스프레드가 있는 경우 1.2006(입찰가)에서 공매도, 1.2000(매도)에서 TP, 1.1996(입찰)에서 공매도합니다.
당신은 단순히 범위의 4/10를 잃게됩니다.

새 버전에서는 그리드 크기와 TP를 다른 숫자로 설정할 수 있으므로 사용자가 무엇인지 구현할 수 있습니다.
4 포인트 스프레드가 있는 경우 그리드를 10으로 설정하고 TP를 6으로 설정합니다.

dd를 절반으로 줄일 수 있을지는 모르겠지만 수익은 확실히 줄어들 것입니다.

알려줘요.

ps.. 다음 포스트의 v1.2
 
이것은 gridmaker의 v1.2입니다.

유일한 차이점은 다음과 같습니다.
1) 원할 경우 선택적 손절매를 추가했습니다. 0은 손절매가 없음을 의미하고 양수는 손절매 를 의미합니다.
그리드에서 정지 손실을 사용하는 경우 크게 만들어야 합니다.
2) 그리드 크기와 다른 TP를 지정할 수 있습니다. darkstonexa 는 이전 게시물에서 이중 '매달린' 위치를 제거하려고 합니다.
내 초기 의도는 그리드 크기에 비해 더 큰 TP를 시도하는 것이었습니다.

이를 Expert Advisor 폴더( C:\Program Files\MetaTrader 4\experts\ 와 같은 것)에 저장하고 스크립트 폴더에 선택적 복사본을 저장합니다.
스크립트로 원하는 경우(C:\Program Files\MetaTrader 4\experts\scripts\).

원하는 경우 열린 그리드 주문을 제거하는 스크립트가 있습니다. 설정을 변경하려는 경우 매우 유용합니다.

참고: 기본 설정은 마지막 버전 이후 변경되었을 수 있습니다. 다시 컴파일하기 전에 원하는 설정을 지정했는지 확인하십시오.

관리자에게 질문: 아마도 이런 종류의 것을 전문 고문 라이브러리에 넣어야 할 것입니다. 이것이 맞습니까?

//+------------------------------------------------------------------+
//|                                                     MakeGrid.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"
//#property version      "1.2beta"

extern string GridName = "Grid";       // identifies the grid. allows for several co-existing grids
extern double Lots = 0.1;              // 
extern double GridSize = 6;            // pips between orders - grid or mesh size
extern double GridSteps = 10;          // total number of orders to place
extern double TakeProfit = 6 ;         // number of ticks to take profit. normally is = grid size but u can override
extern double StopLoss = 0;            // if u want to add a stop loss. normal grids dont use stop losses
extern double UpdateInterval = 15;     // update orders every x minutes
extern bool   wantLongs = true;        //  do we want long positions
extern bool   wantShorts = true;       //  do we want short positions
extern bool   wantBreakout = true;     // do we want longs above price, shorts below price
extern bool   wantCounter = false;      // do we want longs below price, shorts above price
extern bool   limitEMA34 = false;      // do we want longs above ema only, shorts below ema only
extern double LastUpdate = 0;          // counter used to note time of last update
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---- 
 #property show_inputs                  // shows the parameters - thanks Slawa...    
 if ( TakeProfit <= 0 )                 // 
   { TakeProfit = GridSize; }
//----
   return(0);
  }
//+------------------------------------------------------------------------+
//| tests if there is an open position or order in the region of atRate    |
//|     will check for longs if checkLongs is true, else will check        |
//|     for shorts                                                         |
//+------------------------------------------------------------------------+

bool IsPosition(double atRate, double inRange, bool checkLongs )
  {
  
     int totalorders = OrdersTotal();
     for(int j=0;j<totalorders;j++)                                // scan all orders and positions...
      {
        OrderSelect(j, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && OrderComment() == GridName )  // only look if mygrid and symbol...
         {  int type = OrderType();
            if (MathAbs( OrderOpenPrice() - atRate) < inRange) // dont look for exact price but price proximity (less than gridsize)
              { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT  || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT  || type == OP_SELLSTOP ) ) )
                 { return(true); }
              }
         }
      } 

   return(false);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//---- 
   int    i, j,k, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, traderate;
 
//----
  if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60)           // we update the first time it is called and every UpdateInterval minutes
   {
   LastUpdate = CurTime();
   Print("Updating");
   point = MarketInfo(Symbol(),MODE_POINT);
   startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
   k = startrate ;
   k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
   
   double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0);
   
   for( i=0;i<GridSteps;i++)
   {
     traderate = startrate + i*point*GridSize;
     if ( wantLongs && (!limitEMA34 || traderate > EMA34))
       {
         if (!IsPosition(traderate,point*GridSize,true) )           // test if i have no open orders close to my price: if so, put one on
          {
             double myStopLoss = 0;
             if ( StopLoss > 0 )
               { myStopLoss = traderate-point*StopLoss ; }
               
             if ( traderate > Ask ) 
              { entermode = OP_BUYSTOP; } 
              else 
              { entermode = OP_BUYLIMIT ; } 
             if ( (traderate > Ask ) && (wantBreakout) || ((traderate < Ask ) && (wantCounter)) ) 
              { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,16384,0,Green); }
          }
       }

     if ( wantShorts && (!limitEMA34 || traderate < EMA34))
       {
         if (!IsPosition(traderate,point*GridSize,false) )           // test if i have no open orders close to my price: if so, put one on
          {
             myStopLoss = 0;
             if ( StopLoss > 0 )
               { myStopLoss = traderate+point*StopLoss ; }
             if ( traderate > Bid ) 
              { entermode = OP_SELLLIMIT; } 
              else 
              { entermode = OP_SELLSTOP ; } 
              
              if ( (traderate < Bid ) && (wantBreakout) || ((traderate > Bid ) && (wantCounter)) ) 
                { ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,16384,0,Red); }
          }
       }

    }
   }
   return(0);
  }
//+------------------------------------------------------------------+
 
대단하다..

TP 옵션이 있는 현재 문제에 대한 솔루션입니다.

드로다운 금액을 과대평가했을 수도 있습니다. 하지만 범위의 끝에서 2개의 주문을 본 경우를 많이 막을 수 있기를 바랍니다.
각각 $2000 이상 손실되는 일은 과거의 일이 될 것입니다. :)

이제 마지막으로 사용할 수 있는 것은 지정가 주문에 만료 옵션을 설정하는 것입니다.
현재 만료되지 않도록 설정되어 있습니다.
따라서 수동으로 삭제해야 합니다.

현재 약 3일 정도 된 주문이 많이 있으며 조만간 적중될 가능성이 없습니다.

그럼 좋은 작품이라고 말하고 싶네요.. :)
 
다음은 특정 통화 쌍 에 대한 모든 미결 주문을 제거하는 스크립트입니다. 코드는 약간 불쾌하지만 작동하는 것 같습니다.

//+------------------------------------------------------------------+
//|                                                   RemoveGrid.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"

extern string GridName = "Grid";

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {

 #property show_inputs              // shows the parameters - thanks Slawa... 

//---- 
  int total = OrdersTotal();
  int i ;
  
      for(i=total-1; i>=0;i--)
 
      {
        OrderSelect(i, SELECT_BY_POS);
        int type   = OrderType();

        if ( OrderSymbol()==Symbol() && OrderComment() == GridName )
        {
          bool result = false;
    
          switch(type)
          {
             case OP_BUY       : result = true ;
      
            case OP_SELL      : result = true ;

            //Close pending orders
            case OP_BUYLIMIT  : result = OrderDelete( OrderTicket() ); 
            case OP_BUYSTOP   : result = OrderDelete( OrderTicket() ); 
            case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); 
            case OP_SELLSTOP  : result = OrderDelete( OrderTicket() ); 
          }
    
          if(result == false)
          {
     //       Alert("Order " , OrderTicket() , " failed to close. Error:" , GetLastError() );
     //       Sleep(3000);
          }  
        }
      }
 
//----
   return(0);
  }
//+------------------------------------------------------------------+