
//
// Handle Indirectional Supports ...
void XEU5HandleIndirectionalSupport()
{
    //
    // Disable Indirections ...
    if (!xEU5EnableIndirectionalSupportTrades)
    {
        return;
    }

    //
    XSignal signals[];
    xEU5Trader.GetSignals(
        signals);
    int signalsCount = ArraySize(signals);
    if (signalsCount <= 0)
    {
        return;
    }

    //
    // Loop Through Open Positions ...
    for (int i = 0; i < signalsCount; i++)
    {
        //
        // Retrieve i Signal ...
        XSignal iSignal = signals[i];

        //
        // Generate iSignals Default Comment ...
        string iDefComment = xEU5Trader.GenerateSignalComment(iSignal);

        //
        // Check Trade is Main Trade or not ...
        bool isMainTrade = iSignal.comment == iDefComment;
        if (!isMainTrade)
        {
            continue;
        }

        //
        // Check Trade Age Bigger Than 5 and Smaller Than 10 candle ...
        int iSignalAge = xEU5Trader.GetSignalAge(iSignal);
        bool isAgeVerified = iSignalAge >= 5; // && iSignalAge < 145;
        if (!isAgeVerified)
        {
            continue;
        }

        //
        // Has InDD Before ...
        string comment = XEU5GenerateIndirectionalSupportComment(iSignal.ticket);
        XSignal inDDs[];
        xEU5Trader.FilterSignals(
            inDDs,
            comment);
        int inDDsCount = ArraySize(inDDs);
        bool hasInDD = inDDsCount >= 1;
        if (hasInDD)
        {
            continue;
        }

        //
        // Check iSignal doesn't have sl ...
        bool isSLPassed = iSignal.sl <= 0;
        if (!isSLPassed)
        {
            continue;
        }

        //
        bool isILong = iSignal.type == X_SIGNAL_LONG;
        double exitPrice = GetExit(
            iSignal.symbol,
            iSignal.type);

        //
        // Check Trade Profit isNegative and Has Enough Price Distance ...
        double priceDistance = PipsToPrice(10);
        double iSignalHitPrice = isILong
                                     ? iSignal.entry - priceDistance
                                     : iSignal.entry + priceDistance;
        bool isPriceDistanceReached = isILong
                                          ? exitPrice <= iSignalHitPrice
                                          : exitPrice >= iSignalHitPrice;
        if (!isPriceDistanceReached)
        {
            continue;
        }

        //
        // Generate Requirements for Indirectional Support Trade ...
        string symbol = iSignal.symbol;
        ulong magic = iSignal.magicNumber;
        datetime time = iTime(iSignal.symbol, _Period, 0);
        ENUM_X_SIGNAL_TYPE type = xEU5Trader.GetSignalIndirectionType(iSignal);

        //
        bool isLong = type == X_SIGNAL_LONG;
        double entry = GetEntry(
            symbol,
            type);
        double spread = GetSpread(iSignal.symbol);

        //
        double risk = PipsToPrice(2);
        double reward = PipsToPrice(xEU5RiskFreeStepInPips); // PipsToPrice(xEU5RiskFreeStepInPips); // xEU5MinReward;
        double riskFreeRate = xEU5RiskFreeRate;
        double riskFreeStep = xEU5RiskFreeStepInPips;
        double volume = xEU5StaticVolume; // iSignal.volume;

        //
        double sl = 0;
        // isLong
        //                 ? (entry - risk) - spread
        //                 : (entry + risk) + spread;
        double tp = isLong
                        ? entry + reward
                        : entry - reward;

        //
        // Generate Indirectional Support Signal ...
        XSignal inDSSignal = {};
        inDSSignal.tp = tp;
        inDSSignal.sl = sl;
        inDSSignal.type = type;
        inDSSignal.time = time;
        inDSSignal.entry = entry;
        inDSSignal.symbol = symbol;
        inDSSignal.volume = volume;
        inDSSignal.comment = comment;
        inDSSignal.magicNumber = magic;
        inDSSignal.riskFreeRate = riskFreeRate;
        inDSSignal.riskFreeStep = riskFreeStep;

        //
        // Check Generated Signal Validation ...
        bool isInDSignalValid = IsValid(inDSSignal, xEU5MagicNumber);
        if (!isInDSignalValid)
        {
            continue;
        }

        //
        // Execute Signal ...
        ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEU5Trader.ExecuteSignal(
            inDSSignal,
            false, // Ignore TP/SL Virtuals ...
            true,  // Ignore Number of Trades ...
            true   // Check Account Conditions ...
        );
        bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION;
        if (isExecuted)
        {
            //
            // TODO: Alert this ...
            LogMessage("InDirectional Support Trade Executed for: " + (string)iSignal.ticket);
        }
        else
        {
            //
            // TODO: Alert this ...
            LogMessage("Error in Executing Indirectional Support Trade for: " + (string)iSignal.ticket + "\n" + GetSignalExecutionError(executionResult));
        }
    }
}

//
// Generate Comment ...
string XEU5GenerateIndirectionalSupportComment(ulong ticket)
{
    //
    string result = "";

    //
    result += XEU5_INDIRECTION_SUPPORT_ID + "(" + (string)ticket + ")";

    //
    return result;
}

//
// Check a Comment is Indirectional or not ...
bool XEU5IsIndirectionalSupport(string comment)
{
    //
    bool result = false;

    //
    // Validate Args ...
    if (StringLen(comment) <= 0)
    {
        return result;
    }

    //
    int pos = StringFind(
        comment,
        XEU5_INDIRECTION_SUPPORT_ID);
    result = pos >= 0;

    //
    return result;
}

//
// Retrieve Parent Position Ticket ...
ulong XEU5GetIndirectionalParentTicket(string comment)
{
    //
    ulong result = -1;

    //
    // Validate Arg ...
    if (!XEU5IsIndirectionalSupport(comment))
    {
        return result;
    }

    //
    // Parent ...
    string ticketStr = ExtractString(
        comment,
        XEU5_INDIRECTION_SUPPORT_ID + "(",
        ")");
    if (StringLen(ticketStr) > 0)
    {
        result = (ulong)ticketStr;
    }

    //
    return result;
}
