[MT4]仮想通貨(ビットコイン)のシステムトレード検証(ソースコードあり)

MT4/MT5でも仮想通貨の取扱業者が増えてきたので、そろそろ自動売買やらバックテストやらができるようになってきました。

 

仮想通貨FXトレードができるおすすめ海外FX会社一覧(MT4/MT5)


現物でアービトラージをするならいざ知らず、テクニカルベースのシステムトレードをするならやっぱりMT4が便利です。

という訳で適当にテクニカルイニジケーターでバックテストしてみました。同じことを独自開発のシステムでやろうとすると鬼のように大変なので、様子見ということでやってみるのはありだと思います。

 

今回はまず手始めとしてBTCUSDチャートに対して従来の一般的なシステムトレードの流れを試してみます。

 

移動平均線のゴールデンクロスで買い、デッドクロスで売り

具体的には、移動平均線のゴールデンクロスで買い、デッドクロスで売り。決済は固定幅SLTPを行い、数値最適化を行います。

forex-mt4-mt5-ea
BTCUSD 日足チャート

仮想通貨から相場の世界に入ってきた人はそもそもMT4が何なのか知らない人もいるかもしれませんが、自動売買やシステムトレードに特化した業者をまたいで使えるツールだと思ってください。
他にもcTraderやjForexなどがありますが、MT4がシェア9割以上なのでとりあえず慣れておいて損はないです。

 

エントリー条件の記述

