🐈

執行だけで勝てるのか検証する

2023/05/21に公開

過去検証や、バックテストは無意味だ。

  • ナンピンマーチンのみで勝つ

  • テクニカル指標は一切不要

目をつむって、両建てエントリーしてても通貨ペアの価格は行ったり来たりでいずれは戻ってくる

だから絶対に勝てます

ランダムウォークと呼ばれてても国家の通貨が0になったり急に半額になることは無いです。

なので売られすぎたら買われるし、買われすぎたら売られるはずなのです。

今回はEURUSDのナンピンEAです。

常に両建てエントリーしています。

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
input int MagicNumber = 111;
input int Slippage = 10;
input double input_lot_size = 0.01;

input int nanpin_nehaba = 2000;
input int rigui_nehaba = 2000;
input double martin = 1.5;

input int input_side = 3;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(input_side==3)
     {
      ryoudate();
     }
   if(order_count() != 0)
     {
      return;
     }
   if(position_count(input_side)==0)
     {
      position_entry(input_side);
     }
   if(position_count(input_side)>0)
     {
      if(input_side==0)
        {
         if(position_heikin_syutoku_tanka(0) - nanpin_nehaba * _Point > iClose(NULL,PERIOD_CURRENT,0))
           {
            position_entry(input_side);
           }
        }
      if(input_side==1)
        {
         if(position_heikin_syutoku_tanka(1) + nanpin_nehaba * _Point < iClose(NULL,PERIOD_CURRENT,0))
           {
            position_entry(input_side);
           }
        }
     }

   if(position_count(input_side)>0)
     {
      if(input_side==0)
        {
         if(get_position_info_last_lots_price(input_side) + rigui_nehaba * _Point < iClose(NULL,PERIOD_CURRENT,0))
           {
            position_close(input_side);
           }
        }
      if(input_side==1)
        {
         if(get_position_info_last_lots_price(input_side) - rigui_nehaba * _Point > iClose(NULL,PERIOD_CURRENT,0))
           {
            position_close(input_side);
           }
        }

     }

  }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ryoudate()
  {
   if(order_count() != 0)
     {
      return;
     }
   if(position_count(0)==0)
     {
      position_entry(0);
     }

   if(position_count(1)==0)
     {
      position_entry(1);
     }
   if(position_count(0)>0)

     {
      if(position_heikin_syutoku_tanka(0) - nanpin_nehaba * _Point > iClose(NULL,PERIOD_CURRENT,0))
        {
         position_entry(0);
        }
     }
   if(position_count(1)>0)
     {
      if(position_heikin_syutoku_tanka(1) + nanpin_nehaba * _Point < iClose(NULL,PERIOD_CURRENT,0))
        {
         position_entry(1);
        }
     }

   if(position_count(0)>0)
        {
         if(get_position_info_last_lots_price(0) + rigui_nehaba * _Point < iClose(NULL,PERIOD_CURRENT,0))
           {
            position_close(0);
           }
        }
   if(position_count(1)>0)
        {
         if(get_position_info_last_lots_price(1) - rigui_nehaba * _Point > iClose(NULL,PERIOD_CURRENT,0))
           {
            position_close(1);
           }
        }

     




  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void position_entry(int side)
  {
   if(position_count(side)==0)
     {
      if(side == 0)
        {
         iTrade.Buy(input_lot_size,NULL,0,0,0,"");
        }

      if(side== 1)
        {
         iTrade.Sell(input_lot_size,NULL,0,0,0,"");
        }
      return;
     }
   if(position_count(side)>0)
     {
      double lot_size = get_position_info_max_lots(side) * martin;
      lot_size = NormalizeDouble(lot_size,2);
      if(side == 0)
        {
         iTrade.Buy(lot_size,NULL,0,0,0,"");
        }

      if(side== 1)
        {
         iTrade.Sell(lot_size,NULL,0,0,0,"");
        }

     }

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void position_close(int side)
  {
   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)
                 {
                  iTrade.PositionClose(PositionGetTicket(i));
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int position_count(int side)
  {
   int count =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)
                 {
                  count++;
                 }
              }
           }
        }
     }

   return count ;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double position_heikin_syutoku_tanka(int side)
  {
   double price_sum = 0;
   double lots_sum = 0;
   double heikin = 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)
                 {
                  price_sum+=PositionGetDouble(POSITION_PRICE_OPEN) * PositionGetDouble(POSITION_VOLUME);
                  lots_sum+=PositionGetDouble(POSITION_VOLUME);
                 }
              }
           }
        }
     }
   if(price_sum!=0)
     {
      heikin = price_sum/lots_sum;
     }

   return heikin ;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double get_position_info_max_lots(int side)
  {
   double max = 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)
                 {
                  if(max < PositionGetDouble(POSITION_VOLUME))
                    {
                     max= PositionGetDouble(POSITION_VOLUME);
                    }
                 }
              }
           }
        }
     }

   return max ;

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double get_position_info_last_lots_price(int side)
  {
   double price = side==1?0:99999999;
   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)
                 {
                  if(side==1)
                     if(price < PositionGetDouble(POSITION_PRICE_OPEN))
                       {
                        price= PositionGetDouble(POSITION_PRICE_OPEN);
                       }
                 }
               if(side==0)
                  if(price > PositionGetDouble(POSITION_PRICE_OPEN))
                    {
                     price= PositionGetDouble(POSITION_PRICE_OPEN);
                    }
              }
           }
        }
     }


   return price ;

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int order_count()
  {
   int count =0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if("" != OrderGetString(ORDER_SYMBOL))
        {
         if(Symbol()==OrderGetString(ORDER_SYMBOL))
           {
            if(OrderGetInteger(ORDER_MAGIC)==MagicNumber)
              {
               count++;
              }
           }
        }
     }

   return count ;
  }
