OnCalculate

From binaryoption
Jump to navigation Jump to search
Баннер1
  1. OnCalculate – A Comprehensive Guide for Beginners

OnCalculate is a powerful and versatile function within the MetaQuotes Language 4 (MQL4) and MetaQuotes Language 5 (MQL5) used extensively in custom indicators and Expert Advisors (EAs) for the MetaTrader platforms. It’s a function that allows you to perform calculations *on each tick* of the market, providing real-time data processing capabilities crucial for dynamic trading strategies. This article provides a detailed, beginner-friendly explanation of OnCalculate, its uses, parameters, best practices, and common pitfalls. It's geared towards individuals new to MQL programming and looking to understand this fundamental component of algorithmic trading.

What is OnCalculate?

At its core, the `OnCalculate` function is an event handler. In MQL4/MQL5, event handlers are special functions that are automatically called by the MetaTrader platform when specific events occur. In this case, `OnCalculate` is triggered whenever a new tick arrives – a new price update – for the financial instrument the indicator or EA is attached to.

Unlike the `OnInit()` function which runs only once when the indicator/EA is initialized, or the `OnDeinit()` function which runs only once when the indicator/EA is removed, `OnCalculate` runs *repeatedly* throughout the lifespan of the indicator/EA, processing each new price change. This makes it the ideal place to perform calculations that require up-to-date market data.

Think of it like a continuously running loop that is activated by incoming price data. Inside the `OnCalculate` function, you write the code that performs the necessary computations based on this new data, updating indicator buffers, variables, or triggering trading signals.

Syntax and Parameters

The syntax of the `OnCalculate` function varies slightly between MQL4 and MQL5, but the underlying concept remains the same.

MQL4 Syntax:

```mql4 void 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 double spread[],
                 const double bid[],
                 const double ask[])

```

MQL5 Syntax:

```mql5 void OnCalculate(const int rates_total,

                 const int prev_calculated,
                 const MqlTick &tick)

```

Let's break down the parameters:

  • `rates_total`: This integer represents the total number of bars (candles) available in the chart's history. It's a useful parameter for iterating through historical data if your calculations require it.
  • `prev_calculated`: This integer indicates the index of the first bar that *has already been calculated* in the previous call to `OnCalculate`. This is a crucial optimization parameter. You should only recalculate values for bars *after* `prev_calculated`. Recalculating previously calculated values is redundant and wastes processing power. Understanding this parameter is key to writing efficient code.
  • `time[]`: (MQL4 only) An array of datetime values representing the time of each bar.
  • `open[]`: (MQL4 only) An array of double values representing the opening price of each bar.
  • `high[]`: (MQL4 only) An array of double values representing the highest price of each bar.
  • `low[]`: (MQL4 only) An array of double values representing the lowest price of each bar.
  • `close[]`: (MQL4 only) An array of double values representing the closing price of each bar.
  • `tick_volume[]`: (MQL4 only) An array of long values representing the tick volume of each bar.
  • `spread[]`: (MQL4 only) An array of double values representing the spread of each bar.
  • `bid[]`: (MQL4 only) An array of double values representing the bid price of each bar.
  • `ask[]`: (MQL4 only) An array of double values representing the ask price of each bar.
  • `tick`: (MQL5 only) A structure of type `MqlTick` containing information about the current tick, including its time, price (bid and ask), volume, and flags. MQL5 simplifies data access significantly.

The key difference between MQL4 and MQL5 is how price data is passed. MQL4 uses arrays for historical data, while MQL5 uses the `MqlTick` structure for the current tick. For historical data in MQL5 you’d typically use `iClose()`, `iHigh()`, etc. functions instead of relying on the `OnCalculate` parameters for historical data access.

Common Use Cases

`OnCalculate` is the workhorse of many indicators and EAs. Here are some common applications:

  • **Calculating Moving Averages:** Moving averages, like the SMA or EMA, are fundamental technical indicators. `OnCalculate` is used to update these averages with each new tick, providing a smooth representation of price trends.
  • **Determining RSI and Stochastic Levels:** The RSI and Stochastic Oscillator are momentum indicators that require continuous calculation based on price data. `OnCalculate` allows for real-time updates of these indicators.
  • **Detecting Candlestick Patterns:** Identifying patterns like Doji, Engulfing Patterns, or Hammer requires analyzing the relationship between open, high, low, and close prices. `OnCalculate` provides access to this data on each tick.
  • **Implementing Trading Strategies:** EAs often use `OnCalculate` to evaluate trading conditions based on various indicators or price patterns. If the conditions are met, the EA can then execute trades. A common strategy involves using a combination of MACD and Bollinger Bands.
  • **Alerting Systems:** `OnCalculate` can be used to monitor price levels or indicator values and trigger alerts when specific conditions are met.
  • **Volume Analysis:** Analyzing OBV and other volume-based indicators relies heavily on tick-by-tick data processing within `OnCalculate`.
  • **Volatility Calculation:** Indicators like ATR and Standard Deviation require continuous calculation of price volatility.

Example: Simple Moving Average (SMA) in MQL4

```mql4

  1. property indicator_chart_window

double sma_value; int sma_period = 20;

int OnInit()

 {
  SetIndexBuffer(0, sma_value);
  IndicatorBuffers(1);
  SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 2, clrBlue);
  return(INIT_SUCCEEDED);
 }

void 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 double spread[],
                 const double bid[],
                 const double ask[])
 {
  double sum = 0.0;
  for(int i = prev_calculated; i < rates_total; i++)
    {
     sum += close[i];
    }
  sma_value = sum / sma_period;
  PlotIndex(0, 0, sma_value);
 }

```