買いエントリーの条件ですが、シンプルに記述します。
最新の未確定足(#0バー)を条件に使うと、リペイントしたり、反応し過ぎたりするので、数値が確定した最新の足から演算に使うのが最近では主流です。

//MQL4
bool BuyCondition()
{
   double sMA[3],lMA[3];
   
   sMA[1] = iMA(Symbol(),Period(),ShortPeriod,0,MA_MODE,PRICE_MODE,1);
   sMA[2] = iMA(Symbol(),Period(),ShortPeriod,0,MA_MODE,PRICE_MODE,2);
   lMA[1] = iMA(Symbol(),Period(),LongPeriod,0,MA_MODE,PRICE_MODE,1);
   lMA[2] = iMA(Symbol(),Period(),LongPeriod,0,MA_MODE,PRICE_MODE,2);
   
   if( sMA[1] >= lMA[1] && sMA[2] < lMA[2] )
   {
      return(true);
   }
   else return(false);

}

仮想通貨チャートの場合、最小桁数が偶数なので(小数点第二位)、FX用の自動売買ソフトを使うと桁がずれて不具合を起こす可能性があります。
forex-mt4-mt5-ea

何年も昔ではFXチャートでも少数第2位や第4位のFX業者もありましたが、今では少数第3位か第5位しかないので、仮想通貨用に少し修正を加える必要があります。

また、ボラティリティが大きいのでSL,TPの固定幅が10000Point(100USD)とかになったりしますが、チャートで確認してみると意外と妥当な値だったりします。

forex-mt4-mt5-ea
ビジュアルモードバックテスト

2017年は急成長した期間なので、順張りが大正義になることは目に見えているため、テスト期間は2018年の1年にしました。

forex-mt4-mt5-ea
2018/1/1~2018/12/13 H1の期間でSL,TPを数値最適化したグラフ(横がSL、縦がTP)

forex-mt4-mt5-ea
SL=100000(1000USD), TP=90000(900USD)でやったときの資産グラフ(横が取引、縦が資産)

やりようによっては勝てるトレードもある、ということがわかります。

問題点としては、ヒストリーデータの信頼性が低い(欠損が多い)ことと、取引回数が少ないことがやはり気になります。
時間枠を下げて取引回数を増やしてもいいのですが、スプレッドを考慮するとH1あたりが限界じゃないかと思います。

また、仮想通貨によってはボラティリティに開きがあるので、固定SLTPはあまり役に立たないんじゃないかという気もします。

こういう場合、ATRの2倍、3倍…をSLTP幅の計算に使うのが正攻法ですが、
初心者の方にとってはわかりにくくなるばかりなので、決済も移動平均を使う方向に改良してみます。

 

トレードロジックを少し変えてみる

【ストラテジ】
ゴールデンクロスで買い、デッドクロスで売り、固定SLTPで決済(変更前)

ゴールデンクロスで買い、デッドクロスで売り、デッドクロスで買い決済、ゴールデンクロスで売り決済(変更後)
.
エントリー用の移動平均期間と決済用の移動平均期間をそれぞれ分けて、数値の最適化を行いました。
成績の良い組み合わせが以下の表です。
forex-mt4-mt5-ea

試しに、ShortPeriod_entry=18 LongPeriod_entry=36 ShortPeriod_exit=18 LongPeriod_exit=36
で資産推移曲線を見てみると、

forex-mt4-mt5-ea

さっきよりは良くなったんじゃないかと思います。

 

リップルの場合

次に、試しにリップルチャートでもテストを行ってみました。
forex-mt4-mt5-ea

期間は同じく2019/1/1~2019/12/31です。

最適化の結果はこちら。
forex-mt4-mt5-ea

上位の成績の資産グラフはこちら。
forex-mt4-mt5-ea

 

 

仮想通貨FXトレードができるおすすめ海外FX会社一覧(MT4)

ソースコード

EA(自動売買プログラム)のダウンロード

mq4(ソースコード)のダウンロード

extern double Lot = 0.01;
extern double SL = 0;
extern double TP = 0;

extern int ShortPeriod_entry = 12;
extern int LongPeriod_entry = 24;
extern int ShortPeriod_exit = 12;
extern int LongPeriod_exit = 24;
extern int MA_MODE = MODE_SMA;
extern string note = "SMA:"+MODE_SMA+" EMA:"+MODE_EMA+" LWMA:"+MODE_LWMA+" SMMA:"+MODE_SMMA;
extern int PRICE_MODE = PRICE_CLOSE;
extern string note2 = "CLOSE:"+PRICE_CLOSE+" OPEN:"+PRICE_OPEN+" HIGH:"+PRICE_HIGH+" LOW:"+PRICE_LOW;


extern int Slippage = 30;
extern int MagicNumber = 88888;

int OrdersTotal_;
int LastOpenBar;
bool R;
int Ticket;
int i;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
//---

//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//---
   //CLOSE-------------------------
   OrdersTotal_ = OrdersTotal();
   for( i=0; i<OrdersTotal_; i++ )
   {
      R = OrderSelect(i,SELECT_BY_POS);
      if( OrderMagicNumber() == MagicNumber && Symbol() == OrderSymbol() )
      {
         if( OrderType() == OP_BUY )
         {
            if( BuyCloseCondition() )
            {
               R = OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,clrYellow);
            }
         }
         else if( OrderType() == OP_SELL )
         {
            if( SellCloseCondition() )
            {
               R = OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,clrYellow);
            }
         }  
      }
   }
   
   //Entry
   if( EAOpenedPositions() == 0 &&
       LastOpenBar != Bars)
   {
      double SLrate,TPrate;
      if( BuyCondition() )
      {
         Ticket = OrderSend(Symbol(),OP_BUY,Lot,Ask,Slippage,0,0,WindowExpertName(),MagicNumber,0,clrRed);
         
         if( SL != 0 || TP != 0 )
         {
            R = OrderSelect(Ticket,SELECT_BY_TICKET);
            SLrate = OrderOpenPrice() - SL*Point;
            TPrate = OrderOpenPrice() + TP*Point;
            SLrate = NormalizeDouble(SLrate,Digits);
            TPrate = NormalizeDouble(TPrate,Digits);
            R = OrderModify(Ticket,OrderOpenPrice(),SLrate,TPrate,0,clrRed);
         }
         LastOpenBar = Bars;
      }
      else if( SellCondition() )
      {
         Ticket = OrderSend(Symbol(),OP_SELL,Lot,Bid,Slippage,0,0,WindowExpertName(),MagicNumber,0,clrBlue);
         if( SL != 0 || TP != 0 )
         {
            R = OrderSelect(Ticket,SELECT_BY_TICKET);
            SLrate = OrderOpenPrice() + SL*Point;
            TPrate = OrderOpenPrice() - TP*Point;
            SLrate = NormalizeDouble(SLrate,Digits);
            TPrate = NormalizeDouble(TPrate,Digits);
            R = OrderModify(Ticket,OrderOpenPrice(),SLrate,TPrate,0,clrBlue);
         }
         LastOpenBar = Bars;
      }
   
   }
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
//---

}
//+------------------------------------------------------------------+

int EAOpenedPositions()
{
   int EAorders = 0;
   OrdersTotal_ = OrdersTotal();
   for(i=0;i < OrdersTotal_;i++)
   { 
      R = OrderSelect(i,SELECT_BY_POS);
      if( (OrderMagicNumber() == MagicNumber) && (OrderSymbol() == Symbol()) )
      {
         if( (OrderType() == OP_BUY) || (OrderType() == OP_SELL)  )
         {  
            EAorders++;
         }
      }
   }  
   return(EAorders);
}  


