253 lines
20 KiB
MQL5
253 lines
20 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| NorthfoxTrueEdge.mq5 |
|
|
//| Copyright 2024, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
// Henrik: muutettu niin, että buy ja sell omina aliohjelminaan
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2019, MetaQuotes Software Corp."
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
|
|
//--- Input parameters
|
|
input int StopLoss = 30; // Stop Loss in pips
|
|
input int TakeProfit = 100; // Take Profit in pips
|
|
input int ADX_Period = 8; // ADX Period
|
|
input int MA_Period = 8; // Moving Average Period
|
|
input int EA_Magic = 12345; // EA Magic Number
|
|
input double Adx_Min = 22.0; // Minimum ADX Value
|
|
input double Lot = 0.1; // Lots to Trade
|
|
|
|
//--- Other parameters
|
|
int adxHandle; // Handle for ADX indicator
|
|
int maHandle; // Handle for Moving Average indicator
|
|
double plsDI[], minDI[], adxVal[]; // Dynamic arrays for indicators
|
|
double maVal[]; // Dynamic array for Moving Average
|
|
double previousClose; // Variable to store the close value of the previous bar
|
|
int stopLossPips, takeProfitPips; // Variables for Stop Loss & Take Profit values
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//--- Get handles for indicators
|
|
adxHandle = iADX(NULL, 0, ADX_Period);
|
|
maHandle = iMA(_Symbol, _Period, MA_Period, 0, MODE_EMA, PRICE_CLOSE);
|
|
|
|
//--- Check for valid handles
|
|
if (adxHandle < 0 || maHandle < 0)
|
|
{
|
|
Alert("Error creating handles for indicators - error: ", GetLastError(), "!!");
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//--- Adjust Stop Loss and Take Profit for 5 or 3 digit prices
|
|
stopLossPips = StopLoss;
|
|
takeProfitPips = TakeProfit;
|
|
if (_Digits == 5 || _Digits == 3)
|
|
{
|
|
stopLossPips *= 10;
|
|
takeProfitPips *= 10;
|
|
}
|
|
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//--- Release indicator handles
|
|
IndicatorRelease(adxHandle);
|
|
IndicatorRelease(maHandle);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Buy trade execution function |
|
|
//+------------------------------------------------------------------+
|
|
bool ExecuteBuyTrade()
|
|
{
|
|
//--- Prepare trade request
|
|
MqlTradeRequest mrequest;
|
|
MqlTradeResult mresult;
|
|
ZeroMemory(mrequest); // Initialize request structure
|
|
|
|
mrequest.action = TRADE_ACTION_DEAL; // Immediate order execution
|
|
mrequest.price = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits); // Latest ask price
|
|
mrequest.sl = NormalizeDouble(mrequest.price - stopLossPips * _Point, _Digits); // Stop Loss
|
|
mrequest.tp = NormalizeDouble(mrequest.price + takeProfitPips * _Point, _Digits); // Take Profit
|
|
mrequest.symbol = _Symbol; // Currency pair
|
|
mrequest.volume = Lot; // Number of lots to trade
|
|
mrequest.magic = EA_Magic; // Order Magic Number
|
|
mrequest.type = ORDER_TYPE_BUY; // Buy Order
|
|
mrequest.type_filling = ORDER_FILLING_FOK; // Order execution type
|
|
mrequest.deviation = 100; // Deviation from current price
|
|
|
|
//--- Send order
|
|
OrderSend(mrequest, mresult);
|
|
|
|
// Check order result
|
|
if (mresult.retcode == 10009 || mresult.retcode == 10008) // Request completed or order placed
|
|
{
|
|
Alert("A Buy order has been successfully placed with Ticket#:", mresult.order, "!!");
|
|
return true; // Buy order executed successfully
|
|
}
|
|
else
|
|
{
|
|
Alert("The Buy order request could not be completed - error:", GetLastError());
|
|
ResetLastError();
|
|
return false; // Buy order execution failed
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Sell trade execution function |
|
|
//+------------------------------------------------------------------+
|
|
bool ExecuteSellTrade()
|
|
{
|
|
//--- Prepare trade request
|
|
MqlTradeRequest mrequest;
|
|
MqlTradeResult mresult;
|
|
ZeroMemory(mrequest); // Initialize request structure
|
|
|
|
mrequest.action = TRADE_ACTION_DEAL; // Immediate order execution
|
|
mrequest.price = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits); // Latest bid price
|
|
mrequest.sl = NormalizeDouble(mrequest.price + stopLossPips * _Point, _Digits); // Stop Loss
|
|
mrequest.tp = NormalizeDouble(mrequest.price - takeProfitPips * _Point, _Digits); // Take Profit
|
|
mrequest.symbol = _Symbol; // Currency pair
|
|
mrequest.volume = Lot; // Number of lots to trade
|
|
mrequest.magic = EA_Magic; // Order Magic Number
|
|
mrequest.type = ORDER_TYPE_SELL; // Sell Order
|
|
mrequest.type_filling = ORDER_FILLING_FOK; // Order execution type
|
|
mrequest.deviation = 100; // Deviation from current price
|
|
|
|
//--- Send order
|
|
OrderSend(mrequest, mresult);
|
|
|
|
// Check order result
|
|
if (mresult.retcode == 10009 || mresult.retcode == 10008) // Request completed or order placed
|
|
{
|
|
Alert("A Sell order has been successfully placed with Ticket#:", mresult.order, "!!");
|
|
return true; // Sell order executed successfully
|
|
}
|
|
else
|
|
{
|
|
Alert("The Sell order request could not be completed - error:", GetLastError());
|
|
ResetLastError();
|
|
return false; // Sell order execution failed
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
//--- Ensure there are enough bars to work with
|
|
if (Bars(_Symbol, _Period) < 60)
|
|
{
|
|
Alert("We have less than 60 bars, EA will now exit!!");
|
|
return;
|
|
}
|
|
|
|
//--- Check for new bar
|
|
static datetime oldTime;
|
|
datetime newTime[1];
|
|
bool isNewBar = false;
|
|
|
|
// Copy the last bar time
|
|
int copied = CopyTime(_Symbol, _Period, 0, 1, newTime);
|
|
if (copied > 0)
|
|
{
|
|
if (oldTime != newTime[0]) // If a new bar has appeared
|
|
{
|
|
isNewBar = true; // New bar detected
|
|
oldTime = newTime[0]; // Update the old time
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Alert("Error copying historical times data, error =", GetLastError());
|
|
ResetLastError();
|
|
return;
|
|
}
|
|
|
|
//--- Proceed only if there is a new bar
|
|
if (!isNewBar)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//--- Define MQL5 structures for trade
|
|
MqlRates mrate[];
|
|
ZeroMemory(mrate); // Initialize array
|
|
|
|
//--- Copy indicator values to buffers
|
|
if (CopyBuffer(adxHandle, 0, 0, 3, adxVal) < 0 ||
|
|
CopyBuffer(adxHandle, 1, 0, 3, plsDI) < 0 ||
|
|
CopyBuffer(adxHandle, 2, 0, 3, minDI) < 0 ||
|
|
CopyRates(_Symbol, _Period, 0, 3, mrate) < 0)
|
|
{
|
|
Alert("Error copying indicator or rates data - error:", GetLastError(), "!!");
|
|
return;
|
|
}
|
|
|
|
//--- Check for existing positions
|
|
bool buyOpened = false; // Flag for Buy position
|
|
bool sellOpened = false; // Flag for Sell position
|
|
|
|
if (PositionSelect(_Symbol))
|
|
{
|
|
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
|
|
{
|
|
buyOpened = true; // Existing Buy position found
|
|
}
|
|
else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
|
|
{
|
|
sellOpened = true; // Existing Sell position found
|
|
}
|
|
}
|
|
|
|
//--- Get previous bar close price
|
|
previousClose = mrate[1].close; // Previous bar close price
|
|
|
|
//--- Conditions for Buy setup
|
|
bool buyCondition1 = (maVal[0] > maVal[1]) && (maVal[1] > maVal[2]); // MA-8 increasing
|
|
bool buyCondition2 = (previousClose > maVal[1]); // Previous close above MA-8
|
|
bool buyCondition3 = (adxVal[0] > Adx_Min); // Current ADX above minimum
|
|
bool buyCondition4 = (plsDI[0] > minDI[0]); // +DI greater than -DI
|
|
|
|
//--- Execute Buy trade if conditions are met
|
|
if (buyCondition1 && buyCondition2 && buyCondition3 && buyCondition4)
|
|
{
|
|
if (!buyOpened) // Only execute if no buy position is open
|
|
{
|
|
ExecuteBuyTrade();
|
|
}
|
|
else
|
|
{
|
|
Alert("We already have a Buy Position!!!");
|
|
}
|
|
}
|
|
|
|
//--- Conditions for Sell setup
|
|
bool sellCondition1 = (maVal[0] < maVal[1]) && (maVal[1] < maVal[2]); // MA-8 decreasing
|
|
bool sellCondition2 = (previousClose < maVal[1]); // Previous close below MA-8
|
|
bool sellCondition3 = (adxVal[0] > Adx_Min); // Current ADX above minimum
|
|
bool sellCondition4 = (plsDI[0] < minDI[0]); // -DI greater than +DI
|
|
|
|
//--- Execute Sell trade if conditions are met
|
|
if (sellCondition1 && sellCondition2 && sellCondition3 && sellCondition4)
|
|
{
|
|
if (!sellOpened) // Only execute if no sell position is open
|
|
{
|
|
ExecuteSellTrade();
|
|
}
|
|
else
|
|
{
|
|
Alert("We already have a Sell Position!!!");
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|