MQL4 お金の健康

FXの自動売買プログラムを自作したい!ボリンジャーバンドを使った順張り戦略2

投資を自動でやってほしいなあ。
 
自分でプログラムを作れるの?
 
どんな戦略がいいの?

という悩みを解決できる記事になっています。

なぜなら、私はプログラミング言語MQL4で
FXの自動売買をしているからです。

結論だけ言うと、

プログラミング言語MQL4を使えば

誰でも自動売買できます。

この記事ではボリンジャーバンドを使った順張りプログラムを紹介します。

読み終えていただければ、

自動売買プログラムを自作できるようになります。

※おすすめの自動売買プログラムショップ

平均レビュー評価:★4.85の高評価!

FX自動売買プログラムのオンラインショップです。

自作する時間がもったいないと感じたら

購入して使うのもひとつの手です。

FXの自動売買プログラムを自作しよう

FXの自動売買プログラムを自作しよう

誰でも放置で稼げるシステムづくりを目指して

FXに挑戦しているうっちゃんです。

前回の記事ではボリンジャーバンドを使ったトレード戦略を紹介しました。

反省点はレンジ相場に弱いことです。

無駄な注文を繰り返すと

損失が膨らむんですよね。

そこで、今回は改良プログラムを考えました。

長時間足のミドルラインも使うことです。

H1でトレードする時は

H4、D1のミドルラインの傾きも見ます。

  • 買い注文の時はすべて上向き
  • 売り注文の時はすべて下向き

プログラムでこの条件を追加しました。

他の条件は前回と同じであり、

こちらの本を参考に作成しました。

これをFXの自動売買プログラムに落とし込みます。

FX自動売買プログラムのコード

作り方はこちらの記事をご覧ください。

さっそくコードを書きます。

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                                          Copyright 2021, uchida. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2021, uchida"
#property link        "http://tsumawosettoku20200808.com"
#property description "Instagram @uchy8893 present"

#define MAGICMA  2021102902
//#define ACCOUNT 253036986
//--- Inputs
input double Lots          =0.01;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =200;
input int    MovingShift   =0;

extern double TakeProfit   = 0; //利食い
extern double StopLoss     = 0; //損切り
extern int    Slippage     =10; 
extern string Comments     = "EA has traded";

extern int    BBPeriod     = 21;   //ボリンジャーバンドの期間
int           Adjusted_Slippage =0;
double        _point;       // Pips入力値用の変数

int          Ticket        =0;
bool         Closed        =false;

//スリッページの調整------------------------------------------------------
int AdjustSlippage(string Currency, int Slippage_Pips)
{
    int Symbol_Digits = MarketInfo(Currency, MODE_DIGITS);
    
    int Calculated_Slippage = 0;
    
    if(Symbol_Digits == 2 || Symbol_Digits ==4)
    {
        Calculated_Slippage = Slippage_Pips;    
    }
    else if(Symbol_Digits == 3 || Symbol_Digits == 5)
    {
        Calculated_Slippage = Slippage_Pips * 10;
    }
    
    return(Calculated_Slippage);
}

//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
  

//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
int CheckForOpen(double bbU1,double bbL1,double middle1,double middle2,double middle3,double ema)
  {
   int    res;
   double sl = 0, tp = 0;
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return(Ticket);
//---bollingerbands
   
//--- buy conditions
   if(ema < middle1  &&middle1 >0 && middle2 >0&& middle3 > 0&& Close[0] > bbU1)// 
     {
     
      if (StopLoss > 0) sl = Ask - StopLoss * _point;
      if (TakeProfit > 0) tp = Ask + TakeProfit * _point;
      
      res=OrderSend(Symbol(),
      OP_BUY,
      Lots,
      Ask,
      Adjusted_Slippage,
      sl,
      tp,
      Comments,
      MAGICMA,
      0, 
      Blue);
      return(Ticket);
     
     }
//--- sell conditions
   if(ema > middle1 && middle1 < 0 && middle2 < 0  && middle3 < 0&& Close[0] < bbL1)  // 
     {
      if (StopLoss > 0) sl = Bid + StopLoss * _point;
      if (TakeProfit > 0) tp = Bid - TakeProfit * _point;
      
      res=OrderSend(Symbol(),
      OP_SELL,
      Lots,
      Bid,
      Adjusted_Slippage,
      sl,
      tp,
      Comments,
      MAGICMA,
      0, 
      Red);
      return(Ticket);
     }
  
     
//---
  return(Ticket);
  }
  
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
int CheckForClose(double bbU1,double bbL1)
  {
     
//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return(Ticket);

//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if(bbL1 > Close[0])
           {
            if(!OrderClose(OrderTicket(),OrderLots(),Bid,Adjusted_Slippage,White))
               Print("OrderClose error ",GetLastError());
           }
         //break;
        }
      if(OrderType()==OP_SELL)
        {
          if(bbU1 < Close[0])
           {
            if(!OrderClose(OrderTicket(),OrderLots(),Ask,Adjusted_Slippage,White))
               Print("OrderClose error ",GetLastError());
           }
         //break;
        }
     }
  return(Ticket);
  }
  
  
//---------初期化関数------------------------------------------------
int init()
{
   _point = Point;
   if (Digits % 2 == 1)
   {
      _point *= 10;
      Slippage *= 10;
   }
    Adjusted_Slippage = AdjustSlippage(Symbol(), Slippage);
        
    return(0);
}

//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false) // ||AccountNumber()!=ACCOUNT
      return;
//---BB
    double bbU1 = iBands(NULL,60,BBPeriod,1,0,PRICE_CLOSE,MODE_UPPER,1);
    double bbL1 = iBands(NULL,60,BBPeriod,1,0,PRICE_CLOSE,MODE_LOWER,1); 
    
    double middle1 =iMA(NULL,60,BBPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,1);
    double middle2 =iMA(NULL,240,BBPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,1);
    double middle3 =iMA(NULL,1440,BBPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,1);
//---EMA
    double ema = iMA(NULL,0,MovingPeriod,MovingShift,MODE_EMA,PRICE_CLOSE,1); 
       
   //--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen(bbU1,bbL1,middle1,middle2,middle3,ema);
   else    CheckForClose(bbU1,bbL1);
   
   
   
//---
  }
//+------------------------------------------------------------------+

条件がかなり増えましたね〜。

さて、気になるのは結果です!

EURUSDのH1でバックテスを行いました。

結果はこちら

FX自動売買の結果

微減!

前回は増加したので、追加した条件は

良くない方向に行くようです。

また改良を進めます。

※おすすめの自動売買プログラムショップ

平均レビュー評価:★4.85の高評価!

FX自動売買プログラムのオンラインショップです。

自作する時間がもったいないと感じたら

購入して使うのもひとつの手です。

ここまで読んでくださりありがとうございました。^^

-MQL4, お金の健康
-,