Category Oscilators  Published on 24/06/2019

StochOptimizer

Description

Follow my cTrader Telegram group at https://t.me/cTraderCommunity; it's a new community but it will grow fast, plus everyone can talk about cTrader indicators and algorithm without restrictions, though it is not allowed to spam commercial indicators to sell them.

This indicator finds optimal parameters for the stochastic oscillator by optimizing it on the selected chart segment.

As for others of my indicators, the chart segment can be selected by ctrl + click and alt + click.

Be Aware: computation can take a very long time depending on the range selected for the parameters; keep in mind that times are exponential!!!

Here it is.

The label in the top left of the screen indicates the probability that if a candle is in OB or OS zone of the oscillator there will be an inversion of at least X pips (specified in the Deviation parameter) on that very candle.

Obviously, this is not a practical probability, since it has been "overfitted" on the analyzed chart, however, the user who has a certain confidence with calculus, statistics and curve fitting will know that a certain optimization retains its performances if utilized on an interval of Out Of Sample data that is small enough (look for Differentiation on google and wikipedia for more informations)

Enjoy ;)


using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Collections.Generic;
using System.Threading;
namespace cAlgo
{
    [Levels(80, 20)]
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class StochOptimizer : Indicator
    {
        [Parameter(DefaultValue = 4)]
        public int minPer { get; set; }
        [Parameter(DefaultValue = 50)]
        public int maxPer { get; set; }

        [Parameter(DefaultValue = 4)]
        public int minSmt { get; set; }
        [Parameter(DefaultValue = 20)]
        public int maxSmt { get; set; }

        [Parameter("Deviation in Pips", DefaultValue = 50)]
        public double Deviation { get; set; }

        [Output("%K", PlotType = PlotType.Line)]
        public IndicatorDataSeries K { get; set; }
        [Output("%D", Color = Colors.Red, PlotType = PlotType.Line)]
        public IndicatorDataSeries D { get; set; }

        private StochasticOscillator sto;
        private ZigZagAndFiboLevels zz;

        private int countUp = 0, countDown = 0, zzCount = 0;
        private int HBought = 0, HSold = 0;
        public int start, end;

        private bool _start = false, _end = false;

        protected override void Initialize()
        {
            Deviation = 100 * Deviation * Symbol.PipSize / Symbol.Bid;
            zz = Indicators.GetIndicator<ZigZagAndFiboLevels>(Deviation, false, false, false);
            Chart.MouseDown += OnChartMouseDown;
        }

        void OnChartMouseDown(ChartMouseEventArgs obj)
        {
            if (obj.CtrlKey && !obj.AltKey && !obj.ShiftKey)
            {
                start = (int)obj.BarIndex;
                Chart.DrawVerticalLine("start", start, Color.White);
                _start = true;
            }
            else if (!obj.CtrlKey && obj.AltKey && !obj.ShiftKey)
            {
                end = (int)obj.BarIndex;
                Chart.DrawVerticalLine("end", end, Color.White);
                _end = true;
            }
            if (_start && _end && start > end)
            {
                start = end - start;
                end = end - start;
                start = start + end;
            }
            if ((obj.CtrlKey || obj.AltKey) && _start && _end)
            {
                for (int i = 0; i < Chart.BarsTotal; i++)
                {
                    K[i] = double.NaN;
                    D[i] = double.NaN;
                }
                calculate();
            }
        }

        public void calculate()
        {
            List<double[]> stochs = new List<double[]>();
            for (int i = minPer; i <= maxPer; i++)
            {
                //Print("Loading: " + 100 * (i - minPer) / (maxPer - minPer) + "%");
                for (int k = minSmt; k <= maxSmt; k++)
                {
                    sto = Indicators.StochasticOscillator(i, k, 0, MovingAverageType.Simple);
                    Reset_Vars();
                    for (int j = start; j < end; j++)
                    {
                        Count(j);
                    }
                    stochs.Add(new double[3]);
                    stochs[stochs.Count - 1][0] = i;
                    stochs[stochs.Count - 1][1] = k;
                    stochs[stochs.Count - 1][2] = 100 * ((double)(countUp + countDown) / zzCount);
                    Print(i + " " + k + " " + 100 * ((double)(countUp + countDown) / zzCount));
                }
            }


            int index = 0;
            double Value = 0;


            for (int i = 0; i < stochs.Count; i++)
            {
                if (stochs[i][2] > Value)
                {
                    Value = stochs[i][2];
                    index = i;
                }
            }
            sto = Indicators.StochasticOscillator((int)stochs[index][0], (int)stochs[index][1], 12, MovingAverageType.Simple);
            Chart.DrawStaticText("prob", "Probabilities of an inversion with current settings (" + stochs[index][0] + ", " + stochs[index][1] + ") is: " + Math.Round(stochs[index][2], 2) + "%", VerticalAlignment.Top, HorizontalAlignment.Left, Color.YellowGreen);
            for (int i = 0; i < Chart.BarsTotal; i++)
            {
                K[i] = sto.PercentK[i];
                D[i] = sto.PercentD[i];
            }
            stochs = null;
        }

        public override void Calculate(int index)
        {
            if (sto != null)
            {
                K[index] = sto.PercentK[index];
                D[index] = sto.PercentD[index];
            }
        }

        private void Count(int i)
        {
            if (!double.IsNaN(zz.Value[i]))
            {
                zzCount++;
                if (sto.PercentK[i] < 20 && zz.Value[i] == MarketSeries.Low[i])
                    countUp++;
                else if (sto.PercentK[i] > 80 && zz.Value[i] == MarketSeries.High[i])
                    countDown++;
            }

            if (sto.PercentK[i] > 80)
                HBought++;
            else if (sto.PercentK[i] < 20)
                HSold++;
            return;
        }

        private void Reset_Vars()
        {
            countUp = 0;
            countDown = 0;
            zzCount = 0;
            HBought = 0;
            HSold = 0;
            return;
        }

    }
}


CY
cysecsbin.01

Joined on 10.11.2018 Blocked

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: StochOptimizer.algo
  • Rating: 0
  • Installs: 1570
  • Modified: 13/10/2021 09:54
Comments
Log in to add a comment.
No comments found.