Using iCustom with keltnet_channel315.ex5

 

Hi,


I would like to create an Advisor Robot to trade using the Keltner channel indicator but I'm not being able to access the upper and lower bands of it through it's handle.

I'm using the keltnet_channel315.ex5 indicator that's available in the library but I have not found a way to directly retrieve the upper and lower bands price value.

Maybe there is a way to point to the many buffers of this indicator somehow.

My code to access the handle is as follows:

   keltnerHandle = iCustom(_Symbol,0,"Indicator\\keltnet_channel315.ex5",
                     periods,
                     "ma_Simple",
                     "mv_Visible",
                     "pr_typical",
                     clrDeepSkyBlue,
                     clrPaleVioletRed,
                     periods,
                     coeficient,
                     "art_Rng",
                     "cm_None",
                     true // usando o fechamento de preços
                     );
 

This code is only to get the handle.

Where is the rest of your code.

You can specify the buffer number in a copyBuffer call.

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
CopyBuffer - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Marco vd Heijden:

This code is only to get the handle.

Where is the rest of your code.

You can specify the buffer number in a copyBuffer call.

Just after I posted I have found just that I need to use CopyBuffer like you just said, here is the full code, it's not fully implemented but not I'm getting a error "cannot load custom indicator" I have a attached a picture.


I think the iCustom parameters are wrong.

#property copyright "K1"
#property link      "GG"
#property version   "1.00"

//+------------------------------------------------------------------+
//| INCLUDES                                                         |
//+------------------------------------------------------------------+
#include <Trade/Trade.mqh> // biblioteca-padrão CTrade
#resource "\\Indicators\\keltner_channel315.ex5" //include the indicator in your file for convenience


//+------------------------------------------------------------------+
//| INPUTS                                                           |
//+------------------------------------------------------------------+
input int lot = 1;
input int coeficient = 2.2;
input int periods = 20;
input string EndTime = "23:56"; // Do not trade after (server time)...
input string StartTime = "01:30"; // Do not trade before (server time)...
//+------------------------------------------------------------------+
//| GLOBAIS                                                          |
//+------------------------------------------------------------------+
//--- manipuladores dos indicadores de média móvel
int keltnerHandle = INVALID_HANDLE;

//--- vetores de dados dos indicadores de média móvel

