//+------------------------------------------------------------------+
//| Scalping Robot |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"

#include <Trade/Trade.mqh>

CTrade trade;
CPositionInfo pos;
COrderInfo ord;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+

input group "*** Trading Inputs ***"
input double LotSize = 0.01; // Lot size for trading
input int Tppoints = 800; // Take Profit (10 points = 1 pip)
input int Slpoints = 800; // Stoploss Points (10 points = 1 pip)
input int TslTriggerPoints = 35; // Points in profit before Trailing SL is activated (10 points = 1 pip)
input int TslPoints = 10; // Trailing Stoploss (10 points = 1 pip)
input ENUM_TIMEFRAMES Timeframe = PERIOD_CURRENT; // Time frame to run
input int InpMagic = 891245; // EA identification no
input string TradeComment = "Wendel Cassiano";
input int MaxSpread = 100; // Maximum spread allowed (in points)
input int Slippage = 50; // Slippage in points
input int MaxOrders = 2; // Máximo de ordens permitidas simultaneamente

enum StarHour { Inactive=0, _0100=1, _0200=2, _0300=3, _0400=4, _0500=5, _0600=6, _0700=7, _0800=8, _0900=9, _1000=10, _1100=11, _1200=12, _1300=13, _1400=14, _1500=15, _1600=16, _1700=17, _1800=18, _1900=19, _2000=20, _2100=21, _2200=22, _2300=23 };
input StarHour SHInput = 0; // Start Hour

enum EndHour { Inactive=0, _0100=1, _0200=2, _0300=3, _0400=4, _0500=5, _0600=6, _0700=7, _0800=8, _0900=9, _1000=10, _1100=11, _1200=12, _1300=13, _1400=14, _1500=15, _1600=16, _1700=17, _1800=18, _1900=19, _2000=20, _2100=21, _2200=22, _2300=23 };
input EndHour EHInput = 0; // End Hour

int SHChoice;
int EHChoice;

int BarsN = 5;
int ExpirationBars = 100;
int OrderDistPoints = 100;

int OnInit()
{
//---
trade.SetExpertMagicNumber(InpMagic);
ChartSetInteger(0, CHART_SHOW_GRID, false);


return (INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---


TrailStop();

if (!IsNewBar()) return;

MqlDateTime time;
TimeToStruct(TimeCurrent(), time);

int Hournow = time.hour;

SHChoice = SHInput;
EHChoice = EHInput;

 if (Hournow < SHChoice) { CloseAllOrders(); return; }
if (Hournow >= EHChoice && EHChoice != 0) { CloseAllOrders(); return; }

double spread = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID)) / _Point;
if (spread > MaxSpread) return;

int BuyTotal = 0;
int SellTotal = 0;

for (int i = PositionsTotal() - 1; i >= 0; i--)
{
    pos.SelectByIndex(i);
    if (pos.PositionType() == POSITION_TYPE_BUY && pos.Symbol() == _Symbol && pos.Magic() == InpMagic) BuyTotal++;
    if (pos.PositionType() == POSITION_TYPE_SELL && pos.Symbol() == _Symbol && pos.Magic() == InpMagic) SellTotal++;
}

for (int i = OrdersTotal() - 1; i >= 0; i--)
{
    ord.SelectByIndex(i);
    if (ord.OrderType() == ORDER_TYPE_BUY_STOP && ord.Symbol() == _Symbol && ord.Magic() == InpMagic) BuyTotal++;
    if (ord.OrderType() == ORDER_TYPE_SELL_STOP && ord.Symbol() == _Symbol && ord.Magic() == InpMagic) SellTotal++;
}

int TotalOrders = BuyTotal + SellTotal;
if (TotalOrders >= MaxOrders) return;

if (BuyTotal <= 0)
{
    double high = findHigh();
    if (high > 0)
    {
        SendBuyOrder(high);
    }
}

if (SellTotal <= 0)
{
    double low = findLow();
    if (low > 0)
    {
        SendSellOrder(low);
    }
}
}
//+------------------------------------------------------------------+

