134 lines
5.1 KiB
Plaintext
134 lines
5.1 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| MinChangeSignal.mq5 |
|
|
//| Copyright 2013, Rone. |
|
|
//| rone.sergey@gmail.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2013, Rone."
|
|
#property link "rone.sergey@gmail.com"
|
|
#property version "1.00"
|
|
#property description "The signal is formed if the changes sum calculated on the last bar "
|
|
#property description "is less, than the smallest of sums calculated on the specified number of previous bars."
|
|
//---
|
|
#property indicator_separate_window
|
|
#property indicator_buffers 3
|
|
#property indicator_plots 3
|
|
//--- plot CurrentChange
|
|
#property indicator_label1 "Current Change Sum"
|
|
#property indicator_type1 DRAW_LINE
|
|
#property indicator_color1 clrBlue
|
|
#property indicator_style1 STYLE_SOLID
|
|
#property indicator_width1 2
|
|
//--- plot MinChange
|
|
#property indicator_label2 "Min Change Sum"
|
|
#property indicator_type2 DRAW_LINE
|
|
#property indicator_color2 clrRed
|
|
#property indicator_style2 STYLE_SOLID
|
|
#property indicator_width2 2
|
|
//--- plot Signal
|
|
#property indicator_label3 "Signal"
|
|
#property indicator_type3 DRAW_ARROW
|
|
#property indicator_color3 clrLime
|
|
#property indicator_style3 STYLE_SOLID
|
|
#property indicator_width3 3
|
|
//--- input parameters
|
|
input int InpChangesPeriod = 4; // Changes Period
|
|
input int InpCheckPeriod = 10; // Check Period
|
|
input bool InpAbsChange = false; // Abs Change
|
|
//--- indicator buffers
|
|
double CurrentSumBuffer[];
|
|
double MinSumBuffer[];
|
|
double SignalBuffer[];
|
|
//---
|
|
int changes_period;
|
|
int check_period;
|
|
int min_required_bars;
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit() {
|
|
//---
|
|
if ( InpChangesPeriod < 1 || InpCheckPeriod < 2 ) {
|
|
changes_period = 3;
|
|
check_period = 10;
|
|
printf("Incorrect input value InpChangesPeriod = %d or/and InpCheckPeriod =%d. "
|
|
"Indicator will use values %d and %d respectively.", InpChangesPeriod, InpCheckPeriod,
|
|
changes_period, check_period);
|
|
} else {
|
|
changes_period = InpChangesPeriod;
|
|
check_period = InpCheckPeriod;
|
|
}
|
|
min_required_bars = changes_period + check_period + 1;
|
|
//--- indicator buffers mapping
|
|
SetIndexBuffer(0, CurrentSumBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(1, MinSumBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);
|
|
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
|
|
PlotIndexSetInteger(2, PLOT_ARROW, 159);
|
|
//---
|
|
for ( int plot = 0; plot < 3; plot++ ) {
|
|
PlotIndexSetInteger(plot, PLOT_DRAW_BEGIN, min_required_bars - 1);
|
|
PlotIndexSetInteger(plot, PLOT_SHIFT, 0);
|
|
PlotIndexSetDouble(plot, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
}
|
|
//---
|
|
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
|
IndicatorSetString(INDICATOR_SHORTNAME, "Min Price Change ("+(string)changes_period
|
|
+", "+(string)check_period+")");
|
|
//---
|
|
return(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator iteration function |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total,
|
|
const int prev_calculated,
|
|
const int begin,
|
|
const double &price[])
|
|
{
|
|
//---
|
|
int change_start_bar, check_start_bar, signal_start_bar;
|
|
//---
|
|
if ( rates_total < min_required_bars ) {
|
|
Print("Not enough bars for calculations.");
|
|
return(0);
|
|
}
|
|
//---
|
|
if ( prev_calculated > rates_total || prev_calculated <= 0 ) {
|
|
change_start_bar = changes_period;
|
|
check_start_bar = change_start_bar + check_period;
|
|
signal_start_bar = check_start_bar + 1;
|
|
} else {
|
|
change_start_bar = prev_calculated - 1;
|
|
check_start_bar = change_start_bar;
|
|
signal_start_bar = change_start_bar;
|
|
}
|
|
//---
|
|
for ( int bar = change_start_bar; bar < rates_total; bar++ ) {
|
|
double sum = 0.0;
|
|
|
|
for ( int shift = bar - changes_period + 1; shift <= bar; shift++ ) {
|
|
if ( InpAbsChange ) {
|
|
sum += MathAbs(price[shift] - price[shift-1]);
|
|
} else {
|
|
sum += price[shift] - price[shift-1];
|
|
}
|
|
}
|
|
CurrentSumBuffer[bar] = MathAbs(sum);
|
|
}
|
|
for ( int bar = check_start_bar; bar < rates_total; bar++ ) {
|
|
MinSumBuffer[bar] = CurrentSumBuffer[ArrayMinimum(CurrentSumBuffer,
|
|
bar-check_period, check_period)];
|
|
}
|
|
for ( int bar = signal_start_bar; bar < rates_total; bar++ ) {
|
|
SignalBuffer[bar] = EMPTY_VALUE;
|
|
if ( CurrentSumBuffer[bar] < MinSumBuffer[bar]
|
|
&& CurrentSumBuffer[bar-1] >= MinSumBuffer[bar-1] )
|
|
{
|
|
SignalBuffer[bar] = MinSumBuffer[bar];
|
|
}
|
|
}
|
|
//--- return value of prev_calculated for next call
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|