モンテカルロ法の計算方法MQL4、PineScript
モンテカルロ法っていうのがあって計算は簡単だけど、紙に都度メモる必要があるのでとても面倒くさい方法です。
ベラジョンから引用します。
いちいち紙にメモは面倒くさいのでギャンブラーみたいな単細胞には向いてないです。
そこでプログラミングで自動計算するので冷静にモンテカルロ法が使えます。
半裁量EA ELDRAでバックテスト
モンテカルロ法はRR比率が固定されている場合に有効なので、それ以外はなんかがおかしいかも。
Pine Script
//@version=5
strategy('[ホソノP]ASCTrendでエントリー(モンテカルロ法or固定ロット数)', overlay=true, default_qty_type=strategy.cash, default_qty_value=1000)
// Inputs for ASC Trend
eternalfg = input(false, title='eternal 確定')
eternal = eternalfg ? 1 : 0
ASClength = input.int(title='ASC Length', minval=4, defval=10)
RISK = input.int(title='RISK', minval=0, defval=3)
// Inputs for Blackflag FTS
trailType = input.string('modified', 'Trailtype', options=['modified', 'unmodified'])
ATRPeriod = input(28, 'ATR Period')
ATRFactor = input(5, 'ATR Factor')
// ロットサイズ設定のための新しい入力
lotSizeMethod = input.string("Fixed", title="ロットサイズ方式", options=["Fixed", "MonteCarlo"])
fixedLotSize = input.float(0.01, "固定ロットサイズ", minval=0.01, step=0.01)
initialLotSize = input.float(0.01, "モンテカルロ初期ロットサイズ", minval=0.01, step=0.01)
maxSequenceSize = input.int(100, "最大数列サイズ", minval=3)
// ASC Trend Calculations
x1 = 67 + RISK
x2 = 33 - RISK
Range = ta.highest(ASClength) - ta.lowest(ASClength)
AvgRange = ta.sma(Range, ASClength)
CountFg = math.abs(open - close) >= AvgRange * 2.0 ? 1 : 0
TrueCount = math.sum(CountFg, ASClength)
CountFg2 = math.abs(close[3] - close) >= AvgRange * 4.6 ? 1 : 0
TrueCount2 = math.sum(CountFg2, ASClength - 3)
wpr3RR = ta.wpr(3 + RISK + RISK)
wpr3 = ta.wpr(3)
wpr4 = ta.wpr(4)
WprAbs = 100 + (TrueCount2 > 0 ? wpr4 : TrueCount > 0 ? wpr3 : wpr3RR)
ASC_Trend = 0
ASC_Trend := WprAbs[eternal] < x2[eternal] ? -1 : WprAbs[eternal] > x1[eternal] ? 1 : ASC_Trend[1]
// Blackflag FTS Calculations
norm_o = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, open)
norm_h = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, high)
norm_l = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, low)
norm_c = request.security(ticker.new(syminfo.prefix, syminfo.ticker), timeframe.period, close)
Wild_ma(_src, _malength) =>
_wild = 0.0
_wild := nz(_wild[1]) + (_src - nz(_wild[1])) / _malength
_wild
HiLo = math.min(norm_h - norm_l, 1.5 * nz(ta.sma(norm_h - norm_l, ATRPeriod)))
HRef = norm_l <= norm_h[1] ? norm_h - norm_c[1] : norm_h - norm_c[1] - 0.5 * (norm_l - norm_h[1])
LRef = norm_h >= norm_l[1] ? norm_c[1] - norm_l : norm_c[1] - norm_l - 0.5 * (norm_l[1] - norm_h)
trueRange = trailType == 'modified' ? math.max(HiLo, HRef, LRef) : math.max(norm_h - norm_l, math.abs(norm_h - norm_c[1]), math.abs(norm_l - norm_c[1]))
loss = ATRFactor * Wild_ma(trueRange, ATRPeriod)
Up = norm_c - loss
Dn = norm_c + loss
TrendUp = Up
TrendDown = Dn
Trend = 1
TrendUp := norm_c[1] > TrendUp[1] ? math.max(Up, TrendUp[1]) : Up
TrendDown := norm_c[1] < TrendDown[1] ? math.min(Dn, TrendDown[1]) : Dn
Trend := norm_c > TrendDown[1] ? 1 : norm_c < TrendUp[1] ? -1 : nz(Trend[1], 1)
trail = Trend == 1 ? TrendUp : TrendDown
macdLine = ta.ema(close, 12) - ta.ema(close, 26)
signalLine = ta.ema(macdLine, 9)
histogram = macdLine - signalLine
sb = histogram // This is your Impulse MACD histogram value
// Define the threshold for the Impulse MACD signal (sikiti)
sikiti = input(0.02, title='Impulse MACD Threshold')
// Combine all conditions and plot the buy/sell signals
ConditionForSignal = sb <= sikiti and sb >= -sikiti
// Signal conditions
longCondition = ta.crossover(ASC_Trend, 0) and Trend == 1 and not ConditionForSignal
shortCondition = ta.crossunder(ASC_Trend, 0) and Trend == -1 and not ConditionForSignal
// Calculate stop loss and take profit levels
stopLossLong = low[1]
takeProfitLong = close + (close - stopLossLong) * 1
stopLossShort = high[1]
takeProfitShort = close - (stopLossShort - close) * 1
// モンテカルロ法のためのグローバル変数
var float[] sequence = array.new_float(3, 1.0) // 初期数列 [1, 2, 3]
var int sequenceSize = 3
var int lastOrderId = 0
var float currentLotSize = initialLotSize * 10000 // 初期ロットサイズに10000を掛ける
// 現在の取引ID(バーのインデックス)を取得
currentOrderId = bar_index
if (strategy.closedtrades > 0)
currentOrderId := strategy.closedtrades.exit_bar_index(strategy.closedtrades - 1)
// モンテカルロ法でロットサイズを計算
if (lotSizeMethod == "MonteCarlo" and currentOrderId > lastOrderId)
lastOrderId := currentOrderId
isWin = strategy.closedtrades.profit(strategy.closedtrades - 1) > 0
if isWin
// 勝った場合、数列の両端を削除
if sequenceSize > 2
array.shift(sequence)
array.pop(sequence)
sequenceSize := sequenceSize - 2
else
// 数列が空になったら初期化
array.clear(sequence)
array.push(sequence, 1.0)
array.push(sequence, 2.0)
array.push(sequence, 3.0)
sequenceSize := 3
else
// 負けた場合、ベット額を数列の最後に追加
if sequenceSize < maxSequenceSize
array.push(sequence, currentLotSize / (initialLotSize * 10000))
sequenceSize := sequenceSize + 1
// 新しいロットサイズを計算
currentLotSize := (array.get(sequence, 0) + array.get(sequence, sequenceSize - 1)) * initialLotSize * 10000
// 固定ロットサイズの場合
if (lotSizeMethod == "Fixed")
currentLotSize := fixedLotSize * 10000
// デバッグ情報の出力
if (lotSizeMethod == "MonteCarlo")
sequenceStr = array.join(sequence, ",")
label.new(bar_index, high, text="Lot Size: " + str.tostring(currentLotSize, "#.##") + " Sequence: " + sequenceStr)
else
label.new(bar_index, high, text="Fixed Lot Size: " + str.tostring(currentLotSize, "#.##"))
// 戦略の実行
if (longCondition)
strategy.entry("Long", strategy.long, qty=currentLotSize / close)
strategy.exit("Take Profit Long", "Long", limit=takeProfitLong, stop=stopLossLong)
if (shortCondition)
strategy.entry("Short", strategy.short, qty=currentLotSize / close)
strategy.exit("Take Profit Short", "Short", limit=takeProfitShort, stop=stopLossShort)
MQL4
double CalculateMonteCarloLotSize()
{
static double sequence[100] = {1, 2, 3}; // 初期数列
static int sequenceSize = 3; // 初期数列の長さ
static bool isInitialized = false; // 初期化フラグ
static int lastOrderTicket = 0; // 最後に処理した注文のチケット番号
// 初期化(EA起動時に一度だけ実行)
if (!isInitialized)
{
InitializeFromHistory(sequence, sequenceSize);
isInitialized = true;
}
// ロットサイズの計算
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);
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++;
}
}
break; // 最新の取引のみを処理
}
}
}
// デバッグ情報の出力
string sequenceStr = "";
for (int i = 0; i < sequenceSize; i++)
{
sequenceStr += DoubleToString(sequence[i], 2);
if (i < sequenceSize - 1) sequenceStr += ",";
}
Print("Lot Size: ", DoubleToString(lotSize, 2), " Sequence: ", sequenceStr);
if (sequenceSize == 0)
{
// 数列が空になったら初期化
sequence[0] = 1;
sequence[1] = 2;
sequence[2] = 3;
sequenceSize = 3;
}
return NormalizeDouble(lotSize, 2);
}
// TradeHistoryから初期状態を設定
void InitializeFromHistory(double &sequence[], int &sequenceSize)
{
int historyCount = 0;
sequenceSize = 3;
sequence[0] = 1;
sequence[1] = 2;
sequence[2] = 3;
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;
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] = usedLotSize;
sequenceSize++;
}
}
if (sequenceSize == 0)
{
sequence[0] = 1;
sequence[1] = 2;
sequence[2] = 3;
sequenceSize = 3;
}
// 最新の20取引まで遡る
if (historyCount >= 20) break;
}
}
}
ここから先は
0字
このマガジンで読み放題です。
FX自動売買開発入門サンプルコードセット
10,000円
EA開発者のためのサンプルコード集
よろしければサポートお願いします! いただいたサポートはクリエイターとしての活動費に使わせていただきます!