Source » Trix Index - source code

// Forex Strategy Builder
// Copyright (c) 2006 - 2008 Miroslav Popov - All rights reserved!
// http://forexsb.com
// info(a)forexsb.com
//
// Last changed on: 2007-06-12

using System;
using System.Drawing;

namespace Forex_Strategy_Builder
{
    /// <summary>
    /// Indicator: Trix Index
    /// </summary>
    public class Trix_Index : Indicator
    {
        /// <summary>
        /// The default constructor.
        /// </summary>
        public Trix_Index()
        {
        }

        /// <summary>
        /// Sets the default parameters for the designated slot type.
        /// </summary>
        /// <param name="slotType">The slot type.</param>
        public Trix_Index(SlotTypes slotType)
        {
            sIndicatorName  = "Trix Index";
            parameters      = new IndicatorParam();
            component       = new IndicatorComp[] { };
            afSpecValue     = new float[1] { 0f };
            bSeparatedChart = true;
            bIsCalculated   = false;


            // The indicator name.
            parameters.IndicatorName = sIndicatorName;

            // The slot type.
            parameters.SlotType = slotType;

            // The ComboBox parameters.
            parameters.ListParam[0].Caption = "Logic";
            parameters.ListParam[0].ItemList = new string[]
            {
                "The Trix Index line rises",
                "The Trix Index line falls",
                "The Trix Index line is higher than zero",
                "The Trix Index line is lower than zero",
                "The Trix Index line crosses the zero line upward",
                "The Trix Index line crosses the zero line downward",
                "The Trix Index line changes its direction upward",
                "The Trix Index line changes its direction downward",
                "The Trix Index line crosses the Signal line upward",
                "The Trix Index line crosses the Signal line downward",
                "The Trix Index line is higher than the Signal line",
                "The Trix Index line is lower than the Signal line"
            };
            parameters.ListParam[0].Index    = 0;
            parameters.ListParam[0].Text     = parameters.ListParam[0].ItemList[parameters.ListParam[0].Index];
            parameters.ListParam[0].Enabled  = true;
            parameters.ListParam[0].ToolTip  = "Logic of application of the indicator";

            parameters.ListParam[1].Caption  = "Smoothing method";
            parameters.ListParam[1].ItemList = Enum.GetNames(typeof(MAMethod));
            parameters.ListParam[1].Index    = 2;
            parameters.ListParam[1].Text     = parameters.ListParam[1].ItemList[parameters.ListParam[1].Index];
            parameters.ListParam[1].Enabled  = true;
            parameters.ListParam[1].ToolTip  = "The Moving Average method used for smoothing the Trix Index value";

            parameters.ListParam[2].Caption  = "Base price";
            parameters.ListParam[2].ItemList = Enum.GetNames(typeof(BasePrice));
            parameters.ListParam[2].Index    = 3;
            parameters.ListParam[2].Text     = parameters.ListParam[2].ItemList[parameters.ListParam[2].Index];
            parameters.ListParam[2].Enabled  = true;
            parameters.ListParam[2].ToolTip  = "The price the indicator is based on";

            // The NumericUpDown parameters.
            parameters.NumParam[0].Caption = "Period of Trix";
            parameters.NumParam[0].Value   = 9;
            parameters.NumParam[0].Min     = 1;
            parameters.NumParam[0].Max     = 200;
            parameters.NumParam[0].Enabled = true;
            parameters.NumParam[0].ToolTip = "The period of Trix Moving Averages";

            // The CheckBox parameters.
            parameters.CheckParam[0].Caption = "Use previous bar value";
            parameters.CheckParam[0].Checked = Data.Strategy.PrepareUsePrevBarValueCheckBox(slotType);
            parameters.CheckParam[0].Enabled = true;
            parameters.CheckParam[0].ToolTip = "Use the indicator value from the previous bar";
        }

