見出し画像

ナンピンマーチンEAにボラティリティフィルターをつける


ソースコード



bool entry_on = true;//グローバルスコープの変数
void OnTick(){

//ローソク足が切り替わるタイミングで
//entry_onをtrueに戻す方法
static datetime prev_time =iTime(NULL,PERIOD_CURRENT,0);//static == 静的な 固定させる効果を持つ
if(prev_time != iTime(NULL,PERIOD_CURRENT,0)){
prev_time = iTime(NULL,PERIOD_CURRENT,0);
entry_on = true;
}



if(order_count()==0 && entry_on==true){

bool posi0 = position_count(ORDER_TYPE_BUY) == 0 && position_count(ORDER_TYPE_SELL) == 0;
bool buy_posi_1_ijou = position_count(ORDER_TYPE_BUY) > 0;
bool sell_posi_1_ijou = position_count(ORDER_TYPE_SELL) > 0;

if(posi0==true){mode_syokai();}
if(buy_posi_1_ijou){mode_nanpin(ORDER_TYPE_BUY);mode_rikaku(ORDER_TYPE_BUY);}//0
if(sell_posi_1_ijou){mode_nanpin(ORDER_TYPE_SELL);mode_rikaku(ORDER_TYPE_SELL);}//1
}
}


// 高値と安値の変動率を返す関数
double GetFluctuationPercent(int barIndex = 0)
{
   // 指定されたバーの高値と安値を取得
   double currentHigh = iHigh(Symbol(),PERIOD_H1, barIndex);
   double currentLow = iLow(Symbol(), PERIOD_H1, barIndex);

   // 変動率をパーセントで計算
   double fluctuationPercent = (currentHigh - currentLow) / currentLow * 100;

   return fluctuationPercent;
}



void mode_syokai(){
double genzaikakaku = iClose(NULL,PERIOD_CURRENT,1);
double BBUP = getBollingerBand(1,1);
double BBLO = getBollingerBand(2,1);
if(BBUP < genzaikakaku){position_entry(ORDER_TYPE_SELL,0.01);}
if(BBLO > genzaikakaku){position_entry(ORDER_TYPE_BUY,0.01);}
}

//side 0 or 1 
void mode_nanpin(int side){

bool A = GetFluctuationPercent(2) < 0.1 && GetFluctuationPercent(1) < 0.1&& GetFluctuationPercent(0) < 0.1;//変動率が0.1%未満

double max_lot = position_max_lotsize(side);
double next_lot_size=NormalizeDouble(max_lot*1.5,2);
next_lot_size = next_lot_size==0.01?0.02:next_lot_size;
double last_entry_price = get_last_position_entry_price(side);
double genzai_kakaku = iClose(NULL,PERIOD_CURRENT,0);
if(side== ORDER_TYPE_BUY){
if(last_entry_price - 2000 * _Point>genzai_kakaku && A){position_entry(ORDER_TYPE_BUY,next_lot_size);}
}
if(side== ORDER_TYPE_SELL){
if(last_entry_price + 2000 * _Point<genzai_kakaku && A){position_entry(ORDER_TYPE_SELL,next_lot_size);}
}

}

void mode_rikaku(int side){
double heikinsyutokukakaku = position_average_price(side);
double genzai_kakaku = iClose(NULL,PERIOD_CURRENT,0);
if(side== ORDER_TYPE_BUY){if(heikinsyutokukakaku + 2000* _Point < genzai_kakaku){position_all_close(ORDER_TYPE_BUY);}}
if(side== ORDER_TYPE_SELL){if(heikinsyutokukakaku - 2000* _Point > genzai_kakaku){position_all_close(ORDER_TYPE_SELL);}}

}


double getBollingerBand(int mode,int shift)
  {
  
  //mode == 0 Base Line
  //mode == 1 Upper Band
  //mode == 2 Lower Band
  
static int handle = -1;

// ボリンジャーバンド指標のハンドルを取得
if(handle == -1){
handle = iBands(_Symbol, PERIOD_CURRENT, 20, 0, 2.0, PRICE_CLOSE);
}
double Band[];

// バッファをコピーしてラインの値を取得
CopyBuffer(handle, mode, shift, 1, Band);   // 基本線

return Band[0];
  }


int MagicNumber = 123;       // マジックナンバー
int slippage = 10;          // スリッページ

