/////////////////////////////////////////////////////// // // SaherElm IT Center RSIMA MQL5 Expert Advisor // ------------------------------------------------- // Name: XDONCHAINEA // Description: an Exper Advisor which used RSI and MA // to Analyse Market ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // //////////////////////////////////////////////////////x // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XDONCHAINEA" #property strict // #include // #define ShortName "XDONCHAINEA" // // Inputs ... long magicNumber = 78692110; double lotSize = 0.01; // double stopLoss = 200; double takeProfit = 400; // // // // int xdonHandler; double xdonUpperBuffer[]; double xdonLowerBuffer[]; // int ma20Handler; double ma20Buffer[]; // int ma50Handler; double ma50Buffer[]; // int ma100Handler; double ma100Buffer[]; // CTrade trade; // ENUM_TIMEFRAMES scPeriod = NULL; ENUM_TIMEFRAMES mcPeriod = NULL; ENUM_TIMEFRAMES lcPeriod = NULL; ENUM_TIMEFRAMES hcPeriod = NULL; // MqlTick currentTick; MqlRates rates[]; MqlRates scRates[]; MqlRates mcRates[]; MqlRates lcRates[]; MqlRates hcRates[]; // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // trade.SetExpertMagicNumber(magicNumber); // xdonHandler = iCustom( // _Symbol, _Period, "x-saherelm.xdon", // // Inputs ... 52, 0 // ); // ma20Handler = iMA( _Symbol, _Period, 20, 0, MODE_SMA, PRICE_OPEN); // ma50Handler = iMA( _Symbol, _Period, 50, 0, MODE_SMA, PRICE_OPEN); // ma100Handler = iMA( _Symbol, _Period, 100, 0, MODE_SMA, PRICE_OPEN); // if (xdonHandler == INVALID_HANDLE || ma20Handler == INVALID_HANDLE || ma50Handler == INVALID_HANDLE || ma100Handler == INVALID_HANDLE) { return INIT_FAILED; } // ArraySetAsSeries(rates, true); ArraySetAsSeries(ma20Buffer, true); ArraySetAsSeries(ma50Buffer, true); ArraySetAsSeries(ma100Buffer, true); ArraySetAsSeries(xdonUpperBuffer, true); ArraySetAsSeries(xdonLowerBuffer, true); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // // De Initialize XEA Providers ... IndicatorRelease(ma20Handler); IndicatorRelease(ma50Handler); IndicatorRelease(ma100Handler); IndicatorRelease(xdonHandler); } // // On Tick Handler ... void OnTick() { // if (!IsNewBar()) { return; } // // Reading Tick ... if (!SymbolInfoTick(_Symbol, currentTick)) { return; } // // if (scPeriod == NULL) { // scPeriod = GetNearest // } // // Prepare Rates ... int ratesCopied = CopyRates( _Symbol, _Period, 0, 15, rates); // int xdonUpperCopied = CopyBuffer( xdonHandler, 0, 0, 15, xdonUpperBuffer); int xdonLowerCopied = CopyBuffer( xdonHandler, 1, 0, 15, xdonLowerBuffer); if (xdonUpperCopied <= 0 || xdonLowerCopied <= 0) { return; } // int ma20Copied = CopyBuffer( ma20Handler, 0, 0, 15, ma20Buffer); int ma50Copied = CopyBuffer( ma50Handler, 0, 0, 15, ma50Buffer); int ma100Copied = CopyBuffer( ma100Handler, 0, 0, 15, ma100Buffer); if (ma20Copied <= 0 || ma50Copied <= 0 || ma100Copied <= 0) { return; } // // BUY ... bool buyConditions = // // First Condition ... // ma20Buffer[1] < MathMin(ma50Buffer[1], ma100Buffer[1]) // // // && // // Donchain Condition ... // Candle Must Shadow Hunt ... (rates[1].low < xdonLowerBuffer[1] && MathMin(rates[1].open, rates[1].close) > xdonLowerBuffer[1]) // || // (rates[1].low < xdonLowerBuffer[1] && rates[2].low < xdonLowerBuffer[2]) // ; if (buyConditions) { // // double sl = stopLoss <= 0 ? 0 : currentTick.bid - (stopLoss * _Point); if (!NormalizePrice(sl)) { return; } // double tp = takeProfit <= 0 ? 0 : currentTick.bid + (takeProfit * _Point); if (!NormalizePrice(tp)) { return; } // trade.PositionOpen( _Symbol, ORDER_TYPE_BUY, lotSize, currentTick.ask, sl, tp, ShortName); } // // SELL ... bool sellConditions = // // First Condition ... // ma20Buffer[1] > MathMax(ma50Buffer[1], ma100Buffer[1]) // // // && // // Donchain Condition ... // Candle Must Shadow Hunt ... (rates[1].high > xdonUpperBuffer[1] && MathMax(rates[1].open, rates[1].close) < xdonUpperBuffer[1]) // || // (rates[1].high > xdonUpperBuffer[1] && rates[2].high > xdonUpperBuffer[2]) // ; if (sellConditions) { // double sl = stopLoss <= 0 ? 0 : currentTick.ask - (stopLoss * _Point); if (!NormalizePrice(sl)) { return; } // double tp = takeProfit <= 0 ? 0 : currentTick.ask + (takeProfit * _Point); if (!NormalizePrice(tp)) { return; } // trade.PositionOpen( _Symbol, ORDER_TYPE_SELL, lotSize, currentTick.bid, sl, tp, ShortName); } } // // TOOLS ... bool IsNewBar() { // static datetime prevTime = 0; datetime currentTime = iTime(_Symbol, _Period, 0); // if (prevTime != currentTime) { // prevTime = currentTime; return true; } // return false; } // bool ValidateInputs() { // bool result = true; // return result; } // bool NormalizePrice( double &price // What to Normal ) { // bool result = false; // double tickSize = 0; result = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize); if (!result) { return result; } // price = NormalizeDouble(MathRound(price / tickSize) * tickSize, _Digits); // return result; } // bool CountOpenPositions( int &buyCount, // Buys int &sellCount // Sells ) { // bool result = false; // buyCount = 0; sellCount = 0; // int total = PositionsTotal(); if (total <= 0) { return true; } // for (int i = total - 1; i >= 0; i--) { // ulong ticket = PositionGetTicket(i); if (ticket <= 0) { continue; } // bool isSelected = PositionSelectByTicket(ticket); if (!isSelected) { continue; } // long magic; bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic); if (!isMagicSelected || (isMagicSelected && magic != magicNumber)) { continue; } // long typeInt; ENUM_POSITION_TYPE type; bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt); if (!isTypeSelected) { continue; } // type = (ENUM_POSITION_TYPE)typeInt; // if (type == POSITION_TYPE_BUY) { buyCount++; } else if (type == POSITION_TYPE_SELL) { sellCount++; } } // result = true; // return result; } // bool ClosePositions(ENUM_POSITION_TYPE type) { // bool result = false; // int total = PositionsTotal(); if (total <= 0) { return true; } // for (int i = total - 1; i >= 0; i--) { // ulong ticket = PositionGetTicket(i); if (ticket <= 0) { continue; } // bool isSelected = PositionSelectByTicket(ticket); if (!isSelected) { continue; } // long magic; bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic); if (!isMagicSelected || (isMagicSelected && magic != magicNumber)) { continue; } // long typeInt; ENUM_POSITION_TYPE pType; bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt); if (!isTypeSelected) { continue; } // pType = (ENUM_POSITION_TYPE)typeInt; // if (type != pType) { continue; } // trade.PositionClose(ticket); } // result = true; // return result; } // template string ToString(const T value) { // return (string)value; }