Forex Strategy Builder and Forex Strategy Trader
// Fisher Transform Indicator // Last changed on 2009-05-05 // Part of Forex Strategy Builder & Forex Strategy Trader // Website http://forexsb.com/ // Copyright (c) 2006 - 2009 Miroslav Popov - All rights reserved. // This code or any part of it cannot be used in other applications without a permission. using System; using System.Drawing; namespace Forex_Strategy_Builder { /// <summary> /// Fisher Transform Indicator /// </summary> public class Fisher_Transform : Indicator { /// <summary> /// Sets the default indicator parameters for the designated slot type /// </summary> public Fisher_Transform(SlotTypes slotType) { // General properties IndicatorName = "Fisher Transform"; PossibleSlots = SlotTypes.OpenFilter | SlotTypes.CloseFilter; SeparatedChart = true; // Setting up the indicator parameters IndParam = new IndicatorParam(); IndParam.IndicatorName = IndicatorName; IndParam.SlotType = slotType; // The ComboBox parameters IndParam.ListParam[0].Caption = "Logic"; IndParam.ListParam[0].ItemList = new string[] { "The Fisher Transform rises", "The Fisher Transform falls", "The Fisher Transform is higher than the zero line", "The Fisher Transform is lower than the zero line", "The Fisher Transform crosses the zero line upward", "The Fisher Transform crosses the zero line downward", "The Fisher Transform changes its direction upward", "The Fisher Transform changes its direction downward" }; IndParam.ListParam[0].Index = 0; IndParam.ListParam[0].Text = IndParam.ListParam[0].ItemList[IndParam.ListParam[0].Index]; IndParam.ListParam[0].Enabled = true; IndParam.ListParam[0].ToolTip = "Logic of application of the indicator."; IndParam.ListParam[1].Caption = "Base price"; IndParam.ListParam[1].ItemList = Enum.GetNames(typeof(BasePrice)); IndParam.ListParam[1].Index = (int)BasePrice.Median; IndParam.ListParam[1].Text = IndParam.ListParam[1].ItemList[IndParam.ListParam[1].Index]; IndParam.ListParam[1].Enabled = true; IndParam.ListParam[1].ToolTip = "The price the Fisher Transform is based on."; // The NumericUpDown parameters IndParam.NumParam[0].Caption = "Period"; IndParam.NumParam[0].Value = 10; IndParam.NumParam[0].Min = 3; IndParam.NumParam[0].Max = 100; IndParam.NumParam[0].Enabled = true; IndParam.NumParam[0].ToolTip = "The smoothing period."; // The CheckBox parameters IndParam.CheckParam[0].Caption = "Use previous bar value"; IndParam.CheckParam[0].Checked = PrepareUsePrevBarValueCheckBox(slotType); IndParam.CheckParam[0].Enabled = true; IndParam.CheckParam[0].ToolTip = "Use the indicator value from the previous bar."; return; } /// <summary> /// Calculates the indicator's components /// </summary> public override void Calculate(SlotTypes slotType) { // Reading the parameters BasePrice basePrice = (BasePrice)IndParam.ListParam[1].Index; int iPeriod = (int)IndParam.NumParam[0].Value; int iPrvs = IndParam.CheckParam[0].Checked ? 1 : 0; // Calculation int iFirstBar = iPeriod + 2; double[] adPrice = Price(basePrice); double[] adValue = new double[Bars]; for (int iBar = 0; iBar < iPeriod; iBar++) adValue[iBar] = 0; for (int iBar = iPeriod; iBar < Bars; iBar++) { double dHighestHigh = double.MinValue; double dLowestLow = double.MaxValue; for (int i = 0; i < iPeriod; i++) { if (adPrice[iBar - i] > dHighestHigh) dHighestHigh = adPrice[iBar - i]; if (adPrice[iBar - i] < dLowestLow) dLowestLow = adPrice[iBar - i]; } if (dHighestHigh == dLowestLow) dHighestHigh = dLowestLow + Point; if (dHighestHigh - dLowestLow == 0.5) dHighestHigh += Point; adValue[iBar] = 0.33 * 2 * ((adPrice[iBar] - dLowestLow) / (dHighestHigh - dLowestLow) - 0.5) + 0.67 * adValue[iBar - 1]; } double[] adFT = new double[Bars]; adFT[0] = 0; for (int iBar = 1; iBar < Bars; iBar++) { adFT[iBar] = 0.5 * (double)Math.Log10((1 + adValue[iBar]) / (1 - adValue[iBar])) + 0.5 * adFT[iBar - 1]; } // Saving the components Component = new IndicatorComp[3]; Component[0] = new IndicatorComp(); Component[0].CompName = "Fisher Transform"; Component[0].DataType = IndComponentType.IndicatorValue; Component[0].ChartType = IndChartType.Histogram; Component[0].FirstBar = iFirstBar; Component[0].Value = adFT; Component[1] = new IndicatorComp(); Component[1].ChartType = IndChartType.NoChart; Component[1].FirstBar = iFirstBar; Component[1].Value = new double[Bars]; Component[2] = new IndicatorComp(); Component[2].ChartType = IndChartType.NoChart; Component[2].FirstBar = iFirstBar; Component[2].Value = new double[Bars]; // Sets the Component's type if (slotType == SlotTypes.OpenFilter) { Component[1].DataType = IndComponentType.AllowOpenLong; Component[1].CompName = "Is long entry allowed"; Component[2].DataType = IndComponentType.AllowOpenShort; Component[2].CompName = "Is short entry allowed"; } else if (slotType == SlotTypes.CloseFilter) { Component[1].DataType = IndComponentType.ForceCloseLong; Component[1].CompName = "Close out long position"; Component[2].DataType = IndComponentType.ForceCloseShort; Component[2].CompName = "Close out short position"; } // Calculation of the logic IndicatorLogic indLogic = IndicatorLogic.It_does_not_act_as_a_filter; switch (IndParam.ListParam[0].Text) { case "The Fisher Transform rises": indLogic = IndicatorLogic.The_indicator_rises; break; case "The Fisher Transform falls": indLogic = IndicatorLogic.The_indicator_falls; break; case "The Fisher Transform is higher than the zero line": indLogic = IndicatorLogic.The_indicator_is_higher_than_the_level_line; break; case "The Fisher Transform is lower than the zero line": indLogic = IndicatorLogic.The_indicator_is_lower_than_the_level_line; break; case "The Fisher Transform crosses the zero line upward": indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_upward; break; case "The Fisher Transform crosses the zero line downward": indLogic = IndicatorLogic.The_indicator_crosses_the_level_line_downward; break; case "The Fisher Transform changes its direction upward": indLogic = IndicatorLogic.The_indicator_changes_its_direction_upward; break; case "The Fisher Transform changes its direction downward": indLogic = IndicatorLogic.The_indicator_changes_its_direction_downward; break; default: break; } OscillatorLogic(iFirstBar, iPrvs, adFT, 0, 0, ref Component[1], ref Component[2], indLogic); return; } /// <summary> /// Sets the indicator logic description /// </summary> public override void SetDescription(SlotTypes slotType) { EntryFilterLongDescription = "the " + ToString() + " "; EntryFilterShortDescription = "the " + ToString() + " "; ExitFilterLongDescription = "the " + ToString() + " "; ExitFilterShortDescription = "the " + ToString() + " "; switch (IndParam.ListParam[0].Text) { case "The Fisher Transform rises": EntryFilterLongDescription += "rises"; EntryFilterShortDescription += "falls"; ExitFilterLongDescription += "rises"; ExitFilterShortDescription += "falls"; break; case "The Fisher Transform falls": EntryFilterLongDescription += "falls"; EntryFilterShortDescription += "rises"; ExitFilterLongDescription += "falls"; ExitFilterShortDescription += "rises"; break; case "The Fisher Transform is higher than the zero line": EntryFilterLongDescription += "is higher than the zero line"; EntryFilterShortDescription += "is lower than the zero line"; ExitFilterLongDescription += "is higher than the zero line"; ExitFilterShortDescription += "is lower than the zero line"; break; case "The Fisher Transform is lower than the zero line": EntryFilterLongDescription += "is lower than the zero line"; EntryFilterShortDescription += "is higher than the zero line"; ExitFilterLongDescription += "is lower than the zero line"; ExitFilterShortDescription += "is higher than the zero line"; break; case "The Fisher Transform crosses the zero line upward": EntryFilterLongDescription += "crosses the zero line upward"; EntryFilterShortDescription += "crosses the zero line downward"; ExitFilterLongDescription += "crosses the zero line upward"; ExitFilterShortDescription += "crosses the zero line downward"; break; case "The Fisher Transform crosses the zero line downward": EntryFilterLongDescription += "crosses the zero line downward"; EntryFilterShortDescription += "crosses the zero line upward"; ExitFilterLongDescription += "crosses the zero line downward"; ExitFilterShortDescription += "crosses the zero line upward"; break; case "The Fisher Transform changes its direction upward": EntryFilterLongDescription += "changes its direction upward"; EntryFilterShortDescription += "changes its direction downward"; ExitFilterLongDescription += "changes its direction upward"; ExitFilterShortDescription += "changes its direction downward"; break; case "The Fisher Transform changes its direction downward": EntryFilterLongDescription += "changes its direction downward"; EntryFilterShortDescription += "changes its direction upward"; ExitFilterLongDescription += "changes its direction downward"; ExitFilterShortDescription += "changes its direction upward"; break; default: break; } return; } /// <summary> /// Indicator to string /// </summary> public override string ToString() { string sString = IndicatorName + (IndParam.CheckParam[0].Checked ? "* (" : " (") + IndParam.ListParam[1].Text + ", " + // Price IndParam.NumParam[0].ValueToString + ")"; // Period return sString; } } }