0% found this document useful (0 votes)
94 views8 pages

Volatility Profile - mq5

The document is a MetaTrader 5 Expert Advisor (EA) script that implements a trading strategy based on various technical indicators including ATR, Bollinger Bands, RSI, and EMA. It allows user-configurable settings for trading parameters, risk management, and trade execution. The EA operates by analyzing market conditions and placing buy or sell orders based on predefined signals derived from the indicators.

Uploaded by

muhapikarim
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
94 views8 pages

Volatility Profile - mq5

The document is a MetaTrader 5 Expert Advisor (EA) script that implements a trading strategy based on various technical indicators including ATR, Bollinger Bands, RSI, and EMA. It allows user-configurable settings for trading parameters, risk management, and trade execution. The EA operates by analyzing market conditions and placing buy or sell orders based on predefined signals derived from the indicators.

Uploaded by

muhapikarim
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

//+------------------------------------------------------------------+

//| TranslatedPythonBotEA.mq5 |
//| Based on Python Bot Logic Mentor |
//| Your Name Here |
//+------------------------------------------------------------------+
#property copyright "Your Name Here"
#property link "Your Link Here"
#property version "1.02" // Incremented version
#property strict

// Include necessary standard library files


#include <Trade\[Link]> // For CTrade class (trading functions)
#include <Trade\[Link]> // For CSymbolInfo class (symbol properties)
#include <Trade\[Link]> // For CAccountInfo class (account properties)

// --- Input Parameters (User-configurable EA settings) ---


input group "Symbol & Timeframe Settings"
// string InpSymbolToTrade = "Volatility 75 Index"; // EA uses
_Symbol (chart symbol) by default
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_M1; //
Timeframe for indicator calculations

input group "Indicator Parameters"


input int InpATRPeriod = 14;
input int InpBBandsPeriod = 20;
input double InpBBandsStdDev = 2.0;
input int InpRSIPeriod = 14;
input int InpEMAFastPeriod = 12;
input int InpEMASlowPeriod = 50;

input group "Risk & Trade Management"


input double InpRiskPerTradePercent = 1.0; // e.g., 1.0 for 1% of
equity
input double InpATR_SL_Multiplier = 1.5; // Stop Loss based on ATR *
Multiplier
input double InpATR_TP_Multiplier = 3.0; // Take Profit based on ATR
* Multiplier
input int InpDefaultSLPips = 100; // Fallback Stop Loss in
Points (not pips if [Link] != pip unit)
input int InpDefaultTPPips = 200; // Fallback Take Profit in
Points
input ulong InpBotMagicNumber = 23052025; // Unique Magic Number
for this EA's trades
input int InpSlippagePips = 20; // Max allowed slippage in
points

// --- Global Variables ---


CTrade trade; // Trading object from [Link]
CSymbolInfo symbol; // Symbol information object from [Link]
(GLOBAL)
CAccountInfo account; // Account information object from
[Link] (GLOBAL)
string G_CurrentSymbol; // Stores the symbol the EA is running on
(GLOBAL)

// Indicator Handles (to store references to initialised indicators)


int h_ATR;
int h_BB;
int h_RSI;
int h_EMAFast;
int h_EMASlow;

// Arrays to store indicator and price data


double atr_buffer[];
double bb_main_buffer[]; // Bollinger Bands Middle line
double bb_upper_buffer[]; // Bollinger Bands Upper line
double bb_lower_buffer[]; // Bollinger Bands Lower line
double rsi_buffer[];
double ema_fast_buffer[];
double ema_slow_buffer[];
MqlRates rates[]; // For OHLC, Time, Volume (price data)

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
G_CurrentSymbol = _Symbol; // Get the symbol of the chart the EA is attached to
PrintFormat("OnInit: EA Starting on symbol %s, timeframe %s", G_CurrentSymbol,
EnumToString(InpTimeframe));

// Initialize GLOBAL SymbolInfo object


if(![Link](G_CurrentSymbol)) // Set the symbol for the GLOBAL CSymbolInfo
object
{
PrintFormat("Error setting symbol '%s' for CSymbolInfo: %d", G_CurrentSymbol,
GetLastError());
return(INIT_FAILED);
}
// Initialize GLOBAL AccountInfo object and refresh data
[Link]();

