1 //+------------------------------------------------------------------+
\r
3 //| Copyright 2011, Zarko Asenov |
\r
4 //| http://jaltoh.6x.to |
\r
5 //+------------------------------------------------------------------+
\r
6 #property copyright "Copyright 2011, Zarko Asenov"
\r
7 #property link "http://jaltoh.6x.to"
\r
9 #property indicator_chart_window
\r
10 #property indicator_buffers 3
\r
11 #property indicator_color1 DeepSkyBlue
\r
12 #property indicator_color2 DeepSkyBlue
\r
13 #property indicator_color3 DeepSkyBlue
\r
14 #property indicator_width1 2
\r
15 #property indicator_width2 1
\r
16 #property indicator_width3 1
\r
17 #property indicator_style2 STYLE_SOLID
\r
19 //--- input parameters
\r
20 extern double Q = 0.022;
\r
21 extern double R = 0.617;
\r
22 extern int Num_Bars = 25;
\r
23 extern int Num_Sub_Bars = 64;
\r
25 extern int Sub_Time_Frame = PERIOD_M1;
\r
26 extern double Error_Weight = 2.0;
\r
28 extern bool Self_Correct = true;
\r
29 extern int Num_Cycles_Bar = 4;
\r
30 extern double Scatter = 33.3;
\r
32 extern bool Verbose = false;
\r
36 double ExtMapBuffer1[];
\r
37 double ExtMapBuffer2[];
\r
38 double ExtMapBuffer3[];
\r
44 //the noise in the system
\r
53 double sum_error_kalman;
\r
54 double median_error_kalman;
\r
55 datetime prev_subbar_time;
\r
56 double prev_sum_error_kalman = 0.0;
\r
64 //+------------------------------------------------------------------+
\r
65 //| Custom indicator initialization function |
\r
66 //+------------------------------------------------------------------+
\r
68 double subbars_period;
\r
69 double inv_subbars_period;
\r
74 SetIndexStyle(0,DRAW_LINE);
\r
75 SetIndexBuffer(0,ExtMapBuffer1);
\r
76 SetIndexStyle(1,DRAW_LINE);
\r
77 SetIndexBuffer(1,ExtMapBuffer2);
\r
78 SetIndexStyle(2,DRAW_LINE);
\r
79 SetIndexBuffer(2,ExtMapBuffer3);
\r
80 SetIndexEmptyValue(0, 0.0);
\r
81 SetIndexEmptyValue(1, 0.0);
\r
82 SetIndexEmptyValue(2, 0.0);
\r
84 prev_subbar_time = 0;
\r
91 // init_kalman( iClose(Symbol(), Period(), Num_Bars * Period() / Sub_Time_Frame) );
\r
93 adj_scatter = Scatter;
\r
95 subbars_period = Period() / Sub_Time_Frame;
\r
96 inv_subbars_period = 1.0 / subbars_period;
\r
100 //+------------------------------------------------------------------+
\r
101 //| Custom indicator deinitialization function |
\r
102 //+------------------------------------------------------------------+
\r
116 //initial values for the kalman filter
\r
118 //initialize with a measurement
\r
119 x_est_last = init_value;
\r
122 sum_error_kalman = 0.0;
\r
123 median_error_kalman = 0.0;
\r
124 iter_ctr = 0; // for median
\r
135 P_temp = P_last + q;
\r
137 //calculate the Kalman gain
\r
138 K = P_temp / (P_temp + r);
\r
141 x_est = x_est_last + K * (value - x_est_last);
\r
142 P = (1.0 - K) * P_temp;
\r
143 //we have our new system
\r
145 if (train_val != 0.0) {
\r
146 double abserror = MathAbs(train_val - x_est);
\r
147 sum_error_kalman += abserror;
\r
149 median_error_kalman = median_error_kalman * iter_ctr + Error_Weight * abserror;
\r
150 median_error_kalman /= (iter_ctr + Error_Weight);
\r
154 //update our last's
\r
156 x_est_last = x_est;
\r
162 do_cycle(int start_bar, int end_bar, double q, double r, double reference_value)
\r
165 sum_error_kalman = 0.0;
\r
167 for (int i = start_bar; i >= end_bar; i--) {
\r
168 double hist_val = iClose(NULL, Sub_Time_Frame, i);
\r
169 est = do_kalman(hist_val, reference_value, q, r);
\r
179 double &prev_qr_coef)
\r
181 if (prev_qr_coef == 0.0) return;
\r
183 qr_coef = prev_qr_coef + (prev_qr_coef / adj_scatter);
\r
189 double &prev_qr_coef)
\r
191 if (prev_qr_coef == 0.0) return;
\r
193 qr_coef = prev_qr_coef - (prev_qr_coef / adj_scatter);
\r
196 #define INCR_R_COEF 0
\r
197 #define DECR_R_COEF 1
\r
198 #define INCR_Q_COEF 0
\r
199 #define DECR_Q_COEF 1
\r
201 int last_r_adj = INCR_R_COEF;
\r
202 int last_q_adj = INCR_Q_COEF;
\r
206 filter_bar(int index)
\r
209 double ref_value = Close[index];
\r
214 est = do_cycle( Num_Sub_Bars + index * subbars_period, index * subbars_period, used_q, used_r, ref_value);
\r
216 if (Self_Correct == true) {
\r
218 if (sum_error_kalman < prev_sum_error_kalman) {
\r
220 if (last_q_adj == INCR_Q_COEF) incr_coef(next_q, used_q);
\r
221 else decr_coef(next_q, used_q);
\r
223 if (last_r_adj == INCR_R_COEF ) incr_coef(next_r, used_r);
\r
224 else decr_coef(next_r, used_r);
\r
226 } else if (prev_sum_error_kalman < sum_error_kalman) {
\r
228 if (last_q_adj == INCR_Q_COEF) decr_coef(next_q, used_q);
\r
229 else incr_coef(next_q, used_q);
\r
231 if (last_r_adj == INCR_R_COEF) decr_coef(next_r, used_r);
\r
232 else incr_coef(next_r, used_r);
\r
239 prev_sum_error_kalman = sum_error_kalman;
\r
243 if (est > ref_value) {
\r
244 ExtMapBuffer1[index] = est;
\r
245 ExtMapBuffer2[index] = est - median_error_kalman;
\r
246 ExtMapBuffer3[index] = 0.0;
\r
248 if (ExtMapBuffer2[index + 1] == 0.0) {
\r
249 double prev_err = ExtMapBuffer3[index + 1] - ExtMapBuffer1[index + 1];
\r
250 ExtMapBuffer2[index + 1] = ExtMapBuffer1[index + 1] - prev_err;
\r
254 ExtMapBuffer1[index] = est;
\r
255 ExtMapBuffer2[index] = 0.0;
\r
256 ExtMapBuffer3[index] = est + median_error_kalman;
\r
258 if (ExtMapBuffer3[index + 1] == 0.0) {
\r
259 prev_err = ExtMapBuffer1[index + 1] - ExtMapBuffer2[index + 1];
\r
260 ExtMapBuffer3[index + 1] = ExtMapBuffer1[index + 1] + prev_err;
\r
267 //+------------------------------------------------------------------+
\r
268 //| Custom indicator iteration function |
\r
269 //+------------------------------------------------------------------+
\r
273 int counted_bars = IndicatorCounted();
\r
274 int limit = Bars - counted_bars - 1;
\r
275 if (limit < 0) return (0);
\r
276 if (limit > Num_Bars) limit = Num_Bars;
\r
280 if (prev_subbar_time == iTime(NULL, Sub_Time_Frame, 0)) return (0);
\r
281 else prev_subbar_time = iTime(NULL, Sub_Time_Frame, 0);
\r
284 for (int i = limit; i >= 0; i--) {
\r
285 init_kalman( iClose(Symbol(), Sub_Time_Frame, (i + 1) * subbars_period - 1) );
\r
287 for (int j = 0;j < Num_Cycles_Bar; j++) filter_bar(i);
\r
290 if (Verbose == true) {
\r
292 "\n\nTotal error this bar: ", sum_error_kalman, " (", iter_ctr," bars) \n",
\r
293 "Last bar median weighted Kalman error: ", median_error_kalman, "\n",
\r
294 "Q:",used_q," R:",used_r," \n",
\r
295 "Prediction: ", x_est, "\n");
\r
300 //+------------------------------------------------------------------+