Algorithmic trading logic problem

 
How to write a condition where, starting from the latest candlestick, there are at least three consecutive bullish candlesticks, followed by at least one bearish candlestick, and finally, the latest candlestick is a bullish candlestick.


It's my code but it didin't work.


#include <Trade\Trade.mqh>

// 宣告交易操作物件
CTrade trade;

//+------------------------------------------------------------------+
//| Function to check if at least three consecutive candles are bullish |
//| followed by at least one bearish candle and the latest being bullish |
//+------------------------------------------------------------------+
bool AreThreeBullishFollowedByBearishThenBullish()
{
    // Ensure we have enough bars to analyze
    if (Bars(_Symbol, _Period) < 5) // At least 5 bars to check the pattern
    {
        Print("Not enough bars to analyze.");
        return false;
    }

    // Check for continuous bullish candles
    int bullishCount = 0;
    for (int i = 1; i < Bars(_Symbol, _Period); i++)
    {
        double openPrice = iOpen(NULL, 0, i);
        double closePrice = iClose(NULL, 0, i);

        if (closePrice > openPrice) // Bullish candle
        {
            bullishCount++;
        }
        else // Not bullish, stop counting
        {
            break;
        }
    }

    // Ensure at least three consecutive bullish candles
    if (bullishCount < 3)
    {
        return false;
    }

    // Check for at least one bearish candle after the bullish sequence
    int bearishCount = 0;
    for (int i = 1; i < Bars(_Symbol, _Period); i++)
    {
        double openPrice = iOpen(NULL, 0, i);
        double closePrice = iClose(NULL, 0, i);

        if (closePrice < openPrice) // Bearish candle
        {
            bearishCount++;
        }
        else // Not bearish, stop counting
        {
            break;
        }
    }

    // Ensure at least one bearish candle
    if (bearishCount < 1)
    {
        return false;
    }

    // Check if the latest completed candle is bullish
    double openPriceLatest = iOpen(NULL, 0, 1);   // Open price of the latest completed candle
    double closePriceLatest = iClose(NULL, 0, 1); // Close price of the latest completed candle

    return (closePriceLatest > openPriceLatest); // Latest candle must be bullish
}

// 定義多單進場函數
void EnterBuy(double lotSize, double stopLoss, double takeProfit)
{
    if (PositionSelect(Symbol()) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
    {
        Print("已有多單存在,無法進場。");
        return;
    }

    MqlTradeRequest request;
    MqlTradeResult result;
    ZeroMemory(request);
    ZeroMemory(result);

    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = lotSize;
    request.type = ORDER_TYPE_BUY;
    request.price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    request.sl = NormalizeDouble(request.price - stopLoss * _Point, _Digits);
    request.tp = NormalizeDouble(request.price + takeProfit * _Point, _Digits);
    request.deviation = 2;
    request.type_filling = ORDER_FILLING_FOK;
    request.type_time = ORDER_TIME_GTC;

    if (!OrderSend(request, result))
    {
        Print("多單進場失敗,錯誤代碼: ", GetLastError());
    }
    else
    {
        Print("多單進場成功,訂單編號: ", result.order);
    }
}

// 定義空單進場函數
void EnterSell(double lotSize, double stopLoss, double takeProfit)
{
    if (PositionSelect(Symbol()) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
    {
        Print("已有空單存在,無法進場。");
        return;
    }

    MqlTradeRequest request;
    MqlTradeResult result;
    ZeroMemory(request);
    ZeroMemory(result);

    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = lotSize;
    request.type = ORDER_TYPE_SELL;
    request.price = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    request.sl = NormalizeDouble(request.price + stopLoss * _Point, _Digits);
    request.tp = NormalizeDouble(request.price - takeProfit * _Point, _Digits);
    request.deviation = 2;
    request.type_filling = ORDER_FILLING_FOK;
    request.type_time = ORDER_TIME_GTC;

    if (!OrderSend(request, result))
    {
        Print("空單進場失敗,錯誤代碼: ", GetLastError());
    }
    else
    {
        Print("空單進場成功,訂單編號: ", result.order);
    }
}

// 多單平倉函數
void CloseBuyPositions()
{
    for (int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if (PositionSelect(Symbol()) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
        {
            if (trade.PositionClose(PositionGetTicket(i)))
            {
                Print("多單平倉成功: Ticket#", PositionGetTicket(i));
            }
            else
            {
                Print("多單平倉失敗: Ticket#", PositionGetTicket(i), ", Error: ", GetLastError());
            }
        }
    }
}

// 空單平倉函數
void CloseSellPositions()
{
    for (int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if (PositionSelect(Symbol()) && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
        {
            if (trade.PositionClose(PositionGetTicket(i)))
            {
                Print("空單平倉成功: Ticket#", PositionGetTicket(i));
            }
            else
            {
                Print("空單平倉失敗: Ticket#", PositionGetTicket(i), ", Error: ", GetLastError());
            }
        }
    }
}

// 初始化事件處理函數
int OnInit()
{
    Print("EA 已初始化");
    return INIT_SUCCEEDED;
}

// 去初始化事件處理函數
void OnDeinit(const int reason)
{
    Print("EA 已去初始化");
}

// Tick事件處理函數
void OnTick()
{
    // 檢查條件是否滿足
    if (AreThreeBullishFollowedByBearishThenBullish())
    {
        Print("Pattern matched: Three bullish candles, one or more bearish candles, and the latest bullish candle.");
        EnterBuy(0.1, 500, 500);
    }
}
 
Your topic has been moved to the section: Expert Advisors and Automated Trading
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 
Joe Wu:
How to write a condition where, starting from the latest candlestick, there are at least three consecutive bullish candlesticks, followed by at least one bearish candlestick, and finally, the latest candlestick is a bullish candlestick.


It's my code but it didin't work.


Attempting to repeatedly use a counter to reference a series of prices is a bit "hack-ish."

Consider using CopyRates() instead. Then you can reference prices as [i], [i-1], [i-2] and so on.

CopyRates - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5

Documentation on MQL5: Timeseries and Indicators Access / CopyRates
Documentation on MQL5: Timeseries and Indicators Access / CopyRates
  • www.mql5.com
Gets history data of MqlRates structure of a specified symbol-period in specified quantity into the rates_array array. The elements ordering of the...