MQL4 iCustom return Empty value for some buffers but not all

MQL4 iCustom return Empty value for some buffers but not all

Manage alerts

Loading saved threads...

Infinity Cliff · External communityPost link
External question — Stack Overflow Stack Exchange Author: Infinity Cliff Original post: https://stackoverflow.com/questions/79682030 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. I have the following indicator, that compiles and shows the arrows properly when attached to a chart. When I try to use iCustom to get values from the indicator buffers I get the empty value for the buffers that are calculated in the if ( ExtBULLBuffer , ExtBEARBuffer and PatternID ). Note as a test i added the ExtBULLBuffer calc and set it to close price to check. To show what I mean I have added a sample EA below that print out the values on each new bar. Why is it doing this? #property description "Sample indicator that plots ALL Candle Pattern arrows." #property version "1.0" #property strict //---- Indicator drawing and buffers #property indicator_chart_window #property indicator_buffers 6 #property indicator_color1 clrDodgerBlue #property indicator_color2 clrOrange #property indicator_width1 2 #property indicator_width2 2 int ARROW_OFFSET = 30; // Offset of Arrow from price (PIPS) bool ENGULFING = true; // Engulfing Patterns (Bull & Bear) int TREND_PERIOD = 50; // Period to determine up and down trend entering pattern ENUM_MA_METHOD TREND_MA_METHOD = MODE_SMA; // MA method for trend //---- Buffer Arrays double ExtBULLBuffer[]; double ExtBEARBuffer[]; double PatternID[]; double C_Body[]; double C_BodyAvg[]; double C_Price[]; double C_VolAve[]; int pattern_length = 4; int Body_len = 5; string Bull_index_name = "Candle Pattern Bull"; string Bear_index_name = "Candle Pattern Bear"; // Technical Indicator Page 362 Figure 16.29 Figure 16.30 //+------------------------------------------ //| Custom indicator initialization function //+------------------------------------------ int OnInit() { IndicatorShortName("Candle Patterns"); IndicatorDigits(Digits); IndicatorBuffers(6); // First buffer SetIndexBuffer (0, ExtBULLBuffer); // Assign buffer array SetIndexStyle (0, DRAW_ARROW); // Style to arrow SetIndexArrow (0, 233); // Arrow code SetIndexLabel (0, Bull_index_name); SetIndexEmptyValue(0,-1.0); //Second buffer SetIndexBuffer (1, ExtBEARBuffer); // Assign buffer array SetIndexStyle (1, DRAW_ARROW); // Style to arrow SetIndexArrow (1, 234); // Arrow code SetIndexLabel (1, Bear_index_name); SetIndexEmptyValue(1,-1.0); //PatternID Buffer SetIndexBuffer (2, PatternID); // Assign buffer array SetIndexStyle (2, DRAW_NONE); // Style to arrow SetIndexLabel (2, "Pattern ID"); SetIndexEmptyValue(2, 0.0); SetIndexBuffer (3, C_Body); // Assign buffer array SetIndexStyle (3, DRAW_NONE); // Style to arrow SetIndexLabel (3, "C_Body"); SetIndexEmptyValue(3, 0.0); SetIndexBuffer (4, C_BodyAvg); // Assign buffer array SetIndexStyle (4, DRAW_NONE); // Style to arrow SetIndexLabel (4, "C_BodyAvg"); SetIndexEmptyValue(4, 0.0); SetIndexBuffer (5, C_Price); // Assign buffer array SetIndexStyle (5, DRAW_NONE); // Style to arrow SetIndexLabel (5, "C_Price"); SetIndexEmptyValue(5, 0.0); return(0); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int limit = rates_total-prev_calculated-TREND_PERIOD-1; if ( limit < 5 ) limit = 5; int i; i = limit; while ( i >= 0 ) { C_Body[i] = Body(i, open, close); C_BodyAvg[i] = BodyAvg(i, open, close); i--; } i = 0; while ( i <= limit ) { C_Price[i] = close[i]; // Bull Patterns ----------------------------------------------------------------------------------------------- if( EngulfingBull(i, open, low, close) ) { ExtBULLBuffer[i] = low[i+1] - ARROW_OFFSET*Point; PatternID[i] = 1.0; } ExtBULLBuffer[i] = close[i]; // Bear Patterns ----------------------------------------------------------------------------------------------- if( EngulfingBear(i, open, high, close) ) { ExtBEARBuffer[i] = high[i+1] + ARROW_OFFSET*Point; PatternID[i] = -1.0; } i++; } return(rates_total); } bool is_DownTrend(int i, const double &close[]){ return iMA(Symbol(), Period(), TREND_PERIOD, 0, TREND_MA_METHOD, PRICE_CLOSE, i) < iMA(Symbol(), Period(), TREND_PERIOD, 0, TREND_MA_METHOD, PRICE_CLOSE, i+1); } bool is_UpTrend(int i, const double &close[]){ return iMA(Symbol(), Period(), TREND_PERIOD, 0, TREND_MA_METHOD, PRICE_CLOSE, i) > iMA(Symbol(), Period(), TREND_PERIOD, 0, TREND_MA_METHOD, PRICE_CLOSE, i+1); } bool is_Bull(int i, const double &open[], const double &close[]) { return open[i] < close[i]; } bool is_Bear(int i, const double &open[], const double &close[]) { return open[i] > close[i]; } bool is_LongBody(int i, const double &open[], const double &close[]) { return Body(i, open, close) >= BodyAvg(i, open, close); } bool is_SmallBody(int i, const double &open[], const double &close[]) { return Body(i, open, close) <= BodyAvg(i, open, close); } double BodyAvg(int i, const double &open[], const double &close[]) { double sum = 0; int j; for (j=i+1; j<=i+Body_len; j++) sum = sum + MathAbs(open[j] - close[j]); return sum / Body_len; } double Body(int i, const double &open[], const double &close[]) { return MathAbs(open[i] - close[i]); } // ===================================================================================================================== // BULL PATTERNS // ===================================================================================================================== bool EngulfingBull(const int i, const double &open[], const double &low[], const double &close[]) { if ( is_LongBody (i+2, open, close) && // Long, is_Bear (i+2, open, close) && // Bear candle entering is_SmallBody(i+1, open, close) && // Short, is_Bear (i+1, open, close) && // Bear target candle is_LongBody (i, open, close) && // Long, is_Bull (i, open, close) && // Bull candle engulfing target candle is_DownTrend(i, close) && // MA is moving down is_DownTrend(i+1, close) && // MA is moving down is_DownTrend(i+2, close) && // MA is moving down close[i] >= open[i+1] && open[i] <= close[i+1] && (close[i] > open[i+1] || open[i] < close[i+1]) ) { return true; } return false; } // ===================================================================================================================== // BEAR PATTERNS // ===================================================================================================================== bool EngulfingBear(const int i, const double &open[], const double &high[], const double &close[]) { if ( is_LongBody (i+2, open, close) && // Long, is_Bull (i+2, open, close) && // Bull candle entering is_SmallBody(i+1, open, close) && // Short, is_Bull (i+1, open, close) && // Bull target candle is_LongBody (i, open, close) && // Long, is_Bear (i, open, close) && // Bear candle engulfing target candle is_UpTrend (i, close) && // MA is moving up is_UpTrend (i+1, close) && // MA is moving up is_UpTrend (i+2, close) && // MA is moving up close[i] <= open[i+1] && open[i] >= close[i+1] && (close[i] < open[i+1] || open[i] > close[i+1]) ) { return true; } return false; } sample EA #define VERSION "6.0" #property version VERSION #property strict #define CandlePatternIND "Indicators\\Valuta\\CandlePatternsTest.ex4" #resource "\\" + CandlePatternIND input int ARROW_OFFSET = 30; // Offset of Arrow from price (PIPS) input bool ENGULFING = true; // Engulfing Patterns (Bull & Bear) input int TREND_PERIOD = 50; // Period to determine up and down trend entering pattern input ENUM_MA_METHOD TREND_MA_METHOD = MODE_SMA; // MA method for trend datetime NewCandleTime = 0; int OnInit() { return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } bool IsNewBar(){ if (NewCandleTime == iTime(NULL, 0, 0)) { return false;} else { NewCandleTime = iTime(NULL, 0, 0); return true; } } void OnTick() { if(IsNewBar()){ double bull = iCustom(Symbol(), Period(), "::" + CandlePatternIND, 0, 1); double bear = iCustom(Symbol(), Period(), "::" + CandlePatternIND, 1, 1); double id = iCustom(Symbol(), Period(), "::" + CandlePatternIND, 2, 1); double body = iCustom(Symbol(), Period(), "::" + CandlePatternIND, 3, 1); double bodyave = iCustom(Symbol(), Period(), "::" + CandlePatternIND, 4, 1); double pp = iCustom(Symbol(), Period(), "::" + CandlePatternIND, 5, 1); Print("bull buff ", bull); Print("bear buff ", bear); Print("body ", body); Print("bodyave ", bodyave); Print("price ", pp); Print("id ", id); Print("---------------"); } }
Quote
Report
user3666197 · External communityPost link
External answer — Stack Overflow Stack Exchange Author: user3666197 Original post: https://stackoverflow.com/a/79748623 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. Why is it doing this? Because computers are ( nothing but dumb, yet fast, my father used to tell me ) finite-state-automatons and the code was not instructing to do anything else but these very things, was it? Let's review the nest of problems -- Our Working Plan : let's make the code work without #resource after (1) works, let's try to decode MQL4 (as-is, EoL-product, Builds used to creep ( dramatically ( may find earlier posts about " New -MQL4" nightmares in production, the more be aware of this) For the sake of (1), let's re-factor and polish futher the Expert Advisor side : /* MQL4 Expert Advisor code --------------------------------------------// https://stackoverflow.com/questions/79682030/mql4-icustom-return-empty-value-for-some-buffers-but-not-all */ #define VERSION "6.0" #property version VERSION #property strict int OnInit() { return( INIT_SUCCEEDED ); } void OnDeinit(const int reason) {} Next get this extended with inputs : /* INPUTs ----------------------------------------------------// INPUTs for Custom Indicator input int ARROW_OFFSET = 30; // Offset of Arrow from price (PIPS) input bool ENGULFING = true; // Engulfing Patterns (Bull & Bear) input int TREND_PERIOD = 50; // Period to determine up and down trend entering pattern input ENUM_MA_METHOD TREND_MA_METHOD = MODE_SMA; // MA method for trend Next get this extended with actually passing these inputs via iCustom() -call signatures, as were defined inside ( original ) Custom indicator source code : void PrintREPORTER() { #define MQL4_Indicator_file_name "Valuta\\CandlePatternsTest" // relative to iCustom()-referenced default location <terminal_dir>/MQL4/Indicators #define _Current_Symbol NULL #define _Current_TimeFrame 0 #define Candle_Pattern_BULL 0 #define Candle_Pattern_BEAR 1 #define Candle_Pattern_ID 2 #define Candle_Pattern_BODY 3 #define Candle_Pattern_BODY_AVG 4 #define Candle_Pattern_PRICE 5 Print("bull buff ", iCustom( _Current_Symbol, // 1 _Current_TimeFrame, // 2 MQL4_Indicator_file_name, // 3 /* ---iCustom()-VARIADIC-SECTION--------- // Custom Indicator specified INPUTs, passed down the line per-call */ ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, /* ---iCustom()-------------------------------------- tail context Candle_Pattern_BULL, // -2 BufferIndex# 1 // -1 bar-offset from [0] ) ); Print("bear buff ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_BEAR, 1) ); Print("body ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_BODY, 1) ); Print("bodyave ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_BODY_AVG, 1) ); Print("price ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_PRICE, 1) ); Print("id ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_ID, 1) ); Print("---------------"); } Next make the Expert process a New Bar Event using a minimalistic OnTick() handler : void OnTick() { if( IsNewBar() ) PrintREPORTER(); } bool IsNewBar() { static int _lastFxTick_iTime = -1; if ( _lastFxTick_iTime == iTime(NULL, 0, 0) ) { return false;} else { _lastFxTick_iTime = iTime(NULL, 0, 0); return true; } } Supposing all the above works as expected, it starts to make sense to turn attention into "baking-in" the well working, RTO-state of the Custom Indicator .EX4, as a " resource ". Forcing MQL4 compiler pre-processor to do this before everything else works is bad idea. Now, given (1) was completed, #resource directive might help "pack"-Custom-Indicator-as-a-resource into Expert Advisor EX4-file. MQL4 documentation is kind-of helping in doing that right, yet we have to admit, the text is not readable or easy to understand, what will work without pain, so be patient and re-read the section " Working with custom indicators included as resources " : "(...)Inclusion of indicators as resources simplifies the distribution of applications. Below is an example of including and using SampleIndicator.ex4 custom indicator located in terminal_data_folder\MQL4\Indicators\ directory(...)" There notice the syntax, used in compiler pre-processor directive #resource "\\Indicators\\SampleIndicator.ex4" ( no expression attempts or other tricks here ) There also notice the syntax, used inside the iCustom() -call signature, denoting by added " :: " in a classical string "::Indicators\\SampleIndicator.ex4" that this call shall resort to a pre-processor, compile-time pre-baked, #resource without trying to find some file ( not distributed ) on target system MT4-Terminal sandbox-filesystem. #define MQL4_Indicator_rsrc_name "::Indicators\\Valuta\\CandlePatternsTest.mq4" // meets https://docs.mql4.com/runtime/resources If we stay within MQL4-documented features, the compiled results ought work as documented, just by swapping the finally #defined symbol MQL4_Indicator_rsrc_name in place of the so far used MQL4_Indicator_file_name symbol.
Quote
Report

