//+------------------------------------------------------------------+
//| DeepNN.mq5 |
//| Joy D Moyo |
//| www.latvianfts.com |
//+------------------------------------------------------------------+
#property copyright "Joy D Moyo"
#property link "www.latvianfts.com"
#property version "1.00"
#include

enum ENUM_ACTIVATIONFX
{
Sigmoid_AF = AF_SIGMOID,
HyperbolicTan_AF = AF_TANH,
LeakyRELU_AF = AF_LRELU,
RELU_AF = AF_RELU
};

enum ENUM_LOSSFX
{
BinaryCrossEntropy = LOSS_BCE,
CategoricalCrossEntropy = LOSS_CCE,
MeanSquaredError = LOSS_MSE,
Hinge = LOSS_HINGE
};

input group "OTHER INPUTS"
input bool HideTesterIndicators = true;

input group "NN INPUTS"
input int NumTrainingBars = 5000;
input int RandomSeed = 42;
input ENUM_ACTIVATIONFX ActivationFx = LeakyRELU_AF;
input ENUM_LOSSFX LossFunction = MeanSquaredError;
input uint Epochs = 1000;
input double LearningRate = 0.0001;
input double PercTrainingSize = 0.7;
input string HiddenLayers = "15,10,7";

input group "MACDHISTOGRAMS"
input int FastEMA = 12;
input int SlowEMA = 26;
input int SignalLine = 9;

input group "RSI"
input int RSIPeriod = 13;

int MACDHandle,RSIHandle,OldSignal=0,Signal;
matrix DataSet(NumTrainingBars,3);
vector HiddenLayer,DataClasses;
bool InBackPropagation = false,IsTrained = false,BullArrowDrawn=false,BearArrowDrawn = false;

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CMatrix
{
public:
matrix Matrix;

};

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CTensor
{
CMatrix* matrices[];
public:
CTensor(uint size);
~CTensor(void);

uint TensorSize;
bool Add(matrix& mat,ulong index);
matrix Get(ulong index);
};

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CTensor::CTensor(uint size)
{
TensorSize = size;
ArrayResize(matrices,TensorSize);
for(uint i=0; i<TensorSize; i++)
matrices[i] = new CMatrix;

for(uint i=0; i<TensorSize; i++)
{
if(CheckPointer(matrices[i])==POINTER_INVALID)
{
printf("Cant create a tensor, Invalid Matrix pointer. ERROR code = ",GetLastError());
return;
}
}
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTensor::Add(matrix &mat,ulong index)
{
if(index>TensorSize)
{
printf("Index stated is greater than the tensor size in the function ",FUNCTION);
return false;
}
this.matrices[index].Matrix = mat;
return true;
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
matrix CTensor::Get(ulong index)
{
if(index>TensorSize)
{
printf("%s index %d out of range, Tensor size = %d", FUNCTION,index,TensorSize);
matrix mat = {};
return (mat);
}
return(this.matrices[index].Matrix);
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CTensor::~CTensor(void)
{
for(uint i=0; i<TensorSize; i++)
{
if(CheckPointer(matrices[i])!=POINTER_INVALID)
delete matrices[i];
}
ArrayFree(matrices);
}

CTensor* WeightsTensor;
CTensor* BiasTensor;
CTensor* InputsTensor;
CTensor* OutPutsTensor;

//+------------------------------------------------------------------+
//| 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_CHART_UP,clrDodgerBlue);
ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,clrDodgerBlue);
ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrWhite);
ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,clrWhite);
ChartSetInteger(0,CHART_COLOR_STOP_LEVEL,clrGold);
ChartSetInteger(0,CHART_SHOW_VOLUMES,false);
TesterHideIndicators(HideTesterIndicators);

IsTrained = false;

ushort Sep = StringGetCharacter(",",0);
string Layers[];
int size = StringSplit(HiddenLayers,Sep,Layers);

HiddenLayer.Resize(size);

for(int i=0; i<size; i++)
{
HiddenLayer[i]=(int)Layers[i];
}

MACDHandle = iMACD(_Symbol,PERIOD_CURRENT,FastEMA,SlowEMA,SignalLine,PRICE_CLOSE);
RSIHandle = iRSI(_Symbol,PERIOD_CURRENT,RSIPeriod,PRICE_OPEN);