double upperKeltner[];
double lowerKeltner[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int lastDealNum = HistoryDealGetTicket((int)HistoryOrdersTotal()-1);
bool entryByLowMA = false;
bool previewsTradeStopped = false;
bool previewsTradeHighMAexit = true;

bool buySignal = false;
bool sellSignal = false;

bool isLong = false;
bool isShort = false;
//--- declarara variável trade
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   ArraySetAsSeries (upperKeltner,true);
   ArraySetAsSeries (lowerKeltner,true);
   


//input ENUM_TIMEFRAMES    TimeFrame       = PERIOD_CURRENT; // Time frame
//input int                MAPeriod        = 20;             // Moving average period
//input enMaModes          MAMethod        = ma_Simple;      // Moving average type
//input enMaVisble         MAVisible       = mv_Visible;     // Midlle line visible ?
//input enPrices           Price           = pr_typical;     // Moving average price 
//input color              MaColorUp       = clrDeepSkyBlue; // Color for slope up
//input color              MaColorDown     = clrPaleVioletRed; // Color for slope down
//input int                AtrPeriod       = 20;             // Range period
//input double             AtrMultiplier   = 2.0;            // Range multiplier
//input enAtrMode          AtrMode         = atr_Rng;        // Range calculating mode 
//input enCandleMode       ViewBars        = cm_None;        // View bars as :
//input bool               Interpolate     = true;           // Interpolate mtf data

   keltnerHandle = iCustom(_Symbol,0,"Indicator\\keltnet_channel315.ex5",
                     periods,
                     "ma_Simple",
                     "mv_Visible",
                     "pr_typical",
                     clrDeepSkyBlue,
                     clrPaleVioletRed,
                     periods,
                     coeficient,
                     "art_Rng",
                     "cm_None",
                     true // usando o fechamento de preços
                     );
                     
   Print("MA_handle = ",keltnerHandle,"  error = ",GetLastError());
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

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

//+------------------------------------------------------------------+
//| Time allowed to Trade                                            |
//+------------------------------------------------------------------+
   bool TradeHours = false;

   MqlDateTime _start_mdt, _end_mdt, _server_mdt;
   TimeToStruct(StartTime,_start_mdt);
   TimeToStruct(EndTime,_end_mdt);
   TimeToStruct(TimeCurrent(),_server_mdt);

   bool CrossedDay = false;
   int StartMin = _start_mdt.hour*60+_start_mdt.min;
   int EndMin = _end_mdt.hour*60+_end_mdt.min;
   int ServerMin = _server_mdt.hour*60+_server_mdt.min;
   if(StartMin>EndMin)
     {
      CrossedDay = true;
     }
   else
     {
      TradeHours = ((!CrossedDay && ServerMin>=StartMin && ServerMin<EndMin) || (CrossedDay && (ServerMin>=StartMin || ServerMin<EndMin)));
     }

//      TradeHours = true;

//+------------------------------------------------------------------+
//| Trading Strategy Begin                                           |
//+------------------------------------------------------------------+

   MqlTick Price;
   SymbolInfoTick(_Symbol,Price);

  
   
   int copied1 = CopyBuffer(keltnerHandle,2,0,3,upperKeltner);
   int copied2 = CopyBuffer(keltnerHandle,3,0,3,lowerKeltner);
   
   
   //Keltner Channel Middle Line = EMA
//Keltner Channel Upper Band = EMA+2∗ATR
//Keltner Channel Lower Band = EMA−2∗ATR
    
   

// execute a lógica operacional do robô

//+------------------------------------------------------------------+
//| ENTRY SIGNALS                                                    |
//+------------------------------------------------------------------+

//--- se os dados tiverem sido copiados corretamente

   if(copied1==3 && copied2==3)
     {
      //--- sinal de compra
      if(lowerKeltner[0] > Price.last)
        {
         //            Print("lowMA: ",lowMA[0]," Price: ",Price.last);
         buySignal = true;
        }
      else
        {
         buySignal = false;
        }
      //--- sinal de venda
      if((Price.last > upperKeltner[0]) && isLong)
        {
         sellSignal = true;
         //            Print("highMA: ",highMA[0]," Price: ",Price.last);
        }
      else
        {
         sellSignal = false;
        }
     }

//+------------------------------------------------------------------+
//| CHECK IS THERE ARE POSITIONS OPENED                              |
//+------------------------------------------------------------------+
//if(PositionSelect(_Symbol))
//  {
//   //--- se a posição for comprada
//   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
//     {
//      isLong = true;
//     }
//   else
//     {
//      isLong = false;
//     }
//   //--- se a posição for vendida
//   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
//     {
//      isShort = true;
//     }
//   else
//     {
//      isShort = false;
//     }
//  }

//+------------------------------------------------------------------+
//| Check PREVIEWS TRADES                                            |
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| ENTRY CONDITIONS FOR Price HIGHER than slowMA                    |
//+------------------------------------------------------------------+
//--- ZERADO
   if(TradeHours)  //&& (lowMA[0] > slowMA[0])
     {
      if(!isLong && !isShort && buySignal && !previewsTradeStopped && previewsTradeHighMAexit)
        {
         trade.Buy(lot,_Symbol,0,Price.last-300,0,"Entry - Long");
         previewsTradeHighMAexit = false;
         entryByLowMA = true;
         isLong = true;
         Print("is Long: ", isLong, " is Short: ", isShort, " #########DT: ", lastDealNum);
         Print("buySignal: ", buySignal, " sellSignal: ", sellSignal);
         Print(" Stopped: ",previewsTradeStopped," entryByLowMA: ",entryByLowMA," previewsTradeHighMAexit: ",previewsTradeHighMAexit);
        }
     }

//+------------------------------------------------------------------+
//| EXIT CONDITIONS                                                  |
//+------------------------------------------------------------------+
   if(isLong && sellSignal)
     {
      trade.Sell(lot,_Symbol,0,0,0,"Exit - Short");
      previewsTradeHighMAexit = true;
      entryByLowMA = false;
      isLong = false;
      Print("is Long: ", isLong, " is Short: ", isShort, " #########DT: ", lastDealNum);
      Print("buySignal: ", buySignal, " sellSignal: ", sellSignal);
      Print(" Stopped: ",previewsTradeStopped," entryByLowMA: ",entryByLowMA," previewsTradeHighMAexit: ",previewsTradeHighMAexit);
     }

//+------------------------------------------------------------------+
//| EXIT CONDITIONS AFTER TRADE HOURS                                |
//+------------------------------------------------------------------+
   if(!TradeHours && isLong)
     {
      trade.Sell(lot,_Symbol,0,0,0,"Fim Dia");
      entryByLowMA = false;
      isLong = false;
      Print("is Long: ", isLong, " is Short: ", isShort, " #########DT: ", lastDealNum);
      Print("buySignal: ", buySignal, " sellSignal: ", sellSignal);
      Print(" Stopped: ",previewsTradeStopped," entryByLowMA: ",entryByLowMA," previewsTradeHighMAexit: ",previewsTradeHighMAexit);
     }





   if(TradeHours)//&& (Price.last > slowMA[0])
     {
      //     Print("Trading ENABLED");
     }
   else
     {
      //     Print("Not Trading");
     }

//   Print("is Long: ", isLong, " is Short: ", isShort);
//   Print("buySignal: ", buySignal, " sellSignal: ", sellSignal);
//   Print("slow MA: ", slowMA[0]," Stopped: ",previewsTradeStopped," entryByLowMA: ",entryByLowMA," previewsTradeHighMAexit: ",previewsTradeHighMAexit);
  } //END ON TICK
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isNewBar()
  {
//--- memorize the time of opening of the last bar in the static variable
   static datetime last_time=0;
//--- current time
   datetime lastbar_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);

