0
Views
0
Downloads
0
Favorites
BreakoutBarsTrend_v2
//+------------------------------------------------------------------+
//| BreakoutBarsTrend_v2.mq5 |
//| Copyright 2012, Rone. |
//| rone.sergey@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Rone."
#property link "rone.sergey@gmail.com"
#property version "1.00"
#property description "The alternative indicator to determine the trend based on the breakthrough bars and the distance from extremums."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_plots 4
//--- plot Values
#property indicator_label1 "BBT Values"
#property indicator_type1 DRAW_NONE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- plot BBT
#property indicator_label2 "BBT Open;BBT High;BBT Low;BBT Close"
#property indicator_type2 DRAW_COLOR_CANDLES
#property indicator_color2 clrBlue,clrRoyalBlue,clrDeepSkyBlue,clrRed,clrTomato,clrOrange
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- plot ReverseToDown
#property indicator_label3 "Reverse To Down"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrDodgerBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- plot ReverseToUp
#property indicator_label4 "Reverse To Up"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrTomato
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//---
enum REVERSAL_MODE {
PIPS, // In pips
PERCENT // In percentage
};
//---
struct bbtData {
int value;
int result;
double firstPrice;
};
//--- input parameters
input REVERSAL_MODE InpReversal = PIPS; // Reversal
input double InpDelta = 1000; // Delta
input bool InpShowReverseLevels = true; // Show the reversal levels
input bool InpShowTrendsInfo = true; // Show the trends info
input int InpTrendsQuantity = 5; // Number of trends
//--- indicator buffers
double ValuesBuffer[];
double OpenBuffer[];
double HighBuffer[];
double LowBuffer[];
double CloseBuffer[];
double ColorsBuffer[];
double ReverseToDownBuffer[];
double ReverseToUpBuffer[];
//--- global variables
int minRequiredBars;
int quantity;
double delta;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//---
minRequiredBars = 2;
//---
delta = InpDelta;
if ( InpReversal == PIPS ) {
if ( InpDelta < 30 ) {
delta = 1000;
printf("The \"Delta\" parameter is specified incorrectly: %d. the: %d. value will be used",
(int)InpDelta, (int)delta);
}
delta *= _Point;
} else {
if ( InpDelta < 0.03 || InpDelta > 30.0 ) {
delta = 1.0;
printf("The \"Delta\" parameter is specified incorrectly: %f. the: %f. value will be used",
InpDelta, delta);
}
}
//---
if ( InpShowTrendsInfo ) {
if ( InpTrendsQuantity < 2 || InpTrendsQuantity > 20 ) {
quantity = 5;
printf("The \"Number of series\" parameter is specified incorrectly: %d. the: %d. value will be used",
InpTrendsQuantity, quantity);
} else {
quantity = InpTrendsQuantity;
}
}
//--- indicator buffers mapping
SetIndexBuffer(0, ValuesBuffer, INDICATOR_DATA);
SetIndexBuffer(1, OpenBuffer, INDICATOR_DATA);
SetIndexBuffer(2, HighBuffer, INDICATOR_DATA);
SetIndexBuffer(3, LowBuffer, INDICATOR_DATA);
SetIndexBuffer(4, CloseBuffer, INDICATOR_DATA);
SetIndexBuffer(5, ColorsBuffer, INDICATOR_COLOR_INDEX);
SetIndexBuffer(6, ReverseToDownBuffer, INDICATOR_DATA);
SetIndexBuffer(7, ReverseToUpBuffer, INDICATOR_DATA);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
PlotIndexSetInteger(2, PLOT_ARROW, 159);
PlotIndexSetInteger(3, PLOT_ARROW, 159);
//---
for ( int i = 0; i < 4; i++ ) {
PlotIndexSetInteger(i, PLOT_DRAW_BEGIN, minRequiredBars);
PlotIndexSetInteger(i, PLOT_SHIFT, 0);
PlotIndexSetDouble(i, PLOT_EMPTY_VALUE, 0.0);
}
//---
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
//---
string modeData = (InpReversal == PIPS) ? DoubleToString(InpDelta, 0)+" pips" : DoubleToString(InpDelta, 2)+"%";
IndicatorSetString(INDICATOR_SHORTNAME, "Breakout Bars Trend v2 ("+modeData+")");
//---
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
Comment("");
//---
}
//+------------------------------------------------------------------+
//| Get Reversal Value function |
//+------------------------------------------------------------------+
double getReversal(double price) {
//---
if ( InpReversal == PIPS ) {
return(delta);
}
return(NormalizeDouble((price/100)*delta, _Digits));
//---
}
//+------------------------------------------------------------------+
//| Calculate Trends Info function |
//+------------------------------------------------------------------+
void calculateTrendsInfo(bbtData &data[], int bar, const double &price[], int qty) {
//---
double curPrice = price[bar];
//---
data[0].value = (int)ValuesBuffer[bar];
for ( int i = 1; i < qty && bar > 0; bar-- ) {
//---
if ( ValuesBuffer[bar-1] * ValuesBuffer[bar] < 0 ) {
data[i].value = (int)ValuesBuffer[bar-1];
data[i-1].firstPrice = price[bar];
calculateResult(data[i-1], curPrice);
curPrice = price[bar];
i += 1;
}
}
for ( ; bar > 0; bar-- ) {
if ( ValuesBuffer[bar-1] * ValuesBuffer[bar] < 0 ) {
data[qty-1].firstPrice = price[bar];
calculateResult(data[qty-1], curPrice);
break;
}
}
//---
}
//+------------------------------------------------------------------+
//| function |
//+------------------------------------------------------------------+
void calculateResult(bbtData &data, double price) {
//---
if ( data.value > 0 ) {
data.result = int((price - data.firstPrice) / _Point);
} else {
data.result = int((data.firstPrice - price) / _Point);
}
//---
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
int startBar, lastBar;
bool upTrend;
double minPrice, maxPrice, reversal;
static bool _upTrend;
static double _minPrice, _maxPrice;
//---
lastBar = rates_total - 1;
//---
if ( prev_calculated > rates_total || prev_calculated <= 0 ) {
ArrayInitialize(ReverseToDownBuffer, 0.0);
ArrayInitialize(ReverseToUpBuffer, 0.0);
reversal = getReversal(close[0]);
for ( startBar = 1; MathAbs(close[startBar]-close[0]) - reversal <= 0.00001; startBar++ );
for ( int bar = 0; bar < startBar; bar++ ) {
ValuesBuffer[bar] = 0.0;
OpenBuffer[bar] = 0.0;
HighBuffer[bar] = 0.0;
LowBuffer[bar] = 0.0;
CloseBuffer[bar] = 0.0;
ReverseToDownBuffer[bar] = 0.0;
ReverseToUpBuffer[bar] = 0.0;
}
if ( close[startBar] > close[0] ) {
ValuesBuffer[startBar] = 1;
_upTrend = true;
_minPrice = low[0];
_maxPrice = high[startBar];
} else {
ValuesBuffer[startBar] = -1;
_upTrend = false;
_minPrice = low[startBar];
_maxPrice = high[0];
}
} else {
startBar = prev_calculated - 1;
}
//---
upTrend = _upTrend;
minPrice = _minPrice;
maxPrice = _maxPrice;
//---
for ( int bar = startBar; bar < rates_total && !IsStopped(); bar++ ) {
int prevBar = bar - 1;
//---
minPrice = MathMin(minPrice, low[prevBar]);
maxPrice = MathMax(maxPrice, high[prevBar]);
//---
if ( prev_calculated != rates_total && bar == lastBar ) {
if ( ValuesBuffer[prevBar] * ValuesBuffer[prevBar-1] < 0 ) {
minPrice = low[prevBar];
maxPrice = high[prevBar];
}
_upTrend = upTrend;
_minPrice = minPrice;
_maxPrice = maxPrice;
}
//---
OpenBuffer[bar] = open[bar];
HighBuffer[bar] = high[bar];
LowBuffer[bar] = low[bar];
CloseBuffer[bar] = close[bar];
//---
if ( upTrend ) {
reversal = getReversal(maxPrice);
if ( close[bar] > maxPrice ) {
ValuesBuffer[bar] = ValuesBuffer[prevBar] + 1;
ColorsBuffer[bar] = 0;
} else if ( close[bar] < MathMax(maxPrice, high[bar]) - reversal && close[bar] < low[prevBar] ) {
upTrend = false;
ValuesBuffer[bar] = -1;
ColorsBuffer[bar] = 3;
if ( bar != lastBar ) {
maxPrice = high[bar];
minPrice = low[bar];
}
} else {
ValuesBuffer[bar] = ValuesBuffer[prevBar];
if ( close[bar] >= open[bar] ) {
ColorsBuffer[bar] = 1;
} else {
ColorsBuffer[bar] = 2;
}
}
} else {
reversal = getReversal(minPrice);
if ( close[bar] < minPrice ) {
ValuesBuffer[bar] = ValuesBuffer[prevBar] - 1;
ColorsBuffer[bar] = 3;
} else if ( close[bar] > MathMin(minPrice, low[bar]) + reversal && close[bar] > high[prevBar] ) {
upTrend = true;
ValuesBuffer[bar] = 1;
ColorsBuffer[bar] = 0;
if ( bar != lastBar ) {
minPrice = low[bar];
maxPrice = high[bar];
}
} else {
ValuesBuffer[bar] = ValuesBuffer[prevBar];
if ( close[bar] >= open[bar] ) {
ColorsBuffer[bar] = 5;
} else {
ColorsBuffer[bar] = 4;
}
}
}
//---
if ( InpShowReverseLevels ) {
if ( upTrend ) {
ReverseToDownBuffer[bar] = maxPrice - reversal;
ReverseToUpBuffer[bar] = 0.0;
} else {
ReverseToDownBuffer[bar] = 0.0;
ReverseToUpBuffer[bar] = minPrice + reversal;
}
}
}
//---
if ( InpShowTrendsInfo ) {
bbtData trendsData[];
ArrayResize(trendsData, quantity);
calculateTrendsInfo(trendsData, lastBar, close, quantity);
//---
string comm = "Trends Info:\n";
for ( int i = quantity - 1; i >= 0; i-- ) {
comm += (string)trendsData[i].value + ": " + (string)trendsData[i].result + " pips\n";
}
Comment(comm);
}
//--- return value of prev_calculated for next call
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
---