01 // Price Oscillator Indicator
02 // Last changed on 2009-05-05
03 // Part of Forex Strategy Builder v2.8.3.7+
04 // Website http://forexsb.com/
05 // This code or any part of it cannot be used in other applications without a permission.
06 // Copyright (c) 2006 - 2009 Miroslav Popov - All rights reserved.
07
08 using System;
09 using System.Drawing;
10
11 namespace Forex_Strategy_Builder
12 {
13 /// <summary>
14 /// Price Oscillator Indicator
15 /// </summary>
16 public class Price_Oscillator : Indicator
17 {
18 /// <summary>
19 /// Sets the default indicator parameters for the designated slot type
20 /// </summary>
21 public Price_Oscillator(SlotTypes slotType)
22 {
23 // General properties
24 IndicatorName = "Price Oscillator";
25 PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter;
26 SeparatedChart = true;
27
28 // Setting up the indicator parameters
29 IndParam = new IndicatorParam();
30 IndParam.IndicatorName = IndicatorName;
31 IndParam.SlotType = slotType;
32
33 // The ComboBox parameters
34 IndParam.ListParam[0].Caption = "Logic";
35 IndParam.ListParam[0].ItemList = new string[]
36 {
37 "The Price Oscillator rises",
38 "The Price Oscillator falls",
39 "The Price Oscillator is higher than the Level line",
40 "The Price Oscillator is lower than the Level line",
41 "The Price Oscillator crosses the Level line upward",
42 "The Price Oscillator crosses the Level line downward",
43 "The Price Oscillator changes its direction upward",
44 "The Price Oscillator changes its direction downward"
45 };
46 IndParam.ListParam[0].Index = 0;
47 IndParam.ListParam[0].Text = IndParam.ListParam[0].ItemList[IndParam.ListParam[0].Index];
48 IndParam.ListParam[0].Enabled = true;
49 IndParam.ListParam[0].ToolTip = "Logic of application of the oscillator.";
50
51 IndParam.ListParam[1].Caption = "Smoothing method";
52 IndParam.ListParam[1].ItemList = Enum.GetNames(typeof(MAMethod));
53 IndParam.ListParam[1].Index = (int)MAMethod.Simple;
54 IndParam.ListParam[1].Text = IndParam.ListParam[1].ItemList[IndParam.ListParam[1].Index];
55 IndParam.ListParam[1].Enabled = true;
56 IndParam.ListParam[1].ToolTip = "The Moving Average method used for smoothing the PO.";
57
58 IndParam.ListParam[2].Caption = "Base price";
59 IndParam.ListParam[2].ItemList = Enum.GetNames(typeof(BasePrice));
60 IndParam.ListParam[2].Index = (int)BasePrice.Close;
61 IndParam.ListParam[2].Text = IndParam.ListParam[2].ItemList[IndParam.ListParam[2].Index];
62 IndParam.ListParam[2].Enabled = true;
63 IndParam.ListParam[2].ToolTip = "The price the indicator is based on.";
64
65 // The NumericUpDown parameters
66 IndParam.NumParam[0].Caption = "Period";
67 IndParam.NumParam[0].Value = 10;
68 IndParam.NumParam[0].Min = 1;
69 IndParam.NumParam[0].Max = 200;
70 IndParam.NumParam[0].Enabled = true;
71 IndParam.NumParam[0].ToolTip = "The period of Price Oscillator.";
72
73 IndParam.NumParam[1].Caption = "Additional smoothing";
74 IndParam.NumParam[1].Value = 0;
75 IndParam.NumParam[1].Min = 0;
76 IndParam.NumParam[1].Max = 200;
77 IndParam.NumParam[1].Enabled = true;
78 IndParam.NumParam[1].ToolTip = "The value of smoothing period.";
79
80 IndParam.NumParam[2].Caption = "Level";
81 IndParam.NumParam[2].Value = 0;
82 IndParam.NumParam[2].Min = -100;
83 IndParam.NumParam[2].Max = 100;
84 IndParam.NumParam[2].Point = 4;
85 IndParam.NumParam[2].Enabled = true;
86 IndParam.NumParam[2].ToolTip = "A critical level (for the appropriate logic).";
87
88 // The CheckBox parameters.
89 IndParam.CheckParam[0].Caption = "Use previous bar value";
90 IndParam.CheckParam[0].Checked = PrepareUsePrevBarValueCheckBox(slotType);
91 IndParam.CheckParam[0].Enabled = true;
92 IndParam.CheckParam[0].ToolTip = "Use the indicator value from the previous bar.";
93
94 return;
95 }
96
97 /// <summary>
98 /// Calculates the indicator's components
99 /// </summary>
100 public override void Calculate(SlotTypes slotType)
101 {
102 // Reading the parameters
103 MAMethod maMethod = (MAMethod)IndParam.ListParam[1].Index;
104 BasePrice basePrice = (BasePrice)IndParam.ListParam[2].Index;
105 int iPeriod = (int)IndParam.NumParam[0].Value;
106 int iSmooth = (int)IndParam.NumParam[1].Value;
107 double dLevel = IndParam.NumParam[2].Value;
108 int iPrvs = IndParam.CheckParam[0].Checked ? 1 : 0;
109
110 // Calculation
111 int iFirstBar = iPeriod + iSmooth + 2;
112
113 double[] adBasePrice = Price(basePrice);
114 double[] adCumulSum = new double[Bars];
115 double[] adPriceOsc = new double[Bars];
116
117 adCumulSum[iPeriod - 1] = 0;
118
119 for (int iBar = 0; iBar < iPeriod; iBar++)
120 {
121 adCumulSum[iPeriod - 1] += adBasePrice[iBar];
122 }
123
124 adPriceOsc[iPeriod - 1] = adCumulSum[iPeriod - 1] / adBasePrice[iPeriod - 1] - iPeriod;
125
126 for (int iBar = iPeriod; iBar < Bars; iBar++)
127 {
128 adCumulSum[iBar] = adCumulSum[iBar - 1] - adBasePrice[iBar - iPeriod] + adBasePrice[iBar];
129 adPriceOsc[iBar] = iPeriod - adCumulSum[iBar] / adBasePrice[iBar];
130 }
131
132 adPriceOsc = MovingAverage(iSmooth, 0, maMethod, adPriceOsc);
133
134 // Saving the components
135 Component = new IndicatorComp[3];
136
137 Component[0] = new IndicatorComp();
138 Component[0].CompName = "Price Oscillator";
139 Component[0].DataType = IndComponentType.IndicatorValue;
140 Component[0].ChartType = IndChartType.Line;
141 Component[0].ChartColor = Color.Blue;
142 Component[0].FirstBar = iFirstBar;
143 Component[0].Value = adPriceOsc;
144
145 Component[1] = new IndicatorComp();
146 Component[1].ChartType = IndChartType.NoChart;
147 Component[1].FirstBar = iFirstBar;
148 Component[1].Value = new double[Bars];
149
150 Component[2] = new IndicatorComp();
151 Component[2].ChartType = IndChartType.NoChart;
152 Component[2].FirstBar = iFirstBar;
153 Component[2].Value = new double[Bars];
154
155 // Sets the Component's type
156 if (slotType == SlotTypes.OpenFilter)
157 {
158 Component[1].DataType = IndComponentType.AllowOpenLong;
159 Component[1].CompName = "Is long entry allowed";
160 Component[2].DataType = IndComponentType.AllowOpenShort;
161 Component[2].CompName = "Is short entry allowed";
162 }
163 else if (slotType == SlotTypes.CloseFilter)
164 {
165 Component[1].DataType = IndComponentType.ForceCloseLong;
166 Component[1].CompName = "Close out long position";
167 Component[2].DataType = IndComponentType.ForceCloseShort;
168 Component[2].CompName = "Close out short position";
169 }
170
171 // Calculation of the logic
172 IndicatorLogic indLogic = IndicatorLogic.It_does_not_act_as_a_filter;
173
174 switch (IndParam.ListParam[0].Text)
175 {
176 case "The Price Oscillator rises":
177 indLogic = IndicatorLogic.The_indicator_rises;
178 SpecialValues = new double[1] { 0 };
179 break;
180
181 case "The Price Oscillator falls":
182 indLogic = IndicatorLogic.The_indicator_falls;
183 SpecialValues = new double[1] { 0 };
184 break;
185
186 case "The Price Oscillator is higher than the Level line":
187 indLogic = IndicatorLogic.The_indicator_is_higher_than_the_level_line;
188 SpecialValues = new double[2] { dLevel, - dLevel };
189 break;
190
191 case "The Price Oscillator is lower than the Level line":
192 indLogic = IndicatorLogic.The_indicator_is_lower_than_the_level_line;
193 SpecialValues = new double[2] { dLevel, - dLevel };
194 break;
195
196 case "The Price Oscillator crosses the Level line upward":
197 indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_upward;
198 SpecialValues = new double[2] { dLevel, - dLevel };
199 break;
200
201 case "The Price Oscillator crosses the Level line downward":
202 indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_downward;
203 SpecialValues = new double[2] { dLevel, - dLevel };
204 break;
205
206 case "The Price Oscillator changes its direction upward":
207 indLogic = IndicatorLogic.The_indicator_changes_its_direction_upward;
208 SpecialValues = new double[1] { 0 };
209 break;
210
211 case "The Price Oscillator changes its direction downward":
212 indLogic = IndicatorLogic.The_indicator_changes_its_direction_downward;
213 SpecialValues = new double[1] { 0 };
214 break;
215
216 default:
217 break;
218 }
219
220 OscillatorLogic(iFirstBar, iPrvs, adPriceOsc, dLevel, - dLevel, ref Component[1], ref Component[2], indLogic)
221 ;
222
223 return;
224 }
225
226 /// <summary>
227 /// Sets the indicator logic description
228 /// </summary>
229 public override void SetDescription(SlotTypes slotType)
230 {
231 string sLevelLong = (IndParam.NumParam[2].Value == 0 ? "0" : IndParam.NumParam[2].ValueToString);
232 string sLevelShort = (IndParam.NumParam[2].Value == 0 ? "0" : "-" + IndParam.NumParam[2].ValueToString);
233
234 EntryFilterLongDescription = "the " + ToString() + " ";
235 EntryFilterShortDescription = "the " + ToString() + " ";
236 ExitFilterLongDescription = "the " + ToString() + " ";
237 ExitFilterShortDescription = "the " + ToString() + " ";
238
239 switch (IndParam.ListParam[0].Text)
240 {
241 case "The Price Oscillator rises":
242 EntryFilterLongDescription += "rises";
243 EntryFilterShortDescription += "falls";
244 ExitFilterLongDescription += "rises";
245 ExitFilterShortDescription += "falls";
246 break;
247
248 case "The Price Oscillator falls":
249 EntryFilterLongDescription += "falls";
250 EntryFilterShortDescription += "rises";
251 ExitFilterLongDescription += "falls";
252 ExitFilterShortDescription += "rises";
253 break;
254
255 case "The Price Oscillator is higher than the Level line":
256 EntryFilterLongDescription += "is higher than the Level " + sLevelLong;
257 EntryFilterShortDescription += "is lower than the Level " + sLevelShort;
258 ExitFilterLongDescription += "is higher than the Level " + sLevelLong;
259 ExitFilterShortDescription += "is lower than the Level " + sLevelShort;
260 break;
261
262 case "The Price Oscillator is lower than the Level line":
263 EntryFilterLongDescription += "is lower than the Level " + sLevelLong;
264 EntryFilterShortDescription += "is higher than the Level " + sLevelShort;
265 ExitFilterLongDescription += "is lower than the Level " + sLevelLong;
266 ExitFilterShortDescription += "is higher than the Level " + sLevelShort;
267 break;
268
269 case "The Price Oscillator crosses the Level line upward":
270 EntryFilterLongDescription += "crosses the Level " + sLevelLong + " upward";
271 EntryFilterShortDescription += "crosses the Level " + sLevelShort + " downward";
272 ExitFilterLongDescription += "crosses the Level " + sLevelLong + " upward";
273 ExitFilterShortDescription += "crosses the Level " + sLevelShort + " downward";
274 break;
275
276 case "The Price Oscillator crosses the Level line downward":
277 EntryFilterLongDescription += "crosses the Level " + sLevelLong + " downward";
278 EntryFilterShortDescription += "crosses the Level " + sLevelShort + " upward";
279 ExitFilterLongDescription += "crosses the Level " + sLevelLong + " downward";
280 ExitFilterShortDescription += "crosses the Level " + sLevelShort + " upward";
281 break;
282
283 case "The Price Oscillator changes its direction upward":
284 EntryFilterLongDescription += "changes its direction upward";
285 EntryFilterShortDescription += "changes its direction downward";
286 ExitFilterLongDescription += "changes its direction upward";
287 ExitFilterShortDescription += "changes its direction downward";
288 break;
289
290 case "The Price Oscillator changes its direction downward":
291 EntryFilterLongDescription += "changes its direction downward";
292 EntryFilterShortDescription += "changes its direction upward";
293 ExitFilterLongDescription += "changes its direction downward";
294 ExitFilterShortDescription += "changes its direction upward";
295 break;
296
297 default:
298 break;
299 }
300
301 return;
302 }
303
304 /// <summary>
305 /// Indicator to string
306 /// </summary>
307 public override string ToString()
308 {
309 string sString = IndicatorName +
310 (IndParam.CheckParam[0].Checked ? "* (" : " (") +
311 IndParam.ListParam[1].Text + ", " + // Smoothing method
312 IndParam.ListParam[2].Text + ", " + // Base price
313 IndParam.NumParam[0].ValueToString + ", " + // Period
314 IndParam.NumParam[1].ValueToString + ")"; // Additional moothing
315
316 return sString;
317 }
318 }
319 }
Top