double findHigh()
{
double highestHigh = 0;
for (int i = 0; i < 200; i++)
{
double high = iHigh(_Symbol, Timeframe, i);
if (i > BarsN && iHighest(_Symbol, Timeframe, MODE_HIGH, BarsN * 2 + 1, i - BarsN) == i)
{
if (high > highestHigh)
{
return high;
}
}
highestHigh = MathMax(high, highestHigh);
}
return -1;
}

double findLow()
{
double LowestLow = DBL_MAX;
for (int i = 0; i < 200; i++)
{
double Low = iLow(_Symbol, Timeframe, i);
if (i > BarsN && iLowest(_Symbol, Timeframe, MODE_LOW, BarsN * 2 + 1, i - BarsN) == i)
{
if (Low < LowestLow)
{
return Low;
}
}
LowestLow = MathMin(Low, LowestLow);
}
return -1;
}

bool IsNewBar()
{
static datetime previousTime = 0;
datetime currentTime = iTime(_Symbol, Timeframe, 0);
if (previousTime != currentTime)
{
previousTime = currentTime;
return true;
}
return false;
}

void SendBuyOrder(double entry)
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);


if (ask > entry - OrderDistPoints * _Point) return;

double tp = entry + Tppoints * _Point;
double sl = entry - Slpoints * _Point;

// Use configured lot size
double lots = LotSize;

datetime expiration = iTime(_Symbol, Timeframe, 0) + ExpirationBars * PeriodSeconds(Timeframe);

trade.BuyStop(lots, entry, _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiration, Slippage);
}

void SendSellOrder(double entry)
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);


if (bid < entry + OrderDistPoints * _Point) return;

double tp = entry - Tppoints * _Point;
double sl = entry + Slpoints * _Point;

// Use configured lot size
double lots = LotSize;

datetime expiration = iTime(_Symbol, Timeframe, 0) + ExpirationBars * PeriodSeconds(Timeframe);

trade.SellStop(lots, entry, _Symbol, sl, tp, ORDER_TIME_SPECIFIED, expiration, Slippage);
}

double calcLots(double slPoints)
{
// Return the configured lot size
return LotSize;
}

void CloseAllOrders()
{
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
ord.SelectByIndex(i);
ulong ticket = ord.Ticket();
if (ord.Symbol() == _Symbol && ord.Magic() == InpMagic)
{
trade.OrderDelete(ticket);
}
}
}

void TrailStop()
{
double sl = 0;
double tp = 0;


double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

for (int i = PositionsTotal() - 1; i >= 0; i--)
{
    if (pos.SelectByIndex(i))
    {
        ulong ticket = pos.Ticket();

        if (pos.Magic() == InpMagic && pos.Symbol() == _Symbol)
        {

            if (pos.PositionType() == POSITION_TYPE_BUY)
            {
                if (bid - pos.PriceOpen() > TslTriggerPoints * _Point)
                {
                    tp = pos.TakeProfit();
                    sl = bid - (TslPoints * _Point);

                    if (sl > pos.StopLoss() && sl != 0)
                    {
                        trade.PositionModify(ticket, sl, tp);
                    }
                }
            }
            else if (pos.PositionType() == POSITION_TYPE_SELL)
            {
                if (ask + (TslTriggerPoints * _Point) < pos.PriceOpen())
                {
                    tp = pos.TakeProfit();
                    sl = ask + (TslPoints * _Point);

                    if (sl < pos.StopLoss() && sl != 0)
                    {
                        trade.PositionModify(ticket, sl, tp);
                    }
                }
            }
        }
    }
}
}

mantenha o meu a estrategia do meu codigo original acima e implemente redes neurais com exemplo do codigo abaixo apenas para melhorar a assertividade do meu robo:

//+------------------------------------------------------------------+
//| RedFairy v1.3.mq5 |
//| Joy D Moyo |
//| www.latvianfts.com |
//+------------------------------------------------------------------+
#property copyright "Joy D Moyo"
#property link "www.latvianfts.com"
#property version "1.3"

#define NumNodes 10
#include <Trade\Trade.mqh>

CTrade *Trade;
CPositionInfo PositionInfo;

input group "GENERAL INPUTS"
input string SymbolTraded = "EURUSD";
input ENUM_TIMEFRAMES PeriodTraded = PERIOD_M5;
input int EAMagic = 76755544;
input int MaxSlippage = 1;