This simple example calculates a 20-period SMA. Notice how it only iterates from `prev_calculated` to `rates_total`, optimizing the calculation. The `PlotIndex` function then displays the SMA value on the chart.

Example: Simple Moving Average (SMA) in MQL5

```mql5

  1. property indicator_chart_window

double sma_value; int sma_period = 20;

int OnInit()

 {
  SetIndexBuffer(0, sma_value);
  IndicatorBuffers(1);
  SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 2, clrBlue);
  return(INIT_SUCCEEDED);
 }

void OnCalculate(const int rates_total,

                 const int prev_calculated,
                 const MqlTick &tick)
 {
  double sum = 0.0;
  for(int i = prev_calculated; i < rates_total; i++)
    {
     sum += iClose(Symbol(), PERIOD_CURRENT, i);
    }
  sma_value = sum / sma_period;
  PlotIndex(0, 0, sma_value);
 }

```

This MQL5 example achieves the same result, but utilizes the `iClose()` function to access historical closing prices. The `MqlTick` parameter provides current tick data, but isn’t directly used in this SMA calculation.

Best Practices and Optimization

  • **Use `prev_calculated`:** This is *the* most important optimization. Always start your calculations from `prev_calculated` to avoid redundant work.
  • **Minimize Calculations:** Only perform the calculations that are absolutely necessary. Avoid complex operations if simpler ones will suffice.
  • **Use Local Variables:** Declare variables locally within the `OnCalculate` function to reduce memory usage.
  • **Avoid Global Variables (Where Possible):** While sometimes unavoidable, excessive use of global variables can slow down execution.
  • **Optimize Array Access:** Accessing array elements can be time-consuming. Try to minimize the number of array accesses.
  • **Consider Buffering:** For complex calculations, consider buffering intermediate results to avoid recalculating them repeatedly.
  • **Profiling:** Use the MetaTrader Strategy Tester's profiling tools to identify performance bottlenecks in your code.
  • **Use Fixed-Point Arithmetic (Carefully):** In specific scenarios, fixed-point arithmetic can be faster than floating-point arithmetic, but it requires careful consideration of precision and potential errors.
  • **Understand Market Data Frequency:** Be aware that the frequency of ticks can vary significantly depending on the broker and the financial instrument. Don’t assume every tick represents a significant price change.
  • **Implement Error Handling:** Include checks for potential errors, such as invalid data or unexpected conditions.

Common Pitfalls

  • **Ignoring `prev_calculated`:** This leads to significant performance degradation.
  • **Performing Calculations on Every Tick:** Not all calculations need to be done on every tick. Consider performing calculations less frequently if the data doesn't change significantly.
  • **Excessive Use of Global Variables:** This can lead to memory leaks and performance issues.
  • **Incorrect Data Types:** Using the wrong data types can lead to precision errors or unexpected behavior.
  • **Division by Zero:** Always check for potential division by zero errors.
  • **Array Out-of-Bounds Access:** Ensure that your array indices are within the valid range.
  • **Not Handling Exceptions:** Failing to handle exceptions can cause your indicator or EA to crash.
  • **Over-Optimization:** While optimization is important, over-optimization can make your code difficult to understand and maintain. Prioritize readability and maintainability.
  • **Assuming Constant Tick Data:** Tick data is not always consistent or reliable. Account for potential gaps or errors in the data. Consider using Heikin Ashi to smooth out noise.

Advanced Concepts

  • **Indicator Buffers:** `OnCalculate` is often used to update indicator buffers, which are arrays of data that are displayed on the chart. Understanding how to work with indicator buffers is crucial for creating custom indicators.
  • **Event Context:** The `OnCalculate` function is executed within a specific event context. This context provides access to various functions and variables that can be used to interact with the MetaTrader platform.
  • **Multi-Timeframe Analysis:** You can use `OnCalculate` in conjunction with other MQL functions to perform multi-timeframe analysis, allowing you to analyze price data from multiple timeframes simultaneously. This is often used in Renko and Keltner Channels strategies.
  • **Order Modification and Trading:** Within an EA, `OnCalculate` can trigger functions to modify existing orders or place new trades based on real-time market conditions, employing strategies like Martingale or Grid Trading.
  • **Correlation Analysis:** By calculating correlations between different assets within `OnCalculate`, you can identify potential trading opportunities based on Pairs Trading strategies.

Understanding `OnCalculate` is fundamental to mastering MQL4/MQL5 programming and building sophisticated trading tools. By following the best practices and avoiding common pitfalls outlined in this article, you can create efficient and reliable indicators and EAs that can help you achieve your trading goals. Remember to always test your code thoroughly before deploying it in a live trading environment. Consider researching Ichimoku Cloud and Fibonacci Retracements as indicators often implemented using `OnCalculate`.


MQL4 Reference MQL5 Reference Expert Advisor Custom Indicator Strategy Tester MetaTrader 4 MetaTrader 5 iClose iHigh iLow iOpen



Start Trading Now

Sign up at IQ Option (Minimum deposit $10) Open an account at Pocket Option (Minimum deposit $5)

Join Our Community

Subscribe to our Telegram channel @strategybin to receive: ✓ Daily trading signals ✓ Exclusive strategy analysis ✓ Market trend alerts ✓ Educational materials for beginners

Баннер