bool BuyCondition()
{
   double sMA[3],lMA[3];
   
   sMA[1] = iMA(Symbol(),Period(),ShortPeriod_entry,0,MA_MODE,PRICE_MODE,1);
   sMA[2] = iMA(Symbol(),Period(),ShortPeriod_entry,0,MA_MODE,PRICE_MODE,2);
   lMA[1] = iMA(Symbol(),Period(),LongPeriod_entry,0,MA_MODE,PRICE_MODE,1);
   lMA[2] = iMA(Symbol(),Period(),LongPeriod_entry,0,MA_MODE,PRICE_MODE,2);
   
   if( sMA[1] >= lMA[1] && sMA[2] < lMA[2] )
   {
      return(true);
   }
   else return(false);

}

bool SellCondition()
{
   double sMA[3],lMA[3];
   
   sMA[1] = iMA(Symbol(),Period(),ShortPeriod_entry,0,MA_MODE,PRICE_MODE,1);
   sMA[2] = iMA(Symbol(),Period(),ShortPeriod_entry,0,MA_MODE,PRICE_MODE,2);
   lMA[1] = iMA(Symbol(),Period(),LongPeriod_entry,0,MA_MODE,PRICE_MODE,1);
   lMA[2] = iMA(Symbol(),Period(),LongPeriod_entry,0,MA_MODE,PRICE_MODE,2);
   
   if( sMA[1] <= lMA[1] && sMA[2] > lMA[2] )
   {
      return(true);
   }
   else return(false);
}

bool BuyCloseCondition()
{
   double sMA[3],lMA[3];
   
   sMA[1] = iMA(Symbol(),Period(),ShortPeriod_exit,0,MA_MODE,PRICE_MODE,1);
   sMA[2] = iMA(Symbol(),Period(),ShortPeriod_exit,0,MA_MODE,PRICE_MODE,2);
   lMA[1] = iMA(Symbol(),Period(),LongPeriod_exit,0,MA_MODE,PRICE_MODE,1);
   lMA[2] = iMA(Symbol(),Period(),LongPeriod_exit,0,MA_MODE,PRICE_MODE,2);
   
   if( sMA[1] <= lMA[1] && sMA[2] > lMA[2] )
   {
      return(true);
   }
   else return(false);

}

bool SellCloseCondition()
{
   double sMA[3],lMA[3];
   
   sMA[1] = iMA(Symbol(),Period(),ShortPeriod_exit,0,MA_MODE,PRICE_MODE,1);
   sMA[2] = iMA(Symbol(),Period(),ShortPeriod_exit,0,MA_MODE,PRICE_MODE,2);
   lMA[1] = iMA(Symbol(),Period(),LongPeriod_exit,0,MA_MODE,PRICE_MODE,1);
   lMA[2] = iMA(Symbol(),Period(),LongPeriod_exit,0,MA_MODE,PRICE_MODE,2);
   
   if( sMA[1] >= lMA[1] && sMA[2] < lMA[2] )
   {
      return(true);
   }
   else return(false);
}

 

 

 

コメント

  1. GT333 より:

    仮想通貨のEAに興味があり、こちらにたどり着きました。
    こちらのEAは制限や条件なくダウンロード利用していいのでしょうか?

    また、ソースコードが公開されていますが、こちらをベースに修正(機能追加)して再利用してもいいでしょうか?

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

MT4のチャート上に複数の仮想通貨取引所のビットコインレートを表示するやり方

先日、ブログを読んでいただいてる方からコードをいただいたので、ご紹介します。(OKをもらいました。)

記事を読む

3通貨相関 三角/トライアングルアービトラージEA(MT4MT5)

合成通貨トライアングルアービトラージとは FXは2つの通貨のペアなので、その組み合わせは無数に

記事を読む

[無料.EA4]デイブレイクアウトEA(MT4) コツコツ型

ロットは変動ロットにできますが、マーチンゲールではなく証拠金変動タイプです。 EURUSDの1

記事を読む

日足MACDロジックEA高スプレッド対応 (MT4)

バックテスト結果 ご覧の通り、固定ロットできれいなグラフを出せています。ただ、取引回数が少ない

記事を読む

普通のスキャルピングEA(MT4)[無料EAダウンロード]

バックテスト結果 . EURUSD 2019/1/1~2019/12/31 M5 spr

記事を読む

 

上に戻る