Okay, here's a breakdown of what the provided MetaTrader script does, explained in a way that's easy to understand for someone who doesn't code:
Overall Purpose:
The script is designed to generate trading signals (buy or sell recommendations) based on patterns it detects in price charts. It does this by using a combination of two other "helper" indicators. It then draws arrows on the chart to visually represent these buy or sell signals.
Key Components and How They Work Together:
-
Visual Display: The script draws arrows directly on the price chart. Green arrows point upwards, suggesting a "buy" signal. Magenta (pink) arrows point downwards, suggesting a "sell" signal. The thickness of these arrows can be adjusted.
-
Helper Indicators: The script relies on another custom indicator named "2pbIdeal1MA". Critically, it uses two instances of this indicator, one analyzing the "open" price of each candle (the price at the start of the trading period) and the other analyzing the "close" price (the price at the end of the trading period). It also uses the standard ATR indicator, also called Average True Range, to measure the volatility of a financial asset.
-
Input Parameters: The script has adjustable settings that the user can change:
Period1
andPeriod2
: These are numbers that control how the "2pbIdeal1MA" indicator calculates its averages. Higher numbers mean the indicator looks at a wider range of past prices, which can smooth out the signal.
-
Initialization: When the script starts, it does the following:
-
Gets Handles: It "finds" and connects to the two instances of the "2pbIdeal1MA" indicator and ATR. It needs these connections (called "handles") to get data from them. If it can't find these indicators, it stops and displays an error message.
-
Sets Up Arrays: It creates special "arrays" (think of them as lists of numbers) to store the buy and sell signals. These arrays are directly linked to the arrows it will draw on the chart.
-
Configures the Chart: It sets up how the arrows will look (color, shape, etc.) and what values should be considered "empty" (meaning no arrow should be drawn).
-
-
Calculation Loop: The script constantly runs a calculation loop to check for new price data and update the signals. Here's the logic:
-
Checks for Enough Data: It makes sure it has enough price history to perform its calculations.
-
Copies Data: It copies the latest data from the two "2pbIdeal1MA" indicators into its own arrays, also the ATR indicator is copyed.
-
Signal Generation: This is the core logic:
- The script loops through each price bar (candle) on the chart.
- For each bar, it checks the values of "2pbIdeal1MA" using "open" and "close" prices from the helper indicators.
- If the "2pbIdeal1MA" indicator using the "open" price indicated a decrease from the last candle to this candle, and the "2pbIdeal1MA" indicator using the "close" price indicated an increase, a buy signal is generated. This is shown by an arrow appearing under the candle. It uses the low price of the candle minus some ATR volatility measure to determine the arrow location.
- If the "2pbIdeal1MA" indicator using the "open" price indicated an increase from the last candle to this candle, and the "2pbIdeal1MA" indicator using the "close" price indicated a decrease, a sell signal is generated. This is shown by an arrow appearing above the candle. It uses the high price of the candle plus some ATR volatility measure to determine the arrow location.
-
In Simple Terms:
Imagine you have two separate weather forecasters ("2pbIdeal1MA" indicators). One focuses on morning temperatures (open price), and the other focuses on evening temperatures (close price). This script looks for situations where the morning temperature was decreasing and the evening temperature was increasing. This pattern triggers a "buy" signal. The opposite pattern (morning temperature increasing, evening temperature decreasing) triggers a "sell" signal. Then it adds some volatility to determine the final location of those signals on the screen. The arrows on the chart are like flags telling you when these patterns occur. The user can configure the weather forecasters by changing their "period" settings.
Important Note: This is just an explanation of what the script does. It doesn't guarantee that the signals generated will be profitable or accurate. Trading always involves risk.
//+------------------------------------------------------------------+
//| 2pbIdeal1MACandleSign.mq5 |
//| Copyright © 2015, Nikolay Kositsin |
//| Khabarovsk, farria@mail.redcom.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
#property description "Ñåìàôîðíûé ñèãíàëüíûé èíäèêàòîð ñ èñïîëüçîâàíèåì äâóõ èíäèêàòîðîâ 2pbIdeal1MA, ïîñòðîåííûõ íà Open è Close çíà÷åíèÿõ öåíîâîãî ðÿäà"
//---- íîìåð âåðñèè èíäèêàòîðà
#property version "1.00"
//--- îòðèñîâêà èíäèêàòîðà â ãëàâíîì îêíå
#property indicator_chart_window
//--- äëÿ ðàñ÷åòà è îòðèñîâêè èíäèêàòîðà èñïîëüçîâàíî äâà áóôåðà
#property indicator_buffers 2
//--- èñïîëüçîâàíî âñåãî äâà ãðàôè÷åñêèõ ïîñòðîåíèÿ
#property indicator_plots 2
//+----------------------------------------------+
//| Ïàðàìåòðû îòðèñîâêè ìåäâåæüåãî èíäèêàòîðà |
//+----------------------------------------------+
//--- îòðèñîâêà èíäèêàòîðà 1 â âèäå ñèìâîëà
#property indicator_type1 DRAW_ARROW
//--- â êà÷åñòâå öâåòà ìåäâåæüåé ëèíèè èíäèêàòîðà èñïîëüçîâàí ðîçîâûé öâåò
#property indicator_color1 clrMagenta
//--- òîëùèíà ëèíèè èíäèêàòîðà 1 ðàâíà 2
#property indicator_width1 2
//--- îòîáðàæåíèå ìåäâåæüåé ìåòêè èíäèêàòîðà
#property indicator_label1 "2pbIdeal1MACandle Sell"
//+----------------------------------------------+
//| Ïàðàìåòðû îòðèñîâêè áû÷üåãî èíäèêàòîðà |
//+----------------------------------------------+
//--- îòðèñîâêà èíäèêàòîðà 2 â âèäå ñèìâîëà
#property indicator_type2 DRAW_ARROW
//--- â êà÷åñòâå öâåòà áû÷üåé ëèíèè èíäèêàòîðà èñïîëüçîâàí çåëåíûé öâåò
#property indicator_color2 clrGreen
//--- òîëùèíà ëèíèè èíäèêàòîðà 2 ðàâíà 2
#property indicator_width2 2
//--- îòîáðàæåíèå áû÷üåé ìåòêè èíäèêàòîðà
#property indicator_label2 "2pbIdeal1MACandle Buy"
//+----------------------------------------------+
//| Îáúÿâëåíèå êîíñòàíò |
//+----------------------------------------------+
#define RESET 0 // êîíñòàíòà äëÿ âîçâðàòà òåðìèíàëó êîìàíäû íà ïåðåñ÷åò èíäèêàòîðà
//+----------------------------------------------+
//| Âõîäíûå ïàðàìåòðû èíäèêàòîðà |
//+----------------------------------------------+
input uint Period1 = 10; // Ãðóáîå óñðåäíåíèå
input uint Period2 = 10; // Óòî÷íÿþùåå óñðåäíåíèå
//+----------------------------------------------+
//--- îáúÿâëåíèå äèíàìè÷åñêèõ ìàññèâîâ, êîòîðûå â äàëüíåéøåì
//--- áóäóò èñïîëüçîâàíû â êà÷åñòâå èíäèêàòîðíûõ áóôåðîâ
double SellBuffer[];
double BuyBuffer[];
//---- îáúÿâëåíèå öåëî÷èñëåííûõ ïåðåìåííûõ íà÷àëà îòñ÷åòà äàííûõ
int min_rates_total;
//---- îáúÿâëåíèå öåëî÷èñëåííûõ ïåðåìåííûõ äëÿ õåíäëîâ èíäèêàòîðîâ
int O_Handle,C_Handle,ATR_Handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---- èíèöèàëèçàöèÿ ãëîáàëüíûõ ïåðåìåííûõ
min_rates_total=2+1;
int ATR_Period=15;
min_rates_total=int(MathMax(min_rates_total,ATR_Period))+1;
//--- ïîëó÷åíèå õåíäëà èíäèêàòîðà ATR
ATR_Handle=iATR(NULL,0,ATR_Period);
if(ATR_Handle==INVALID_HANDLE)
{
Print(" Íå óäàëîñü ïîëó÷èòü õåíäë èíäèêàòîðà ATR");
return(INIT_FAILED);
}
//---- ïîëó÷åíèå õåíäëîâ èíäèêàòîðà 2pbIdeal1MA
O_Handle=iCustom(NULL,0,"2pbIdeal1MA",Period1,Period2,0,PRICE_OPEN);
if(O_Handle==INVALID_HANDLE)
{
Print(" Íå óäàëîñü ïîëó÷èòü õåíäë èíäèêàòîðà i2pbIdeal1MA[OPEN]!");
return(INIT_FAILED);
}
C_Handle=iCustom(NULL,0,"2pbIdeal1MA",Period1,Period2,0,PRICE_CLOSE);
if(C_Handle==INVALID_HANDLE)
{
Print(" Íå óäàëîñü ïîëó÷èòü õåíäë èíäèêàòîðà i2pbIdeal1MA[CLOSE]!");
return(INIT_FAILED);
}
//--- ïðåâðàùåíèå äèíàìè÷åñêîãî ìàññèâà â èíäèêàòîðíûé áóôåð
SetIndexBuffer(0,SellBuffer,INDICATOR_DATA);
//--- îñóùåñòâëåíèå ñäâèãà íà÷àëà îòñ÷åòà îòðèñîâêè èíäèêàòîðà 1
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
//--- ñèìâîë äëÿ èíäèêàòîðà
PlotIndexSetInteger(0,PLOT_ARROW,172);
//---- óñòàíîâêà çíà÷åíèé èíäèêàòîðà, êîòîðûå íå áóäóò âèäèìû íà ãðàôèêå
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//--- èíäåêñàöèÿ ýëåìåíòîâ â áóôåðå êàê â òàéìñåðèè
ArraySetAsSeries(SellBuffer,true);
//--- ïðåâðàùåíèå äèíàìè÷åñêîãî ìàññèâà â èíäèêàòîðíûé áóôåð
SetIndexBuffer(1,BuyBuffer,INDICATOR_DATA);
//--- îñóùåñòâëåíèå ñäâèãà íà÷àëà îòñ÷åòà îòðèñîâêè èíäèêàòîðà 2
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total);
//--- ñèìâîë äëÿ èíäèêàòîðà
PlotIndexSetInteger(1,PLOT_ARROW,172);
//---- óñòàíîâêà çíà÷åíèé èíäèêàòîðà, êîòîðûå íå áóäóò âèäèìû íà ãðàôèêå
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
//--- èíäåêñàöèÿ ýëåìåíòîâ â áóôåðå êàê â òàéìñåðèè
ArraySetAsSeries(BuyBuffer,true);
//--- óñòàíîâêà ôîðìàòà òî÷íîñòè îòîáðàæåíèÿ èíäèêàòîðà
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- èìÿ äëÿ îêîí äàííûõ è ìåòêà äëÿ ñóáúîêîí
string short_name="2pbIdeal1MACandle";
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- çàâåðøåíèå èíèöèàëèçàöèè
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(BarsCalculated(O_Handle)<rates_total
|| BarsCalculated(C_Handle)<rates_total
|| BarsCalculated(ATR_Handle)<rates_total
|| rates_total<min_rates_total)
return(RESET);
//---- îáúÿâëåíèå ëîêàëüíûõ ïåðåìåííûõ
int to_copy,limit,bar;
double ATR[],FOpen[],FClose[];
//---- ðàñ÷åòû íåîáõîäèìîãî êîëè÷åñòâà êîïèðóåìûõ äàííûõ è ñòàðòîâîãî íîìåðà limit äëÿ öèêëà ïåðåñ÷åòà áàðîâ
if(prev_calculated>rates_total || prev_calculated<=0)// ïðîâåðêà íà ïåðâûé ñòàðò ðàñ÷åòà èíäèêàòîðà
{
limit=rates_total-2; // ñòàðòîâûé íîìåð äëÿ ðàñ÷åòà âñåõ áàðîâ
}
else
{
limit=rates_total-prev_calculated; // ñòàðòîâûé íîìåð äëÿ ðàñ÷åòà íîâûõ áàðîâ
}
//----
to_copy=limit+2;
//---- êîïèðóåì âíîâü ïîÿâèâøèåñÿ äàííûå â ìàññèâû
if(CopyBuffer(O_Handle,0,0,to_copy,FOpen)<=0) return(RESET);
if(CopyBuffer(C_Handle,0,0,to_copy,FClose)<=0) return(RESET);
if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(RESET);
//--- èíäåêñàöèÿ ýëåìåíòîâ â ìàññèâàõ êàê â òàéìñåðèÿõ
ArraySetAsSeries(FOpen,true);
ArraySetAsSeries(FClose,true);
ArraySetAsSeries(ATR,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
//---- îñíîâíîé öèêë èñïðàâëåíèÿ è îêðàøèâàíèÿ ñâå÷åé
for(bar=limit; bar>=0 && !IsStopped(); bar--)
{
BuyBuffer[bar]=0.0;
SellBuffer[bar]=0.0;
if(FOpen[bar+1]>=FClose[bar+1] && FOpen[bar]<FClose[bar]) BuyBuffer[bar]=low[bar]-ATR[bar]*3/8;
if(FOpen[bar+1]<=FClose[bar+1] && FOpen[bar]>FClose[bar]) SellBuffer[bar]=high[bar]+ATR[bar]*3/8;
}
//----
return(rates_total);
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---