Code error - Open Buy & Sell trades using Nadaraya Envelope

 

I have used the code of Nadaraya Envelope from LuxAlgo, the indicator code is as below

//+------------------------------------------------------------------+
//|                                                           nd.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Grasco."
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE
#property indicator_width1  2
#property indicator_width2  2
#property indicator_color1  Blue
#property indicator_color2  Red
#property indicator_applied_price PRICE_WEIGHTED
//--- input parameters
input int                Length=500;              // Bars Count
input int                Bandwidth=17;                // Bandwidth
input double             Multiplayer=1.5;
// n = get the bar index

//--- indicator buffers
double                   ExtUpBuffer[];
double                   ExtDownBuffer[];
double                   ExtCABuffer[];
double                   y[]; // for calculation
int                      ExtBarsHandle;
int                      k = 2;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtUpBuffer);
   SetIndexBuffer(1,ExtDownBuffer);
   SetIndexBuffer(2,y,INDICATOR_CALCULATIONS);
//---
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,0);
   PlotIndexGetInteger(1,PLOT_DRAW_BEGIN,0);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
//--- name for DataWindow
   string short_name=StringFormat("Nadraya",Length);
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   PlotIndexSetString(0,PLOT_LABEL,short_name+" Upper");
   PlotIndexSetString(1,PLOT_LABEL,short_name+" Lower");
   
   ExtBarsHandle = iMA(_Symbol,_Period,Length,0,MODE_EMA,PRICE_WEIGHTED);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   if(IsStopped()) return 0;
   int calculated=BarsCalculated(ExtBarsHandle);
   if(rates_total<calculated) return(0);
   if(rates_total<Length)
      return(0);
   
   int copyBars = 0;
   if (prev_calculated>rates_total || prev_calculated<=0){
      copyBars = rates_total;
   }
   else{
      copyBars = rates_total-prev_calculated;
      if(prev_calculated>0) copyBars++;
   }
   int start=prev_calculated-1;
   if(start<Length)
      start=Length;
   
   
   double sum_e = 0.0;
   for(int i=rates_total-Length; i<rates_total && !IsStopped(); i++){
      double sum = 0.0;
      double sumw= 0.0;
      for(int j = rates_total-Length;j<rates_total-1;j++){
         double w = MathExp(-(MathPow(i-j,2)/(Bandwidth*Bandwidth*2)));
         sum += price[j]*w;
         sumw += w;
      }
      double y2 = sum/sumw;
      sum_e += (MathAbs(price[i]-y2));
      y[i] = y2;
   }
   double mae = sum_e/Length*Multiplayer;
   for(int i=rates_total-Length+1; i<rates_total && !IsStopped(); i++){
      double y2 = y[i];
      double y1 = y[i-1];
         
      ExtUpBuffer[i]=y2+mae;
      ExtDownBuffer[i]=y2-mae;
      //Print(mae);
      //Print(y[i]);
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

And I have added the below condition to return true value when the current price is above the envelope and below the envelope.

When I am running the EA, this is not opening any trades, Can someone tell, whether any error is there in the code?

bool NW_Rule(int option){
   if(!NW_Filter) return true;
   if(NW_Filter){
   if(option==1 && (ExtDownBuffer[0]>=Bid)) return true;
   if(option==2 && (Ask>=ExtUpBuffer[0])) return true;     
}
   return false;
}
 

An indicator cannot open trades only EAs can:

Quickstart for newbies: https://www.mql5.com/en/articles/496
and: https://www.mql5.com/en/articles/100
cookbook: https://www.mql5.com/en/search#!keyword=cookbook

Quick Start: Short Guide for Beginners
Quick Start: Short Guide for Beginners
  • www.mql5.com
Hello dear reader! In this article, I will try to explain and show you how you can easily and quickly get the hang of the principles of creating Expert Advisors, working with indicators, etc. It is beginner-oriented and will not feature any difficult or abstruse examples.
 
Carl Schreiber #:

An indicator cannot open trades only EAs can:

Quickstart for newbies: https://www.mql5.com/en/articles/496
and: https://www.mql5.com/en/articles/100
cookbook: https://www.mql5.com/en/search#!keyword=cookbook

Sir,

Thanks for your reply and i have read and added the code as below, but still it is not working, will you please help resolving this.  I am herewith pasting the entire code


#property copyright "https://www.mql5.com/"
#property link      "https://www.mql5.com/"
#property version   "2.00"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\DealInfo.mqh>
CTrade trade;
COrderInfo orderInfo;
CDealInfo dealInfo;

input double BuyLot=0.01;     //Buy Lot #1
input double SellLot=0.01;    //Sell Lot #1
input double BuySL=0;         //Buy SL
input double SellSL=0;        //Sell SL
input double BuyTP=0;         //Buy TP
input double SellTP=0;        //Sell TP
input int Magic=56798;        //Magic Number
input bool NW_Filter=false;   //NW Filter
//--- input parameters for NW Envelope
input int                Length=500;              // Bars Count
input int                Bandwidth=8;             // Bandwidth
input double             Multiplayer=3;

//+------------------------------------------------------------------+
//| VARIABLES
//+------------------------------------------------------------------+

double neg=-1;
ulong Buy1=0;
ulong Sell1=0;
double Ask;
double Bid;
//--- indicator buffers for NW Envelope
double                   ExtUpBuffer[];
double                   ExtDownBuffer[];
double                   ExtCABuffer[];
double                   y[]; // for calculation
int                      ExtBarsHandle;
int                      k = 2;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(){

   //INDICATORS      
   ExtBarsHandle = iMA(Symbol(),Period(),Length,0,MODE_EMA,PRICE_WEIGHTED);
   
   //MN
   trade.SetExpertMagicNumber(Magic);
   
   //RETURN
   return(INIT_SUCCEEDED);
   
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(){
 
//define Ask, Bid
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   
//Indicators
   Load_NW();
      
//First Entry
   FirstTrade(); //BUY & SELL
   
//EXITS

   SL();
   TP(); 
   
}


//+------------------------------------------------------------------+
//| Custom iteration function Nadaraya Watson Envelope     |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   if(IsStopped()) return 0;
   int calculated=BarsCalculated(ExtBarsHandle);
   if(rates_total<calculated) return(0);
   if(rates_total<Length)
      return(0);
   
   int copyBars = 0;
   if (prev_calculated>rates_total || prev_calculated<=0){
      copyBars = rates_total;
   }
   else{
      copyBars = rates_total-prev_calculated;
      if(prev_calculated>0) copyBars++;
   }
   int start=prev_calculated-1;
   if(start<Length)
      start=Length;
   
   
   double sum_e = 0.0;
   for(int i=rates_total-Length; i<rates_total && !IsStopped(); i++){
      double sum = 0.0;
      double sumw= 0.0;
      for(int j = rates_total-Length;j<rates_total-1;j++){
         double w = MathExp(-(MathPow(i-j,2)/(Bandwidth*Bandwidth*2)));
         sum += price[j]*w;
         sumw += w;
      }
      double y2 = sum/sumw;
      sum_e += (MathAbs(price[i]-y2));
      y[i] = y2;
   }
   
   double mae = sum_e/Length*Multiplayer;
   for(int i=rates_total-Length+1; i<rates_total && !IsStopped(); i++){
      double y2 = y[i];
      double y1 = y[i-1];
         
      ExtUpBuffer[i]=y2+mae;
      ExtDownBuffer[i]=y2-mae;
      //Print(mae);
      //Print(y[i]);
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| NADARAYA WATSON ENVELOPE FILTER
//+------------------------------------------------------------------+

bool NW_Rule(int option){
   if(!NW_Filter) return true;
   if(NW_Filter){
   if(option==1 && (ExtDownBuffer[0]-Bid)>0) return true;
   if(option==2 && (Ask-ExtUpBuffer[0])>0) return true;     
}
   return false;
}

//+------------------------------------------------------------------+
//| TP
//+------------------------------------------------------------------+
void TP(){
      if(TotalProfit(1)>=BuyTP){
         CloseAll(1);
         ResetTicket(1);
      }
      if(TotalProfit(2)>=SellTP){
         CloseAll(2);
         ResetTicket(2);
      }
}

//+------------------------------------------------------------------+
//| SL
//+------------------------------------------------------------------+
void SL(){

      if(TotalProfit(1)<=BuySL*neg){
         CloseAll(1);
         ResetTicket(1);
         
      } 
      if(TotalProfit(2)<=SellSL*neg){
         CloseAll(2);
         ResetTicket(2);
         
      }
}

//+------------------------------------------------------------------+
//| FIRST TRADE
//+------------------------------------------------------------------+
void FirstTrade(){ 
   //BUY
   if(Buy1==0 && Sell1==0 && NW_Rule(1)){
         trade.Buy(BuyLot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_ASK),0,0,NULL);
         Buy1=PositionGetTicket(PositionsTotal()-1);
   }
   //SELL
   if(Sell1==0 && Buy1==0 && NW_Rule(2)){
         trade.Sell(SellLot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_BID),0,0,NULL);
         Sell1=PositionGetTicket(PositionsTotal()-1);
}
}


//+------------------------------------------------------------------+
//| TOTAL PROFIT
//+------------------------------------------------------------------+
double TotalProfit(int option){
   double Profit=0;
   for(int pos=PositionsTotal()-1; pos>=0; pos--){
      ulong ticket=PositionGetTicket(pos);
      PositionSelectByTicket(ticket);
      if(PositionGetInteger(POSITION_MAGIC)==Magic){
         if(option==0) Profit+=PositionGetDouble(POSITION_PROFIT);
         if(option==1 && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)  Profit+=PositionGetDouble(POSITION_PROFIT);
         if(option==2 && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) Profit+=PositionGetDouble(POSITION_PROFIT);
      }
   }
   return Profit;
}

//+------------------------------------------------------------------+
//| CLOSE ALL
//+------------------------------------------------------------------+
void CloseAll(int option){
   for(int pos=PositionsTotal()-1; pos>=0; pos--){
      ulong ticket=PositionGetTicket(pos);
      PositionSelectByTicket(ticket);
      if(PositionGetInteger(POSITION_MAGIC)==Magic){
         if(option==0) trade.PositionClose(ticket,-1);
         if(option==1 && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)  trade.PositionClose(ticket,-1);
         if(option==2 && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) trade.PositionClose(ticket,-1);
      }
   }
}

//+------------------------------------------------------------------+
//| RESET TICKET
//+------------------------------------------------------------------+
void ResetTicket(int option){
   if(option==1){
      Buy1=0;
   }
   if(option==2){
      Sell1=0;
   }
}

//+------------------------------------------------------------------+
//| LOAD NADARAYA WATSON ENVELOPE
//+------------------------------------------------------------------+
void Load_NW(){
   ArraySetAsSeries(ExtUpBuffer,true);
   ArraySetAsSeries(ExtDownBuffer,true);
   
   CopyBuffer(ExtBarsHandle,0,0,iBars(Symbol(),Period()),ExtUpBuffer);
   CopyBuffer(ExtBarsHandle,1,0,iBars(Symbol(),Period()),ExtDownBuffer);  
}
 
Sathish Justin #:

Sir,

Thanks for your reply and i have read and added the code as below, but still it is not working, will you please help resolving this.  I am herewith pasting the entire code


Waiting for someone to answer plz

 
Sathish Justin #:

Waiting for someone to answer plz

Dear do you think converting an indocator to an EA is that easy? Definitely it is not.

You should keep your indicator and create a separate EA for trading purpose. use iCustom to access buffers from indicator in your EA.

 
Yashar Seyyedin #:

Dear do you think converting an indocator to an EA is that easy? Definitely it is not.

You should keep your indicator and create a separate EA for trading purpose. use iCustom to access buffers from indicator in your EA.

Will you please share some articles to refer the code

 
Sathish Justin #:

Will you please share some articles to refer the code

int nd_handle=0;

int OnInit()
  {
//---
   nd_handle=iCustom(_Symbol, PERIOD_CURRENT, "nd");
//---
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {   
   if(NW_Rule_Buy(0)) //buy
   if(NW_Rule_Sell(0)) //sell
  }

bool NW_Rule_Buy(int index)
{
   double Bid=SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double array[];
   ArraySetAsSeries(array, true);
   CopyBuffer(nd_handle, 0, index, 1, array);
   return Bid>array[0];
}

bool NW_Rule_Sell(int index)
{
   double Bid=SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double array[];
   ArraySetAsSeries(array, true);
   CopyBuffer(nd_handle, 1, index, 1, array);
   return Bid<array[0];
}