カジノのモンテカルロ法を使ったEAのサンプル
モンテカルロ法のMQLのサンプルです。
個人的にモンテカルロ法は好きじゃない。マーチンゲールのほうが好きだ。
モンテカルロ法は微妙に勝ち負けを繰り返す展開なら勝てるけど、負けを引きずると負け越しが発生する可能性があるのでマーチンみたいに勝てばすべて捲れるわけじゃない。
捲れてないのにリセットされるので、もやる瞬間がでてくるんだ。
さらに連戦連勝をしてもしょぼ勝ちになってしまうので、あんまりお金は増えない。
//+------------------------------------------------------------------+
//| MonteCarloEA_RR1_1.mq4 |
//| Copyright 2024, Your Name |
//| https://www.yourwebsite.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Your Name"
#property link "https://www.yourwebsite.com"
#property version "1.00"
#property strict
// 入力パラメータ
input double InitialLotSize = 0.01; // 初期ロットサイズ
input int MagicNumber = 12345; // マジックナンバー
input double StopLoss = 500; // ストップロス(ポイント)
input double TakeProfit = 500; // テイクプロフィット(ポイント)
// グローバル変数
double sequence[100];
int sequenceSize;
bool isInitialized = false;
int lastOrderTicket = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 初期化
sequenceSize = 3;
sequence[0] = 1;
sequence[1] = 2;
sequence[2] = 3;
if (!isInitialized)
{
InitializeFromHistory();
isInitialized = true;
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// オープンポジションがある場合は何もしない
if (OrdersTotal() > 0) return;
// 新しいポジションを開く
double lotSize = CalculateMonteCarloLotSize();
int ticket = OpenPosition(lotSize);
if (ticket > 0)
{
Print("新しいポジションを開きました。チケット番号: ", ticket, " ロットサイズ: ", lotSize);
}
}
//+------------------------------------------------------------------+
//| モンテカルロ法でロットサイズを計算 |
//+------------------------------------------------------------------+
double CalculateMonteCarloLotSize()
{
// ロットサイズの計算
double lotSize = (sequence[0] + sequence[sequenceSize - 1]) * InitialLotSize;
// 直前の取引結果の処理
if (OrdersHistoryTotal() > 0)
{
for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) &&
OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber &&
OrderTicket() > lastOrderTicket)
{
lastOrderTicket = OrderTicket();
bool isWin = (OrderProfit() > 0);
UpdateSequence(isWin, lotSize);
break; // 最新の取引のみを処理
}
}
}
// デバッグ情報の出力
PrintSequence();
return NormalizeDouble(lotSize, 2);
}
//+------------------------------------------------------------------+
//| 数列を更新 |
//+------------------------------------------------------------------+
void UpdateSequence(bool isWin, double lotSize)
{
if (isWin)
{
// 勝った場合、数列の両端を削除
if (sequenceSize > 2)
{
for (int j = 0; j < sequenceSize - 2; j++)
{
sequence[j] = sequence[j + 1];
}
sequenceSize -= 2;
}
else
{
// 数列が空になったら終了
sequenceSize = 0;
}
}
else
{
// 負けた場合、ベット額を数列の最後に追加
if (sequenceSize < ArraySize(sequence))
{
sequence[sequenceSize] = lotSize / InitialLotSize; // ベット額を数列に追加
sequenceSize++;
}
}
if (sequenceSize == 0)
{
// 数列が空になったら初期化
sequence[0] = 1;
sequence[1] = 2;
sequence[2] = 3;
sequenceSize = 3;
}
}
//+------------------------------------------------------------------+
//| 取引履歴から初期状態を設定 |
//+------------------------------------------------------------------+
void InitializeFromHistory()
{
int historyCount = 0;
for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) &&
OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
historyCount++;
bool isWin = (OrderProfit() > 0);
double usedLotSize = OrderLots() / InitialLotSize;
UpdateSequence(isWin, usedLotSize);
// 最新の20取引まで遡る
if (historyCount >= 20) break;
}
}
}
//+------------------------------------------------------------------+
//| 新しいポジションを開く |
//+------------------------------------------------------------------+
int OpenPosition(double lotSize)
{
int ticket = 0;
double price = 0;
double sl = 0;
double tp = 0;
if (MathRand() % 2 == 0) // ランダムに買いまたは売りを選択
{
price = Ask;
sl = NormalizeDouble(price - StopLoss * Point, Digits);
tp = NormalizeDouble(price + TakeProfit * Point, Digits);
ticket = OrderSend(Symbol(), OP_BUY, lotSize, price, 3, sl, tp, "MonteCarloEA", MagicNumber, 0, clrGreen);
}
else
{
price = Bid;
sl = NormalizeDouble(price + StopLoss * Point, Digits);
tp = NormalizeDouble(price - TakeProfit * Point, Digits);
ticket = OrderSend(Symbol(), OP_SELL, lotSize, price, 3, sl, tp, "MonteCarloEA", MagicNumber, 0, clrRed);
}
return ticket;
}
//+------------------------------------------------------------------+
//| 数列をプリント |
//+------------------------------------------------------------------+
void PrintSequence()
{
string sequenceStr = "";
for (int i = 0; i < sequenceSize; i++)
{
sequenceStr += DoubleToString(sequence[i], 2);
if (i < sequenceSize - 1) sequenceStr += ",";
}
Print("Sequence: ", sequenceStr);
}
Claude 3.5 Sonnetで生成しました。
コードは著作権フリーです。自由に使ってね!
よろしければサポートお願いします! いただいたサポートはクリエイターとしての活動費に使わせていただきます!