// Initialize CTrade object


[Link](InpBotMagicNumber);
[Link](InpSlippagePips);
[Link](G_CurrentSymbol);

// --- Initialize Indicator Handles ---


h_ATR = iATR(G_CurrentSymbol, InpTimeframe, InpATRPeriod);
if(h_ATR == INVALID_HANDLE) { PrintFormat("Error creating ATR indicator: %d",
GetLastError()); return(INIT_FAILED); }

h_BB = iBands(G_CurrentSymbol, InpTimeframe, InpBBandsPeriod, 0,


InpBBandsStdDev, PRICE_CLOSE);
if(h_BB == INVALID_HANDLE) { PrintFormat("Error creating Bollinger Bands
indicator: %d", GetLastError()); return(INIT_FAILED); }

h_RSI = iRSI(G_CurrentSymbol, InpTimeframe, InpRSIPeriod, PRICE_CLOSE);


if(h_RSI == INVALID_HANDLE) { PrintFormat("Error creating RSI indicator: %d",
GetLastError()); return(INIT_FAILED); }

h_EMAFast = iMA(G_CurrentSymbol, InpTimeframe, InpEMAFastPeriod, 0, MODE_EMA,


PRICE_CLOSE);
if(h_EMAFast == INVALID_HANDLE) { PrintFormat("Error creating Fast EMA
indicator: %d", GetLastError()); return(INIT_FAILED); }

h_EMASlow = iMA(G_CurrentSymbol, InpTimeframe, InpEMASlowPeriod, 0, MODE_EMA,


PRICE_CLOSE);
if(h_EMASlow == INVALID_HANDLE) { PrintFormat("Error creating Slow EMA
indicator: %d", GetLastError()); return(INIT_FAILED); }

// Set arrays as series (important for correct indexing: latest data at index 0)
ArraySetAsSeries(rates, true);
ArraySetAsSeries(atr_buffer, true);
ArraySetAsSeries(bb_main_buffer, true);
ArraySetAsSeries(bb_upper_buffer, true);
ArraySetAsSeries(bb_lower_buffer, true);
ArraySetAsSeries(rsi_buffer, true);
ArraySetAsSeries(ema_fast_buffer, true);
ArraySetAsSeries(ema_slow_buffer, true);

Print("OnInit: Initialization successful.");


return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
PrintFormat("OnDeinit: EA Stopping. Reason code: %d", reason);
IndicatorRelease(h_ATR);
IndicatorRelease(h_BB);
IndicatorRelease(h_RSI);
IndicatorRelease(h_EMAFast);
IndicatorRelease(h_EMASlow);
}

//+------------------------------------------------------------------+
//| Expert tick function (called on every new price tick) |
//+------------------------------------------------------------------+
void OnTick()
{
if(!TerminalInfoInteger(TERMINAL_CONNECTED) || !
TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)
|| IsStopped())
{
return;
}

// Refresh GLOBAL symbol object for latest prices (Ask, Bid, Point etc.)
[Link]();
// Refresh GLOBAL account object for latest equity etc. (optional here if done
before lot calc)
// [Link](); // Already called in CalculateLotSize and OnInit

if(CopyRates(G_CurrentSymbol, InpTimeframe, 0, 3, rates) < 3)


{
PrintFormat("Error copying rates for %s: %d", G_CurrentSymbol,
GetLastError());
return;
}

int bars_to_copy = 3;
if(CopyBuffer(h_ATR, 0, 0, bars_to_copy, atr_buffer) < bars_to_copy) {
/*Print("Error copying ATR buffer");*/ return; } // Reduced print frequency for
brevity
if(CopyBuffer(h_BB, 0, 0, bars_to_copy, bb_main_buffer) < bars_to_copy) {
/*Print("Error copying BB Main buffer");*/ return; }
if(CopyBuffer(h_BB, 1, 0, bars_to_copy, bb_upper_buffer) < bars_to_copy) {
/*Print("Error copying BB Upper buffer");*/ return; }
if(CopyBuffer(h_BB, 2, 0, bars_to_copy, bb_lower_buffer) < bars_to_copy) {
/*Print("Error copying BB Lower buffer");*/ return; }
if(CopyBuffer(h_RSI, 0, 0, bars_to_copy, rsi_buffer) < bars_to_copy) {
/*Print("Error copying RSI buffer");*/ return; }
if(CopyBuffer(h_EMAFast, 0, 0, bars_to_copy, ema_fast_buffer) < bars_to_copy)
{ /*Print("Error copying EMA Fast buffer");*/ return; }
if(CopyBuffer(h_EMASlow, 0, 0, bars_to_copy, ema_slow_buffer) < bars_to_copy)
{ /*Print("Error copying EMA Slow buffer");*/ return; }

if(CheckExistingPosition())
{
return;
}

double ema_fast_prev = ema_fast_buffer[1];


double ema_slow_prev = ema_slow_buffer[1];
double rsi_prev = rsi_buffer[1];
double ema_fast_bar2 = ema_fast_buffer[2];
double ema_slow_bar2 = ema_slow_buffer[2];

string signal = "HOLD";

if (ema_fast_bar2 <= ema_slow_bar2 && ema_fast_prev > ema_slow_prev && rsi_prev


< 70.0)
{
signal = "BUY";
}
else if (ema_fast_bar2 >= ema_slow_bar2 && ema_fast_prev < ema_slow_prev &&
rsi_prev > 30.0)
{
signal = "SELL";
}

if(signal != "HOLD")
{
double current_atr_value = atr_buffer[1]; // ATR from last closed bar
double sl_distance_price_units;
double tp_distance_price_units;

// Use NormalizeDouble with [Link]() for ATR checks


if(current_atr_value <= 0 || NormalizeDouble(current_atr_value,
[Link]()) <= NormalizeDouble([Link]() / 10.0, [Link]()))
{
PrintFormat("ATR value (%.*f) is zero or too small. Using default Points
for SL/TP.", [Link](), current_atr_value);
sl_distance_price_units = InpDefaultSLPips * [Link](); // Assuming
InpDefaultSLPips are "points"
tp_distance_price_units = InpDefaultTPPips * [Link]();

if(sl_distance_price_units <=0 ) sl_distance_price_units = 100 *


[Link]();
if(tp_distance_price_units <=0 ) tp_distance_price_units = 200 *
[Link]();
}
else
{
sl_distance_price_units = current_atr_value * InpATR_SL_Multiplier;
tp_distance_price_units = current_atr_value * InpATR_TP_Multiplier;
}
PlaceTrade(signal, sl_distance_price_units, tp_distance_price_units);
}
}

//+------------------------------------------------------------------+
//| Helper Function: Place Trade |
//+------------------------------------------------------------------+
void PlaceTrade(string signal_type, double sl_distance_price_units, double
tp_distance_price_units)
{
double lot_size = CalculateLotSize(sl_distance_price_units);
if(lot_size < [Link]()) // Check against actual min lot from symbol info
{
PrintFormat("Calculated lot size %.2f is less than minimum allowed %.2f.
Skipping trade.", NormalizeDouble(lot_size, 8), [Link]());
return;
}

// Ensure GLOBAL symbol object has fresh rates


// [Link](); // Already called at the start of OnTick

double entry_price_ask = [Link]();


double entry_price_bid = [Link]();
double sl_price = 0.0;
double tp_price = 0.0;
string comment = "EA_Trade_" + TimeToString(TimeCurrent(), TIME_SECONDS);

if(signal_type == "BUY")
{
sl_price = entry_price_ask - sl_distance_price_units;
tp_price = entry_price_ask + tp_distance_price_units;
sl_price = NormalizeDouble(sl_price, [Link]());
tp_price = NormalizeDouble(tp_price, [Link]());

PrintFormat("Attempting BUY: Lot=%.*f, EntryAsk=%.*f, SL=%.*f, TP=%.*f",


[Link](), lot_size, [Link](),
entry_price_ask, [Link](), sl_price, [Link](), tp_price);

if(![Link](lot_size, G_CurrentSymbol, entry_price_ask, sl_price, tp_price,


comment))
{
PrintFormat("BUY order failed: %d - %s", [Link](),
[Link]());
}
else
{
PrintFormat("BUY order placed successfully. Ticket: %d",
(int)[Link]());
}
}
else if(signal_type == "SELL")
{
sl_price = entry_price_bid + sl_distance_price_units;
tp_price = entry_price_bid - tp_distance_price_units;
sl_price = NormalizeDouble(sl_price, [Link]());
tp_price = NormalizeDouble(tp_price, [Link]());

PrintFormat("Attempting SELL: Lot=%.*f, EntryBid=%.*f, SL=%.*f, TP=%.*f",


[Link](), lot_size, [Link](),
entry_price_bid, [Link](), sl_price, [Link](), tp_price);

if(![Link](lot_size, G_CurrentSymbol, entry_price_bid, sl_price,


tp_price, comment))
{
PrintFormat("SELL order failed: %d - %s", [Link](),
[Link]());
}
else
{
PrintFormat("SELL order placed successfully. Ticket: %d",
(int)[Link]());
}
}
}

//+------------------------------------------------------------------+
//| Helper Function: Calculate Lot Size based on Risk % and SL |
//+------------------------------------------------------------------+
double CalculateLotSize(double sl_distance_price_units)
{
[Link](); // Ensure latest equity
double acc_equity = [Link]();
double risk_amount_deposit_currency = acc_equity * (InpRiskPerTradePercent /
100.0);

// Ensure SL distance is at least one point, otherwise lot calculation is


problematic
if(sl_distance_price_units < [Link]())
{
PrintFormat("SL distance (%.*f) is less than one point. Cannot accurately
calculate lot size. Using min lot.", [Link](), sl_distance_price_units);
return([Link]());
}

double tick_value = [Link]();


double tick_size = [Link]();
double point_size = [Link]();

if(tick_size <= 0 || point_size <= 0 || tick_value <=0) // Added tick_value


check
{
Print("Symbol tick_size, point_size, or tick_value is zero or negative.
Cannot calculate lot. Using min lot.");
return([Link]());
}

double value_per_point_one_lot = tick_value / (tick_size / point_size);


if(value_per_point_one_lot <=0) // Check if value_per_point is valid
{
PrintFormat("Value per point for 1 lot (%.2f) is zero or negative. Cannot
calculate lot size. Using min lot.", value_per_point_one_lot);
return([Link]());
}
double sl_value_for_one_lot = (sl_distance_price_units / point_size) *
value_per_point_one_lot;

if(sl_value_for_one_lot <= 0)
{
PrintFormat("SL value per lot (%.2f) is zero or negative. Using min lot.",
sl_value_for_one_lot);
return([Link]());
}

double desired_lot_size = risk_amount_deposit_currency / sl_value_for_one_lot;

double min_lot = [Link]();


double max_lot = [Link]();
double step_lot = [Link]();

desired_lot_size = MathMax(min_lot, desired_lot_size);


if(max_lot > 0 && max_lot > min_lot) desired_lot_size = MathMin(max_lot,
desired_lot_size);

if(step_lot > 0)
{
desired_lot_size = MathFloor(desired_lot_size / step_lot) * step_lot;
// For fractional lots, NormalizeDouble is important
desired_lot_size = NormalizeDouble(desired_lot_size,
[Link]());
}

if (desired_lot_size < min_lot) desired_lot_size = min_lot; // Final check after


stepping

PrintFormat("LotCalc: Equity=%.2f, RiskAmt=%.2f, SL_Dist_Price=%.*f,


SL_Val_Per_Lot=%.2f, CalcLot=%.*f",
acc_equity, risk_amount_deposit_currency,
[Link](), sl_distance_price_units,
sl_value_for_one_lot,
[Link](), desired_lot_size);

return(desired_lot_size);
}

//+------------------------------------------------------------------+
//| Helper Function: Check if a position by this EA already exists |
//+------------------------------------------------------------------+
bool CheckExistingPosition()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong pos_ticket = PositionGetTicket(i);
if(pos_ticket == 0) continue;

if(PositionSelectByTicket(pos_ticket))
{
if(PositionGetString(POSITION_SYMBOL) == G_CurrentSymbol &&
PositionGetInteger(POSITION_MAGIC) == InpBotMagicNumber)
{
return(true);
}
}
}
return(false);
}
//+------------------------------------------------------------------+

You might also like