//--- if it is the first call of the function
   if(last_time==0)
     {
      //--- set the time and exit
      last_time=lastbar_time;
      return(false);
     }

//--- if the time differs
   if(last_time!=lastbar_time)
     {
      //--- memorize the time and return true
      last_time=lastbar_time;
      return(true);
     }
//--- if we passed to this line, then the bar is not new; return false
   return(false);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction & trans,
                        const MqlTradeRequest & request,
                        const MqlTradeResult & result)
  {
   if(HistoryDealSelect(trans.deal))
     {
      ENUM_DEAL_ENTRY deal_entry = (ENUM_DEAL_ENTRY) HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
      ENUM_DEAL_REASON deal_reason = (ENUM_DEAL_REASON) HistoryDealGetInteger(trans.deal, DEAL_REASON);
      if(EnumToString(deal_entry) == "DEAL_ENTRY_IN")
        {
         if(EnumToString(deal_reason) == "DEAL_REASON_EXPERT" && EnumToString(trans.deal_type) == "DEAL_TYPE_BUY")
           {
            //            Alert("Buy");
           }
         else
            if(EnumToString(deal_reason) == "DEAL_REASON_EXPERT" && EnumToString(trans.deal_type) == "DEAL_TYPE_SELL")
              {
               //               Alert("Sell");
              }
        }
      else
         if(EnumToString(deal_entry) == "DEAL_ENTRY_OUT")
           {
            if(EnumToString(deal_reason) == "DEAL_REASON_SL" && EnumToString(trans.deal_type) == "DEAL_TYPE_BUY")
              {
               Alert("Sell SL");
               previewsTradeStopped = true;

              }
            else
               if(EnumToString(deal_reason) == "DEAL_REASON_SL" && EnumToString(trans.deal_type) == "DEAL_TYPE_SELL")
                 {
                  Alert("Buy SL");
                  previewsTradeStopped = true;
                  isLong = false;
                 }
               else
                  if(EnumToString(deal_reason) == "DEAL_REASON_TP" && EnumToString(trans.deal_type) == "DEAL_TYPE_BUY")
                    {
                     //                     Alert("Sell TP");
                    }
                  else
                     if(EnumToString(deal_reason) == "DEAL_REASON_TP" && EnumToString(trans.deal_type) == "DEAL_TYPE_SELL")
                       {
                        //                       Alert("Buy TP");
                       }
           }
     }
  }