void position_entry(ENUM_ORDER_TYPE order_type,double lot_size=0.01) {
   MqlTradeRequest req = {};
   MqlTradeResult res = {};

   req.action = TRADE_ACTION_DEAL;  // 成行注文
   req.symbol = Symbol();
   req.volume = lot_size;               // 注文数量
   req.type = order_type;           // 売買方向 ORDER_TYPE_BUY or ORDER_TYPE_SELL
   req.deviation = slippage;        // スリップページ
   req.magic = MagicNumber;         // マジックナンバー
   req.comment = "";                // コメント

   bool order_result = OrderSend(req, res);

   if (order_result == false) {
       Print(res.retcode);
   }
}

int position_count(ENUM_ORDER_TYPE order_type)
  {
   int count =0;
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
     if("" != PositionGetSymbol(i))
        {
         if(PositionGetInteger(POSITION_TYPE)==order_type)
           {
            if(Symbol()==PositionGetString(POSITION_SYMBOL))
              {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
                 {
                  count++;
                 }
              }
           }
        }
     }
   return count ;
  }
  
  double get_last_position_entry_price(int side)
  {
   double lastEntryPrice = 0;
   long lastEntryTime = 0;
   long entryTime = 0;

   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if("" != PositionGetSymbol(i))
        {
         if(PositionGetInteger(POSITION_TYPE) == side)
           {
            if(Symbol() == PositionGetString(POSITION_SYMBOL))
              {
               if(PositionGetInteger(POSITION_MAGIC) == MagicNumber)
                 {
                  entryTime = PositionGetInteger(POSITION_TIME);
                  if(entryTime > lastEntryTime)
                    {
                     lastEntryTime = entryTime;
                     lastEntryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                    }
                 }
              }
           }
        }
     }

   return lastEntryPrice;
  }
  
double position_max_lotsize(int side)
  {
   double max_lotsize = 0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if("" != PositionGetSymbol(i))
        {
         if(PositionGetInteger(POSITION_TYPE)==side)
           {
            if(Symbol()==PositionGetString(POSITION_SYMBOL))
              {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
                 {
                  double current_lotsize = PositionGetDouble(POSITION_VOLUME);
                  if(current_lotsize > max_lotsize)
                    {
                     max_lotsize = current_lotsize;
                    }
                 }
              }
           }
        }
     }

   return max_lotsize;
  }

double position_average_price(int side)
{
   double lots_sum = 0;
   double price_sum = 0;
   double average_price = 0;
   
   for(int i=PositionsTotal()-1; i>=0; i--)
   {
      if("" != PositionGetSymbol(i))
      {
         if(PositionGetInteger(POSITION_TYPE)==side)
         {
            if(Symbol()==PositionGetString(POSITION_SYMBOL))
            {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
               {
                  lots_sum += PositionGetDouble(POSITION_VOLUME);
                  price_sum += PositionGetDouble(POSITION_PRICE_OPEN) * PositionGetDouble(POSITION_VOLUME);
               }
            }
         }
      }
   }
   
   if(lots_sum > 0)
   {
      average_price = price_sum / lots_sum;
   }

   return NormalizeDouble(average_price, _Digits);
}

void position_close(ENUM_ORDER_TYPE order_type,ulong position_ticket,double lot_size)
  {
   MqlTradeRequest req = {};
   MqlTradeResult res = {};

   order_type = order_type==ORDER_TYPE_BUY?ORDER_TYPE_SELL:ORDER_TYPE_BUY;

   req.action = TRADE_ACTION_DEAL;  // 成行注文
   req.symbol = Symbol();
   req.volume = lot_size;               // 注文数量
   req.type = order_type;           // 売買方向 ORDER_TYPE_BUY or ORDER_TYPE_SELL
   req.deviation = slippage;        // スリップページ
   req.magic = MagicNumber;         // マジックナンバー
   req.comment = "";                // コメント
   req.position = position_ticket;  //決済するポジションを指定する

   bool order_result = OrderSend(req, res);

   if(order_result == false)
     {
      Print(res.retcode);
     }
  }
  
  void position_all_close(ENUM_ORDER_TYPE side)
  {
  
  entry_on = false;
  
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if("" != PositionGetSymbol(i))
        {
         if(PositionGetInteger(POSITION_TYPE)==side)
           {
            if(Symbol()==PositionGetString(POSITION_SYMBOL))
              {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
                 {
                  position_close(side,PositionGetInteger(POSITION_TICKET),PositionGetDouble(POSITION_VOLUME));
                 }
              }
           }
        }
     }
  }
  
  int order_count()
  {
   int count =0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(OrderGetTicket(i)))
        {
         if(Symbol()==OrderGetString(ORDER_SYMBOL))
           {
            if(OrderGetInteger(ORDER_MAGIC)==MagicNumber)
              {
                  count++;
              }
           }
        }
     }


   return count ;
  }

この記事が気に入ったらサポートをしてみませんか?