        /// <summary>
        /// Calculates the indicator's components.
        /// </summary>
        /// <param name="slotType">The slot type.</param>
        public override void Calculate(SlotTypes slotType)
        {
            if (parameters.SlotType == SlotTypes.NotDefined) return;

            // Reading the parameters
            MAMethod  maMethod  = (MAMethod )Enum.GetValues(typeof(MAMethod )).GetValue(parameters.ListParam[1].Index);
            BasePrice basePrice = (BasePrice)Enum.GetValues(typeof(BasePrice)).GetValue(parameters.ListParam[2].Index);
            int       nPeriod   = (int)parameters.NumParam[0].Value;
            int       iPrvs     = parameters.CheckParam[0].Checked ? 1 : 0;

            // Calculation
            int iFirstBar = 2 * nPeriod + 2;

            float[] ma1 = MovingAverage(nPeriod, 0, maMethod, Price(basePrice));
            float[] ma2 = MovingAverage(nPeriod, 0, maMethod, ma1);
            float[] ma3 = MovingAverage(nPeriod, 0, maMethod, ma2);

            float[] afTrix = new float[Bars];

            for (int iBar = iFirstBar; iBar < Bars; iBar++)
                afTrix[iBar] = 100 * (ma3[iBar] - ma3[iBar - 1]) / ma3[iBar - 1];

            float[] afSignal = MovingAverage(nPeriod, 0, maMethod, afTrix);

            // afHistogram reprezents the Trix Index oscillator
            float[] afHistogram = new float[Bars];
            for (int iBar = iFirstBar; iBar < Bars; iBar++)
                afHistogram[iBar] = afTrix[iBar] - afSignal[iBar];

            // Saving the components
            component = new IndicatorComp[5];

            component[0] = new IndicatorComp();
            component[0].CompName   = "Histogram";
            component[0].DataType   = IndComponentType.IndicatorValue;
            component[0].ChartType  = IndChartType.Histogram;
            component[0].FirstBar   = iFirstBar;
            component[0].Value      = afHistogram;

            component[1] = new IndicatorComp();
            component[1].CompName   = "Signal";
            component[1].DataType   = IndComponentType.IndicatorValue;
            component[1].ChartType  = IndChartType.Line;
            component[1].ChartColor = Color.Yellow;
            component[1].FirstBar   = iFirstBar;
            component[1].Value      = afSignal;

            component[2] = new IndicatorComp();
            component[2].CompName   = "Trix Line";
            component[2].DataType   = IndComponentType.IndicatorValue;
            component[2].ChartType  = IndChartType.Line;
            component[2].ChartColor = Color.Blue;
            component[2].FirstBar   = iFirstBar;
            component[2].Value      = afTrix;

            component[3] = new IndicatorComp();
            component[3].ChartType = IndChartType.NoChart;
            component[3].FirstBar  = iFirstBar;
            component[3].Value     = new float[Bars];

            component[4] = new IndicatorComp();
            component[4].ChartType = IndChartType.NoChart;
            component[4].FirstBar  = iFirstBar;
            component[4].Value     = new float[Bars];

            // Sets the component's type.
            if (slotType == SlotTypes.OpenFilter)
            {
                component[3].DataType = IndComponentType.AllowOpenLong;
                component[3].CompName = "Allows long positions opening";
                component[4].DataType = IndComponentType.AllowOpenShort;
                component[4].CompName = "Allows short positions opening";
            }
            else if (slotType == SlotTypes.CloseFilter)
            {
                component[3].DataType = IndComponentType.ForceCloseLong;
                component[3].CompName = "Forces long positions closing";
                component[4].DataType = IndComponentType.ForceCloseShort;
                component[4].CompName = "Forces short positions closing";
            }

            switch (parameters.ListParam[0].Text)
            {
                case "The Trix Index line rises":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = afTrix[iBar - iPrvs - 1] < afTrix[iBar - iPrvs] ? 1 : 0;
                        component[4].Value[iBar] = afTrix[iBar - iPrvs - 1] > afTrix[iBar - iPrvs] ? 1 : 0;
                    }
                    break;

                case "The Trix Index line falls":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = afTrix[iBar - iPrvs - 1] > afTrix[iBar - iPrvs] ? 1 : 0;
                        component[4].Value[iBar] = afTrix[iBar - iPrvs - 1] < afTrix[iBar - iPrvs] ? 1 : 0;
                    }
                    break;

