2

This is my first post on Stackoverflow although I've visited here for years.

I have read the message guidelines so I'll be as succinct and specific as possible.

I have been attempting to embed the code of a Custom Indicator directly in an Expert Advisor without having to call iCustom:

iCustom(Symbol(),60,"MB",3D,0,1)>0;

Thus far I've failed and whilst I believe it is probably a trivial thing to do for many, if you don't know, you don't know.

The iCustom code in question is the following and I'd be grateful for any assistance:

#property indicator_chart_window

#property  indicator_buffers 2 
#property  indicator_color1 Blue
#property  indicator_color2 Red
#property  indicator_width1 5
#property  indicator_width2 5


extern int 3D= 5


double AIAIAI[];
double B1B1B1[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   SetIndexBuffer( 0, AIAIAI );
   SetIndexEmptyValue( 0, 0.0 );
   SetIndexStyle( 0, DRAW_ARROW );
   SetIndexArrow( 0, 250 ); 
   SetIndexLabel( 0, NULL );

   SetIndexBuffer( 1, B1B1B1);
   SetIndexEmptyValue( 1, 0.0 );
   SetIndexStyle( 1, DRAW_ARROW );
   SetIndexArrow( 1, 250 ); 
   SetIndexLabel( 1, NULL ); 

   IndicatorDigits( 5 );

   //---- name for DataWindow and indicator subwindow label
   IndicatorShortName( MB(" + 3D+ ")" );

   return( 0 );
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   return( 0 );
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   int counted_bars = IndicatorCounted();

   if (counted_bars < 0) return (-1);
   if (counted_bars > 0) counted_bars--;
   int intLimit = Bars - counted_bars;
   int LO, HI;

   for( int NINI = intLimit; NINI >= 0; NINI-- )
   {          
      AIAIAI[NINI] = 0.0;
      B1B1B1[NINI] = 0.0;

      LO = iLowest( Symbol(), Period(), MODE_LOW, 3D, NINI );

      if ( LO == NINI )
      {
         AIAIAI[NINI] = Low[NINI];
      }

      HI = iHighest( Symbol(), Period(), MODE_HIGH, 3D, NINI );

      if ( HI == NINI )
      {
         B1B1B1[NINI] = High[NINI];
      }
   }

   return( 0 );
}

Thank you

3 Answers3

3

The best way to package the indicator code with the compiled EA is to include it as a resource and continue to call it using icustom. When you do it this way, there is no need to refactor and extract indicator logic.

The syntax is as follows:

#resource "MyCustomIndicator.ex4"

double my_custom_zero_buffer(string symbol, int period, int setting, int i)
{
   return iCustom(symbol, period, "::MyCustomIndicator.ex4", setting, 0, i);
}

When you compile this EA the Indicator will also be compiled and packaged together so you can use/distribute it without exposing the indicator logic

nicholishen
  • 2,602
  • 2
  • 9
  • 13
  • Thank you. I've followed your instructions but unfortunately I receive the "cannot load resource" message in the journal. I'll look online for more examples of using resources. – Frank Matthews Dec 26 '18 at 19:20
  • UPDATE: I managed to get it to work. Thanks again!!! Can .DLLs be included as resources? – Frank Matthews Dec 26 '18 at 19:26
  • What value does my_custom_zero_buffer return? The custom indicator always seems to return 0. I'm attempting my first custom indicator and EA, but can't figure out how to get a value from the indicator to my EA. – Gerry Mar 10 '21 at 04:58
0

If you use the indicator as an example only, that is probably not a good indicator as it does not use buffers and overall very simple indicator. It should be quite easy to recompute the buffer value from the ea when you need it.

double iCustomValue(const int param,const int buffer,const int shift)
   {
    switch(buffer)
      {
       case 0:
          if(iLowest(_Symbol,0,MODE_LOW,param,shift)==shift)
              return iLow(_Symbol,0,shift);
          break;
       case 1:
          if(iHighest(_Symbol,0,MODE_HIGH,param,shift)==shift)
              return iLow(_Symbol,0,shift);
          break;
      }
    return(0.0);
   }

and use the function instead of your indicator. For more complicated indicators - keep in mind that calling indicators is slower of course but allows to test easier.

Daniel Kniaz
  • 4,603
  • 2
  • 14
  • 20
0

I have realized and this should make sense that this works only when the compiled indicator .ex4 file is in the same directory as the EA. It seems to ignore the directory path, although I've gotten that the work before where path = "c:\...\Indicators\mycustomindicator.ex4". I think it depends on the version of MT4 as there seems to be a variance in how that's treated.

Funny thing, the recommended approach doesn't work at all! Maybe for the same reason, not looking in the right place: looking at the Experts folder instead of the Indicators folder.

Neat trick, the resource thing!

Oliver
  • 76
  • 1