//+------------------------------------------------------------------+ //| 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!!!"); } } } //+------------------------------------------------------------------+