#include <Trade\Trade.mqh>
CTrade iTrade;
void InitTrade()
  {
   iTrade.SetDeviationInPoints(Slippage);
   iTrade.SetExpertMagicNumber(MagicNumber);
   iTrade.SetTypeFillingBySymbol(Symbol());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   InitTrade();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+


このプログラムは、MetaTrader 4プラットフォームで動作する自動売買プログラム(Expert Advisor)のMQL4コードです。以下、コードの解説です。

プログラムのヘッダー部分には、プロジェクト名や著作権情報などが記述されています。

MagicNumberは、注文やポジションを識別するためのマジックナンバーです。この値は一意である必要があります。

Slippageは、許容されるスリッページ(注文執行時の許容価格差)を設定するパラメータです。

input_lot_sizeは、取引ロットサイズ(注文の数量)を設定するパラメータです。

nanpin_nehabaとrigui_nehabaは、指定した価格からの上下幅を表すパラメータです。

martinは、追加の取引ロットサイズを計算するための係数です。

input_sideは、取引の方向を表すパラメータです(0が買い、1が売り)。

OnTick関数は、価格が指定の条件を満たした場合に取引を行うメインの処理が記述されています。

position_entry関数は、指定された方向で新規のポジションを取るための関数です。

position_close関数は、指定された方向のポジションをクローズするための関数です。

position_count関数は、指定された方向のポジションの数を返すための関数です。

position_heikin_syutoku_tanka関数は、指定された方向のポジションの平均取得価格を返すための関数です。

get_position_info_max_lots関数は、指定された方向のポジションの中で最大のロットサイズを返すための関数です。

get_position_info_last_lots_price関数は、指定された方向のポジションの中で最後に取得したロットの価格を返すための関数です。

order_count関数は、指定されたマジックナンバーに対応するオーダーの数を返すための関数です。

OnInit関数は、プログラムの初期化処理を行うための関数です。ここでは、CTradeクラスのインスタンスを作成し、設定を行っています。

以上が、このプログラムの主な構成と機能の解説です。ただし、このコードがどのような取引戦略を実装しているのかについては、コメントや関数内のロジックの詳細が不足しているため、完全な理解はできません。

Discussion