input group "RSI INPUTS"
input int RSIPeriod = 14;
input ENUM_APPLIED_PRICE RSIAppliedPrice = PRICE_CLOSE;
input int OSLevel = 30;
input int OBLevel = 70;
input int BuyCloseLevel = 60;
input int SellCloseLevel = 40;

input group "TRADE MANAGEMENT INPUTS"
input bool UseCostAveraging = false;
input double LotMultiplier = 2;
input double GridDistance = 20;

input group "RISK INPUTS"
input double BalanceIncrease = 200;
input double VolumeIncrease = 0.01;

input group "NEURAL NETWORK INPUTS"
input double Coefficient = 0.1;
input double BuyTargetOutput = 0.3;
input double SellTargetOutput = -0.3;
input double LearningRate = 0.1;

int RSIHandle,OldNumBars = 0,MyDigits;
double RSIBuffer[],MyPoint,NormalizedInputs[NumNodes],NNOutPut,NextBuyPrice = 0,NextSellPrice = 0,NextBuyLot = 0, NextSellLot = 0, GridDistancePoints;
double Weight[];
int DataUsed = NumNodes;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
ChartSetInteger(0,CHART_SHOW_GRID,false);
ChartSetInteger(0,CHART_MODE,CHART_CANDLES);
ChartSetInteger(0,CHART_COLOR_BACKGROUND,clrBlack);
ChartSetInteger(0,CHART_COLOR_FOREGROUND,clrWhite);
ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrWhite);
ChartSetInteger(0,CHART_COLOR_CHART_UP,clrWhite);
ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrRed);
ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrRed);
ChartSetInteger(0,CHART_COLOR_STOP_LEVEL,clrGold);
ChartSetInteger(0,CHART_SHOW_VOLUMES,false);

Trade = new CTrade;
ulong MaxSlippagePoints = MaxSlippage*10;
Trade.SetDeviationInPoints(MaxSlippagePoints);
Trade.SetExpertMagicNumber(EAMagic);

ArrayResize(Weight,NumNodes);

for(int i=0; i<NumNodes; i++)
{
Weight[i] = 0.5;
}

MyPoint = SymbolInfoDouble(SymbolTraded,SYMBOL_POINT);
MyDigits = (int)SymbolInfoInteger(SymbolTraded,SYMBOL_DIGITS);
GridDistancePoints = GridDistance10MyPoint;

RSIHandle = iRSI(SymbolTraded,PeriodTraded,RSIPeriod,RSIAppliedPrice);
ArraySetAsSeries(RSIBuffer,true);

return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(RSIHandle);
delete Trade;
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(!NewBarPresent())
return;

CopyBuffer(RSIHandle,0,0,DataUsed,RSIBuffer);

NormalizingInputs();
OutPutLayerCalculation();

double TargetOutPut = 0;

if(RSIBuffer[1]>=50)
TargetOutPut = BuyTargetOutput;
if(RSIBuffer[1]<50)
TargetOutPut = SellTargetOutput;

BackPropagation(NormalizedInputs,Weight,NNOutPut,TargetOutPut,LearningRate);

Buy();
Sell();

if(UseCostAveraging)
{
GridBuy();
GridSell();
}

CloseMatureTrades();
if(RSIBuffer[1]>=OSLevel&&RSIBuffer[2]<OSLevel)
{
double PriceClose = iClose(SymbolTraded,PeriodTraded,1);
string ObjName = "ObjName"+(string)iTime(SymbolTraded,PeriodTraded,1);
if(!ObjectCreate(0,ObjName,OBJ_TREND,0,iTime(SymbolTraded,PeriodTraded,1),PriceClose,iTime(SymbolTraded,PeriodTraded,0),PriceClose))
return;
else
{
ObjectSetInteger(0,ObjName,OBJPROP_COLOR,clrBlue);
ObjectSetInteger(0,ObjName,OBJPROP_WIDTH,5);
}
}

if(RSIBuffer[1]<=OBLevel&&RSIBuffer[2]>OBLevel)
{
double PriceClose = iClose(SymbolTraded,PeriodTraded,1);
string ObjName = "ObjName"+(string)iTime(SymbolTraded,PeriodTraded,1);
if(!ObjectCreate(0,ObjName,OBJ_TREND,0,iTime(SymbolTraded,PeriodTraded,1),PriceClose,iTime(SymbolTraded,PeriodTraded,0),PriceClose))
return;
else
{
ObjectSetInteger(0,ObjName,OBJPROP_COLOR,clrYellow);
ObjectSetInteger(0,ObjName,OBJPROP_WIDTH,5);
}
}

