Description
This indicator is inspired by the idea of the "Ten-Day Moving Average Trading Rule" introduced by Chester W. Keltner in 1960. It calculates the %d between the price and the 10 periods MA using typical price. The histogram uses a MA of the high/low prices as a filter. I added an adicional filter of %level (it can be turned off with 0 value). This filter must be adjusted according to the volatility of the timeframe and asset.
Log:
Tue Sep 21, 2021: Added two signal types for the arrows.
Tue Sep 21, 2021: Added Smoothing.
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class KCOscillatorModv1 : Indicator
{
[Parameter("MA Period", DefaultValue = 10, MinValue = 2, Step = 1)]
public int maPeriod { get; set; }
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
public MovingAverageType maType { get; set; }
[Parameter("%D Filter", DefaultValue = 0.2, MinValue = 0)]
public double percDFilter { get; set; }
[Parameter("Smoothing", DefaultValue = 1, MinValue = 1)]
public int smoothing { get; set; }
[Parameter("Arrows", DefaultValue = true)]
public bool arrows { get; set; }
[Parameter("Arrow Distance", DefaultValue = 1)]
public double arrowDistance { get; set; }
[Parameter("H/L MA Crossing Signal", DefaultValue = true)]
public bool hlSignal { get; set; }
[Parameter("%D Crossing Signal", DefaultValue = true)]
public bool percDSignal { get; set; }
[Output("Up Histogram 1", LineColor = "FF008080", PlotType = PlotType.Histogram, Thickness = 4)]
public IndicatorDataSeries up1 { get; set; }
[Output("Up Histogram 2", LineColor = "FF77B0B2", PlotType = PlotType.Histogram, Thickness = 4)]
public IndicatorDataSeries up2 { get; set; }
[Output("Down Histogram 1", LineColor = "FFA52A2A", PlotType = PlotType.Histogram, Thickness = 4)]
public IndicatorDataSeries down1 { get; set; }
[Output("Down Histogram 2", LineColor = "FFC4898A", PlotType = PlotType.Histogram, Thickness = 4)]
public IndicatorDataSeries down2 { get; set; }
[Output("Neutral Histogram", LineColor = "FFC0C0C0", PlotType = PlotType.Histogram, Thickness = 4)]
public IndicatorDataSeries neutral { get; set; }
[Output("Difference Line", LineColor = "FFC0C0C0", LineStyle = LineStyle.Solid, PlotType = PlotType.Line, Thickness = 2)]
public IndicatorDataSeries diff { get; set; }
[Output("Highfilter", LineColor = "FFC0C0C0", LineStyle = LineStyle.DotsRare, Thickness = 1)]
public IndicatorDataSeries highFilter { get; set; }
[Output("Lowfilter", LineColor = "FFC0C0C0", LineStyle = LineStyle.DotsRare, Thickness = 1)]
public IndicatorDataSeries lowFilter { get; set; }
private IndicatorDataSeries source, source2, source3, priceDiff, maHigh, maLow, range;
private MovingAverage maTypical, smooth11, smooth21, smooth31, smooth12, smooth22, smooth32;
private AverageTrueRange atr;
protected override void Initialize()
{
source = CreateDataSeries();
source2 = CreateDataSeries();
source3 = CreateDataSeries();
maHigh = CreateDataSeries();
maLow = CreateDataSeries();
range = CreateDataSeries();
priceDiff = CreateDataSeries();
smooth11 = Indicators.MovingAverage(source2, smoothing, MovingAverageType.WilderSmoothing);
smooth21 = Indicators.MovingAverage(smooth11.Result, smoothing, MovingAverageType.WilderSmoothing);
smooth31 = Indicators.MovingAverage(smooth21.Result, smoothing, MovingAverageType.WilderSmoothing);
smooth12 = Indicators.MovingAverage(source3, smoothing, MovingAverageType.WilderSmoothing);
smooth22 = Indicators.MovingAverage(smooth12.Result, smoothing, MovingAverageType.WilderSmoothing);
smooth32 = Indicators.MovingAverage(smooth22.Result, smoothing, MovingAverageType.WilderSmoothing);
maTypical = Indicators.MovingAverage(source, maPeriod, maType);
atr = Indicators.AverageTrueRange(27, MovingAverageType.Simple);
}
public override void Calculate(int index)
{
// Indicator
source[index] = (Bars.HighPrices[index] + Bars.LowPrices[index] + Bars.ClosePrices[index]) / 3;
source2[index] = maTypical.Result[index];
source3[index] = ((Bars.ClosePrices[index] - smooth31.Result[index]) / ((Bars.ClosePrices[index] + smooth31.Result[index]) / 2)) * 100;
range[index] = (Bars.HighPrices[index] - Bars.LowPrices[index]) / 2;
maHigh[index] = smooth31.Result[index] + range[index];
maLow[index] = smooth31.Result[index] - range[index];
priceDiff[index] = smooth32.Result[index];
if (priceDiff[index] > percDFilter && Bars.ClosePrices[index] > maHigh[index])
{
if (priceDiff[index] >= priceDiff[index - 1])
{
up1[index] = priceDiff[index];
up2[index] = double.NaN;
down1[index] = double.NaN;
down2[index] = double.NaN;
neutral[index] = double.NaN;
}
else
{
up1[index] = double.NaN;
up2[index] = priceDiff[index];
down1[index] = double.NaN;
down2[index] = double.NaN;
neutral[index] = double.NaN;
}
}
else if (priceDiff[index] < -percDFilter && Bars.ClosePrices[index] < maLow[index])
{
if (priceDiff[index] <= priceDiff[index - 1])
{
down1[index] = priceDiff[index];
down2[index] = double.NaN;
up1[index] = double.NaN;
up2[index] = double.NaN;
neutral[index] = double.NaN;
}
else
{
down1[index] = double.NaN;
down2[index] = priceDiff[index];
up1[index] = double.NaN;
up2[index] = double.NaN;
neutral[index] = double.NaN;
}
}
else
{
neutral[index] = priceDiff[index];
up1[index] = double.NaN;
up2[index] = double.NaN;
down1[index] = double.NaN;
down2[index] = double.NaN;
}
diff[index] = priceDiff[index];
highFilter[index] = percDFilter;
lowFilter[index] = percDFilter * -1;
if (arrows)
{
if ((percDSignal && priceDiff[index] > percDFilter && priceDiff[index - 1] < percDFilter) || (hlSignal && Bars.ClosePrices[index] > maHigh[index] && Bars.ClosePrices[index - 1] < maHigh[index - 1]))
{
Chart.DrawIcon("KO Oscillator % Up" + Bars.OpenTimes.Last(0).ToString(), ChartIconType.UpArrow, Bars.OpenTimes.Last(0), Bars.LowPrices.Last(0) - (arrowDistance * atr.Result.Last(1)), "Teal");
}
else
{
Chart.RemoveObject("KO Oscillator % Up" + Bars.OpenTimes.Last(0).ToString());
}
if ((percDSignal && priceDiff[index] < -percDFilter && priceDiff[index - 1] > -percDFilter) || (hlSignal && Bars.ClosePrices[index] < maLow[index] && Bars.ClosePrices[index - 1] > maLow[index - 1]))
{
Chart.DrawIcon("KO Oscillator % Down" + Bars.OpenTimes.Last(0).ToString(), ChartIconType.DownArrow, Bars.OpenTimes.Last(0), Bars.HighPrices.Last(0) + (arrowDistance * atr.Result.Last(1)), "Brown");
}
else
{
Chart.RemoveObject("KO Oscillator % Down" + Bars.OpenTimes.Last(0).ToString());
}
}
}
}
}
danieljclsilva
Joined on 15.03.2019
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: KC Oscillator % Mod v1.2.algo
- Rating: 5
- Installs: 1547
- Modified: 13/10/2021 09:54
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Comments
Log in to add a comment.
No comments found.