                case "The Trix Index line is higher than zero":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = afTrix[iBar - iPrvs] > 0 ? 1 : 0;
                        component[4].Value[iBar] = afTrix[iBar - iPrvs] < 0 ? 1 : 0;
                    }
                    break;

                case "The Trix Index line is lower than zero":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = afTrix[iBar - iPrvs] < 0 ? 1 : 0;
                        component[4].Value[iBar] = afTrix[iBar - iPrvs] > 0 ? 1 : 0;
                    }
                    break;

                case "The Trix Index line crosses the zero line upward":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afTrix[iBar - iPrvs - 1] < 0 && afTrix[iBar - iPrvs] > 0) ? 1 : 0;
                        component[4].Value[iBar] = (afTrix[iBar - iPrvs - 1] > 0 && afTrix[iBar - iPrvs] < 0) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line crosses the zero line downward":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afTrix[iBar - iPrvs - 1] > 0 && afTrix[iBar - iPrvs] < 0) ? 1 : 0;
                        component[4].Value[iBar] = (afTrix[iBar - iPrvs - 1] < 0 && afTrix[iBar - iPrvs] > 0) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line changes its direction upward":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afTrix[iBar - iPrvs - 2] > afTrix[iBar - iPrvs - 1] && afTrix[iBar - iPrvs - 1] < afTrix[iBar - iPrvs]) ? 1 : 0;
                        component[4].Value[iBar] = (afTrix[iBar - iPrvs - 2] < afTrix[iBar - iPrvs - 1] && afTrix[iBar - iPrvs - 1] > afTrix[iBar - iPrvs]) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line changes its direction downward":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afTrix[iBar - iPrvs - 2] < afTrix[iBar - iPrvs - 1] && afTrix[iBar - iPrvs - 1] > afTrix[iBar - iPrvs]) ? 1 : 0;
                        component[4].Value[iBar] = (afTrix[iBar - iPrvs - 2] > afTrix[iBar - iPrvs - 1] && afTrix[iBar - iPrvs - 1] < afTrix[iBar - iPrvs]) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line crosses the Signal line upward":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afHistogram[iBar - iPrvs - 1] < 0 && afHistogram[iBar - iPrvs] > 0) ? 1 : 0;
                        component[4].Value[iBar] = (afHistogram[iBar - iPrvs - 1] > 0 && afHistogram[iBar - iPrvs] < 0) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line crosses the Signal line downward":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afHistogram[iBar - iPrvs - 1] > 0 && afHistogram[iBar - iPrvs] < 0) ? 1 : 0;
                        component[4].Value[iBar] = (afHistogram[iBar - iPrvs - 1] < 0 && afHistogram[iBar - iPrvs] > 0) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line is higher than the Signal line":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afHistogram[iBar - iPrvs - 1] > 0) ? 1 : 0;
                        component[4].Value[iBar] = (afHistogram[iBar - iPrvs - 1] < 0) ? 1 : 0;
                    }
                    break;

                case "The Trix Index line is lower than the Signal line":
                    for (int iBar = iFirstBar; iBar < Bars; iBar++)
                    {
                        component[3].Value[iBar] = (afHistogram[iBar - iPrvs - 1] < 0) ? 1 : 0;
                        component[4].Value[iBar] = (afHistogram[iBar - iPrvs - 1] > 0) ? 1 : 0;
                    }
                    break;

                default:
                    break;
            }

            bIsCalculated = true;
        }
    }
}

Top