Comment("Weight Value 1 = ", Weight[0],"\nWeight Value 2 = ", Weight[1],"\nWeight Value 3 = ", Weight[2],"\nWeight Value 4 = ", Weight[3]);
}
//+------------------------------------------------------------------+
bool NewBarPresent()
{
int bars = Bars(SymbolTraded,PeriodTraded);
if(OldNumBars != bars)
{
OldNumBars = bars;
return true;
}
return false;
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int NumOfBuy()
{
int Num = 0;
for(int i = PositionsTotal()-1; i>=0; i--)
{
if(!PositionInfo.SelectByIndex(i))
continue;
if(PositionInfo.Magic()!=EAMagic)
continue;
if(PositionInfo.Symbol()!=SymbolTraded)
continue;
if(PositionInfo.PositionType()!=POSITION_TYPE_BUY)
continue;
Num++;
}
return Num;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int NumOfSell()
{
int Num = 0;
for(int i = PositionsTotal()-1; i>=0; i--)
{
if(!PositionInfo.SelectByIndex(i))
continue;
if(PositionInfo.Magic()!=EAMagic)
continue;
if(PositionInfo.Symbol()!=SymbolTraded)
continue;
if(PositionInfo.PositionType()!=POSITION_TYPE_SELL)
continue;
Num++;
}
return Num;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool BuySignal()
{
if(NumOfBuy()==0&&RSIBuffer[1]>=OSLevel&&RSIBuffer[2]<OSLevel&&NNOutPut>0)
return true;
return false;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool SellSignal()
{
if(NumOfSell()==0&&RSIBuffer[1]<=OBLevel&&RSIBuffer[2]>OBLevel&&NNOutPut<0)
return true;
return false;
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool GridSellSignal()
{
if(NumOfSell()>0&&RSIBuffer[1]<=OBLevel&&RSIBuffer[2]>OBLevel)
return true;
return false;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool GridBuySignal()
{
if(NumOfBuy()>0&&RSIBuffer[1]>=OSLevel&&RSIBuffer[2]<OSLevel)
return true;
return false;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double LotSize()
{
double Lot = NormalizeDouble(VolumeIncrease*AccountInfoDouble(ACCOUNT_BALANCE)/BalanceIncrease,2);
if(Lot > SymbolInfoDouble(SymbolTraded,SYMBOL_VOLUME_MAX))
Lot = SymbolInfoDouble(SymbolTraded,SYMBOL_VOLUME_MAX);
if(Lot < SymbolInfoDouble(SymbolTraded,SYMBOL_VOLUME_MIN))
Lot = SymbolInfoDouble(SymbolTraded,SYMBOL_VOLUME_MIN);
return Lot;
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Buy()
{
if(!BuySignal())
return;
double LotUsed = LotSize();
double ASK = SymbolInfoDouble(SymbolTraded,SYMBOL_ASK);
if(!Trade.Buy(LotUsed,SymbolTraded,ASK,0,0,"FirstBuy"))
Print("Failed First Buy : ",GetLastError());
else
{
NextBuyLot = NormalizeDouble(LotUsed*LotMultiplier,2);
NextBuyPrice = NormalizeDouble(ASK - GridDistancePoints,MyDigits);
}
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Sell()
{
if(!SellSignal())
return;
double LotUsed = LotSize();
double BID = SymbolInfoDouble(SymbolTraded,SYMBOL_BID);
if(!Trade.Sell(LotUsed,SymbolTraded,BID,0,0,"FirstSell"))
Print("Failed First Sell : ",GetLastError());
else
{
NextSellLot = NormalizeDouble(LotUsed*LotMultiplier,2);
NextSellPrice = NormalizeDouble(BID+GridDistancePoints,MyDigits);
}
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void GridBuy()
{
if(!GridBuySignal())
return;
double ASK = SymbolInfoDouble(SymbolTraded,SYMBOL_ASK);
if(ASK<NextBuyPrice)
{
if(!Trade.Buy(NextBuyLot,SymbolTraded,ASK,0,0,"GridBuy"))
Print("Failed Grid Buy : ",GetLastError());
else
{
NextBuyLot = NormalizeDouble(NextBuyLot*LotMultiplier,2);
NextBuyPrice = NormalizeDouble(ASK - GridDistancePoints,MyDigits);
}
}
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void GridSell()
{
if(!GridSellSignal())
return;
double BID = SymbolInfoDouble(SymbolTraded,SYMBOL_BID);
if(BID>NextSellPrice)
{
if(!Trade.Sell(NextSellLot,SymbolTraded,BID,0,0,"GridSell"))
Print("Failed Grid Sell : ",GetLastError());
else
{
NextSellLot = NormalizeDouble(NextSellLot*LotMultiplier,2);
NextSellPrice = NormalizeDouble(BID+GridDistancePoints,MyDigits);
}
}
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseAllBuys()
{
for(int i = PositionsTotal()-1; i>=0; i--)
{
if(!PositionInfo.SelectByTicket(PositionGetTicket(i)))
continue;
if(PositionInfo.Magic()!=EAMagic)
continue;
if(PositionInfo.Symbol()!=SymbolTraded)
continue;
if(PositionInfo.PositionType()!=POSITION_TYPE_BUY)
continue;
if(!Trade.PositionClose(PositionGetInteger(POSITION_TICKET)))
Print("Failed to close position : ",GetLastError());
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseAllSell()
{
for(int i = PositionsTotal()-1; i>=0; i--)
{
if(!PositionInfo.SelectByTicket(PositionGetTicket(i)))
continue;
if(PositionInfo.Magic()!=EAMagic)
continue;
if(PositionInfo.Symbol()!=SymbolTraded)
continue;
if(PositionInfo.PositionType()!=POSITION_TYPE_SELL)
continue;
if(!Trade.PositionClose(PositionGetInteger(POSITION_TICKET)))
Print("Failed to close position : ",GetLastError());
}
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseMatureTrades()
{
if(NumOfBuy()>0&&RSIBuffer[1]>BuyCloseLevel&&RSIBuffer[2]<BuyCloseLevel)
{
CloseAllBuys();
NextBuyPrice = 0;
NextBuyLot = 0;
}
if(NumOfSell()>0&&RSIBuffer[1]<SellCloseLevel&&RSIBuffer[2]>SellCloseLevel)
{
CloseAllSell();
NextSellLot = 0;
NextSellPrice = 0;
}
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void NormalizingInputs()
{
double LowerNormRange = -1;
double UpperNormRange = 1;
double MinRangeValue = RSIBuffer[ArrayMinimum(RSIBuffer)];
double MaxRangeValue = RSIBuffer[ArrayMaximum(RSIBuffer)];

for(int i=0; i<DataUsed; i++)
{
NormalizedInputs[i] = (((RSIBuffer[i]-MinRangeValue)*(UpperNormRange-LowerNormRange))/(MaxRangeValue-MinRangeValue))+LowerNormRange;
}
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HiddenLayerCalculation(double &inputs[],double &Weights[])
{
double TotalWeightedInputs = 0.0;
for(int i=0; i<ArraySize(inputs); i++)
{
TotalWeightedInputs+= inputs[i]*Weights[i];
}
TotalWeightedInputs *= Coefficient;
return TanHActivationFunction(TotalWeightedInputs);
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double TanHActivationFunction(double WeightedInputs)
{
return((exp(WeightedInputs)-exp(-WeightedInputs))/((exp(WeightedInputs)+exp(-WeightedInputs))));
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OutPutLayerCalculation()
{
NNOutPut = 1*HiddenLayerCalculation(NormalizedInputs,Weight);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void BackPropagation(double &Inputs[],double &Weights[],double &Outputs,double TargetOutputs,double LearningRates)
{
double error = TargetOutputs -Outputs;
double derivative = 1-MathPow(Outputs,2);
for(int i=0; i<ArraySize(Inputs); i++)
{
double gradient = errorderivativeInputs[i];
Weights[i] += LearningRate*gradient;
}
}
//+------------------------------------------------------------------+

implemente e me entregue completo