//+------------------------------------------------------------------+ 

Files:
Capture.PNG  42 kb
 

There seem to be some typos...

   keltnerHandle = iCustom(_Symbol,0,"::Indicators\\keltner_channel315.ex5",
 

I have changed that line but it is still giving me the same error


   keltnerHandle = iCustom(_Symbol,0,"::Indicator\\keltnet_channel315.ex5",
                           PERIOD_CURRENT,
                           periods,
                           "ma_Simple",
                           "mv_Visible",
                           "pr_typical",
                           clrDeepSkyBlue,
                           clrPaleVioletRed,
                           periods,
                           coeficient,
                           "art_Rng",
                           "cm_None",
                           true
                          );

Bellow you find the log and attached the indicator location

PS      0       10:54:04.351    Tester  WIN$,M1: testing of Experts\Advisors\k1.ex5 from 2021.01.01 00:00 to 2021.01.16 00:00 started with inputs:
CP      0       10:54:04.351    Tester    lot=1
LP      0       10:54:04.351    Tester    coeficient=2
MI      0       10:54:04.351    Tester    periods=20
FL      0       10:54:04.351    Tester    EndTime=23:56
EO      0       10:54:04.351    Tester    StartTime=01:30
OK      2       10:54:04.387    MQL5    2021.01.01 00:00:00   cannot load resource 'C:\Users\Elise\AppData\Roaming\MetaQuotes\Tester\FB9A56D617EDDDFE29EE54EBEFFE96C1\Agent-127.0.0.1-3000\MQL5\Experts\Advisors\k1.ex5::Indicator\keltnet_channel315.ex5'
NH      2       10:54:04.387    Custom Indicator        loading of keltnet_channel315 WIN$,M1 failed [554]
EO      2       10:54:04.387    k1 (WIN$,M1)    2021.01.01 00:00:00   cannot load custom indicator 'C:\Users\Elise\AppData\Roaming\MetaQuotes\Tester\FB9A56D617EDDDFE29EE54EBEFFE96C1\Agent-127.0.0.1-3000\MQL5\Experts\Advisors\k1.ex5::Indicator\keltnet_channel315.ex5' [4802]
ON      2       10:54:04.387    k1 (WIN$,M1)    2021.01.01 00:00:00   indicator create error
EI      2       10:54:04.387    Tester  OnInit critical error
FR      2       10:54:04.387    Tester  tester stopped because OnInit failed
IG      0       10:54:04.387    Tester  log file "C:\Users\Elise\AppData\Roaming\MetaQuotes\Tester\FB9A56D617EDDDFE29EE54EBEFFE96C1\Agent-127.0.0.1-3000\logs\20210116.log" written
QM      0       10:54:04.387            test Experts\Advisors\k1.ex5 on WIN$,M1 thread finished
RK      0       10:54:04.428    127.0.0.1       prepare for shutdown
Files:
Capture_1.PNG  11 kb
 

Not

::Indicator

yes:

::Indicators
 
Nicole de Melo:

I have changed that line but it is still giving me the same error


Bellow you find the log and attached the indicator location

Ernst Van Der Merwe:

There seem to be some typos...

keltnerHandle = iCustom(_Symbol,0,"::Indicators\\keltner_channel315.ex5",
Reason: