ウッチーゴールドゼニヒロイEA.Ver①

トレードで新しいことを思いついたので早速EAを作りました。自分への記録用として。

このEAは「ボラティリティを基準にロットサイズと利確幅を自動計算して、手動でボタンを押して売買できる仕組み」を持ったEAです。ポイントをまとめると次のとおりです👇


📌 機能概要

  1. チャート上に操作パネルを作成
    • SELLボタン(赤) … 押すと売り注文を発注
    • BUYボタン(青) … 押すと買い注文を発注
    • Target Profit入力ボックス … 目標利益額(通貨単位)を入力できる
  2. ボラティリティ計算
    • 過去 VolatilityPeriod 日間の 日足の高値‐安値の平均値 を計算
    • その平均値を VolatilityDivisor で割って、利確幅(TP幅)を決定
  3. ロットサイズの自動計算
    • 「目標利益額(TargetProfit)」を入力すると、それを達成するために必要なロット数を計算
    • 計算結果を、ブローカーの最小ロット・ロットステップに合わせて調整
  4. 注文実行
    • BUY注文 … Askでエントリー、TPは「Ask+ボラティリティ幅」、SLはなし
    • SELL注文 … Bidでエントリー、TPは「Bid-ボラティリティ幅」、SLはなし
    • 発注後はチケット番号やロットサイズをログに出力
  5. パラメータ
    • TargetProfit … 目標利益額(例:1000円)
    • VolatilityPeriod … ボラティリティ計算に使う日数(例:10日)
    • VolatilityDivisor … ボラティリティを割る値。大きいほどTP幅が狭くなる
  6. その他
    • チャートを切り替えても「目標利益額」は保持される
    • 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));
}

}

//+——————————————————————+

コメント

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