return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(CheckPointer(WeightsTensor)!=POINTER_INVALID)
delete WeightsTensor;
if(CheckPointer(BiasTensor)!=POINTER_INVALID)
delete BiasTensor;
if(CheckPointer(InputsTensor)!=POINTER_INVALID)
delete InputsTensor;
if(CheckPointer(OutPutsTensor)!=POINTER_INVALID)
delete OutPutsTensor;
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(!IsTrained)
{
CollectTrainTest(1,NumTrainingBars);
IsTrained = true;
}

vector IndicatorBuffer;
vector inputs(2);

IndicatorBuffer.CopyIndicatorBuffer(MACDHandle,0,0,1);
inputs[0] = IndicatorBuffer[0];

IndicatorBuffer.CopyIndicatorBuffer(RSIHandle,0,0,1);
inputs[1] = IndicatorBuffer[0];

if(NewBar())
{
BPMinMaxNormalization(inputs);
Signal = SingleForwardPass(inputs);

if(Signal == 1 && !BullArrowDrawn)
{
string Name = "BName" + (string)TimeCurrent();
datetime Time = iTime(_Symbol,PERIOD_CURRENT,1);
double Price = iLow(_Symbol,PERIOD_CURRENT,1)-(310_Point);
ArrowCreate(Name,Time,Price,233,clrLimeGreen,STYLE_SOLID,0);
BullArrowDrawn = true;
BearArrowDrawn = false;
}

if(Signal ==0 && !BearArrowDrawn)
{
string Name = "SName"+(string)TimeCurrent();
datetime Time = iTime(_Symbol,PERIOD_CURRENT,1);
double Price = iHigh(_Symbol,PERIOD_CURRENT,1)+(310_Point);
ArrowCreate(Name,Time,Price,234,clrRed, STYLE_SOLID,0);
BearArrowDrawn = true;
BullArrowDrawn = false;
}
}
}
//+------------------------------------------------------------------+