Post Reply

Quoted from Forex.com.bd-Editorial External answer — Stack Overflow Stack Exchange Author: user3666197 Source score (net votes, not local likes): 0 Original post: https://stackoverflow.com/a/79748623 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. Why is it doing this? Because computers are ( nothing but dumb, yet fast, my father used to tell me ) finite-state-automatons and the code was not instructing to do anything else but these very things, was it? Let's review the nest of problems -- Our Working Plan : let's make the code work without #resource after (1) works, let's try to decode MQL4 (as-is, EoL-product, Builds used to creep ( dramatically ( may find earlier posts about " New -MQL4" nightmares in production, the more be aware of this) For the sake of (1), let's re-factor and polish futher the Expert Advisor side : /* MQL4 Expert Advisor code --------------------------------------------// https://stackoverflow.com/questions/79682030/mql4-icustom-return-empty-value-for-some-buffers-but-not-all */ #define VERSION "6.0" #property version VERSION #property strict int OnInit() { return( INIT_SUCCEEDED ); } void OnDeinit(const int reason) {} Next get this extended with inputs : /* INPUTs ----------------------------------------------------// INPUTs for Custom Indicator input int ARROW_OFFSET = 30; // Offset of Arrow from price (PIPS) input bool ENGULFING = true; // Engulfing Patterns (Bull & Bear) input int TREND_PERIOD = 50; // Period to determine up and down trend entering pattern input ENUM_MA_METHOD TREND_MA_METHOD = MODE_SMA; // MA method for trend Next get this extended with actually passing these inputs via iCustom() -call signatures, as were defined inside ( original ) Custom indicator source code : void PrintREPORTER() { #define MQL4_Indicator_file_name "Valuta\\CandlePatternsTest" // relative to iCustom()-referenced default location <terminal_dir>/MQL4/Indicators #define _Current_Symbol NULL #define _Current_TimeFrame 0 #define Candle_Pattern_BULL 0 #define Candle_Pattern_BEAR 1 #define Candle_Pattern_ID 2 #define Candle_Pattern_BODY 3 #define Candle_Pattern_BODY_AVG 4 #define Candle_Pattern_PRICE 5 Print("bull buff ", iCustom( _Current_Symbol, // 1 _Current_TimeFrame, // 2 MQL4_Indicator_file_name, // 3 /* ---iCustom()-VARIADIC-SECTION--------- // Custom Indicator specified INPUTs, passed down the line per-call */ ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, /* ---iCustom()-------------------------------------- tail context Candle_Pattern_BULL, // -2 BufferIndex# 1 // -1 bar-offset from [0] ) ); Print("bear buff ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_BEAR, 1) ); Print("body ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_BODY, 1) ); Print("bodyave ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_BODY_AVG, 1) ); Print("price ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_PRICE, 1) ); Print("id ", iCustom( _Current_Symbol, _Current_TimeFrame, MQL4_Indicator_file_name, ARROW_OFFSET, ENGULFING, TREND_PERIOD, TREND_MA_METHOD, Candle_Pattern_ID, 1) ); Print("---------------"); } Next make the Expert process a New Bar Event using a minimalistic OnTick() handler : void OnTick() { if( IsNewBar() ) PrintREPORTER(); } bool IsNewBar() { static int _lastFxTick_iTime = -1; if ( _lastFxTick_iTime == iTime(NULL, 0, 0) ) { return false;} else { _lastFxTick_iTime = iTime(NULL, 0, 0); return true; } } Supposing all the above works as expected, it starts to make sense to turn attention into "baking-in" the well working, RTO-state of the Custom Indicator .EX4, as a " resource ". Forcing MQL4 compiler pre-processor to do this before everything else works is bad idea. Now, given (1) was completed, #resource directive might help "pack"-Custom-Indicator-as-a-resource into Expert Advisor EX4-file. MQL4 documentation is kind-of helping in doing that right, yet we have to admit, the text is not readable or easy to understand, what will work without pain, so be patient and re-read the section " Working with custom indicators included as resources " : "(...)Inclusion of indicators as resources simplifies the distribution of applications. Below is an example of including and using SampleIndicator.ex4 custom indicator located in terminal_data_folder\MQL4\Indicators\ directory(...)" There notice the syntax, used in compiler pre-processor directive #resource "\\Indicators\\SampleIndicator.ex4" ( no expression attempts or other tricks here ) There also notice the syntax, used inside the iCustom() -call signature, denoting by added " :: " in a classical string "::Indicators\\SampleIndicator.ex4" that this call shall resort to a pre-processor, compile-time pre-baked, #resource without trying to find some file ( not distributed ) on target system MT4-Terminal sandbox-filesystem. #define MQL4_Indicator_rsrc_name "::Indicators\\Valuta\\CandlePatternsTest.mq4" // meets https://docs.mql4.com/runtime/resources If we stay within MQL4-documented features, the compiled results ought work as documented, just by swapping the finally #defined symbol MQL4_Indicator_rsrc_name in place of the so far used MQL4_Indicator_file_name symbol.

Cancel quote

Checking account access…