I am building a Indicator to look at Tick Imbalances. However, sometimes the indicator works while other times it crashes the terminal. I have narrowed down the issue to be the call to CopyTick calls. More specifically this function
Code:
tick_candle is a very basic struct to calculate the imbalances and datetime_to_msc merely converts the datetime to get milliseconds. TICKS_AT_A_TIME is a constant that looks at how many ticks to read a time. Currently that value is 30. The Timeframe that I ran this function/indicator on was the M1 timeframe.
Impossible to be sure without the full context of this function call.
My guess is for an endless loop.
Impossible to be sure without the full context of this function call.
My guess is for an endless loop.
Full Code (All Headers were collapsed into this one paste so sorry for length)
//+---------------------------------------------------------------------+ //| OrderFlowImbalance.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+---------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_LINE #property indicator_color1 Yellow #property indicator_label1 "Imbalance Ratio" #define TICKS_AT_A_TIME 30 #define MILLISECONDS_IN_SECOND 1000 void handle_possible_errors(const ulong from, const int ticks_found){ if(ticks_found < 0){ datetime from_dt = msc_to_datetime(from); PrintFormat("Found an error: %d for %s", _LastError, TimeToString(from_dt)); } } ulong datetime_to_msc(const datetime dt){ return ((ulong) dt) * MILLISECONDS_IN_SECOND; } datetime msc_to_datetime(const ulong dt_msc){ return (datetime) (dt_msc/MILLISECONDS_IN_SECOND); } struct tick_candle{ double buy_ticks; double sell_ticks; tick_candle() : buy_ticks(0.0), sell_ticks(0.0){} double get_imbalance(){ return this.buy_ticks + this.sell_ticks > 0.0 ? (this.buy_ticks - this.sell_ticks)/(this.buy_ticks + this.sell_ticks) : 0.0; } void update_ticks(const MqlTick& ticks [], const double previous_bid, const int num_of_ticks){ if(previous_bid > 0.0){ this.buy_ticks += int(ticks[0].bid > previous_bid); this.sell_ticks += int(ticks[0].bid < previous_bid); } for(int i = 1; i < num_of_ticks; i++){ bool up_tick; bool down_tick; up_tick = ticks[i].bid > ticks[i - 1].bid; down_tick = ticks[i].bid < ticks[i - 1].bid; this.buy_ticks += double(int(up_tick)); this.sell_ticks += double(int(down_tick)); } } }; int get_ticks(const datetime from, const datetime to, MqlTick& result [], tick_candle& imbalance_struct){ ulong curr_msc= datetime_to_msc(from); ulong to_msc = datetime_to_msc(to); int ticks_received = 0; int total_ticks_received = 0; ticks_received = CopyTicks(_Symbol, result, COPY_TICKS_INFO, curr_msc, TICKS_AT_A_TIME); handle_possible_errors(curr_msc, ticks_received); while(ticks_received > 0 && curr_msc < to_msc){ //PrintFormat("Array Size Pre-Receive: %d", ArraySize(result)); //PrintFormat("Ticks Received: %d, Array Size: %d", ticks_received, ArraySize(result)); curr_msc = fmin(result[ticks_received - 1].time_msc + 1, datetime_to_msc(TimeCurrent()) - 1); double previous_bid = result[ticks_received - 1].bid * int(total_ticks_received > 0); imbalance_struct.update_ticks(result, previous_bid, ticks_received); total_ticks_received+= ticks_received; ticks_received = CopyTicks(_Symbol, result, COPY_TICKS_INFO, curr_msc, TICKS_AT_A_TIME); handle_possible_errors(curr_msc, ticks_received); } return total_ticks_received; } double get_tick_imbalance(const MqlTick& ticks [], const double previous_bid, const int num_of_ticks, tick_candle& imbalance_struct){ for(int i = 1; i < num_of_ticks; i++){ bool up_tick; bool down_tick; /* if(i == 0){ up_tick = ticks[i].bid > previous_bid; down_tick = ticks[i].bid < previous_bid; } else{ up_tick = ticks[i].bid > ticks[i - 1].bid; down_tick = ticks[i].bid < ticks[i - 1].bid; } */ up_tick = ticks[i].bid > ticks[i - 1].bid; down_tick = ticks[i].bid < ticks[i - 1].bid; imbalance_struct.buy_ticks += double(int(up_tick)); imbalance_struct.sell_ticks += double(int(down_tick)); } return imbalance_struct.get_imbalance(); } double candle_imbalance_buffer []; double last_bid; MqlTick curr_ticks [TICKS_AT_A_TIME]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, candle_imbalance_buffer, INDICATOR_DATA); // Setting Precision IndicatorSetInteger(INDICATOR_DIGITS, 3); PlotIndexGetInteger(0, PLOT_DRAW_BEGIN, 1); IndicatorSetString(INDICATOR_SHORTNAME, "OrderFlowImbalance"); /* //--- set drawing line empty value PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); */ PlotIndexSetString(0, PLOT_LABEL, "OrderFlowImbalance"); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- if(rates_total < 2){ return 0; } int start, i; int ticks_received = 0; tick_candle imbalance_struct; if(prev_calculated == 0){ //Print(":D "); i = 1; do{ ticks_received = get_ticks(time[i - 1], time[i], curr_ticks, imbalance_struct); i++; }while(ticks_received <= 0 && i < rates_total); if(ticks_received <= 0){ Print("No Ticks Found"); return 0; } else{ Print("Got First Set of Ticks"); } ZeroMemory(imbalance_struct); start = i + 1; } else{ //Print(":( "); start = prev_calculated - 1; } for(i = start; i < rates_total && !IsStopped(); i++){ if(i == rates_total - 2){ Print("Pretty Much Done"); } if(i == rates_total - 1){ candle_imbalance_buffer[i] = 0.0; continue; } ticks_received = get_ticks(time[i - 1], time[i], curr_ticks, imbalance_struct); if(ticks_received <= 0){ candle_imbalance_buffer[i] = 0.0; continue; } candle_imbalance_buffer[i] = imbalance_struct.get_imbalance(); ZeroMemory(curr_ticks); ZeroMemory(imbalance_struct); } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am building a Indicator to look at Tick Imbalances. However, sometimes the indicator works while other times it crashes the terminal. I have narrowed down the issue to be the call to CopyTick calls. More specifically this function
Code:
tick_candle is a very basic struct to calculate the imbalances and datetime_to_msc merely converts the datetime to get milliseconds. TICKS_AT_A_TIME is a constant that looks at how many ticks to read a time. Currently that value is 30. The Timeframe that I ran this function/indicator on was the M1 timeframe.