分解モンテカルロ法をライブラリ化する

ゼロから始めるEA開発
スポンサーリンク

分解モンテカルロ法はなかなか有用なベットシステムのようなので、使いやすいようにライブラリ化してみることにします。

ライブラリ化といってもDLLにするのではなく、ただincludeで呼び出して使えるようにするだけです。

ついでに通常のモンテカルロ法も含めて「モンテカルロライブラリ」としましょう。

まず用意するのは以前開発したモンテカルロ法のソースコードです。MonteCarlo.mq4をコピーしてincludeフォルダの下にペースト、ファイル名をMonteCarlo.mqhとします。

どこをどう修正したか‥という内容は不要だと思うので割愛します。

使い方

MonteCarloLib.zip

上記のファイルを解凍して、MonteCarlo.mqhをMT4のMQL4\Includeフォルダに入れます。

EAの先頭あたり(#propertyの下)に

#include <MonteCarlo.mqh>

と記述することでモンテカルロライブラリが使用可能になります。

そしてOnInit()あたりでInitLotsArrayを実行します。引数にはBetModeを指定してください。(モンテカルロ法=MonteCarlo、分解モンテカルロ法=DMonteCarlo)

GetLots関数を実行するとLotsが取得できます。ロットは0.01が最小値となっています。変更したい場合にはGetLots関数内、100で除算している箇所を変更してください。

SetLots関数に勝敗を設定して実行すると内部のロットがベットルールに沿って変更されます。

トレードに勝利した場合にはSetLots(true)、敗北した場合にはSetLots(false)を実行してください。

その後、GetLots関数を実行すると勝敗によって変更された新しいロット数が取得できます。

Ver1.02 機能追加(2024/4/27)

SetInitLots関数で初期ロットが設定できるようになりました。

引数value(double)に初期ロットを設定します。0.01を設定した場合には0.01から分解モンテカルロ法がスタートし、1.00を設定した場合には1.00からスタートします。

GetIsInitLots()関数を実行すると初期状態(配列が空っぽの状態)かどうかを判断できます。

初期ロットを設定する場合にはGetIsInitLots()の戻り値がtrueの場合に行ってください。分解モンテカルロ法の実行途中で外部から初期ロットを変更してしまうとGetLotsで取得できる値が変わってしまい、分解モンテカルロ法の意味が無くなってしまいます。

動作確認用テストコード

使い方の参考にもなるようなテストコードを用意しました。

//+------------------------------------------------------------------+
//|                                            MonteCarloLibTest.mq4 |
//|                                 Copyright 2024, TradeAndSoftware |
//|                                            https://www.tasfx.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, TradeAndSoftware"
#property link      "https://www.tasfx.net"
#property version   "1.00"
#property strict

#include <MonteCarlo.mqh>

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

input BetMode BetType = MonteCarlo;
input int Magic = 20240410;
input int StopLoss = 100;
input double TakeProfitRate = 1.5;

string EAComment = "MonteCarlo";
int Slippage = 2;
double Points;
bool IsPositions = false;
int TakeProfit;

int OnInit()
{
   InitLotsArray(BetType);
   Points = Point;
   if(Digits%2 == 1) Points *= 10.0;
   
   TakeProfit = (int)(StopLoss * TakeProfitRate);

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(CountOrders() == 0)
   {
      if(IsPositions)
      {
         IsPositions = false;
         SetLots(IsWinTrade());
      }
      
      double sl = Ask - StopLoss * Points;
      double tp = Ask + TakeProfit * Points;
      double lots = GetLots();
      lots = NormalizeDouble(lots,2);
      int ticket = OrderSend(Symbol(),OP_BUY,lots,Ask,Slippage,sl,tp,EAComment,Magic,0,Blue);
      if(ticket < 0)
      {
         OutputError("Open Error");
      }
   }
   else
   {
      IsPositions = true;
   }
}

int CountOrders()
{
   int count = 0;
   for(int i=0; i<=OrdersTotal()-1; i++)
   {
       if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false) break;
       if(OrderMagicNumber() != Magic || OrderSymbol() !=Symbol()) continue;
         count++;
   }
   return(count);   
}

bool IsWinTrade()
{
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
      {
         if(OrderMagicNumber() == Magic)
         {
            if(OrderType() == OP_BUY || OrderType() == OP_SELL)
            {
               if(OrderProfit() > 0) return true;
               else return false;
            }
         }
      }
   }
   OutputError("No trade history.");
   return false;
}

MonteCarloLibTest.mq4としました。ファイルはMonteCarloLib.zipに同梱しています。

EAにモンテカルロ法や分解モンテカルロ法を組み込んでみたい方はお試しください。

もし不具合などがありましたら、お手数ですがコメント等でご連絡いただけますと幸いです。

次回はZigzagBreakoutEAにモンテカルロ法/分解モンテカルロ法を組み込んでみます。

コメント

タイトルとURLをコピーしました