//+------------------------------------------------------------------+
//| QuantStrategyEA.mq5 |
//| Example EA for Advanced Quant Behavior Strategy |
//+------------------------------------------------------------------+
#property copyright "Achilleus Capital"
#property link "Quant Trading Firm"
#property version "1.00"
#include <Trade\Trade.mqh>
#include <Indicators\Indicators.mqh>
CTrade Trade;
// Input parameters
input double RiskPercent = 1.0; // Risk per trade in percentage
input int MA_Period = 50; // Period for the Simple Moving Average
(SMA)
input int ATR_Period = 14; // ATR period for volatility-based stop
input double ATR_Multiplier = 2.0; // Multiplier to set Stop Loss distance
input double LotSize_Min = 0.01; // Minimum lot size
input double LotSize_Factor = 0.1; // Factor to adjust lot size based on
account equity
// Global variables for indicator handles
int smaHandle;
int atrHandle;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Create handles for indicators
smaHandle = iMA(_Symbol, _Period, MA_Period, 0, MODE_SMA, PRICE_CLOSE);
if(smaHandle == INVALID_HANDLE)
{
Print("Failed to create SMA handle");
return(INIT_FAILED);
}
atrHandle = iATR(_Symbol, _Period, ATR_Period);
if(atrHandle == INVALID_HANDLE)
{
Print("Failed to create ATR handle");
return(INIT_FAILED);
}
Print("EA initialized successfully");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Release indicator handles
if(smaHandle != INVALID_HANDLE)
IndicatorRelease(smaHandle);
if(atrHandle != INVALID_HANDLE)
IndicatorRelease(atrHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Make sure we have enough bars
if(Bars(_Symbol, _Period) < (MathMax(MA_Period, ATR_Period)+1))
return;
//--- Copy SMA data
double smaArray[3]; // current and previous values
if(CopyBuffer(smaHandle, 0, 0, 3, smaArray) <= 0)
{
Print("Error copying SMA data");
return;
}
//--- Copy ATR data
double atrArray[3];
if(CopyBuffer(atrHandle, 0, 0, 3, atrArray) <= 0)
{
Print("Error copying ATR data");
return;
}
//--- Copy Close prices into an array
double closeArray[3];
if(CopyClose(_Symbol, _Period, 0, 3, closeArray) <= 0)
{
Print("Error copying Close prices");
return;
}
// Get current price (using Bid price)
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// Define a simple behavior:
// If the previous bar's close was below the SMA and the current close is above
the SMA, then long.
// If the previous bar's close was above the SMA and the current close is below
the SMA, then short.
bool longSignal = (closeArray[1] < smaArray[1] && closeArray[0] > smaArray[0]);
bool shortSignal = (closeArray[1] > smaArray[1] && closeArray[0] < smaArray[0]);
// Do not trade if there is already an open position on this symbol
if(PositionSelect(_Symbol))
{
// Optionally, you can add trailing stop logic or exit conditions here.
return;
}
// Calculate risk-based lot size
double lot = CalculateLotSize(price, atrArray[0]);
if(lot < LotSize_Min)
lot = LotSize_Min;
// Calculate stop loss distance based on ATR
double slDistance = atrArray[0] * ATR_Multiplier;
double tpDistance = slDistance * 2.0; // Example risk:reward ratio 1:2
// Trading logic for long positions
if(longSignal)
{
double stopLoss = price - slDistance;
double takeProfit = price + tpDistance;
if(Trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, lot, price, stopLoss,
takeProfit))
Print("Long position opened at price: ", price);
else
Print("Failed to open long position. Error: ", GetLastError());
}
// Trading logic for short positions
else if(shortSignal)
{
double stopLoss = price + slDistance;
double takeProfit = price - tpDistance;
if(Trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, lot, price, stopLoss,
takeProfit))
Print("Short position opened at price: ", price);
else
Print("Failed to open short position. Error: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Function: CalculateLotSize |
//| Calculates lot size based on account equity and risk per trade |
//+------------------------------------------------------------------+
double CalculateLotSize(double price, double atrValue)
{
// Calculate risk in money
double accountEquity = AccountInfoDouble(ACCOUNT_EQUITY);
double riskMoney = accountEquity * (RiskPercent / 100.0);
// Stop loss in price units, using ATR value multiplied by our multiplier
double stopLossPrice = atrValue * ATR_Multiplier;
// Calculate lot size: riskMoney divided by stop loss (in monetary terms per
lot)
// Note: Adjust the multiplier below based on instrument specifications (e.g.,
contract size)
double lotSize = riskMoney / (stopLossPrice * LotSize_Factor);
// Normalize lot size to the broker's allowed step size (2 decimals)
lotSize = NormalizeDouble(lotSize, 2);
return(lotSize);
}
//+------------------------------------------------------------------+