int OldNumBars = 0;
bool NewBar()
{
if(OldNumBars!=Bars(_Symbol,PERIOD_CURRENT))
{
OldNumBars = Bars(_Symbol,PERIOD_CURRENT);
return true;
}
return false;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CollectTrainTest(int StartBar,int TotalBars)
{
vector IndicatorBuffer;

DataSet.Resize(NumTrainingBars,3);

IndicatorBuffer.CopyIndicatorBuffer(MACDHandle,0,StartBar,TotalBars);
DataSet.Col(IndicatorBuffer,0);

IndicatorBuffer.CopyIndicatorBuffer(RSIHandle,0,StartBar,TotalBars);
DataSet.Col(IndicatorBuffer,1);

int size = TotalBars-StartBar;
vector y(size);

for(int i=0; i<size; i++)
{
if(iClose(_Symbol,PERIOD_CURRENT,i)>iOpen(_Symbol,PERIOD_CURRENT,i))
y[i] = 1; //Bullish
if(iClose(_Symbol,PERIOD_CURRENT,i)<iOpen(_Symbol,PERIOD_CURRENT,i))
y[i] = 0; //Bearish
}

DataSet.Col(y,2);

matrix xTrain,xTest;
vector yTrain,yTest;

TrainTestSplitMatrices(DataSet,xTrain,yTrain,xTest,yTest,PercTrainingSize);

Print("\n-----> Training the NN\n");

MinMaxNormalization(xTrain);
BackPropagation(xTrain,yTrain,Epochs,LearningRate);

Print("\n------> Testing the NN\n");
BPMinMaxNormalization(xTest);
vector preds = BatchForwardPass(xTest);

Print("Actual Values: ",yTest, "\nPredictions\n", preds);

ConfusionMatrix(yTest,preds,DataClasses,true);
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Randomize(matrix& matrix_)
{
MathSrand(RandomSeed);
int ROWS = (int)matrix_.Rows(), COL = (int)matrix_.Cols();
int SwapIndex;
matrix temp_m = matrix_;
vector temp_v(COL);

for(int i=0; i<ROWS; i++)
{
SwapIndex = MathRand()%ROWS;
temp_v = matrix_.Row(i);
matrix_.Row(matrix_.Row(SwapIndex),i);
matrix_.Row(temp_v,SwapIndex);
}
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool Copy(const vector& CopyFrom, vector& CopyTo, ulong StartFrom,ulong Total = WHOLE_ARRAY)
{
if(Total == WHOLE_ARRAY)
Total = CopyFrom.Size()-StartFrom;

if(Total<=0||CopyFrom.Size()==0)
{
printf("%s Can't copy a vector | Size %d total %d StartFrom %d ",FUNCTION,CopyFrom.Size(),Total,StartFrom);
return false;
}
CopyTo.Resize(Total);
CopyTo.Fill(0);

for(ulong i=StartFrom, index = 0; i<Total+StartFrom; i++)
{
CopyTo[index] = CopyFrom[i];
index++;
}
return true;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void TrainTestSplitMatrices(matrix& matrix_,matrix& x_train,vector& y_train,matrix& x_test,vector& y_test,double TrainSampleSize = 0.7)
{
ulong total = matrix_.Rows(), cols = matrix_.Cols();
ulong last_col = cols-1;

Randomize(matrix_);

int TrainSize = (int)MathFloor(total*TrainSampleSize);
int TestSize = (int)total - TrainSize;

x_train.Resize(TrainSize,cols-1);
x_test.Resize(TestSize,cols-1);

y_train.Resize(TrainSize);
y_test.Resize(TestSize);

int TrainCount = 0,TestCount = 0;

Copy(matrix_.Col(last_col),y_train,0,TrainSize);
Copy(matrix_.Col(last_col),y_test,TrainSize);

for(ulong i=0; i<matrix_.Rows(); i++)
{
if(i<(ulong)TrainSize)
{
x_train.Row(matrix_.Row(i),TrainCount);
TrainCount++;
}
else
{
x_test.Row(matrix_.Row(i),TestCount);
TestCount++;
}
}
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double Random(double mini, double maxi)
{
return mini+double((MathRand()/32767.0)*(maxi-mini));
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void GenerateTensorParameters(uint Inputsf,vector& HiddenLayersf)
{
MathSrand(RandomSeed);

WeightsTensor = new CTensor((uint)HiddenLayersf.Size());
BiasTensor = new CTensor((uint)HiddenLayersf.Size());

uint LayerInput = Inputsf;

matrix Weights,Bias;

for(ulong layer=0; layer<HiddenLayersf.Size(); layer++)
{
Weights.Resize((uint)HiddenLayersf[layer],LayerInput);
for(ulong i=0; i<Weights.Rows(); i++)
{
for(ulong j=0; j<Weights.Cols(); j++)
{
Weights[i][j] = Random(-1,1);
}
}
WeightsTensor.Add(Weights,layer);
Bias.Resize((uint)HiddenLayersf[layer],1);
for(ulong i=0; i<Bias.Rows(); i++)
{
for(ulong j=0; j<Bias.Cols(); j++)
{
Bias[i][j] = Random(-1,1);
}
}
BiasTensor.Add(Bias,layer);
LayerInput = (int)HiddenLayersf[layer];
}
Print("Weights = ",WeightsTensor.Get(0),"\nBias = ",BiasTensor.Get(0));
}

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
vector ForwardPass(vector &x)
{
matrix LayerInput = VectorToMatrix(x);
matrix LayerOutPut = {};
matrix W,B;
ulong NumHiddenLayers = HiddenLayer.Size();

for(ulong i=0; i<NumHiddenLayers; i++)
{
W = WeightsTensor.Get(i);
B = BiasTensor.Get(i);

if(InBackPropagation)
InputsTensor.Add(LayerInput,i);

LayerOutPut = W.MatMul(LayerInput) + B;
if(!LayerOutPut.Activation(LayerOutPut,i+1==NumHiddenLayers?AF_SOFTMAX:ENUM_ACTIVATION_FUNCTION(ActivationFx)))
{
printf("%s failed to calculate the activation function Err = %d",FUNCTION,GetLastError());
}
if(InBackPropagation)
OutPutsTensor.Add(LayerOutPut,i);

LayerInput = LayerOutPut;
}
return MatrixToVector(LayerOutPut);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int SingleForwardPass(vector& x)
{
vector v = ForwardPass(x);
return (int)DataClasses[v.ArgMax()];
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
vector BatchForwardPass(matrix& x)
{
vector v(x.Rows());
for(ulong i=0; i<x.Rows(); i++)
{
v[i] = SingleForwardPass(x.Row(i));
}
return v;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void BackPropagation(matrix& x, vector& y, uint epochs = 100,double learning_rate = 0.001)
{
DataClasses = Classes(y);

uint OutPutsNode = (uint)DataClasses.Size();

HiddenLayer.Resize(HiddenLayer.Size()+1);

HiddenLayer[HiddenLayer.Size()-1] = OutPutsNode;

uint NumHiddenLayers = (uint)HiddenLayer.Size();

GenerateTensorParameters((uint)x.Cols(),HiddenLayer);

vector Predictions, NetworkPred,ActualValues;

matrix ONE_HOT_MATRIX = OneHotEncoding(y);

matrix PartialDerivatives, Delta(HiddenLayer[NumHiddenLayers-1],1);
vector LossGradient;

InputsTensor = new CTensor(NumHiddenLayers);
OutPutsTensor = new CTensor(NumHiddenLayers);

if(MQLInfoInteger(MQL_DEBUG))
Print("Hidden Layers: ",HiddenLayer,"\nClasses in data: ",DataClasses);

matrix weights,bias,dW,dB,layer_inputs;

InBackPropagation = true;

for(uint epoch=0; epoch<epochs && !IsStopped(); epoch++)
{
for(ulong iteration=0; iteration<x.Rows() && !IsStopped(); iteration++)
{
NetworkPred = ForwardPass(x.Row(iteration));
ActualValues = ONE_HOT_MATRIX.Row(iteration);


 Delta.Resize((uint)HiddenLayer[NumHiddenLayers-1],1);

 for(int layer=(int)NumHiddenLayers-1; layer>=0; layer--)
   {
    PartialDerivatives = OutPutsTensor.Get(layer);
    PartialDerivatives.Derivative(PartialDerivatives,layer == NumHiddenLayers-1?AF_SOFTMAX:ENUM_ACTIVATION_FUNCTION(ActivationFx));
    layer_inputs = InputsTensor.Get(layer);

    if(layer == NumHiddenLayers-1)
      {
       LossGradient = NetworkPred.LossGradient(ActualValues,ENUM_LOSS_FUNCTION(LossFunction));
       Delta.Col(LossGradient,0);
      }
    else
      {
       weights = WeightsTensor.Get(layer+1);
       Delta = (weights.Transpose().MatMul(Delta))*PartialDerivatives;
      }

    dB = Delta;
    dW = Delta.MatMul(layer_inputs.Transpose());

    weights = WeightsTensor.Get(layer);
    bias = BiasTensor.Get(layer);

    WeightsTensor.Add(weights -= dW * learning_rate,layer);
    BiasTensor.Add(bias -= dB*learning_rate,layer);
   }
}
vector preds = BatchForwardPass(x);
double loss = preds.Loss(y,ENUM_LOSS_FUNCTION(LossFunction));
printf("[ Epoch %d/%d Cost %.8f Accuracy %.3f]",epoch+1,epochs,loss,ConfusionMatrix(y,preds,DataClasses,false));

if(epoch+1 == epochs)
Print("ActualValues: ",y,"\nPredictions: ",preds);
}
InBackPropagation = false;
}
//+------------------------------------------------------------------+

bool ArrowCreate
(
const string name,
datetime time,
double price,
const uchar arrowcode,
const color clr = clrRed,
const ENUM_LINE_STYLE style = STYLE_SOLID,
const int width = 3
)
{
if(!ObjectCreate(0,name,OBJ_ARROW,0,time,price))
{
printf(FUNCTION," : Failed to create an arrow, Error code = ", GetLastError());
return false;
}
ObjectSetInteger(0,name,OBJPROP_ARROWCODE,arrowcode);
ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
ObjectSetInteger(0,name,OBJPROP_STYLE,style);
ObjectSetInteger(0,name,OBJPROP_WIDTH,width);
return true;
}
//+------------------------------------------------------------------+

use de exemplo a estrutura deep leaning do codigo acima e implemente no meu codigo abaixo o deep learning para aumentar a assertividade no trading, nao altere a estrategia original do meu codigo abaixo apenas adicione a rede neural deep learing para melhor assertividade e depois me entregue o codigo completo:

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