
トレードで新しいことを思いついたので早速EAを作りました。自分への記録用として。
このEAは「ボラティリティを基準にロットサイズと利確幅を自動計算して、手動でボタンを押して売買できる仕組み」を持ったEAです。ポイントをまとめると次のとおりです👇

📌 機能概要
- チャート上に操作パネルを作成
- SELLボタン(赤) … 押すと売り注文を発注
- BUYボタン(青) … 押すと買い注文を発注
- Target Profit入力ボックス … 目標利益額(通貨単位)を入力できる
- ボラティリティ計算
- 過去
VolatilityPeriod日間の 日足の高値‐安値の平均値 を計算 - その平均値を
VolatilityDivisorで割って、利確幅(TP幅)を決定
- 過去
- ロットサイズの自動計算
- 「目標利益額(TargetProfit)」を入力すると、それを達成するために必要なロット数を計算
- 計算結果を、ブローカーの最小ロット・ロットステップに合わせて調整
- 注文実行
- BUY注文 … Askでエントリー、TPは「Ask+ボラティリティ幅」、SLはなし
- SELL注文 … Bidでエントリー、TPは「Bid-ボラティリティ幅」、SLはなし
- 発注後はチケット番号やロットサイズをログに出力
- パラメータ
TargetProfit… 目標利益額(例:1000円)VolatilityPeriod… ボラティリティ計算に使う日数(例:10日)VolatilityDivisor… ボラティリティを割る値。大きいほどTP幅が狭くなる
- その他
- チャートを切り替えても「目標利益額」は保持される
- SLは設定されない仕様(リスク管理は手動で必要)
⚡まとめ
このEAは 「完全自動売買」ではなく、半自動の支援ツール です。
- ボラティリティをもとに「利確幅」と「ロットサイズ」を計算
- チャートのボタン操作でワンクリック発注
- 利確のみ設定、損切りは設定なし
👉 簡単に言うと「ボラティリティを基準に自動でロットを決めて、ワンクリックで売買できるマニュアル補助EA」です。
//+——————————————————————+
//| VolatilityTradingEA.mq4 |
//| |
//| Volatility Based Automated Trading EA |
//+——————————————————————+
property copyright “Custom EA”
property link “”
property version “1.00”
property strict
// External Parameters
extern double TargetProfit = 1000.0; // Target profit amount (currency unit)
extern int VolatilityPeriod = 10; // Volatility calculation period (days)
extern double VolatilityDivisor = 20.0; // Volatility divisor
// Global Variables
string sellButtonName = “SellButton”;
string buyButtonName = “BuyButton”;
string profitBoxName = “ProfitBox”;
string profitLabelName = “ProfitLabel”;
double currentVolatility = 0.0;
double calculatedLots = 0.01;
double savedTargetProfit = 0.0;
//+——————————————————————+
//| Expert initialization function |
//+——————————————————————+
int OnInit()
{
// Preserve target profit value when switching currency pairs
if(savedTargetProfit > 0)
{
TargetProfit = savedTargetProfit;
}
else
{
savedTargetProfit = TargetProfit;
}
CreateButtons();
CreateProfitBox();
CalculateVolatility();
return(INIT_SUCCEEDED);
}
//+——————————————————————+
//| Expert deinitialization function |
//+——————————————————————+
void OnDeinit(const int reason)
{
// Save current target profit value before deinitialization
string inputText = ObjectGetString(0, profitBoxName, OBJPROP_TEXT);
if(StringLen(inputText) > 0)
{
savedTargetProfit = StringToDouble(inputText);
}
ObjectDelete(sellButtonName);
ObjectDelete(buyButtonName);
ObjectDelete(profitBoxName);
ObjectDelete(profitLabelName);
}
//+——————————————————————+
//| Expert tick function |
//+——————————————————————+
void OnTick()
{
// Update volatility periodically
static datetime lastUpdate = 0;
if(Time[0] != lastUpdate)
{
CalculateVolatility();
UpdateLotSize();
lastUpdate = Time[0];
}
}
//+——————————————————————+
//| ChartEvent function |
//+——————————————————————+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK)
{
if(sparam == sellButtonName)
{
ExecuteSellOrder();
ObjectSetInteger(0, sellButtonName, OBJPROP_STATE, false);
}
else if(sparam == buyButtonName)
{
ExecuteBuyOrder();
ObjectSetInteger(0, buyButtonName, OBJPROP_STATE, false);
}
}
else if(id == CHARTEVENT_OBJECT_ENDEDIT)
{
if(sparam == profitBoxName)
{
string inputText = ObjectGetString(0, profitBoxName, OBJPROP_TEXT);
TargetProfit = StringToDouble(inputText);
savedTargetProfit = TargetProfit; // Save the updated value
UpdateLotSize();
}
}
}
//+——————————————————————+
//| Create buttons function |
//+——————————————————————+
void CreateButtons()
{
// Sell button (Red)
ObjectCreate(sellButtonName, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, sellButtonName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, sellButtonName, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, sellButtonName, OBJPROP_YDISTANCE, 10);
ObjectSetInteger(0, sellButtonName, OBJPROP_XSIZE, 80);
ObjectSetInteger(0, sellButtonName, OBJPROP_YSIZE, 30);
ObjectSetString(0, sellButtonName, OBJPROP_TEXT, “SELL”);
ObjectSetInteger(0, sellButtonName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, sellButtonName, OBJPROP_BGCOLOR, clrRed);
ObjectSetInteger(0, sellButtonName, OBJPROP_BORDER_COLOR, clrBlack);
// Buy button (Blue)
ObjectCreate(buyButtonName, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, buyButtonName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, buyButtonName, OBJPROP_XDISTANCE, 100);
ObjectSetInteger(0, buyButtonName, OBJPROP_YDISTANCE, 10);
ObjectSetInteger(0, buyButtonName, OBJPROP_XSIZE, 80);
ObjectSetInteger(0, buyButtonName, OBJPROP_YSIZE, 30);
ObjectSetString(0, buyButtonName, OBJPROP_TEXT, "BUY");
ObjectSetInteger(0, buyButtonName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, buyButtonName, OBJPROP_BGCOLOR, clrBlue);
ObjectSetInteger(0, buyButtonName, OBJPROP_BORDER_COLOR, clrBlack);
}
//+——————————————————————+
//| Create profit input box function |
//+——————————————————————+
void CreateProfitBox()
{
// Label
ObjectCreate(profitLabelName, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, profitLabelName, OBJPROP_CORNER, CORNER_LEFT_LOWER);
ObjectSetInteger(0, profitLabelName, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, profitLabelName, OBJPROP_YDISTANCE, 60);
ObjectSetString(0, profitLabelName, OBJPROP_TEXT, “Target Profit:”);
ObjectSetInteger(0, profitLabelName, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, profitLabelName, OBJPROP_FONTSIZE, 10);
// Input box
ObjectCreate(profitBoxName, OBJ_EDIT, 0, 0, 0);
ObjectSetInteger(0, profitBoxName, OBJPROP_CORNER, CORNER_LEFT_LOWER);
ObjectSetInteger(0, profitBoxName, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, profitBoxName, OBJPROP_YDISTANCE, 40);
ObjectSetInteger(0, profitBoxName, OBJPROP_XSIZE, 100);
ObjectSetInteger(0, profitBoxName, OBJPROP_YSIZE, 20);
ObjectSetString(0, profitBoxName, OBJPROP_TEXT, DoubleToStr(TargetProfit, 2));
ObjectSetInteger(0, profitBoxName, OBJPROP_COLOR, clrBlack);
ObjectSetInteger(0, profitBoxName, OBJPROP_BGCOLOR, clrWhite);
ObjectSetInteger(0, profitBoxName, OBJPROP_BORDER_COLOR, clrBlack);
}
//+——————————————————————+
//| Calculate volatility function |
//+——————————————————————+
void CalculateVolatility()
{
double totalRange = 0.0;
int validDays = 0;
// Get past N days of daily data
for(int i = 1; i <= VolatilityPeriod; i++)
{
double high = iHigh(Symbol(), PERIOD_D1, i);
double low = iLow(Symbol(), PERIOD_D1, i);
if(high > 0 && low > 0)
{
double dailyRange = high - low;
totalRange += dailyRange;
validDays++;
}
}
if(validDays > 0)
{
double averageRange = totalRange / validDays;
currentVolatility = averageRange / VolatilityDivisor;
Print("Average Daily Range: ", DoubleToStr(averageRange / Point, Digits));
Print("Take Profit Width: ", DoubleToStr(currentVolatility / Point, Digits), " pips");
}
else
{
currentVolatility = 0.001; // Default value
}
}
//+——————————————————————+
//| Update lot size function |
//+——————————————————————+
void UpdateLotSize()
{
if(currentVolatility <= 0) return;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
if(tickValue > 0 && tickSize > 0)
{
// Calculate lot size based on expected profit from take profit width
double pipsToProfit = currentVolatility / tickSize;
double profitPerLot = pipsToProfit * tickValue;
if(profitPerLot > 0)
{
calculatedLots = TargetProfit / profitPerLot;
// Adjust to minimum lot unit
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
calculatedLots = MathMax(minLot, MathRound(calculatedLots / lotStep) * lotStep);
Print("Calculated Lots: ", DoubleToStr(calculatedLots, 2));
}
}
}
//+——————————————————————+
//| Execute sell order function |
//+——————————————————————+
void ExecuteSellOrder()
{
if(currentVolatility <= 0)
{
Alert(“Volatility not calculated”);
return;
}
double price = Bid;
double takeProfit = price - currentVolatility;
double stopLoss = 0; // No stop loss
int ticket = OrderSend(Symbol(), OP_SELL, calculatedLots, price, 3, stopLoss, takeProfit, "Volatility Sell", 0, 0, clrRed);
if(ticket < 0)
{
Alert("Sell order error: ", GetLastError());
}
else
{
Print("Sell order success - Ticket: ", ticket, " Lots: ", calculatedLots, " TP: ", DoubleToStr(takeProfit, Digits));
}
}
//+——————————————————————+
//| Execute buy order function |
//+——————————————————————+
void ExecuteBuyOrder()
{
if(currentVolatility <= 0)
{
Alert(“Volatility not calculated”);
return;
}
double price = Ask;
double takeProfit = price + currentVolatility;
double stopLoss = 0; // No stop loss
int ticket = OrderSend(Symbol(), OP_BUY, calculatedLots, price, 3, stopLoss, takeProfit, "Volatility Buy", 0, 0, clrBlue);
if(ticket < 0)
{
Alert("Buy order error: ", GetLastError());
}
else
{
Print("Buy order success - Ticket: ", ticket, " Lots: ", calculatedLots, " TP: ", DoubleToStr(takeProfit, Digits));
}
}
//+——————————————————————+


コメント