├── README.md
└── Indicators
├── IndicatorFundingRates.cs
├── IndicatorTrueRange.cs
├── IndicatorSUM.cs
├── IndicatorAbnormalVolume.cs
├── IndicatorOpenInterest.cs
├── IndicatorBalanceOfPower.cs
├── IndicatorRateOfChange.cs
├── IndicatorRLarryWilliams.cs
├── IndicatorCamarilla.cs
├── IndicatorPivotPointMovingAverage.cs
├── IndicatorMomentum.cs
├── IndicatorRelativeVigorIndex.cs
├── IndicatorSimpleMovingAverage.cs
├── IndicatorFYL.cs
├── IndicatorAroon.cs
├── IndicatorAwesomeOscillator.cs
├── IndicatorKairiRelativeIndex.cs
├── IndicatorLinearlyWeightedMovingAverage.cs
├── IndicatorHullMovingAverage.cs
├── IndicatorChandeMomentumOscillator.cs
├── IndicatorBandas.cs
├── IndicatorBBS.cs
├── IndicatorPolynomialRegressionChannel.cs
├── IndicatorPositiveVolumeIndex.cs
├── IndicatorModifiedMovingAverage.cs
├── IndicatorMoneyFlowIndex.cs
├── IndicatorDeltaDivergenceReversal.cs
├── IndicatorSuperTrend.cs
├── IndicatorRegressionLine.cs
├── IndicatorTripleExponentialAverage.cs
├── IndicatorPriceChannel.cs
├── IndicatorStochasticRelativeStrengthIndex.cs
├── IndicatorTimeHistogram.cs
├── IndicatorAverageTrueRange.cs
├── IndicatorContador.cs
├── IndicatorMcGinleyDynamic.cs
├── IndicatorStandardDeviation.cs
├── IndicatorAccelerationOscillator.cs
├── IndicatorRelativeStrengthIndexSmoothed.cs
├── IndicatorPriceOscillator.cs
├── IndicatorSchaffTrendCycle.cs
├── IndicatorBollingerBands.cs
├── IndicatorMovingAverageEnvelope.cs
├── IndicatorSmoothedMovingAverage.cs
├── IndicatorMovingAverageOfOscillator.cs
├── IndicatorQstick.cs
├── IndicatorBollingerBandsFlat.cs
├── IndicatorCommodityChannelIndex.cs
├── IndicatorKeltnerChannel.cs
├── Indicator3MASignal.cs
├── IndicatorPercentagePriceOscillator.cs
├── IndicatorExponentialMovingAverage.cs
├── IndicatorATRTrailingStopWithFibRetracements.cs
├── IndicatorIchimoku.cs
├── IndicatorDeltaFlow.cs
├── IndicatorSeparatedAverageTrueRange.cs
├── IndicatorTrueStrengthIndex.cs
└── IndicatorRoundNumbers.cs
/README.md:
--------------------------------------------------------------------------------
1 | # Scripts
2 |
--------------------------------------------------------------------------------
/Indicators/IndicatorFundingRates.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2021. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace BarsDataIndicators;
7 |
8 | public sealed class IndicatorFundingRates : Indicator
9 | {
10 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorFundingRates.cs";
11 |
12 | public IndicatorFundingRates()
13 | {
14 | this.Name = "Funding Rates";
15 | this.Description = "";
16 |
17 | this.AddLineSeries("FundingRate", Color.Green, 2);
18 | this.SeparateWindow = true;
19 | }
20 |
21 | protected override void OnUpdate(UpdateArgs args)
22 | {
23 | double fundingRate = this.FundingRate();
24 |
25 | if (!double.IsNaN(fundingRate))
26 | fundingRate *= 100;
27 |
28 | this.SetValue(fundingRate);
29 | }
30 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorTrueRange.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace VolatilityIndicators;
8 |
9 | public class IndicatorTrueRange : Indicator
10 | {
11 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorTrueRange.cs";
12 |
13 | public IndicatorTrueRange()
14 | : base()
15 | {
16 | // Defines indicator's name and description.
17 | Name = "True Range";
18 |
19 | // Defines line on demand with particular parameters.
20 | this.AddLineSeries("TR", Color.CadetBlue, 1, LineStyle.Solid);
21 |
22 | this.SeparateWindow = true;
23 | }
24 |
25 | protected override void OnUpdate(UpdateArgs args)
26 | {
27 | double tr = this.CalculateTrueRange();
28 |
29 | this.SetValue(tr);
30 | }
31 |
32 | public double CalculateTrueRange(int offset = 0)
33 | {
34 | double hi = this.GetPrice(PriceType.High, offset);
35 | double lo = this.GetPrice(PriceType.Low, offset);
36 |
37 | double prevClose = (Count <= offset + 1) ? this.Close(offset)
38 | : this.Close(offset + 1);
39 |
40 | return Math.Max(hi - lo, Math.Max(Math.Abs(prevClose - hi), Math.Abs(prevClose - lo)));
41 | }
42 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorSUM.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2023. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace OscillatorsIndicators;
7 |
8 | public class IndicatorSUM : Indicator
9 | {
10 | #region Parameters
11 | [InputParameter("Period", 10, 1, 99999, 0, 0)]
12 | public int Period = 14;
13 |
14 | [InputParameter("Sources prices", 1, variants: new object[] {
15 | "Close", PriceType.Close,
16 | "Open", PriceType.Open,
17 | "High", PriceType.High,
18 | "Low", PriceType.Low,
19 | "Typical", PriceType.Typical,
20 | "Medium", PriceType.Median,
21 | "Weighted", PriceType.Weighted,
22 | "Volume", PriceType.Volume,
23 | "Open interest", PriceType.OpenInterest
24 | })]
25 | public PriceType SourcePrice = PriceType.Close;
26 |
27 | public override string ShortName => $"{this.Name} ({this.Period}: {this.SourcePrice})";
28 |
29 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorSUM.cs";
30 |
31 | #endregion Parameters
32 |
33 | public IndicatorSUM()
34 | {
35 | this.Name = "Sum";
36 | this.AddLineSeries("Sum", Color.Orange, 1, LineStyle.Solid);
37 | this.SeparateWindow = true;
38 | }
39 |
40 | protected override void OnUpdate(UpdateArgs args)
41 | {
42 | var prevValue = this.Count > 1 ? this.GetValue(1) : 0;
43 | var prevPrice = this.Count <= this.Period ? 0 : this.GetPrice(this.SourcePrice, this.Period);
44 |
45 | var value = this.GetPrice(this.SourcePrice) + (double.IsNaN(prevValue) ? 0 : prevValue) - prevPrice;
46 |
47 | this.SetValue(value);
48 | }
49 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorAbnormalVolume.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace VolumeIndicators;
7 |
8 | public class IndicatorAbnormalVolume : Indicator, IWatchlistIndicator
9 | {
10 | [InputParameter]
11 | public int Period = 60;
12 |
13 | [InputParameter]
14 | public double SignalLine = 5.0;
15 |
16 | [InputParameter]
17 | public Color MarkerColor = Color.Green;
18 |
19 | public int MinHistoryDepths => Period;
20 | public override string ShortName => "AV";
21 |
22 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorAbnormalVolume.cs";
23 |
24 | public IndicatorAbnormalVolume()
25 | : base()
26 | {
27 | this.Name = "Abnormal Volume";
28 | this.Description = "Shows the ratio of the volume of the current bar to the 'Period' of the previous ones";
29 |
30 | this.AddLineSeries("Main Line", Color.CadetBlue, 1, LineStyle.Histogramm);
31 | this.AddLineSeries("Signal Line", Color.CadetBlue, 1, LineStyle.Solid);
32 | this.SeparateWindow = true;
33 | }
34 |
35 | protected override void OnInit()
36 | {
37 | // Add your initialization code here
38 | }
39 |
40 | protected override void OnUpdate(UpdateArgs args)
41 | {
42 | if (this.Count <= this.Period)
43 | return;
44 |
45 | double sum = 0.0; // Sum of prices
46 | for (int i = 1; i <= this.Period; i++)
47 | sum += this.Volume(i);
48 |
49 | double averageVolume = sum / this.Period;
50 | double value = this.Volume() / averageVolume;
51 | this.SetValue(value);
52 | this.SetValue(this.SignalLine, 1);
53 | LinesSeries[0].RemoveMarker(0);
54 | if (GetValue() >= GetValue(0, 1))
55 | {
56 | LinesSeries[0].SetMarker(0, new IndicatorLineMarker(MarkerColor, IndicatorLineMarkerIconType.DownArrow));
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorOpenInterest.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace BarsDataIndicators;
7 |
8 | public sealed class IndicatorOpenInterest : Indicator, IWatchlistIndicator
9 | {
10 | [InputParameter("Smooth period", 10, 1, int.MaxValue, 1, 0)]
11 | public int MaPeriod;
12 |
13 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorOpenInterest.cs";
14 |
15 | public override string ShortName
16 | {
17 | get
18 | {
19 | string name = this.Name;
20 | if (this.LinesSeries[1].Visible)
21 | name += $" ({this.MaPeriod})";
22 |
23 | return name;
24 | }
25 | }
26 |
27 | public int MinHistoryDepths => this.MaPeriod;
28 |
29 | private Indicator sma;
30 |
31 | public IndicatorOpenInterest()
32 | : base()
33 | {
34 | // Defines indicator's group, name and description.
35 | this.Name = "Open Interest";
36 | this.Description = "The total number of outstanding derivative contracts";
37 |
38 | this.MaPeriod = 10;
39 | this.SeparateWindow = true;
40 |
41 | // Defines line on demand with particular parameters.
42 | this.AddLineSeries("OpenInterest", Color.Green, 2, LineStyle.Solid);
43 | this.AddLineSeries("Smooth OI", Color.Orange, 2, LineStyle.Solid);
44 | }
45 |
46 | protected override void OnInit()
47 | {
48 | this.sma = Core.Indicators.BuiltIn.SMA(this.MaPeriod, PriceType.OpenInterest);
49 | this.AddIndicator(this.sma);
50 | }
51 |
52 | protected override void OnUpdate(UpdateArgs args)
53 | {
54 | base.OnUpdate(args);
55 |
56 | if (this.Count > 0 && this.HistoricalData.Count >= this.Count)
57 | {
58 | double openInterest = this.OpenInterest();
59 | this.SetValue(openInterest);
60 |
61 | if (this.Count > this.MaPeriod)
62 | this.SetValue(this.sma.GetValue(), 1, 0);
63 | }
64 | }
65 |
66 | protected override void OnClear()
67 | {
68 | if (this.sma != null)
69 | {
70 | this.RemoveIndicator(this.sma);
71 | this.sma?.Dispose();
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorBalanceOfPower.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace OscillatorsIndicators;
7 |
8 | public class IndicatorBalanceOfPower : Indicator
9 | {
10 | private const int CURRENT_BAR_OFFSET = 0;
11 | private const PriceType INDICATOR_SOURCE_PRICE_TYPE = PriceType.Close;
12 |
13 | [InputParameter("Smoothing period", 0, 1, 999, 1, 2)]
14 | public int SmoothingPeriod = 5;
15 |
16 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorBalanceOfPower.cs";
17 |
18 | [InputParameter("Smoothing Type", 3, variants: new object[]
19 | {
20 | "Simple Moving Average", MaMode.SMA,
21 | "Exponential Moving Average", MaMode.EMA,
22 | "Smoothed Moving Average", MaMode.SMMA,
23 | "Linearly Weighted Moving Average", MaMode.LWMA,
24 | })]
25 | public MaMode MaType = MaMode.SMA;
26 |
27 | public override string ShortName => $"BOP ({this.SmoothingPeriod})";
28 |
29 | private HistoricalDataCustom smoothingSource;
30 | private Indicator smoothing;
31 |
32 | public IndicatorBalanceOfPower()
33 | : base()
34 | {
35 | this.Name = "Balance Of Power";
36 | this.AddLineSeries("BoP Line", Color.CadetBlue, 1, LineStyle.Solid);
37 | this.AddLineSeries("Smoothed Line", Color.Blue, 1, LineStyle.Solid);
38 | this.SeparateWindow = true;
39 | }
40 | protected override void OnInit()
41 | {
42 | this.smoothing = Core.Instance.Indicators.BuiltIn.MA(this.SmoothingPeriod, INDICATOR_SOURCE_PRICE_TYPE, this.MaType);
43 | this.smoothingSource = new HistoricalDataCustom(this);
44 | this.smoothingSource.AddIndicator(this.smoothing);
45 | }
46 | protected override void OnUpdate(UpdateArgs args)
47 | {
48 | if (this.Count <= this.SmoothingPeriod + 1)
49 | return;
50 |
51 | var highLowDeltaPrice = this.High(CURRENT_BAR_OFFSET) - this.Low(CURRENT_BAR_OFFSET);
52 | var bop = highLowDeltaPrice != default
53 | ? (this.Close(CURRENT_BAR_OFFSET) - this.Open(CURRENT_BAR_OFFSET)) / highLowDeltaPrice
54 | : default;
55 |
56 | this.smoothingSource[INDICATOR_SOURCE_PRICE_TYPE] = bop;
57 |
58 | this.SetValue(bop);
59 | this.SetValue(this.smoothing.GetValue(), 1);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Indicators/IndicatorRateOfChange.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | public sealed class IndicatorRateOfChange : Indicator, IWatchlistIndicator
9 | {
10 | // Displays 'Period' input parameter as input field.
11 | [InputParameter("Period of momentum", 0, 1, 999, 1, 0)]
12 | public int Period = 9;
13 |
14 | public int MinHistoryDepths => this.Period + 1;
15 | public override string ShortName => $"ROC ({this.Period})";
16 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/rate-of-change";
17 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorRateOfChange.cs";
18 |
19 | ///
20 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
21 | ///
22 | public IndicatorRateOfChange()
23 | : base()
24 | {
25 | // Defines indicator's name and description.
26 | this.Name = "Rate of Change";
27 | this.Description = "Shows the speed at which price is changing";
28 |
29 | // Defines line on demand with particular parameters.
30 | this.AddLineSeries("ROC", Color.Brown, 2, LineStyle.Solid);
31 | this.AddLineLevel(0d, "Zero", Color.Gray, 2, LineStyle.Solid);
32 |
33 | this.SeparateWindow = true;
34 | }
35 |
36 | ///
37 | /// Calculation entry point. This function is called when a price data updates.
38 | /// Will be runing under the HistoricalBar mode during history loading.
39 | /// Under NewTick during realtime.
40 | /// Under NewBar if start of the new bar is required.
41 | ///
42 | /// Provides data of updating reason and incoming price.
43 | protected override void OnUpdate(UpdateArgs args)
44 | {
45 | // Skip some period for correct calculation.
46 | if (this.Count < this.MinHistoryDepths)
47 | return;
48 |
49 | // Get close price.
50 | double price = this.Close();
51 |
52 | // Get close price by offset.
53 | double priceN = this.Close(this.Period);
54 |
55 | double roc = 100 * (price - priceN) / priceN;
56 |
57 | // Set value to 'ROC' line buffer.
58 | this.SetValue(roc);
59 | }
60 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorRLarryWilliams.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Drawing;
6 | using System.Linq;
7 | using TradingPlatform.BusinessLayer;
8 |
9 | namespace Oscillators;
10 |
11 | public sealed class IndicatorRLarryWilliams : Indicator, IWatchlistIndicator
12 | {
13 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
14 | [InputParameter("Period", 0, 1, 9999, 1, 0)]
15 | public int Period = 14;
16 |
17 | public int MinHistoryDepths => this.Period;
18 | public override string ShortName => $"RLW ({this.Period})";
19 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/r-larry-williams";
20 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorQstick.cs";
21 |
22 | ///
23 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
24 | ///
25 | public IndicatorRLarryWilliams()
26 | : base()
27 | {
28 | // Serves for an identification of related indicators with different parameters.
29 | this.Name = "%R Larry Williams";
30 | this.Description = "Uses Stochastic to determine overbought and oversold levels";
31 |
32 | // Defines line on demand with particular parameters.
33 | this.AddLineSeries("RLW Line", Color.Blue, 1, LineStyle.Solid);
34 | this.AddLineLevel(-20, "Upper Limit", Color.Red, 1, LineStyle.Solid);
35 | this.AddLineLevel(-80, "Lower Limit", Color.Red, 1, LineStyle.Solid);
36 |
37 | this.SeparateWindow = true;
38 | }
39 |
40 | ///
41 | /// Calculation entry point. This function is called when a price data updates.
42 | /// Will be runing under the HistoricalBar mode during history loading.
43 | /// Under NewTick during realtime.
44 | /// Under NewBar if start of the new bar is required.
45 | ///
46 | /// Provides data of updating reason and incoming price.
47 | protected override void OnUpdate(UpdateArgs args)
48 | {
49 | if (this.Count < this.Period)
50 | return;
51 |
52 | double highestPrice = Enumerable.Range(0, this.Period).Select(i => this.GetPrice(PriceType.High, i)).Max();
53 | double lowestPrice = Enumerable.Range(0, this.Period).Select(i => this.GetPrice(PriceType.Low, i)).Min();
54 |
55 | if (highestPrice - lowestPrice > 1e-7)
56 | this.SetValue(-100 * (highestPrice - this.GetPrice(PriceType.Close)) / (highestPrice - lowestPrice));
57 | }
58 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorCamarilla.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace TrendIndicators;
8 |
9 | public class IndicatorCamarilla : Indicator
10 | {
11 | private HistoricalData dailyHistoricalData;
12 |
13 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorCamarilla.cs";
14 |
15 | public IndicatorCamarilla()
16 | : base()
17 | {
18 | Name = "Camarilla";
19 |
20 | AddLineSeries("R1", Color.IndianRed, 1, LineStyle.Solid);
21 | AddLineSeries("S1", Color.IndianRed, 1, LineStyle.Solid);
22 |
23 | AddLineSeries("R2", Color.OrangeRed, 1, LineStyle.Solid);
24 | AddLineSeries("S2", Color.OrangeRed, 1, LineStyle.Solid);
25 |
26 | AddLineSeries("R3", Color.DarkOliveGreen, 1, LineStyle.Solid);
27 | AddLineSeries("S3", Color.DarkOliveGreen, 1, LineStyle.Solid);
28 |
29 | AddLineSeries("R4", Color.Green, 1, LineStyle.Solid);
30 | AddLineSeries("S4", Color.Green, 1, LineStyle.Solid);
31 |
32 | SeparateWindow = false;
33 | }
34 |
35 | protected override void OnInit()
36 | {
37 | // Download daily historical data with a ten-day margin
38 | this.dailyHistoricalData = this.Symbol.GetHistory(Period.DAY1, Time(Count - 1).Date.AddDays(-10));
39 | }
40 |
41 | protected override void OnUpdate(UpdateArgs args)
42 | {
43 | int index = (int)dailyHistoricalData.GetIndexByTime(Time().Date.AddDays(-1).Ticks, SeekOriginHistory.End);
44 |
45 | // Get the bar value of the previous day
46 | HistoryItemBar previousDayBar = (HistoryItemBar)dailyHistoricalData[index];
47 |
48 | for (int i = 1; i <= 8; i++)
49 | {
50 | int number = (int)Math.Round((double)i / 2, MidpointRounding.AwayFromZero);
51 | if (i % 2 == 1)
52 | SetValue((previousDayBar.High - previousDayBar.Low) * (1.1 / Fibonacci(4 - number + 1)) + previousDayBar.Close, i - 1); //Set value for resistance
53 | else
54 | SetValue(previousDayBar.Close - (previousDayBar.High - previousDayBar.Low) * (1.1 / Fibonacci(4 - number + 1)), i - 1);//Set value to support
55 | }
56 | }
57 |
58 | private int Fibonacci(int n) //Get coefficient - 2,4,6,12 in this case
59 | {
60 | int a = 2;
61 | int b = 0;
62 | if (n == 1)
63 | return a;
64 | for (int i = 2; i <= n; i++)
65 | {
66 | if (i % 2 == 0)
67 | b = a * 2;
68 | else
69 | b = a * 3 / 2;
70 | a = b;
71 | }
72 | return b;
73 | }
74 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorPivotPointMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace MovingAverages;
7 |
8 | public sealed class IndicatorPivotPointMovingAverage : Indicator, IWatchlistIndicator
9 | {
10 | // Define 'Period' input parameter and set allowable range (from 1 to 999)
11 | [InputParameter("Period of PPMA", 0, 1, 9999, 1, 0)]
12 | public int Period = 5;
13 |
14 | public int MinHistoryDepths => this.Period;
15 | public override string ShortName => $"PPMA ({this.Period})";
16 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorPivotPointMovingAverage.cs";
17 |
18 | ///
19 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
20 | ///
21 | public IndicatorPivotPointMovingAverage()
22 | {
23 | // Defines indicator's name and description.
24 | this.Name = "Pivot Point Moving Average";
25 | this.Description = "Uses the pivot point calculation as the input a simple moving average";
26 |
27 | // Define two lines with particular parameters
28 | this.AddLineSeries("PP", Color.CadetBlue, 1, LineStyle.Solid);
29 | this.AddLineSeries("PPMA", Color.Yellow, 1, LineStyle.Solid);
30 |
31 | this.SeparateWindow = false;
32 | }
33 |
34 | ///
35 | /// Calculation entry point. This function is called when a price data updates.
36 | /// Will be runing under the HistoricalBar mode during history loading.
37 | /// Under NewTick during realtime.
38 | /// Under NewBar if start of the new bar is required.
39 | ///
40 | /// Provides data of updating reason and incoming price.
41 | protected override void OnUpdate(UpdateArgs args)
42 | {
43 | // Get pivot value for current bar
44 | double pivot = this.GetPivotByOffset(0);
45 |
46 | // Set "pivot" value to the 'PP' line buffer (line index is 0)
47 | this.SetValue(pivot);
48 |
49 | // Skip some period for correct calculation.
50 | if (this.Count < this.MinHistoryDepths)
51 | return;
52 |
53 | // Calculate the sum of pivot values for the range (PPMAPeriod)
54 | double sum = pivot;
55 | for (int i = 1; i < this.Period; i++)
56 | sum += this.GetPivotByOffset(i);
57 |
58 | this.SetValue(sum / this.Period, 1);
59 | }
60 |
61 | ///
62 | /// Compute pivot point value
63 | ///
64 | /// Historical offset
65 | /// Pivot point value
66 | private double GetPivotByOffset(int offset) => (this.High(offset) + this.Low(offset) + this.Close(offset)) / 3;
67 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorMomentum.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | public sealed class IndicatorMomentum : Indicator, IWatchlistIndicator
9 | {
10 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
11 | [InputParameter("Period for Momentum", 0, 1, 999, 1, 0)]
12 | public int Period = 10;
13 |
14 | // Displays Input Parameter as dropdown list.
15 | [InputParameter("Sources prices for Momentum", 1, variants: new object[] {
16 | "Close", PriceType.Close,
17 | "Open", PriceType.Open,
18 | "High", PriceType.High,
19 | "Low", PriceType.Low,
20 | "Typical", PriceType.Typical,
21 | "Medium", PriceType.Median,
22 | "Weighted", PriceType.Weighted,
23 | "Volume", PriceType.Volume,
24 | "Open interest", PriceType.OpenInterest
25 | })]
26 | public PriceType SourcePrice = PriceType.Close;
27 |
28 | public int MinHistoryDepths => this.Period + 1;
29 | public override string ShortName => $"Momentum ({this.Period}: {this.SourcePrice})";
30 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/momentum";
31 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorMomentum.cs";
32 |
33 | ///
34 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
35 | ///
36 | public IndicatorMomentum()
37 | : base()
38 | {
39 | // Serves for an identification of related indicators with different parameters.
40 | this.Name = "Momentum";
41 | this.Description = "Momentum compares where the current price is in relation to where the price was in the past.";
42 |
43 | // Defines line on demand with particular parameters.
44 | this.AddLineSeries("Momentum Line", Color.Blue, 1, LineStyle.Solid);
45 | this.AddLineLevel(0, "Threshold Line", Color.Gray, 1, LineStyle.Dot);
46 |
47 | this.SeparateWindow = true;
48 | }
49 |
50 | ///
51 | /// Calculation entry point. This function is called when a price data updates.
52 | /// Will be runing under the HistoricalBar mode during history loading.
53 | /// Under NewTick during realtime.
54 | /// Under NewBar if start of the new bar is required.
55 | ///
56 | /// Provides data of updating reason and incoming price.
57 | protected override void OnUpdate(UpdateArgs args)
58 | {
59 | if (this.Count < this.MinHistoryDepths)
60 | return;
61 |
62 | this.SetValue(this.GetPrice(this.SourcePrice) - this.GetPrice(this.SourcePrice, this.Period));
63 | }
64 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorRelativeVigorIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace OscillatorsIndicators;
7 |
8 | public class IndicatorRelativeVigorIndex : Indicator
9 | {
10 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorRelativeVigorIndex.cs";
11 |
12 | public IndicatorRelativeVigorIndex()
13 | : base()
14 | {
15 | // Defines indicator's name and description.
16 | Name = "Relative Vigor Index";
17 | Description = "Indicator measures the strength of a trend by comparing a security's closing price to its trading range while smoothing the results using a simple moving average.";
18 |
19 | // Defines line on demand with particular parameters.
20 | AddLineSeries("Signal line", Color.Red, 1, LineStyle.Solid);
21 | AddLineSeries("RVI line", Color.Green, 1, LineStyle.Solid);
22 |
23 | // By default indicator will be applied on main window of the chart
24 | SeparateWindow = true;
25 | }
26 |
27 | protected override void OnInit()
28 | {
29 | // Add your initialization code here
30 | }
31 |
32 | [InputParameter]
33 | public int Period = 2;
34 | protected override void OnUpdate(UpdateArgs args)
35 | {
36 | if (Count <= Period)
37 | return;
38 | SetValue(GetRVI(), 1);
39 | SetValue(GetSignalLine(), 0);
40 | }
41 |
42 | private double CloseMinusOpen(int index = 0)
43 | {
44 | return Close(index) - Open(index);
45 | }
46 | private double HightMinusLow(int index = 0)
47 | {
48 | return High(index) - Low(index);
49 | }
50 | private double Numerator(int index = 0)
51 | {
52 | double numerator = CloseMinusOpen(index) + 2 * CloseMinusOpen(index + 1) + 2 * CloseMinusOpen(index + 2) + CloseMinusOpen(index + 3);
53 | return numerator / 6;
54 | }
55 | private double Denominator(int index = 0)
56 | {
57 | double denominator = HightMinusLow(index) + 2 * HightMinusLow(index + 1) + 2 * HightMinusLow(index + 2) + HightMinusLow(index + 3);
58 | return denominator / 6;
59 | }
60 | private double GetRVI(int index = 0)
61 | {
62 | double numeratorSMA = 0;
63 | double denominatorSMA = 0;
64 |
65 | for (int i = 0; i < Period; i++)
66 | {
67 | numeratorSMA = numeratorSMA + Numerator(i + index);
68 | denominatorSMA = denominatorSMA + Denominator(i + index);
69 | }
70 | numeratorSMA = numeratorSMA / Period;
71 | denominatorSMA = denominatorSMA / Period;
72 | return numeratorSMA / denominatorSMA;
73 | }
74 | private double GetSignalLine()
75 | {
76 | double signalLine = 0;
77 | signalLine = GetRVI() + 2 * GetRVI(1) + 2 * GetRVI(2) + GetRVI(3);
78 |
79 |
80 | return signalLine / 6;
81 | }
82 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorSimpleMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using TradingPlatform.BusinessLayer;
4 | using System.Drawing;
5 |
6 | namespace MovingAverages;
7 |
8 | public sealed class IndicatorSimpleMovingAverage : Indicator, IWatchlistIndicator
9 | {
10 | // Displays Input Parameter as input field.
11 | [InputParameter("Period of Simple Moving Average", 0, 1, 9999, 1, 1)]
12 | public int Period = 20;
13 |
14 | // Displays Input Parameter as dropdown list.
15 | [InputParameter("Sources prices for MA", 1, variants: new object[]{
16 | "Close", PriceType.Close,
17 | "Open", PriceType.Open,
18 | "High", PriceType.High,
19 | "Low", PriceType.Low,
20 | "Typical", PriceType.Typical,
21 | "Median", PriceType.Median,
22 | "Weighted", PriceType.Weighted,
23 | "Base asset volume", PriceType.Volume,
24 | "Quote asset volume", PriceType.QuoteAssetVolume,
25 | "Open interest", PriceType.OpenInterest
26 | })]
27 | public PriceType SourcePrice = PriceType.Close;
28 |
29 | public int MinHistoryDepths => this.Period;
30 | public override string ShortName => $"SMA ({this.Period}:{this.SourcePrice})";
31 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorSimpleMovingAverage.cs";
32 |
33 | ///
34 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
35 | ///
36 | public IndicatorSimpleMovingAverage()
37 | : base()
38 | {
39 | // Defines indicator's name and description.
40 | this.Name = "Simple Moving Average";
41 | this.Description = "Average price for the last N periods";
42 |
43 | // Define one line with particular parameters
44 | this.AddLineSeries("SMA", Color.Red, 1, LineStyle.Solid);
45 |
46 | this.SeparateWindow = false;
47 | }
48 |
49 | ///
50 | /// Calculation entry point. This function is called when a price data updates.
51 | /// Will be runing under the HistoricalBar mode during history loading.
52 | /// Under NewTick during realtime.
53 | /// Under NewBar if start of the new bar is required.
54 | ///
55 | /// Provides data of updating reason and incoming price.
56 | protected override void OnUpdate(UpdateArgs args)
57 | {
58 | // Checking, if current amount of bars
59 | // more, than period of moving average. If it is
60 | // then the calculation is possible
61 | if (this.Count < this.MinHistoryDepths)
62 | return;
63 |
64 | double sum = 0.0; // Sum of prices
65 | for (int i = 0; i < this.Period; i++)
66 | // Adding bar's price to the sum
67 | sum += this.GetPrice(this.SourcePrice, i);
68 |
69 | // Set value to the "SMA" line buffer.
70 | this.SetValue(sum / this.Period);
71 | }
72 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorFYL.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using TradingPlatform.BusinessLayer;
4 | using System.Drawing;
5 |
6 | namespace MovingAverages;
7 |
8 | #warning Не використовуйте абревіатури у назвах, особливо якщо якщо вони не загальноприйняті
9 | public sealed class IndicatorFYL : Indicator, IWatchlistIndicator
10 | {
11 | #region Parameters
12 |
13 | [InputParameter("Period of Linear Regression", 10, 2, 9999)]
14 | public int Period;
15 |
16 | [InputParameter("Sources prices for the regression line", 20, variants: new object[] {
17 | "Close", PriceType.Close,
18 | "Open", PriceType.Open,
19 | "High", PriceType.High,
20 | "Low", PriceType.Low,
21 | "Typical", PriceType.Typical,
22 | "Medium", PriceType.Median,
23 | "Weighted", PriceType.Weighted,
24 | "Volume", PriceType.Volume,
25 | "Open interest", PriceType.OpenInterest
26 | })]
27 | public PriceType SourcePrice;
28 |
29 | public int MinHistoryDepths => this.Period;
30 | public override string ShortName => $"FYL ({this.Period})";
31 |
32 | private double sumX;
33 | private double divisor;
34 |
35 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorFYL.cs";
36 |
37 | #endregion Parameters
38 |
39 | public IndicatorFYL()
40 | : base()
41 | {
42 | // Defines indicator's name and description.
43 | this.Name = "FYL";
44 | this.Description = "Regression line";
45 |
46 | this.Period = 20;
47 | this.SourcePrice = PriceType.Close;
48 |
49 | // By default indicator will be applied on main window of the chart
50 | this.SeparateWindow = false;
51 |
52 | // Defines line on demand with particular parameters.
53 | this.AddLineSeries("line1", Color.CadetBlue, 1, LineStyle.Solid);
54 | }
55 |
56 | protected override void OnInit()
57 | {
58 | this.sumX = (double)this.Period * (this.Period - 1) * 0.5;
59 | this.divisor = this.sumX * this.sumX - (double)this.Period * this.Period * (this.Period - 1) * (2 * this.Period - 1) / 6;
60 | }
61 | protected override void OnUpdate(UpdateArgs args)
62 | {
63 | //Проверяем что истории достаточно
64 | if (this.Count < this.MinHistoryDepths)
65 | {
66 | double price = this.GetPrice(this.SourcePrice);
67 | this.SetValue(price);
68 | return;
69 | }
70 |
71 | double sumY = 0.0;
72 | double sumXY = 0.0;
73 |
74 | // Calculation of sum
75 | for (int i = 0; i < this.Period; i++)
76 | {
77 | double price = this.GetPrice(this.SourcePrice, i);
78 | sumY += price;
79 | sumXY += i * price;
80 | }
81 |
82 | // Calculation of coefficients
83 | double a = (this.Period * sumXY - this.sumX * sumY) / this.divisor;
84 | double b = (sumY - a * this.sumX) / this.Period;
85 |
86 | // Setting of current value
87 | this.SetValue(a * (this.Period - 1) + b);
88 | }
89 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorAroon.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | public sealed class IndicatorAroon : Indicator, IWatchlistIndicator
9 | {
10 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
11 | [InputParameter("AROON Period", 0, 1, 999, 1, 0)]
12 | public int Period = 14;
13 |
14 | public int MinHistoryDepths => this.Period;
15 | public override string ShortName => "AROON (" + this.Period + ")";
16 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/aroon-indicator";
17 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorAroon.cs";
18 |
19 | ///
20 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
21 | ///
22 | public IndicatorAroon()
23 | : base()
24 | {
25 | // Serves for an identification of related indicators with different parameters.
26 | this.Name = "Aroon";
27 | this.Description = "Reveals the beginning of a new trend";
28 |
29 | // Defines line on demand with particular parameters.
30 | this.AddLineSeries("Aroon up Line", Color.Blue, 1, LineStyle.Solid);
31 | this.AddLineSeries("Aroon down Line", Color.Blue, 1, LineStyle.Dot);
32 | this.AddLineLevel(70, "Upper Limit", Color.Red, 1, LineStyle.Solid);
33 | this.AddLineLevel(30, "Lower Limit", Color.Red, 1, LineStyle.Dot);
34 |
35 | this.SeparateWindow = true;
36 | }
37 |
38 | ///
39 | /// Calculation entry point. This function is called when a price data updates.
40 | /// Will be runing under the HistoricalBar mode during history loading.
41 | /// Under NewTick during realtime.
42 | /// Under NewBar if start of the new bar is required.
43 | ///
44 | /// Provides data of updating reason and incoming price.
45 | protected override void OnUpdate(UpdateArgs args)
46 | {
47 | if (this.Count < this.MinHistoryDepths)
48 | return;
49 |
50 | // Getting max and min prices for period
51 | double high = this.GetPrice(PriceType.High);
52 | double low = this.GetPrice(PriceType.Low);
53 | double perHigh = 0;
54 | double perLow = 0;
55 | for (int i = 1; i < this.Period; i++)
56 | {
57 | double price = this.GetPrice(PriceType.High, i);
58 | if (price > high)
59 | {
60 | high = price;
61 | perHigh = i;
62 | }
63 |
64 | price = this.GetPrice(PriceType.Low, i);
65 | if (price < low)
66 | {
67 | low = price;
68 | perLow = i;
69 | }
70 | }
71 | // Getting Aroon up and down lines
72 | this.SetValue((1.0 - perHigh / this.Period) * 100, 0);
73 | this.SetValue((1.0 - perLow / this.Period) * 100, 1);
74 | }
75 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorAwesomeOscillator.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | public sealed class IndicatorAwesomeOscillator : Indicator, IWatchlistIndicator
9 | {
10 | public int MinHistoryDepths => SLOW_PERIOD;
11 | public override string ShortName => "AO";
12 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/awesome-oscillator";
13 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorAwesomeOscillator.cs";
14 |
15 | private Indicator fastMA;
16 | private Indicator slowMA;
17 |
18 | // Fixed periods for SMA indicators.
19 | private const int FAST_PERIOD = 5;
20 | private const int SLOW_PERIOD = 34;
21 |
22 | ///
23 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
24 | ///
25 | public IndicatorAwesomeOscillator()
26 | : base()
27 | {
28 | // Defines indicator's name and description.
29 | this.Name = "Awesome Oscillator";
30 | this.Description = "Awesome Oscillator determines market momentum";
31 |
32 | // Defines line on demand with particular parameters.
33 | this.AddLineSeries("AO", Color.Gray, 2, LineStyle.Histogramm);
34 | this.SeparateWindow = true;
35 | }
36 |
37 | ///
38 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
39 | ///
40 | protected override void OnInit()
41 | {
42 | // Get two SMA indicators from built-in indicator collection.
43 | this.fastMA = Core.Indicators.BuiltIn.SMA(FAST_PERIOD, PriceType.Median);
44 | this.slowMA = Core.Indicators.BuiltIn.SMA(SLOW_PERIOD, PriceType.Median);
45 |
46 | this.AddIndicator(this.fastMA);
47 | this.AddIndicator(this.slowMA);
48 | }
49 |
50 | ///
51 | /// Calculation entry point. This function is called when a price data updates.
52 | /// Will be runing under the HistoricalBar mode during history loading.
53 | /// Under NewTick during realtime.
54 | /// Under NewBar if start of the new bar is required.
55 | ///
56 | /// Provides data of updating reason and incoming price.
57 | protected override void OnUpdate(UpdateArgs args)
58 | {
59 | // Skip max period for correct calculation.
60 | if (this.Count < this.MinHistoryDepths)
61 | return;
62 |
63 | // Calculate the AO value
64 | double ao = this.fastMA.GetValue() - this.slowMA.GetValue();
65 | double prevAO = double.IsNaN(this.GetValue(1))
66 | ? this.GetPrice(PriceType.Close, 0)
67 | : this.GetValue(1);
68 |
69 | // Set values to 'AO' line buffer.
70 | this.SetValue(ao);
71 |
72 | var indicatorColor = (prevAO > ao) ? Color.Red : Color.Green;
73 |
74 | this.LinesSeries[0].SetMarker(0, indicatorColor);
75 | }
76 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorKairiRelativeIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | ///
9 | /// Kairi Relative Index (KRI) calculates deviation of the current price from its simple moving average as a percent of the moving average.
10 | ///
11 | public sealed class IndicatorKairiRelativeIndex : Indicator, IWatchlistIndicator
12 | {
13 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
14 | [InputParameter("Period", 0, 1, 999, 1, 0)]
15 | public int Period = 14;
16 |
17 | public int MinHistoryDepths => this.Period;
18 | public override string ShortName => $"KRI ({this.Period})";
19 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorKairiRelativeIndex.cs";
20 |
21 | // Holds simple moving average values.
22 | private Indicator sma;
23 |
24 | ///
25 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
26 | ///
27 | public IndicatorKairiRelativeIndex()
28 | : base()
29 | {
30 | // Defines indicator's group, name and description.
31 | this.Name = "Kairi Relative Index";
32 | this.Description = "Kairi Relative Index (KRI) calculates deviation of the current price from its simple moving average as a percent of the moving average";
33 |
34 | // Defines line and level on demand with particular parameters.
35 | this.AddLineSeries("KRI'Line", Color.Red, 1, LineStyle.Solid);
36 | this.AddLineLevel(0, "0'Line", Color.Gray, 1, LineStyle.Solid);
37 |
38 | this.SeparateWindow = true;
39 | }
40 |
41 | ///
42 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
43 | ///
44 | protected override void OnInit()
45 | {
46 | // Creates an instance of the proper indicator (SMA) from the default indicators list.
47 | this.sma = Core.Indicators.BuiltIn.SMA(this.Period, PriceType.Close);
48 | // Adds an auxiliary (SMA) indicator to the current one (KRI).
49 | // This will let inner indicator (SMA) to be calculated in advance to the current one (KRI).
50 | this.AddIndicator(this.sma);
51 | }
52 |
53 | ///
54 | /// Calculation entry point. This function is called when a price data updates.
55 | /// Will be runing under the HistoricalBar mode during history loading.
56 | /// Under NewTick during realtime.
57 | /// Under NewBar if start of the new bar is required.
58 | ///
59 | /// Provides data of updating reason and incoming price.
60 | protected override void OnUpdate(UpdateArgs args)
61 | {
62 | // Checking, if current amount of bars less, than period of moving average - calculation is impossible.
63 | if (this.Count < this.Period)
64 | return;
65 |
66 | double val = this.sma.GetValue();
67 | this.SetValue((this.GetPrice(PriceType.Close) - val) / val * 100);
68 | }
69 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorLinearlyWeightedMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using TradingPlatform.BusinessLayer;
4 | using System.Drawing;
5 |
6 | namespace MovingAverages;
7 |
8 | public sealed class IndicatorLinearlyWeightedMovingAverage : Indicator, IWatchlistIndicator
9 | {
10 | // Displays Input Parameter as dropdown list.
11 | [InputParameter("Period of LWMA", 0, 1, 9999, 1, 0)]
12 | public int Period = 20;
13 |
14 | // Displays Input Parameter as dropdown list.
15 | [InputParameter("Sources prices for LWMA", 1, variants: new object[] {
16 | "Close", PriceType.Close,
17 | "Open", PriceType.Open,
18 | "High", PriceType.High,
19 | "Low", PriceType.Low,
20 | "Typical", PriceType.Typical,
21 | "Medium", PriceType.Median,
22 | "Weighted", PriceType.Weighted,
23 | "Volume", PriceType.Volume,
24 | "Open interest", PriceType.OpenInterest
25 | })]
26 | public PriceType SourcePrice = PriceType.Close;
27 |
28 | public int MinHistoryDepths => this.Period;
29 | public override string ShortName => $"LWMA ({this.Period}: {this.SourcePrice})";
30 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorLinearlyWeightedMovingAverage.cs";
31 |
32 | ///
33 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
34 | ///
35 | public IndicatorLinearlyWeightedMovingAverage()
36 | : base()
37 | {
38 | // Serves for an identification of related indicators with different parameters.
39 | this.Name = "Linearly Weighted Moving Average";
40 | this.Description = "The linear average price for the last N periods";
41 | // Defines line on demand with particular parameters.
42 | this.AddLineSeries("LWMA line", Color.Blue, 1, LineStyle.Solid);
43 |
44 | this.SeparateWindow = false;
45 | }
46 |
47 | ///
48 | /// Calculation entry point. This function is called when a price data updates.
49 | /// Will be runing under the HistoricalBar mode during history loading.
50 | /// Under NewTick during realtime.
51 | /// Under NewBar if start of the new bar is required.
52 | ///
53 | /// Provides data of updating reason and incoming price.
54 | protected override void OnUpdate(UpdateArgs args)
55 | {
56 | if (this.Count > this.MinHistoryDepths)
57 | {
58 | double numerator = 0.0;
59 | double denominator = 0.0;
60 |
61 | for (int i = 0; i < this.Period; i++)
62 | {
63 | int weight = this.Period - i;
64 | // Calculation of a coefficient
65 | numerator += weight * this.GetPrice(this.SourcePrice, i);
66 | // Calculation of a coefficient
67 | denominator += weight;
68 | }
69 | this.SetValue(denominator != 0D ? numerator / denominator : 0D);
70 | }
71 | else
72 | {
73 | double price = this.GetPrice(this.SourcePrice);
74 | this.SetValue(price);
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorHullMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace MovingAverageIndicators;
8 |
9 | public class IndicatorHullMovingAverage : Indicator, IWatchlistIndicator
10 | {
11 | #region Parameters
12 |
13 | // Period of moving average.
14 | [InputParameter("Period of Hull Moving Average", 10, 1, 9999, 1, 0)]
15 | public int MaPeriod = 9;
16 |
17 | // Price type of moving average.
18 | [InputParameter("Sources prices for MA", 20, variants: new object[]
19 | {
20 | "Close", PriceType.Close,
21 | "Open", PriceType.Open,
22 | "High", PriceType.High,
23 | "Low", PriceType.Low,
24 | "Typical", PriceType.Typical,
25 | "Median", PriceType.Median,
26 | "Weighted", PriceType.Weighted,
27 | })]
28 | public PriceType SourcePrice = PriceType.Close;
29 |
30 | public override string ShortName => $"HMA ({this.MaPeriod}; {this.SourcePrice})";
31 |
32 | private HistoricalDataCustom hullWMASource;
33 |
34 | private Indicator fullWMA;
35 | private Indicator halfWMA;
36 | private Indicator wma;
37 |
38 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorHullMovingAverage.cs";
39 |
40 | #endregion Parameters
41 |
42 | #region IWatchlistIndicator
43 |
44 | public int MinHistoryDepths => this.MaPeriod;
45 |
46 | #endregion IWatchlistIndicator
47 |
48 | public IndicatorHullMovingAverage()
49 | {
50 | this.Name = "Hull Moving Average";
51 | this.AddLineSeries("HMA", Color.Orange, 2, LineStyle.Dash);
52 | this.SeparateWindow = false;
53 | }
54 |
55 | #region Overrides
56 |
57 | protected override void OnInit()
58 | {
59 | this.fullWMA = Core.Instance.Indicators.BuiltIn.LWMA(this.MaPeriod, this.SourcePrice);
60 | this.halfWMA = Core.Instance.Indicators.BuiltIn.LWMA(this.MaPeriod / 2, this.SourcePrice);
61 | this.wma = Core.Instance.Indicators.BuiltIn.LWMA((int)Math.Floor(Math.Sqrt(this.MaPeriod)), PriceType.Close);
62 |
63 | this.hullWMASource = new HistoricalDataCustom(this);
64 | this.hullWMASource.AddIndicator(this.wma);
65 |
66 | this.AddIndicator(this.fullWMA);
67 | this.AddIndicator(this.halfWMA);
68 | }
69 | protected override void OnUpdate(UpdateArgs args)
70 | {
71 | if (this.Count < this.MaPeriod)
72 | return;
73 | double hullMWASourceValue = 2 * this.halfWMA.GetValue() - this.fullWMA.GetValue();
74 | this.hullWMASource.SetValue(0d, 0d, 0d, hullMWASourceValue);
75 | this.SetValue(this.wma.GetValue());
76 | }
77 | protected override void OnClear()
78 | {
79 | if (this.hullWMASource != null)
80 | {
81 | this.hullWMASource.RemoveIndicator(this.wma);
82 | this.hullWMASource.Dispose();
83 | }
84 |
85 | if (this.fullWMA != null)
86 | this.RemoveIndicator(this.fullWMA);
87 |
88 | if (this.halfWMA != null)
89 | this.RemoveIndicator(this.halfWMA);
90 | }
91 |
92 | #endregion Overrides
93 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorChandeMomentumOscillator.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Volatility;
7 |
8 | public sealed class IndicatorChandeMomentumOscillator : Indicator, IWatchlistIndicator
9 | {
10 | // Displays Input Parameter as input field.
11 | [InputParameter("Period of MA for envelopes", 0, 1, 999, 1, 0)]
12 | public int Period = 9;
13 |
14 | // Displays Input Parameter as dropdown list.
15 | [InputParameter("Sources prices for MA", 1, variants: new object[] {
16 | "Close", PriceType.Close,
17 | "Open", PriceType.Open,
18 | "High", PriceType.High,
19 | "Low", PriceType.Low,
20 | "Typical", PriceType.Typical,
21 | "Medium", PriceType.Median,
22 | "Weighted", PriceType.Weighted,
23 | "Volume", PriceType.Volume,
24 | "Open interest", PriceType.OpenInterest
25 | })]
26 | public PriceType SourcePrice = PriceType.Close;
27 |
28 | public int MinHistoryDepths => this.Period + 1;
29 | public override string ShortName => $"CMO ({this.Period}: {this.SourcePrice})";
30 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorChandeMomentumOscillator.cs";
31 |
32 | ///
33 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
34 | ///
35 | public IndicatorChandeMomentumOscillator()
36 | : base()
37 | {
38 | // Defines indicator's name and description.
39 | this.Name = "Chande Momentum Oscillator";
40 | this.Description = "Calculates the dividing of difference between the sum of all recent gains and the sum of all recent losses by the sum of all price movement over the period.";
41 |
42 | // Defines line on demand with particular parameters.
43 | this.AddLineSeries("CMO", Color.Purple, 2, LineStyle.Solid);
44 | this.AddLineLevel(50, "Up", Color.Blue, 1, LineStyle.Dash);
45 | this.AddLineLevel(-50, "Down", Color.Blue, 1, LineStyle.Dash);
46 | this.SeparateWindow = true;
47 | }
48 |
49 | ///
50 | /// Calculation entry point. This function is called when a price data updates.
51 | /// Will be runing under the HistoricalBar mode during history loading.
52 | /// Under NewTick during realtime.
53 | /// Under NewBar if start of the new bar is required.
54 | ///
55 | /// Provides data of updating reason and incoming price.
56 | protected override void OnUpdate(UpdateArgs args)
57 | {
58 | // Skip some period for correct calculation.
59 | if (this.Count < this.MinHistoryDepths)
60 | return;
61 |
62 | // Calculate the sum
63 | double sum1 = 0d;
64 | double sum2 = 0d;
65 | for (int i = 0; i < this.Period; i++)
66 | {
67 | double diff = this.GetPrice(this.SourcePrice, i) - this.GetPrice(this.SourcePrice, i + 1);
68 | if (diff > 0)
69 | sum1 += diff;
70 | else
71 | sum2 -= diff;
72 | }
73 |
74 | // Compute the cmo value and set its to the 'CMO' line.
75 | this.SetValue(100.0 * ((sum1 - sum2) / (sum1 + sum2)));
76 | }
77 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorBandas.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace OscillatorsIndicators;
7 |
8 | public class IndicatorBandas : Indicator
9 | {
10 | #region Parameters
11 | [InputParameter("Period", 10, 1, 99999, 1, 0)]
12 | public int Period = 52;
13 |
14 | [InputParameter("Distance", 20, 0.1, 99999, 0.1, 1)]
15 | public double Distance = 3.5;
16 |
17 | [InputParameter("Sources prices", 30, variants: new object[]{
18 | "Close", PriceType.Close,
19 | "Open", PriceType.Open,
20 | "High", PriceType.High,
21 | "Low", PriceType.Low,
22 | "Typical", PriceType.Typical,
23 | "Medium", PriceType.Median,
24 | "Weighted", PriceType.Weighted,
25 | "Volume", PriceType.Volume,
26 | "Open interest", PriceType.OpenInterest
27 | })]
28 | public PriceType SourcePrice = PriceType.Close;
29 |
30 | [InputParameter("Type of middle moving average", 40, variants: new object[]{
31 | "Simple Moving Average", MaMode.SMA,
32 | "Exponential Moving Average", MaMode.EMA,
33 | "Smoothed Moving Average", MaMode.SMMA,
34 | "Linearly Weighted Moving Average", MaMode.LWMA,
35 | })]
36 | public MaMode MaType = MaMode.EMA;
37 |
38 | public override string ShortName => $"{this.Name} ({this.Period}: {this.Distance})";
39 |
40 | private HistoricalDataCustom customHD;
41 | private Indicator diffMA;
42 | private Indicator middleMA;
43 |
44 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorBandas.cs";
45 |
46 | #endregion Parameters
47 |
48 | public IndicatorBandas()
49 | {
50 | this.Name = "Bandas";
51 |
52 | this.AddLineSeries("Middle", Color.Orange, 1, LineStyle.Solid);
53 | this.AddLineSeries("Upper", Color.DodgerBlue, 1, LineStyle.Solid);
54 | this.AddLineSeries("Lower", Color.DodgerBlue, 1, LineStyle.Solid);
55 |
56 | this.SeparateWindow = false;
57 | }
58 |
59 | #region Overrides
60 | protected override void OnInit()
61 | {
62 | this.customHD = new HistoricalDataCustom(this);
63 | this.diffMA = Core.Indicators.BuiltIn.EMA(this.Period, this.SourcePrice);
64 | this.customHD.AddIndicator(this.diffMA);
65 |
66 | this.middleMA = Core.Indicators.BuiltIn.MA(this.Period, PriceType.Typical, this.MaType);
67 | this.AddIndicator(this.middleMA);
68 | }
69 | protected override void OnUpdate(UpdateArgs args)
70 | {
71 | var diff = this.High() - this.Low();
72 | this.customHD.SetValue(0, 0, 0, diff);
73 |
74 | if (this.Count < this.Period)
75 | return;
76 |
77 | var middle = this.middleMA.GetValue();
78 | var offset = this.diffMA.GetValue() * this.Distance;
79 |
80 | this.SetValue(middle, 0);
81 | this.SetValue(middle + offset, 1);
82 | this.SetValue(middle - offset, 2);
83 | }
84 | protected override void OnClear()
85 | {
86 | this.customHD.RemoveIndicator(this.diffMA);
87 | this.customHD.Dispose();
88 | this.diffMA.Dispose();
89 |
90 | this.RemoveIndicator(this.middleMA);
91 | this.middleMA.Dispose();
92 | }
93 | #endregion Overrides
94 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorBBS.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace ChanneIsIndicators;
7 |
8 | #warning Не використовуйте абревіатури у назвах, особливо якщо якщо вони не загальноприйняті
9 | public sealed class IndicatorBBS : Indicator
10 | {
11 | [InputParameter("Fast period", 10, 1, 99999, 1, 0)]
12 | public int FastPeriod;
13 |
14 | [InputParameter("Slow period", 20, 1, 99999, 1, 0)]
15 | public int SlowPeriod;
16 |
17 | [InputParameter("Smooth period", 30, 1, 99999, 1, 0)]
18 | public int SmoothPeriod;
19 |
20 | [InputParameter("Period", 10, 1, 99999, 1, 0)]
21 | public int Period;
22 |
23 | [InputParameter("STD num", 10, 1, 99999, 1, 0)]
24 | public int STDNum;
25 |
26 | public override string ShortName => $"{this.Name} ({this.FastPeriod}: {this.SlowPeriod}: {this.SmoothPeriod}: {this.Period}: {this.STDNum})";
27 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorBBS.cs";
28 |
29 | private double c1;
30 | private double c2;
31 | private double c3;
32 | private double c4;
33 |
34 | private double fastValue;
35 | private double slowValue;
36 | private double prevFastValue;
37 | private double prevSlowValue;
38 |
39 | public IndicatorBBS()
40 | {
41 | this.Name = "BBS";
42 |
43 | this.FastPeriod = 12;
44 | this.SlowPeriod = 26;
45 | this.SmoothPeriod = 5;
46 | this.Period = 10;
47 | this.STDNum = 1;
48 |
49 | this.SeparateWindow = true;
50 |
51 | this.AddLineSeries("BBSNUM", Color.Orange, 1, LineStyle.Points);
52 |
53 | this.AddLineLevel(0.3, "Up level", Color.Gray, 1, LineStyle.Dot);
54 | this.AddLineLevel(0, "Middle level", Color.Gray, 1, LineStyle.Dot);
55 | this.AddLineLevel(-0.3, "Down level", Color.Gray, 1, LineStyle.Dot);
56 | }
57 |
58 | protected override void OnInit()
59 | {
60 | base.OnInit();
61 |
62 | this.c1 = 2.0 / (1 + this.FastPeriod);
63 | this.c2 = 1 - this.c1;
64 | this.c3 = 2.0 / (1 + this.SlowPeriod);
65 | this.c4 = 1 - this.c3;
66 | }
67 |
68 | protected override void OnUpdate(UpdateArgs args)
69 | {
70 | double price = this.Close();
71 |
72 | if (this.Count == 1)
73 | {
74 | this.fastValue = price;
75 | this.slowValue = price;
76 |
77 | this.SetValue(0);
78 | }
79 | else
80 | {
81 | if (args.Reason == UpdateReason.HistoricalBar || args.Reason == UpdateReason.NewBar)
82 | {
83 | this.prevFastValue = this.fastValue;
84 | this.prevSlowValue = this.slowValue;
85 | }
86 |
87 | this.fastValue = this.c1 * price + this.c2 * this.prevFastValue;
88 | this.slowValue = this.c3 * price + this.c4 * this.prevSlowValue;
89 |
90 | double bbsnum = this.fastValue - this.slowValue;
91 |
92 | this.SetValue(bbsnum);
93 | }
94 | }
95 |
96 | protected override void OnClear()
97 | {
98 | this.prevFastValue = 0;
99 | this.prevSlowValue = 0;
100 |
101 | base.OnClear();
102 | }
103 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorPolynomialRegressionChannel.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using MathNet.Numerics;
4 | using MathNet.Numerics.Statistics;
5 | using System;
6 | using System.Drawing;
7 | using TradingPlatform.BusinessLayer;
8 |
9 | namespace Channels;
10 |
11 | public sealed class IndicatorPolynomialRegressionChannel : Indicator
12 | {
13 | [InputParameter("Period of Hull Moving Average", 10, 1, 9999, 1, 0)]
14 | public int MaPeriod;
15 |
16 | ///
17 | /// Price type of moving average.
18 | ///
19 | [InputParameter("Sources prices for MA", 20, variants: new object[]
20 | {
21 | "Close", PriceType.Close,
22 | "Open", PriceType.Open,
23 | "High", PriceType.High,
24 | "Low", PriceType.Low,
25 | "Typical", PriceType.Typical,
26 | "Medium", PriceType.Median,
27 | "Weighted", PriceType.Weighted,
28 | })]
29 | public PriceType SourcePrice;
30 |
31 | [InputParameter("Type of moving average", 3, variants: new object[]{
32 | "Simple Moving Average", MaMode.SMA,
33 | "Exponential Moving Average", MaMode.EMA,
34 | "Smoothed Moving Average", MaMode.SMMA,
35 | "Linearly Weighted Moving Average", MaMode.LWMA,
36 | })]
37 | public MaMode MaType;
38 |
39 | [InputParameter("Polynomial degree", 10, 1, 9999, 1, 0)]
40 | public int polynomialDegree;
41 |
42 | private Indicator ma;
43 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorPolynomialRegressionChannel.cs";
44 | public IndicatorPolynomialRegressionChannel()
45 | : base()
46 | {
47 | this.Name = "Polynomial Regression Channel";
48 | this.SeparateWindow = false;
49 | this.MaPeriod = 20;
50 | this.SourcePrice = PriceType.Close;
51 | this.MaType = MaMode.SMA;
52 | this.polynomialDegree = 2;
53 |
54 | this.AddLineSeries("Upper Band", Color.Green, 1, LineStyle.Solid);
55 | this.AddLineSeries("Lower Band", Color.Red, 1, LineStyle.Solid);
56 | this.AddLineSeries("Regression", Color.CadetBlue, 1, LineStyle.Solid);
57 | }
58 | protected override void OnInit()
59 | {
60 | this.ma = Core.Instance.Indicators.BuiltIn.MA(this.MaPeriod, this.SourcePrice, this.MaType);
61 | this.AddIndicator(this.ma);
62 | }
63 | protected override void OnUpdate(UpdateArgs args)
64 | {
65 | double[] xData = new double[this.MaPeriod];
66 | double[] yData = new double[this.MaPeriod];
67 | for (int i = 0; i < this.MaPeriod; i++)
68 | {
69 | xData[i] = i;
70 | yData[i] = this.ma.GetValue(i);
71 | }
72 |
73 | double[] coefficients = Fit.Polynomial(xData, yData, this.polynomialDegree);
74 | double[] predictedValues = new double[this.MaPeriod];
75 | for (int i = 0; i < this.MaPeriod; i++)
76 | {
77 | double predictedValue = 0;
78 | for (int j = 0; j <= this.polynomialDegree; j++)
79 | predictedValue += coefficients[j] * Math.Pow(i, j);
80 |
81 | predictedValues[i] = predictedValue;
82 | }
83 |
84 | double stdDev = Statistics.StandardDeviation(predictedValues);
85 | this.SetValue(predictedValues[0] + 2 * stdDev, 0);
86 | this.SetValue(predictedValues[0] - 2 * stdDev, 1);
87 | this.SetValue(predictedValues[0], 2);
88 | }
89 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorPositiveVolumeIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Volume;
7 |
8 | ///
9 | /// Changes on the periods in which value of volume has increased in comparison with the previous period.
10 | ///
11 | public sealed class IndicatorPositiveVolumeIndex : Indicator, IWatchlistIndicator
12 | {
13 | private const int MIN_PERIOD = 1;
14 |
15 | // Displays Input Parameter as dropdown list.
16 | [InputParameter("Source price", 0, variants: new object[] {
17 | "Close", PriceType.Close,
18 | "Open", PriceType.Open,
19 | "High", PriceType.High,
20 | "Low", PriceType.Low,
21 | "Typical", PriceType.Typical,
22 | "Medium", PriceType.Median,
23 | "Weighted", PriceType.Weighted,
24 | "Volume", PriceType.Volume,
25 | "Open interest", PriceType.OpenInterest
26 | })]
27 | public PriceType SourcePrice = PriceType.Close;
28 |
29 | public int MinHistoryDepths => MIN_PERIOD;
30 | public override string ShortName => $"PVI ({this.SourcePrice})";
31 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorPositiveVolumeIndex.cs";
32 |
33 | // Keeps previous volume, price and PVI values.
34 | private double prevVolume = 0;
35 | private double prevPrice = 0;
36 | private double prevPVI = 1;
37 |
38 | ///
39 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
40 | ///
41 | public IndicatorPositiveVolumeIndex()
42 | : base()
43 | {
44 | // Defines indicator's group, name and description.
45 | this.Name = "Positive Volume Index";
46 | this.Description = "Changes on the periods in which value of volume has increased in comparison with the previous period.";
47 |
48 | // Defines line on demand with particular parameters.
49 | this.AddLineSeries("PVI'Line", Color.Blue, 1, LineStyle.Solid);
50 |
51 | this.SeparateWindow = true;
52 | }
53 |
54 | ///
55 | /// Calculation entry point. This function is called when a price data updates.
56 | /// Will be runing under the HistoricalBar mode during history loading.
57 | /// Under NewTick during realtime.
58 | /// Under NewBar if start of the new bar is required.
59 | ///
60 | /// Provides data of updating reason and incoming price.
61 | protected override void OnUpdate(UpdateArgs args)
62 | {
63 | if (this.Count < this.MinHistoryDepths)
64 | return;
65 |
66 | double volume = this.Volume();
67 | // If symbol type or chart aggregation doesn't provide volumes - use ticks value.
68 | double curVolume = (double.IsNaN(volume) || volume == 0) ? this.Ticks() : volume;
69 |
70 | double curPrice = this.GetPrice(this.SourcePrice, 0);
71 | double curPVI = (curVolume > this.prevVolume && this.prevPrice != 0) ? this.prevPVI + this.prevPVI * (curPrice - this.prevPrice) / this.prevPrice : this.prevPVI;
72 |
73 | this.SetValue(curPVI);
74 |
75 | // Save state.
76 | if (args.Reason != UpdateReason.NewTick)
77 | {
78 | this.prevVolume = curVolume;
79 | this.prevPrice = curPrice;
80 | this.prevPVI = curPVI;
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorModifiedMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace MovingAverages;
7 |
8 | ///
9 | /// Modified Moving Average comprises a sloping factor to help it overtake with the growing or declining value of the trading price of the currency.
10 | ///
11 | public sealed class IndicatorModifiedMovingAverage : Indicator, IWatchlistIndicator
12 | {
13 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
14 | [InputParameter("Period of Modified Moving Average", 0, 1, 9999)]
15 | public int Period = 20;
16 |
17 | // Displays Input Parameter as dropdown list.
18 | [InputParameter("Sources prices for MA", 1, variants: new object[] {
19 | "Close", PriceType.Close,
20 | "Open", PriceType.Open,
21 | "High", PriceType.High,
22 | "Low", PriceType.Low,
23 | "Typical", PriceType.Typical,
24 | "Medium", PriceType.Median,
25 | "Weighted", PriceType.Weighted,
26 | "Volume", PriceType.Volume,
27 | "Open interest", PriceType.OpenInterest
28 | })]
29 | public PriceType SourcePrice = PriceType.Close;
30 |
31 | public int MinHistoryDepths => this.Period;
32 | public override string ShortName => $"MMA ({this.Period}: {this.SourcePrice})";
33 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorModifiedMovingAverage.cs";
34 |
35 | // Calculation coefficient.
36 | private double coeff;
37 |
38 | ///
39 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
40 | ///
41 | public IndicatorModifiedMovingAverage()
42 | : base()
43 | {
44 | // Defines indicator's group, name and description.
45 | this.Name = "Modified Moving Average";
46 | this.Description = "Modified Moving Average comprises a sloping factor to help it overtake with the growing or declining value of the trading price of the currency.";
47 |
48 | // Defines line on demand with particular parameters.
49 | this.AddLineSeries("MMA", Color.DodgerBlue, 1, LineStyle.Solid);
50 |
51 | this.SeparateWindow = false;
52 | }
53 |
54 | ///
55 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
56 | ///
57 | protected override void OnInit()
58 | {
59 | //coefficient calculating
60 | this.coeff = 1.0d / this.Period;
61 | }
62 |
63 | ///
64 | /// Calculation entry point. This function is called when a price data updates.
65 | /// Will be running under the HistoricalBar mode during history loading.
66 | /// Under NewTick during real time.
67 | /// Under NewBar if start of the new bar is required.
68 | ///
69 | /// Provides data of updating reason and incoming price.
70 | protected override void OnUpdate(UpdateArgs args)
71 | {
72 | // Checking, if current amount of bars less, than period of moving average - calculation is impossible.
73 | if (this.Count < this.MinHistoryDepths)
74 | return;
75 |
76 | // Value calculation.
77 | double mma = this.GetPrice(this.SourcePrice);
78 |
79 | for (int i = 0; i < this.Period; i++)
80 | {
81 | double price = this.GetPrice(this.SourcePrice, i);
82 | mma = price * this.coeff + mma * (1.0 - this.coeff);
83 | }
84 |
85 | // Displaying value on the chart.
86 | this.SetValue(mma);
87 | }
88 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorMoneyFlowIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Collections.Generic;
4 | using System.Drawing;
5 | using System.Linq;
6 | using TradingPlatform.BusinessLayer;
7 |
8 | namespace Volume;
9 |
10 | public sealed class IndicatorMoneyFlowIndex : Indicator, IWatchlistIndicator
11 | {
12 | // Displays Input Parameter as input field.
13 | [InputParameter("MFI Period", 0, 2, 999, 1, 0)]
14 | public int Period = 14;
15 |
16 | private readonly List fpmf;
17 | private readonly List fnmf;
18 |
19 | public int MinHistoryDepths => this.Period;
20 | public override string ShortName => $"MFI ({this.Period})";
21 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorMoneyFlowIndex.cs";
22 |
23 | ///
24 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
25 | ///
26 | public IndicatorMoneyFlowIndex()
27 | : base()
28 | {
29 | this.fpmf = new List();
30 | this.fnmf = new List();
31 |
32 | // Defines indicator's name and description.
33 | this.Name = "Money Flow Index";
34 | this.Description = "The Money Flow Index (MFI) is an oscillator that uses both price and volume to measure buying and selling pressure";
35 |
36 | // Defines lines on demand with particular parameters.
37 | this.AddLineSeries("MFI", Color.Orange, 1, LineStyle.Solid);
38 | this.AddLineLevel(80d, "Up", Color.Gray, 1, LineStyle.Dot);
39 | this.AddLineLevel(20d, "Down", Color.Gray, 1, LineStyle.Dot);
40 |
41 | this.SeparateWindow = true;
42 | }
43 |
44 | ///
45 | /// Calculation entry point. This function is called when a price data updates.
46 | /// Will be runing under the HistoricalBar mode during history loading.
47 | /// Under NewTick during realtime.
48 | /// Under NewBar if start of the new bar is required.
49 | ///
50 | /// Provides data of updating reason and incoming price.
51 | protected override void OnUpdate(UpdateArgs args)
52 | {
53 | // Insert new item to collections only on HistoricalBar of NewBar.
54 | if (args.Reason != UpdateReason.NewTick)
55 | {
56 | this.fnmf.Insert(0, 0);
57 | this.fpmf.Insert(0, 0);
58 | }
59 | // Skip the bar at the beginning of the story.
60 | if (this.Count == 1)
61 | return;
62 |
63 | // Get current and previous typical prices.
64 | double curPrice = this.GetPrice(PriceType.Typical, 0);
65 | double prevPrice = this.GetPrice(PriceType.Typical, 1);
66 |
67 | // Try to get volume value. If it's '0' or 'NaN' then get ticks value.
68 | double vol = (this.Volume() == 0 || double.IsNaN(this.Volume())) ? this.Ticks() : this.Volume();
69 | if (double.IsNaN(vol) || vol == 0)
70 | return;
71 |
72 | // Populate collections.
73 | if (curPrice > prevPrice)
74 | this.fpmf[0] = curPrice * vol;
75 | else if (curPrice < prevPrice)
76 | this.fnmf[0] = curPrice * vol;
77 |
78 | // Skip some period for correct calculation.
79 | if (this.Count < this.MinHistoryDepths)
80 | return;
81 |
82 | // Get the sum of values for the specific interval.
83 | double pmf = this.fpmf.Take(this.Period).Sum();
84 | double nmf = this.fnmf.Take(this.Period).Sum();
85 |
86 | // Set value to the "MFI" line buffer.
87 | if (nmf != 0.0 && pmf != -nmf)
88 | this.SetValue(100.0 - 100.0 / (1.0 + pmf / nmf));
89 | else
90 | this.SetValue(100.0);
91 | }
92 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorDeltaDivergenceReversal.cs:
--------------------------------------------------------------------------------
1 |
2 | // Copyright QUANTOWER LLC. © 2017-2021. All rights reserved.
3 |
4 | using System.Collections.Generic;
5 | using System.Drawing;
6 | using TradingPlatform.BusinessLayer;
7 |
8 | namespace OscillatorsIndicators;
9 |
10 | public class IndicatorDeltaDivergenceReversal : Indicator, IVolumeAnalysisIndicator
11 | {
12 | private Color buyColor = Color.Green;
13 | private Color sellColor = Color.Red;
14 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorDeltaDivergenceReversal.cs";
15 |
16 | public IndicatorDeltaDivergenceReversal()
17 | : base()
18 | {
19 | Name = "Delta Divergence Reversal";
20 |
21 | AddLineSeries("Low", Color.CadetBlue, 1, LineStyle.Points);
22 | AddLineSeries("High", Color.IndianRed, 1, LineStyle.Points);
23 |
24 | SeparateWindow = false;
25 | }
26 | public bool IsRequirePriceLevelsCalculation => false;
27 |
28 | public void VolumeAnalysisData_Loaded()
29 | {
30 | for (int i = 0; i < this.Count - 1; i++)
31 | DrawMarkers(i);
32 | }
33 |
34 | protected override void OnUpdate(UpdateArgs args)
35 | {
36 | SetValue(High(), 1);
37 | SetValue(Low(), 0);
38 | if (this.HistoricalData.VolumeAnalysisCalculationProgress == null || this.HistoricalData.VolumeAnalysisCalculationProgress.State != VolumeAnalysisCalculationState.Finished)
39 | return;
40 | DrawMarkers();
41 | }
42 |
43 | private void DrawMarkers(int offset = 0)
44 | {
45 | var currentItem = this.HistoricalData[offset];
46 | if (currentItem.VolumeAnalysisData == null)
47 | return;
48 |
49 | var previousItem = this.HistoricalData[offset + 1];
50 | double delta = currentItem.VolumeAnalysisData.Total.Delta;
51 | double currentHigh = ((HistoryItemBar)currentItem).High;
52 | double previousHigh = ((HistoryItemBar)previousItem).High;
53 | double currentLow = ((HistoryItemBar)currentItem).Low;
54 | double previousLow = ((HistoryItemBar)previousItem).Low;
55 |
56 | if ((currentHigh > previousHigh && currentLow > previousLow) && delta < 0)
57 | LinesSeries[1].SetMarker(offset, new IndicatorLineMarker(sellColor, upperIcon: IndicatorLineMarkerIconType.DownArrow));
58 | else if ((currentHigh < previousHigh && currentLow < previousLow) && delta >= 0)
59 | LinesSeries[0].SetMarker(offset, new IndicatorLineMarker(buyColor, bottomIcon: IndicatorLineMarkerIconType.UpArrow));
60 | else
61 | {
62 | LinesSeries[0].RemoveMarker(offset);
63 | LinesSeries[1].RemoveMarker(offset);
64 | }
65 | }
66 |
67 | public override IList Settings
68 | {
69 | get
70 | {
71 | var settings = base.Settings;
72 | settings.Add(new SettingItemColor("BuyColor", this.buyColor)
73 | {
74 | Text = "Buy Color"
75 | });
76 | settings.Add(new SettingItemColor("SellColor", this.sellColor)
77 | {
78 | Text = "Sell Color"
79 | });
80 | return settings;
81 | }
82 | set
83 | {
84 | base.Settings = value;
85 | if (value.TryGetValue("BuyColor", out Color buyColor))
86 | this.buyColor = buyColor;
87 | if (value.TryGetValue("SellColor", out Color sellColor))
88 | this.sellColor = sellColor;
89 | OnSettingsUpdated();
90 | }
91 | }
92 | protected override void OnSettingsUpdated()
93 | {
94 | base.OnSettingsUpdated();
95 | for (int i = 0; i < this.Count - 1; i++)
96 | DrawMarkers(i);
97 | }
98 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorSuperTrend.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace TrendIndicators;
7 |
8 | public class IndicatorSuperTrend : Indicator, IWatchlistIndicator
9 | {
10 | #region Parameters
11 | [InputParameter("ATR period", 0, 1, 999, 1, 0)]
12 | public int AtrPeriod = 10;
13 | [InputParameter("Digit", 1, 0.01, 10, 0.01, 2)]
14 | public double Digit = 3;
15 | [InputParameter("Up trend color", 3)]
16 | public Color UpTrendColor = Color.Green;
17 | [InputParameter("Down trend color", 3)]
18 | public Color DownTrendColor = Color.Red;
19 |
20 | public override string ShortName => $"ST ({this.AtrPeriod}: {this.Digit})";
21 |
22 | public int MinHistoryDepths => this.AtrPeriod;
23 |
24 | private Indicator atrIndicator;
25 | private int prevTrend;
26 | private double prevDown;
27 | private double prevUP;
28 | private double down;
29 | private double up;
30 | private int currTrend;
31 |
32 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorSuperTrend.cs";
33 |
34 | #endregion Parameters
35 |
36 | public IndicatorSuperTrend()
37 | {
38 | this.Name = "SuperTrend";
39 | this.AddLineSeries("ST line", Color.DodgerBlue, 2, LineStyle.Solid);
40 | this.SeparateWindow = false;
41 | }
42 |
43 | protected override void OnInit()
44 | {
45 | base.OnInit();
46 | this.atrIndicator = Core.Indicators.BuiltIn.ATR(this.AtrPeriod, MaMode.SMA);
47 | this.AddIndicator(this.atrIndicator);
48 | }
49 |
50 | protected override void OnUpdate(UpdateArgs args)
51 | {
52 | base.OnUpdate(args);
53 |
54 | if (this.Count < this.AtrPeriod)
55 | return;
56 |
57 | var isNewBar = false;
58 | if (this.HistoricalData.Aggregation is HistoryAggregationTick)
59 | isNewBar = args.Reason == UpdateReason.NewTick || args.Reason == UpdateReason.HistoricalBar;
60 | else
61 | isNewBar = args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar;
62 |
63 | if (isNewBar)
64 | {
65 | this.prevDown = this.up;
66 | this.prevTrend = this.currTrend;
67 | this.prevUP = this.down;
68 | }
69 |
70 | var middle = (this.GetPrice(PriceType.High) + this.GetPrice(PriceType.Low)) / 2;
71 | this.down = middle + (this.Digit * this.atrIndicator.GetValue());
72 | this.up = middle - (this.Digit * this.atrIndicator.GetValue());
73 |
74 | if (this.GetPrice(PriceType.Close) > this.prevUP)
75 | this.currTrend = 1;
76 | else if (this.GetPrice(PriceType.Close) < this.prevDown)
77 | this.currTrend = -1;
78 | else
79 | this.currTrend = this.prevTrend;
80 |
81 | if (this.currTrend > 0 && up < this.prevDown && this.currTrend <= this.prevTrend)
82 | this.up = this.prevDown;
83 | if (this.currTrend < 0 && this.down > this.prevUP && this.currTrend >= this.prevTrend)
84 | this.down = this.prevUP;
85 |
86 | if (this.currTrend == 1)
87 | {
88 | this.SetValue(this.up);
89 | this.LinesSeries[0].SetMarker(0, this.UpTrendColor);
90 | }
91 | else
92 | {
93 | this.SetValue(this.down);
94 | this.LinesSeries[0].SetMarker(0, this.DownTrendColor);
95 | }
96 | }
97 |
98 | protected override void OnClear()
99 | {
100 | base.OnClear();
101 | if (this.atrIndicator != null)
102 | {
103 | this.RemoveIndicator(this.atrIndicator);
104 | this.atrIndicator.Dispose();
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorRegressionLine.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace MovingAverages;
7 |
8 | public sealed class IndicatorRegressionLine : Indicator, IWatchlistIndicator
9 | {
10 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
11 | [InputParameter("Period of Linear Regression", 0, 1, 9999)]
12 | public int Period = 2;
13 | // Displays Input Parameter as dropdown list.
14 | [InputParameter("Sources prices for the regression line", 1, variants: new object[] {
15 | "Close", PriceType.Close,
16 | "Open", PriceType.Open,
17 | "High", PriceType.High,
18 | "Low", PriceType.Low,
19 | "Typical", PriceType.Typical,
20 | "Medium", PriceType.Median,
21 | "Weighted", PriceType.Weighted,
22 | "Volume", PriceType.Volume,
23 | "Open interest", PriceType.OpenInterest
24 | })]
25 | public PriceType SourcePrice = PriceType.Close;
26 |
27 | public int MinHistoryDepths => this.Period;
28 | public override string ShortName => "REGRESSION " + this.Period;
29 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorRegressionLine.cs";
30 |
31 | private int sumPeriod;
32 |
33 | ///
34 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
35 | ///
36 | public IndicatorRegressionLine()
37 | : base()
38 | {
39 | // Serves for an identification of related indicators with different parameters.
40 | this.Name = "Regression Line";
41 | this.Description = "Linear regression line used to measure trends";
42 |
43 | // Defines line on demand with particular parameters.
44 | this.AddLineSeries("Regression Line", Color.Blue, 1, LineStyle.Solid);
45 | this.SeparateWindow = false;
46 | }
47 | ///
48 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
49 | ///
50 | protected override void OnInit()
51 | {
52 | this.sumPeriod = 0;
53 | for (int i = 0; i < this.Period; i++)
54 | this.sumPeriod += i;
55 | }
56 | ///
57 | /// Calculation entry point. This function is called when a price data updates.
58 | /// Will be runing under the HistoricalBar mode during history loading.
59 | /// Under NewTick during realtime.
60 | /// Under NewBar if start of the new bar is required.
61 | ///
62 | /// Provides data of updating reason and incoming price.
63 | protected override void OnUpdate(UpdateArgs args)
64 | {
65 | if (this.Count < this.MinHistoryDepths)
66 | {
67 | double price = this.GetPrice(this.SourcePrice);
68 | this.SetValue(price);
69 | return;
70 | }
71 | double sumPrices = 0.0; // sum of prices
72 | double sumPeriod_Price = 0.0; // sum of period*price
73 | double sumSqr_Price = 0.0; // sum of price sqr
74 |
75 | // Calculation of sum
76 | for (int i = 0; i < this.Period; i++)
77 | {
78 | double price = this.GetPrice(this.SourcePrice, i);
79 | sumPrices += price;
80 | sumPeriod_Price += i * price;
81 | sumSqr_Price += price * price;
82 | }
83 |
84 | // Calculation of coefficients
85 | double p = (this.Period * sumPeriod_Price - this.sumPeriod * sumPrices) / (this.Period * sumSqr_Price - this.sumPeriod * this.sumPeriod);
86 | double b = (sumPrices * sumSqr_Price - this.sumPeriod * sumPeriod_Price) / (this.Period * sumSqr_Price - this.sumPeriod * this.sumPeriod);
87 |
88 | // Setting of current value
89 | this.SetValue(p * this.Period + b);
90 | }
91 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorTripleExponentialAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace MovingAverageIndicators;
7 |
8 | public class IndicatorTripleExponentialAverage : Indicator, IWatchlistIndicator
9 | {
10 | #region Parameters
11 | [InputParameter("Period of Exponential Moving Average", 0, 1, 9999, 1, 0)]
12 | public int MaPeriod = 9;
13 |
14 | [InputParameter("Sources prices for EMA", 1, variants: new object[]{
15 | "Close", PriceType.Close,
16 | "Open", PriceType.Open,
17 | "High", PriceType.High,
18 | "Low", PriceType.Low,
19 | "Typical", PriceType.Typical,
20 | "Medium", PriceType.Median,
21 | "Weighted", PriceType.Weighted,
22 | "Volume", PriceType.Volume,
23 | "Open interest", PriceType.OpenInterest
24 | })]
25 | public PriceType SourcePrice = PriceType.Close;
26 | //
27 | [InputParameter("Calculation type", 10, variants: new object[]
28 | {
29 | "All available data", IndicatorCalculationType.AllAvailableData,
30 | "By period", IndicatorCalculationType.ByPeriod,
31 | })]
32 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
33 |
34 | public int MinHistoryDepths => this.MaPeriod * 3;
35 | public override string ShortName => $"TRIX ({this.MaPeriod}: {this.SourcePrice})";
36 |
37 | private Indicator emaIndicator;
38 |
39 | private HistoricalDataCustom doubleEmaHD;
40 | private Indicator doubleEmaIndicator;
41 |
42 | private HistoricalDataCustom trixEmaHD;
43 | private Indicator trixEma;
44 |
45 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorTripleExponentialAverage.cs";
46 |
47 | #endregion Parameters
48 |
49 | public IndicatorTripleExponentialAverage()
50 | {
51 | this.Name = "Triple Exponential Average";
52 |
53 | this.AddLineSeries("TRIX line", Color.Orange, 2, LineStyle.Solid);
54 | this.AddLineLevel(0d, "Zero line", Color.Gray, 1, LineStyle.Dot);
55 |
56 | this.SeparateWindow = true;
57 | }
58 |
59 | protected override void OnInit()
60 | {
61 | base.OnInit();
62 |
63 | this.emaIndicator = Core.Indicators.BuiltIn.EMA(this.MaPeriod, PriceType.Close, this.CalculationType);
64 | this.AddIndicator(this.emaIndicator);
65 |
66 | this.doubleEmaHD = new HistoricalDataCustom(this);
67 | this.doubleEmaIndicator = Core.Indicators.BuiltIn.EMA(this.MaPeriod, PriceType.Close, this.CalculationType);
68 | this.doubleEmaHD.AddIndicator(this.doubleEmaIndicator);
69 |
70 | this.trixEmaHD = new HistoricalDataCustom(this);
71 | this.trixEma = Core.Indicators.BuiltIn.EMA(this.MaPeriod, PriceType.Close, this.CalculationType);
72 | this.trixEmaHD.AddIndicator(this.trixEma);
73 | }
74 | protected override void OnUpdate(UpdateArgs args)
75 | {
76 | base.OnUpdate(args);
77 |
78 | if (this.Count < this.MaPeriod)
79 | return;
80 |
81 | this.doubleEmaHD[PriceType.Close] = this.emaIndicator.GetValue();
82 |
83 | if (this.Count < this.MaPeriod * 2)
84 | return;
85 |
86 | this.trixEmaHD[PriceType.Close] = this.doubleEmaIndicator.GetValue();
87 |
88 | if (this.Count < this.MinHistoryDepths)
89 | return;
90 |
91 | var trix = (this.trixEma.GetValue() - this.trixEma.GetValue(1)) / this.trixEma.GetValue(1);
92 | this.SetValue(trix);
93 | }
94 | protected override void OnClear()
95 | {
96 | base.OnClear();
97 |
98 | this.emaIndicator?.Dispose();
99 | this.doubleEmaIndicator?.Dispose();
100 | this.trixEma?.Dispose();
101 |
102 | this.doubleEmaHD?.Dispose();
103 | this.trixEmaHD?.Dispose();
104 | }
105 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorPriceChannel.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Channels;
7 |
8 | public sealed class IndicatorPriceChannel : Indicator, IWatchlistIndicator
9 | {
10 | // Define 'Period' input parameter and set allowable range (from 1 to 999)
11 | [InputParameter("Period of price channel", 0, 1, 999)]
12 | public int Period = 20;
13 |
14 | public int MinHistoryDepths => this.Period;
15 | public override string ShortName => $"Channel ({this.Period})";
16 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorPriceChannel.cs";
17 |
18 | ///
19 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
20 | ///
21 | public IndicatorPriceChannel()
22 | : base()
23 | {
24 | // Defines indicator's name and description.
25 | this.Name = "Price Channel";
26 | this.Description = "Based on measurement of min and max prices for the definite number of periods";
27 |
28 | // Define two lines (on main window) with particular parameters
29 | this.AddLineSeries("Highest", Color.Red, 2, LineStyle.Solid);
30 | this.AddLineSeries("Lowest", Color.CadetBlue, 2, LineStyle.Solid);
31 |
32 | this.SeparateWindow = false;
33 | }
34 |
35 | ///
36 | /// Calculation entry point. This function is called when a price data updates.
37 | /// Will be runing under the HistoricalBar mode during history loading.
38 | /// Under NewTick during realtime.
39 | /// Under NewBar if start of the new bar is required.
40 | ///
41 | /// Provides data of updating reason and incoming price.
42 | protected override void OnUpdate(UpdateArgs args)
43 | {
44 | // Skip some period for correct calculation.
45 | if (this.Count < this.MinHistoryDepths)
46 | return;
47 |
48 | // Get the highest price on the interval
49 | int highestOffset = this.Highest(PriceType.High, 0, this.Period);
50 | double highestPrice = this.GetPrice(PriceType.High, highestOffset);
51 |
52 | // Get the lowest price on the interval
53 | int lowestOffset = this.Lowest(PriceType.Low, 0, this.Period);
54 | double lowestPrice = this.GetPrice(PriceType.Low, lowestOffset);
55 |
56 | // Set highestPrice to 'Highest' line buffer and lowestPrice to 'Lowest' line buffer.
57 | this.SetValue(highestPrice, 0);
58 | this.SetValue(lowestPrice, 1);
59 | }
60 |
61 | ///
62 | ///Get the highest price on an interval.
63 | ///
64 | ///Type of price
65 | ///Start position offset
66 | ///The count of bars in an interval
67 | ///
68 | private int Highest(PriceType priceType, int startOffset, int count)
69 | {
70 | int maxValueOffset = startOffset;
71 | for (int i = 0; i < count; i++)
72 | {
73 | if (this.GetPrice(priceType, maxValueOffset) < this.GetPrice(priceType, startOffset + i))
74 | maxValueOffset = startOffset + i;
75 | }
76 | return maxValueOffset;
77 | }
78 |
79 | ///
80 | ///Get the lowest price on an interval.
81 | ///
82 | ///Type of price
83 | ///Start position offset
84 | ///The count of bars in an interval
85 | ///
86 | private int Lowest(PriceType priceType, int startOffset, int count)
87 | {
88 | int minValueOffset = startOffset;
89 | for (int i = 0; i < count; i++)
90 | {
91 | if (this.GetPrice(priceType, minValueOffset) > this.GetPrice(priceType, startOffset + i))
92 | minValueOffset = startOffset + i;
93 | }
94 | return minValueOffset;
95 | }
96 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorStochasticRelativeStrengthIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Oscillators;
8 |
9 | public sealed class IndicatorStochasticRelativeStrengthIndex : Indicator, IWatchlistIndicator
10 | {
11 | [InputParameter("RSI Period", 10, 1, 999, 1, 0)]
12 | public int rsiPeriod = 14;
13 |
14 | [InputParameter("Stochastic period", 20, 1, 999, 1, 0)]
15 | public int StochPeriod = 14;
16 |
17 | [InputParameter("%K Period", 30, 1, 999, 1, 0)]
18 | public int kPeriod = 3;
19 |
20 | [InputParameter("%D Period", 40, 1, 999, 1, 0)]
21 | public int dPeriod = 3;
22 |
23 | [InputParameter("Calculation type", 50, variants: new object[]
24 | {
25 | "All available data", IndicatorCalculationType.AllAvailableData,
26 | "By period", IndicatorCalculationType.ByPeriod,
27 | })]
28 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
29 |
30 | public int MinHistoryDepths => this.rsiPeriod + Math.Max(this.kPeriod, this.dPeriod);
31 | public override string ShortName => $"StochasticRSI ({this.rsiPeriod}: {this.StochPeriod}: {this.kPeriod}: {this.dPeriod})";
32 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorStochasticRelativeStrengthIndex.cs";
33 |
34 | private Indicator rsi;
35 | private Indicator stochRSI;
36 | private HistoricalDataCustom hCustom;
37 |
38 | ///
39 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
40 | ///
41 | public IndicatorStochasticRelativeStrengthIndex()
42 | : base()
43 | {
44 | // Defines indicator's name and description.
45 | this.Name = "Stochastic x Relative Strength Index";
46 | this.Description = "StochRSI is an oscillator that measures the level of RSI relative to its range";
47 |
48 | // Defines line on demand with particular parameters.
49 | this.AddLineSeries("StochRSI", Color.CornflowerBlue, 1, LineStyle.Solid);
50 | this.AddLineSeries("Signal", Color.LightSkyBlue, 1, LineStyle.Solid);
51 | this.AddLineLevel(80, "up", Color.Gray, 1, LineStyle.Dot);
52 | this.AddLineLevel(20, "down", Color.Gray, 1, LineStyle.Dot);
53 |
54 | this.SeparateWindow = true;
55 | }
56 |
57 | ///
58 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
59 | ///
60 | protected override void OnInit()
61 | {
62 | // Creates an instance of the custom historical data which will be synchronized with the current indicator instance.
63 | this.hCustom = new HistoricalDataCustom(this);
64 | this.rsi = Core.Indicators.BuiltIn.RSI(this.rsiPeriod, PriceType.Close, RSIMode.Exponential, MaMode.SMA, 5);
65 | this.AddIndicator(this.rsi);
66 | this.stochRSI = Core.Indicators.BuiltIn.Stochastic(this.StochPeriod, this.kPeriod, this.dPeriod, MaMode.SMA, this.CalculationType);
67 | this.hCustom.AddIndicator(this.stochRSI);
68 | }
69 |
70 | ///
71 | /// Calculation entry point. This function is called when a price data updates.
72 | /// Will be runing under the HistoricalBar mode during history loading.
73 | /// Under NewTick during realtime.
74 | /// Under NewBar if start of the new bar is required.
75 | ///
76 | /// Provides data of updating reason and incoming price.
77 | protected override void OnUpdate(UpdateArgs args)
78 | {
79 | if (this.Count < this.rsiPeriod)
80 | return;
81 |
82 | // Populates custom HistoricalData with 1 data layers:
83 | this.hCustom.SetValue(0d, this.rsi.GetValue(), this.rsi.GetValue(), this.rsi.GetValue());
84 |
85 | if (this.Count < this.MinHistoryDepths)
86 | return;
87 |
88 | this.SetValue(this.stochRSI.GetValue());
89 | this.SetValue(this.stochRSI.GetValue(0, 1), 1);
90 | }
91 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorTimeHistogram.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using TradingPlatform.BusinessLayer;
7 |
8 | namespace VolumeIndicators;
9 |
10 | internal class IndicatorTimeHistogram : Indicator, IVolumeAnalysisIndicator
11 | {
12 | [InputParameter("Data type", variants: new object[]
13 | {
14 | "Trades", VolumeAnalysisField.Trades,
15 | "Buy trades", VolumeAnalysisField.BuyTrades,
16 | "Sell trades", VolumeAnalysisField.SellTrades,
17 | "Volume", VolumeAnalysisField.Volume,
18 | "Buy volume", VolumeAnalysisField.BuyVolume,
19 | "Buy volume, %", VolumeAnalysisField.BuyVolumePercent,
20 | "Sell volume", VolumeAnalysisField.SellVolume,
21 | "Sell volume, %", VolumeAnalysisField.SellVolumePercent,
22 | "Delta", VolumeAnalysisField.Delta,
23 | "Delta, %", VolumeAnalysisField.DeltaPercent,
24 | "Cumulative delta", VolumeAnalysisField.CumulativeDelta,
25 | "Open interest", VolumeAnalysisField.OpenInterest,
26 | "Average size", VolumeAnalysisField.AverageSize,
27 | "Average buy size", VolumeAnalysisField.AverageBuySize,
28 | "Average sell size", VolumeAnalysisField.AverageSellSize,
29 | "Max one trade Vol.", VolumeAnalysisField.MaxOneTradeVolume,
30 | "Max one trade Vol., %", VolumeAnalysisField.MaxOneTradeVolumePercent,
31 | })]
32 | public VolumeAnalysisField FieldType = VolumeAnalysisField.Volume;
33 |
34 | public override string ShortName => $"Time histogram ({this.FieldType})";
35 |
36 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorTimeHistogram.cs";
37 |
38 | public IndicatorTimeHistogram()
39 | {
40 | this.Name = "Time histogram";
41 |
42 | this.AddLineSeries("Histogram", Color.DodgerBlue, 3, LineStyle.Histogramm);
43 |
44 | this.SeparateWindow = true;
45 | }
46 |
47 | protected override void OnUpdate(UpdateArgs args)
48 | {
49 | if (this.HistoricalData.VolumeAnalysisCalculationProgress == null)
50 | return;
51 |
52 | if (this.HistoricalData.VolumeAnalysisCalculationProgress.State != VolumeAnalysisCalculationState.Finished)
53 | return;
54 |
55 | this.DrawIndicatorValue();
56 | }
57 |
58 | #region IVolumeAnalysisIndicator
59 |
60 | public bool IsRequirePriceLevelsCalculation => false;
61 |
62 | public void VolumeAnalysisData_Loaded()
63 | {
64 | Task.Factory.StartNew(() =>
65 | {
66 | // wait (треба дочекатись поки індикатор пройде всю історію)
67 | while (this.Count != this.HistoricalData.Count)
68 | Thread.Sleep(20);
69 |
70 | // draw history
71 | for (int offset = 0; offset < this.Count; offset++)
72 | this.DrawIndicatorValue(offset);
73 | });
74 | }
75 |
76 | #endregion IVolumeAnalysisIndicator
77 |
78 | private void DrawIndicatorValue(int offset = 0)
79 | {
80 | if (this.GetVolumeAnalysisData(offset) is VolumeAnalysisData analysisData)
81 | {
82 | double value = analysisData.Total.GetValue(this.FieldType);
83 | this.SetValue(value, 0, offset);
84 |
85 | // Coloring
86 | if (this.IsDeltaBased(this.FieldType))
87 | {
88 | int markerOffset = offset + 1;
89 |
90 | if (this.Count <= markerOffset)
91 | return;
92 |
93 | if (value > 0)
94 | this.LinesSeries[0].SetMarker(markerOffset, Color.Green);
95 | else if (value < 0)
96 | this.LinesSeries[0].SetMarker(markerOffset, Color.Red);
97 | }
98 | }
99 | }
100 |
101 | private bool IsDeltaBased(VolumeAnalysisField fieldType) => fieldType == VolumeAnalysisField.Delta || fieldType == VolumeAnalysisField.DeltaPercent || fieldType == VolumeAnalysisField.CumulativeDelta;
102 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorAverageTrueRange.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 | using VolatilityIndicators;
6 |
7 | namespace Volatility;
8 |
9 | public sealed class IndicatorAverageTrueRange : Indicator, IWatchlistIndicator
10 | {
11 | // Displays Input Parameter as input field.
12 | [InputParameter("Period of Moving Average", 0, 1, 999, 1, 0)]
13 | public int Period = 13;
14 |
15 | // Displays Input Parameter as dropdown list.
16 | [InputParameter("Type of Moving Average", 1, variants: new object[] {
17 | "Simple", MaMode.SMA,
18 | "Exponential", MaMode.EMA,
19 | "Smoothed", MaMode.SMMA,
20 | "Linear Weighted", MaMode.LWMA}
21 | )]
22 | public MaMode MAType = MaMode.SMA;
23 | //
24 | [InputParameter("Calculation type", 5, variants: new object[]
25 | {
26 | "All available data", IndicatorCalculationType.AllAvailableData,
27 | "By period", IndicatorCalculationType.ByPeriod,
28 | })]
29 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
30 |
31 | public int MinHistoryDepths => this.Period;
32 | public override string ShortName => $"ATR ({this.Period}: {this.MAType})";
33 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/volatility/average-true-range";
34 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorAverageTrueRange.cs";
35 |
36 | private Indicator ma;
37 | private IndicatorTrueRange tr;
38 | private HistoricalDataCustom customHD;
39 |
40 | ///
41 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
42 | ///
43 | public IndicatorAverageTrueRange()
44 | : base()
45 | {
46 | // Defines indicator's name and description.
47 | this.Name = "Average True Range";
48 | this.Description = "Measures of market volatility.";
49 | this.IsUpdateTypesSupported = false;
50 |
51 | // Defines line on demand with particular parameters.
52 | this.AddLineSeries("ATR", Color.CadetBlue, 1, LineStyle.Solid);
53 |
54 | this.SeparateWindow = true;
55 | }
56 |
57 | ///
58 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
59 | ///
60 | protected override void OnInit()
61 | {
62 | // Get MA indicator from built-in indicator collection (according to selected 'MaType').
63 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, PriceType.Close, this.MAType, this.CalculationType);
64 | this.ma.UpdateType = IndicatorUpdateType.OnTick;
65 | this.AddIndicator(this.tr = new IndicatorTrueRange() { UpdateType = IndicatorUpdateType.OnTick });
66 |
67 | // Create a custom HistoricalData and syncronize it with this(ART) indicator.
68 | this.customHD = new HistoricalDataCustom(this);
69 |
70 | // Attach SMA indicator to custom HistoricalData. The MA will calculate on the data, which will store in custom HD.
71 | this.customHD.AddIndicator(this.ma);
72 | }
73 |
74 | ///
75 | /// Calculation entry point. This function is called when a price data updates.
76 | /// Will be runing under the HistoricalBar mode during history loading.
77 | /// Under NewTick during realtime.
78 | /// Under NewBar if start of the new bar is required.
79 | ///
80 | /// Provides data of updating reason and incoming price.
81 | protected override void OnUpdate(UpdateArgs args)
82 | {
83 | // Get the TR value and store it to the custom HistoricalData.
84 | double tr = this.tr.GetValue();
85 |
86 | this.customHD[PriceType.Close, 0] = tr;
87 |
88 | // Skip some period for correct calculation.
89 | if (this.Count < this.MinHistoryDepths)
90 | return;
91 |
92 | // Get MA value and set it to 'ATR' line buffer.
93 | double maValue = this.ma.GetValue();
94 | this.SetValue(maValue);
95 | }
96 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorContador.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace VolumeIndicators;
7 |
8 | public class IndicatorContador : Indicator
9 | {
10 | // consts
11 | public const string ERROR_MESSAGE = "Tick Counter only works on bars build with a set number of ticks";
12 | public const string TICKS_REMAINING_PREFIX = "Ticks Remaining = ";
13 | public const string TICK_COUNTER_PREFIX = "Ticks Count = ";
14 | public const string COUNTDOWN = "Countdown";
15 | public const string SHOW_PERCENTAGES = "Show percentages";
16 |
17 | // input parameters
18 | [InputParameter(COUNTDOWN, 10)]
19 | public bool IsCountdown = true;
20 | [InputParameter(SHOW_PERCENTAGES, 10)]
21 | public bool ShowPercentages = true;
22 | [InputParameter("Font color", 20)]
23 | public Color FontColor
24 | {
25 | get => this.fontColor;
26 | set
27 | {
28 | this.fontColor = value;
29 | this.fontBrush = new SolidBrush(value);
30 | }
31 | }
32 | private Color fontColor;
33 | private SolidBrush fontBrush;
34 |
35 | public override string ShortName
36 | {
37 | get
38 | {
39 | string parameters = this.IsCountdown ? COUNTDOWN : string.Empty;
40 |
41 | if (this.ShowPercentages)
42 | {
43 | if (this.IsCountdown)
44 | parameters += ": ";
45 |
46 | parameters += SHOW_PERCENTAGES;
47 | }
48 |
49 | return $"{this.Name} ({parameters})";
50 | }
51 | }
52 |
53 | private readonly Font font;
54 | private bool isCorrectTimeFrame = false;
55 | private string calculatedMessage;
56 | private int messageMargin = 0;
57 | private string prefix;
58 | private readonly StringFormat farFarSF;
59 |
60 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorContador.cs";
61 |
62 | public IndicatorContador()
63 | {
64 | this.Name = "Contador";
65 | this.font = new Font("Verdana", 10, FontStyle.Regular, GraphicsUnit.Point);
66 | this.FontColor = Color.Orange;
67 | this.farFarSF = new StringFormat()
68 | {
69 | Alignment = StringAlignment.Far,
70 | LineAlignment = StringAlignment.Far
71 | };
72 | }
73 |
74 | protected override void OnInit()
75 | {
76 | this.calculatedMessage = string.Empty;
77 | this.isCorrectTimeFrame = this.HistoricalData.Aggregation.GetPeriod.BasePeriod == BasePeriod.Tick;
78 | this.messageMargin = this.isCorrectTimeFrame
79 | ? 30
80 | : 70;
81 |
82 | this.prefix = this.IsCountdown
83 | ? TICKS_REMAINING_PREFIX
84 | : TICK_COUNTER_PREFIX;
85 | }
86 | protected override void OnUpdate(UpdateArgs args)
87 | {
88 | if (args.Reason == UpdateReason.Unknown || args.Reason == UpdateReason.HistoricalBar)
89 | return;
90 |
91 | if (this.isCorrectTimeFrame)
92 | {
93 | int ticksCount = this.IsCountdown
94 | ? this.HistoricalData.Aggregation.GetPeriod.PeriodMultiplier - (int)this.Ticks()
95 | : (int)this.Ticks();
96 |
97 | this.calculatedMessage = this.ShowPercentages
98 | ? this.prefix + ticksCount * 100 / this.HistoricalData.Aggregation.GetPeriod.PeriodMultiplier + " %"
99 | : this.prefix + ticksCount.ToString();
100 | }
101 | }
102 | public override void OnPaintChart(PaintChartEventArgs args)
103 | {
104 | var gr = args.Graphics;
105 |
106 | string message = this.isCorrectTimeFrame ? this.calculatedMessage : ERROR_MESSAGE;
107 |
108 | gr.DrawString(message, this.font, this.fontBrush, args.Rectangle.Width - this.messageMargin, args.Rectangle.Height - 2, this.farFarSF);
109 | }
110 | public override void Dispose()
111 | {
112 | this.font?.Dispose();
113 | this.fontBrush?.Dispose();
114 | this.farFarSF?.Dispose();
115 | }
116 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorMcGinleyDynamic.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace MovingAverages;
8 |
9 | ///
10 | /// McGinley Dynamic avoids of most whipsaws and it rapidly moves up or down according to a quickly changing market. It needs no adjusting because it is dynamic and it adjusts itself.
11 | ///
12 | public sealed class IndicatorMcGinleyDynamic : Indicator, IWatchlistIndicator
13 | {
14 | // Period of McGinley Dynamic.
15 | [InputParameter("Period", 0, 2, 999, 1, 0)]
16 | public int Period = 14;
17 |
18 | // Dynamic tracking factor of McGinley Dynamic.
19 | [InputParameter("Dynamic tracking factor", 1, 1, 999, 1, 0)]
20 | public int TrackingFactor = 2;
21 |
22 | // Price type of McGinley Dynamic.
23 | [InputParameter("Source price", 2, variants: new object[]
24 | {
25 | "Close", PriceType.Close,
26 | "Open", PriceType.Open,
27 | "High", PriceType.High,
28 | "Low", PriceType.Low,
29 | "Typical", PriceType.Typical,
30 | "Median", PriceType.Median,
31 | "Weighted", PriceType.Weighted,
32 | "Volume", PriceType.Volume,
33 | "Open interest", PriceType.OpenInterest
34 | })]
35 | public PriceType SourcePrice = PriceType.Close;
36 |
37 | [InputParameter("Calculation type", 5, variants: new object[]
38 | {
39 | "All available data", IndicatorCalculationType.AllAvailableData,
40 | "By period", IndicatorCalculationType.ByPeriod,
41 | })]
42 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
43 |
44 | public int MinHistoryDepths => this.Period + 1;
45 | public override string ShortName => $"MD ({this.Period}: {this.TrackingFactor}: {this.SourcePrice})";
46 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorMcGinleyDynamic.cs";
47 |
48 | // Holds EMA's smoothing values.
49 | private Indicator ema;
50 |
51 | ///
52 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
53 | ///
54 | public IndicatorMcGinleyDynamic()
55 | : base()
56 | {
57 | // Defines indicator's group, name and description.
58 | this.Name = "McGinley Dynamic";
59 | this.Description = "McGinley Dynamic avoids of most whipsaws and it rapidly moves up or down according to a quickly changing market. It needs no adjusting because it is dynamic and it adjusts itself.";
60 |
61 | // Defines line on demand with particular parameters.
62 | this.AddLineSeries("MD", Color.DodgerBlue, 1, LineStyle.Solid);
63 | }
64 |
65 | ///
66 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
67 | ///
68 | protected override void OnInit()
69 | {
70 | // Creates an instance of the proper indicator from the default indicators list.
71 | this.ema = Core.Indicators.BuiltIn.EMA(this.Period, this.SourcePrice, this.CalculationType);
72 | // Adds an auxiliary (MA) indicator to the current one (MD).
73 | // This will let inner indicator (MA) to be calculated in advance to the current one (MD).
74 | this.AddIndicator(this.ema);
75 | }
76 |
77 | ///
78 | /// Calculation entry point. This function is called when a price data updates.
79 | /// Will be runing under the HistoricalBar mode during history loading.
80 | /// Under NewTick during realtime.
81 | /// Under NewBar if start of the new bar is required.
82 | ///
83 | /// Provides data of updating reason and incoming price.
84 | protected override void OnUpdate(UpdateArgs args)
85 | {
86 | // Checking, if current amount of bars less, than period of moving average (+ 1) - calculation is impossible.
87 | if (this.Count < this.MinHistoryDepths)
88 | return;
89 |
90 | // Gets calculated value.
91 | double md = this.GetPrice(this.SourcePrice);
92 | double value = this.ema.GetValue(1);
93 | md = value + (md - value) / (this.TrackingFactor * Math.Pow(md / value, 4));
94 |
95 | // Sets value for displaying on the chart.
96 | this.SetValue(md);
97 | }
98 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorStandardDeviation.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Volatility;
8 |
9 | ///
10 | /// Shows the difference of the volatility value from the average one.
11 | ///
12 | public sealed class IndicatorStandardDeviation : Indicator, IWatchlistIndicator
13 | {
14 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/volatility/standard-deviation";
15 |
16 | // Displays Input Parameter as dropdown list.
17 | [InputParameter("Sources prices for MA", 0, variants: new object[] {
18 | "Close", PriceType.Close,
19 | "Open", PriceType.Open,
20 | "High", PriceType.High,
21 | "Low", PriceType.Low,
22 | "Typical", PriceType.Typical,
23 | "Medium", PriceType.Median,
24 | "Weighted", PriceType.Weighted,
25 | "Volume", PriceType.Volume,
26 | "Open interest", PriceType.OpenInterest
27 | })]
28 | public PriceType SourcePrice = PriceType.Close;
29 |
30 | [InputParameter("Type of Moving Average", 1, variants: new object[] {
31 | "Simple", MaMode.SMA,
32 | "Exponential", MaMode.EMA,
33 | "Modified", MaMode.SMMA,
34 | "Linear Weighted", MaMode.LWMA}
35 | )]
36 | public MaMode MAType = MaMode.SMA;
37 | //
38 | [InputParameter("Calculation type", 5, variants: new object[]
39 | {
40 | "All available data", IndicatorCalculationType.AllAvailableData,
41 | "By period", IndicatorCalculationType.ByPeriod,
42 | })]
43 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
44 |
45 | // Displays Input Parameter as input field (or checkbox if value type is boolean).
46 | [InputParameter("Period", 10, 1, 999, 1, 0)]
47 | public int Period = 20;
48 |
49 | public int MinHistoryDepths => this.Period;
50 | public override string ShortName => $"SD ({this.Period}: {this.SourcePrice}: {this.MAType})";
51 |
52 | // Holds moving average values.
53 | private Indicator ma;
54 |
55 | ///
56 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
57 | ///
58 | public IndicatorStandardDeviation()
59 | : base()
60 | {
61 | // Defines indicator's group, name and description.
62 | this.Name = "Standard Deviation";
63 | this.Description = "Shows the difference of the volatility value from the average one.";
64 |
65 | // Defines line on demand with particular parameters.
66 | this.AddLineSeries("SD'Line", Color.Blue, 1, LineStyle.Solid);
67 |
68 | this.SeparateWindow = true;
69 | }
70 |
71 | ///
72 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
73 | ///
74 | protected override void OnInit()
75 | {
76 | // Creates an instance of the proper indicator from the default indicators list.
77 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, this.SourcePrice, this.MAType, this.CalculationType);
78 | // Adds an auxiliary (MA) indicator to the current one (SD).
79 | // This will let inner indicator (MA) to be calculated in advance to the current one (SD).
80 | this.AddIndicator(this.ma);
81 | }
82 |
83 | ///
84 | /// Calculation entry point. This function is called when a price data updates.
85 | /// Will be runing under the HistoricalBar mode during history loading.
86 | /// Under NewTick during realtime.
87 | /// Under NewBar if start of the new bar is required.
88 | ///
89 | /// Provides data of updating reason and incoming price.
90 | protected override void OnUpdate(UpdateArgs args)
91 | {
92 | // Skip if count is smaller than period value.
93 | if (this.Count < this.MinHistoryDepths)
94 | return;
95 |
96 | // Processes calculating loop.
97 | double dAmount = 0;
98 | double movingAverage = this.ma.GetValue();
99 | for (int j = 0; j < this.Period; j++)
100 | dAmount += Math.Pow(this.GetPrice(this.SourcePrice, j) - movingAverage, 2);
101 |
102 | this.SetValue(Math.Sqrt(dAmount / this.Period));
103 | }
104 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorAccelerationOscillator.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | ///
9 | /// Acceleration/Deceleration Oscillator measures the acceleration and deceleration of the current momentum.
10 | ///
11 | public sealed class IndicatorAccelerationOscillator : Indicator, IWatchlistIndicator
12 | {
13 | private const int AC_PERIOD = 5;
14 | private const int AO_MAX_PERIOD = 34;
15 |
16 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/accelerator-oscillator";
17 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorAccelerationOscillator.cs";
18 | public int MinHistoryDepths => AC_PERIOD + AO_MAX_PERIOD;
19 | public override string ShortName => "AC";
20 |
21 | // Custom historical data to keep calculated values SMA(AO, 5).
22 | private HistoricalDataCustom customHistData;
23 | // Calculation indicators.
24 | private Indicator ao;
25 | private Indicator smaAO;
26 |
27 | ///
28 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
29 | ///
30 | public IndicatorAccelerationOscillator()
31 | : base()
32 | {
33 | // Defines indicator's group, name and description.
34 | this.Name = "Acceleration Oscillator";
35 | this.Description = "Acceleration/Deceleration Oscillator (AC) measures the acceleration and deceleration of the current momentum.";
36 |
37 | // Defines line on demand with particular parameters.
38 | this.AddLineSeries("AC'Line", Color.Gray, 2, LineStyle.Histogramm);
39 | this.SeparateWindow = true;
40 | }
41 |
42 | ///
43 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
44 | ///
45 | protected override void OnInit()
46 | {
47 | // Creates an instance of the custom historical data which will be syncronized by the current indicator instance.
48 | this.customHistData = new HistoricalDataCustom(this);
49 |
50 | // Creates a smoothing indicator which will keep smoothed custom data (for close prices).
51 | this.smaAO = Core.Indicators.BuiltIn.SMA(AC_PERIOD, PriceType.Close);
52 |
53 | // Adds the smoothing indicator to the custom historical data.
54 | this.customHistData.AddIndicator(this.smaAO);
55 |
56 | // Creates auxiliary indicator to calculate AO value with current historical data.
57 | this.ao = Core.Indicators.BuiltIn.AO();
58 | this.AddIndicator(this.ao);
59 | }
60 |
61 | ///
62 | /// Calculation entry point. This function is called when a price data updates.
63 | /// Will be runing under the HistoricalBar mode during history loading.
64 | /// Under NewTick during realtime.
65 | /// Under NewBar if start of the new bar is required.
66 | ///
67 | /// Provides data of updating reason and incoming price.
68 | protected override void OnUpdate(UpdateArgs args)
69 | {
70 | if (this.Count < AO_MAX_PERIOD)
71 | return;
72 |
73 | // Gets AO indicator value.
74 | double aoValue = this.ao.GetValue();
75 |
76 | // The calculated value must be set as close price against the custom HistoricalData (a respective price type argument),
77 | // because the SMA indicator was initialized with the source price - PriceType.Close.
78 | this.customHistData.SetValue(0, 0, 0, aoValue);
79 |
80 | if (this.Count < this.MinHistoryDepths)
81 | return;
82 |
83 | // Calculates difference between AO's value and smoothed custom historical data: AC = AO - SMA(AO,5).
84 | double differ = aoValue - this.smaAO.GetValue();
85 |
86 | // Skips value setting if it's NaN.
87 | if (double.IsNaN(differ))
88 | return;
89 |
90 | double prevDiffer = (this.Count > 1) ? this.GetValue(1) : differ;
91 |
92 | // Sets value for displaying on the chart.
93 | this.SetValue(aoValue - this.smaAO.GetValue());
94 |
95 | if (prevDiffer < differ)
96 | this.LinesSeries[0].SetMarker(0, Color.Green);
97 | else if (prevDiffer > differ)
98 | this.LinesSeries[0].SetMarker(0, Color.Red);
99 | }
100 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorRelativeStrengthIndexSmoothed.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace OscillatorsIndicators;
7 |
8 | public class IndicatorRelativeStrengthIndexSmoothed : Indicator, IWatchlistIndicator
9 | {
10 | #region Parameters
11 | [InputParameter("RSI period", 10, 1, 9999, 1, 0)]
12 | public int Period = 14;
13 |
14 | [InputParameter("Sources prices", 20, variants: new object[] {
15 | "Close", PriceType.Close,
16 | "Open", PriceType.Open,
17 | "High", PriceType.High,
18 | "Low", PriceType.Low,
19 | "Typical", PriceType.Typical,
20 | "Medium", PriceType.Median,
21 | "Weighted", PriceType.Weighted,
22 | "Volume", PriceType.Volume,
23 | "Open interest", PriceType.OpenInterest
24 | })]
25 | public PriceType SourcePrice = PriceType.Close;
26 |
27 | [InputParameter("Smooth period", 30, 1, 9999, 1, 0)]
28 | public int SmoothPeriod = 5;
29 |
30 | [InputParameter("Type of Moving Average", 40, variants: new object[] {
31 | "Simple", MaMode.SMA,
32 | "Exponential", MaMode.EMA,
33 | "Smoothed Modified", MaMode.SMMA,
34 | "Linear Weighted", MaMode.LWMA}
35 | )]
36 | public MaMode MaType = MaMode.SMA;
37 |
38 | [InputParameter("MA period", 50, 1, 9999, 1, 0)]
39 | public int MAPeriod = 9;
40 |
41 | [InputParameter("Calculation type", 60, variants: new object[]
42 | {
43 | "All available data", IndicatorCalculationType.AllAvailableData,
44 | "By period", IndicatorCalculationType.ByPeriod,
45 | })]
46 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
47 | private Indicator ema;
48 | private HistoricalDataCustom customHD;
49 | private Indicator rsi;
50 |
51 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorRelativeStrengthIndexSmoothed.cs";
52 |
53 | #endregion Parameters
54 |
55 | #region IWatchlistIndicator
56 | public int MinHistoryDepths
57 | {
58 | get
59 | {
60 | var rsiPeriod = this.Period + this.MAPeriod;
61 |
62 | if (this.CalculationType == IndicatorCalculationType.ByPeriod)
63 | rsiPeriod *= 2;
64 |
65 | return EmaPeriod + rsiPeriod;
66 | }
67 | }
68 | private int EmaPeriod => this.CalculationType == IndicatorCalculationType.ByPeriod ? this.SmoothPeriod : this.SmoothPeriod * 2;
69 | #endregion IWatchlistIndicator
70 |
71 | public IndicatorRelativeStrengthIndexSmoothed()
72 | {
73 | this.Name = "RSI Smoothed";
74 |
75 | this.AddLineSeries("RSI Smoothed", Color.DodgerBlue, 2, LineStyle.Solid);
76 | this.AddLineSeries("RSI Average", Color.Orange, 1, LineStyle.Solid);
77 |
78 | this.AddLineLevel(70d, "Up level", Color.Gray, 1, LineStyle.Dash);
79 | this.AddLineLevel(30d, "Down level", Color.Gray, 1, LineStyle.Dash);
80 | this.AddLineLevel(50d, "Middle level", Color.Gray, 1, LineStyle.Dash);
81 |
82 | this.SeparateWindow = true;
83 | }
84 |
85 | protected override void OnInit()
86 | {
87 | this.ema = Core.Instance.Indicators.BuiltIn.EMA(this.SmoothPeriod, this.SourcePrice, this.CalculationType);
88 | this.AddIndicator(this.ema);
89 |
90 | this.customHD = new HistoricalDataCustom();
91 | this.rsi = Core.Instance.Indicators.BuiltIn.RSI(this.Period, this.SourcePrice, RSIMode.Exponential, this.MaType, this.MAPeriod, this.CalculationType);
92 | this.customHD.AddIndicator(this.rsi);
93 | }
94 | protected override void OnUpdate(UpdateArgs args)
95 | {
96 | if (this.Count <= this.EmaPeriod)
97 | return;
98 |
99 | var emaValue = this.ema.GetValue();
100 |
101 | if (args.Reason != UpdateReason.NewTick)
102 | this.customHD.AddValue(emaValue, emaValue, emaValue, emaValue);
103 | else
104 | this.customHD.SetValue(emaValue, emaValue, emaValue, emaValue);
105 |
106 | if (this.Count < this.MinHistoryDepths)
107 | return;
108 |
109 | SetValue(this.rsi.GetValue(), 0);
110 | SetValue(this.rsi.GetValue(0, 1), 1);
111 | }
112 | protected override void OnClear()
113 | {
114 | this.RemoveIndicator(this.ema);
115 | this.ema?.Dispose();
116 |
117 | this.customHD.RemoveIndicator(this.rsi);
118 | this.rsi?.Dispose();
119 | this.customHD?.Dispose();
120 | }
121 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorPriceOscillator.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using System.Linq;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Oscillators;
8 |
9 | ///
10 | /// Calculates the variation between price moving averages.
11 | ///
12 | public sealed class IndicatorPriceOscillator : Indicator, IWatchlistIndicator
13 | {
14 | // Displays Input Parameter as dropdown list.
15 | [InputParameter("Type of Moving Average", 0, variants: new object[] {
16 | "Simple", MaMode.SMA,
17 | "Exponential", MaMode.EMA,
18 | "Modified", MaMode.SMMA,
19 | "Linear Weighted", MaMode.LWMA}
20 | )]
21 | public MaMode MAType = MaMode.SMA;
22 | //
23 | [InputParameter("Calculation type", 1, variants: new object[]
24 | {
25 | "All available data", IndicatorCalculationType.AllAvailableData,
26 | "By period", IndicatorCalculationType.ByPeriod,
27 | })]
28 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
29 |
30 |
31 | [InputParameter("Sources prices for MA", 2, variants: new object[] {
32 | "Close", PriceType.Close,
33 | "Open", PriceType.Open,
34 | "High", PriceType.High,
35 | "Low", PriceType.Low,
36 | "Typical", PriceType.Typical,
37 | "Medium", PriceType.Median,
38 | "Weighted", PriceType.Weighted,
39 | "Volume", PriceType.Volume,
40 | "Open interest", PriceType.OpenInterest
41 | })]
42 | public PriceType SourcePrice = PriceType.Close;
43 |
44 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
45 | [InputParameter("Period of MA1", 3, 1, 999, 1, 0)]
46 | public int MAPeriod1 = 10;
47 |
48 | [InputParameter("Period of MA2", 4, 1, 999, 1, 0)]
49 | public int MAPeriod2 = 21;
50 |
51 | public int MinHistoryDepths => Enumerable.Max(new int[] { this.MAPeriod1, this.MAPeriod2 });
52 | public override string ShortName => $"PO ({this.MAPeriod1}: {this.MAPeriod2}: {this.SourcePrice}: {this.MAType})";
53 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorPriceOscillator.cs";
54 |
55 | // Holds moving averages values.
56 | private Indicator ma1, ma2;
57 |
58 | ///
59 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
60 | ///
61 | public IndicatorPriceOscillator()
62 | : base()
63 | {
64 | // Defines indicator's group, name and description.
65 | this.Name = "Price Oscillator";
66 | this.Description = "Calculates the variation between price moving averages.";
67 |
68 | // Defines line and level with particular parameters.
69 | this.AddLineSeries("PO'Line", Color.Blue, 1, LineStyle.Solid);
70 | this.AddLineLevel(0, "0'Line", Color.Gray, 1, LineStyle.Solid);
71 | this.SeparateWindow = true;
72 | }
73 |
74 | ///
75 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
76 | ///
77 | protected override void OnInit()
78 | {
79 | // Creates an instances of the proper indicators (MA1, MA2) from the default indicators list.
80 | this.ma1 = Core.Indicators.BuiltIn.MA(this.MAPeriod1, this.SourcePrice, this.MAType, this.CalculationType);
81 | this.ma2 = Core.Indicators.BuiltIn.MA(this.MAPeriod2, this.SourcePrice, this.MAType, this.CalculationType);
82 |
83 | // Adds an auxiliary (MA1, MA2) indicator to the current one (PO).
84 | // This will let inner indicator (MA1, MA2) to be calculated in advance to the current one (PO).
85 | this.AddIndicator(this.ma1);
86 | this.AddIndicator(this.ma2);
87 | }
88 |
89 | ///
90 | /// Calculation entry point. This function is called when a price data updates.
91 | /// Will be runing under the HistoricalBar mode during history loading.
92 | /// Under NewTick during realtime.
93 | /// Under NewBar if start of the new bar is required.
94 | ///
95 | /// Provides data of updating reason and incoming price.
96 | protected override void OnUpdate(UpdateArgs args)
97 | {
98 | // Skip if count is smaller than maximal period value.
99 | if (this.Count < this.MinHistoryDepths)
100 | return;
101 |
102 | // Sets value for displaying on the chart.
103 | this.SetValue(this.ma1.GetValue() - this.ma2.GetValue());
104 | }
105 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorSchaffTrendCycle.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace TrendIndicators;
7 |
8 | public class IndicatorSchaffTrendCycle : Indicator
9 | {
10 | [InputParameter("Fast Period", 10, 1, 9999, 1, 0)]
11 | public int fastPeriod;
12 |
13 | [InputParameter("Slow Period", 10, 1, 9999, 1, 0)]
14 | public int slowPeriod;
15 |
16 | [InputParameter("k Period", 10, 1, 9999, 1, 0)]
17 | public int kPeriod;
18 |
19 | [InputParameter("d Period", 10, 1, 9999, 1, 0)]
20 | public int dPeriod;
21 |
22 | [InputParameter("High Line", 10, 0, 100)]
23 | public int HighLine;
24 |
25 | [InputParameter("Low Line", 10, 0, 100)]
26 | public int LowLine;
27 |
28 | [InputParameter("Sources prices for MA", 20, variants: new object[]
29 | {
30 | "Close", PriceType.Close,
31 | "Open", PriceType.Open,
32 | "High", PriceType.High,
33 | "Low", PriceType.Low,
34 | "Typical", PriceType.Typical,
35 | "Medium", PriceType.Median,
36 | "Weighted", PriceType.Weighted,
37 | })]
38 | public PriceType SourcePrice;
39 |
40 | [InputParameter("Smoothing type", 3, variants: new object[]{
41 | "Simple Moving Average", MaMode.SMA,
42 | "Exponential Moving Average", MaMode.EMA,
43 | "Smoothed Moving Average", MaMode.SMMA,
44 | "Linearly Weighted Moving Average", MaMode.LWMA,
45 | })]
46 | public MaMode MaType;
47 |
48 | private Indicator fastMA;
49 | private Indicator slowMA;
50 | private Indicator stochasticOscillator;
51 | private Indicator stochasticOscillatorPF;
52 | private Indicator stochasticOscillatorPFF;
53 |
54 | private HistoricalDataCustom macd;
55 | private HistoricalDataCustom pf;
56 | private HistoricalDataCustom pff;
57 |
58 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorSchaffTrendCycle.cs";
59 | public IndicatorSchaffTrendCycle()
60 | : base()
61 | {
62 | this.Name = "Schaff Trend Cycle";
63 | this.SeparateWindow = true;
64 |
65 | this.MaType = MaMode.SMA;
66 | this.SourcePrice = PriceType.Close;
67 |
68 | this.fastPeriod = 23;
69 | this.slowPeriod = 50;
70 | this.kPeriod = 10;
71 | this.dPeriod = 10;
72 | this.HighLine = 80;
73 | this.LowLine = 20;
74 |
75 | this.AddLineSeries("Main Line", Color.CadetBlue, 1, LineStyle.Solid);
76 | this.AddLineSeries("High Line", Color.Green, 1, LineStyle.Solid);
77 | this.AddLineSeries("Low Line", Color.Red, 1, LineStyle.Solid);
78 | }
79 |
80 |
81 | protected override void OnInit()
82 | {
83 | this.fastMA = Core.Instance.Indicators.BuiltIn.EMA(this.fastPeriod, this.SourcePrice);
84 | this.slowMA = Core.Instance.Indicators.BuiltIn.EMA(this.slowPeriod, this.SourcePrice);
85 |
86 | this.stochasticOscillator = Core.Instance.Indicators.BuiltIn.Stochastic(this.kPeriod, this.dPeriod, this.dPeriod * 2, this.MaType);
87 | this.stochasticOscillatorPF = Core.Instance.Indicators.BuiltIn.Stochastic(this.kPeriod, this.dPeriod, this.dPeriod * 2, this.MaType);
88 | this.stochasticOscillatorPFF = Core.Instance.Indicators.BuiltIn.Stochastic(this.kPeriod, this.dPeriod, this.dPeriod * 2, this.MaType);
89 |
90 | this.macd = new HistoricalDataCustom(this);
91 | this.pf = new HistoricalDataCustom(this);
92 | this.pff = new HistoricalDataCustom(this);
93 |
94 | this.AddIndicator(this.fastMA);
95 | this.AddIndicator(this.slowMA);
96 |
97 | this.macd.AddIndicator(this.stochasticOscillator);
98 | this.pf.AddIndicator(this.stochasticOscillatorPF);
99 | this.pff.AddIndicator(this.stochasticOscillatorPFF);
100 | }
101 |
102 | protected override void OnUpdate(UpdateArgs args)
103 | {
104 | if (this.Count < this.slowPeriod)
105 | return;
106 |
107 | double currentMACD = this.fastMA.GetValue() - this.slowMA.GetValue();
108 | this.macd.SetValue(currentMACD, currentMACD, currentMACD, currentMACD);
109 |
110 | double d = this.stochasticOscillator.GetValue(0, 1);
111 | this.pf.SetValue(d, d, d, d);
112 |
113 | double pf = this.stochasticOscillatorPF.GetValue();
114 | this.pff.SetValue(pf, pf, pf, pf);
115 |
116 | double pff = this.stochasticOscillatorPFF.GetValue(0, 1);
117 | this.SetValue(pff);
118 | this.SetValue(this.HighLine, 1);
119 | this.SetValue(this.LowLine, 2);
120 | }
121 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorBollingerBands.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Channels;
8 |
9 | public sealed class IndicatorBollingerBands : Indicator, IWatchlistIndicator
10 | {
11 | //Defines input parameters as input fields
12 | [InputParameter("Period of MA for envelopes", 0, 1, 999)]
13 | public int Period = 20;
14 | [InputParameter("Value of confidence interval", 1, 0.01, 100.0, 0.01, 2)]
15 | public double D = 2.0;
16 |
17 | //Defines input parameters as dropdown lists
18 | [InputParameter("Sources prices for MA", 2, variants: new object[] {
19 | "Close", PriceType.Close,
20 | "Open", PriceType.Open,
21 | "High", PriceType.High,
22 | "Low", PriceType.Low,
23 | "Typical", PriceType.Typical,
24 | "Medium", PriceType.Median,
25 | "Weighted", PriceType.Weighted,
26 | "Volume", PriceType.Volume,
27 | "Open interest", PriceType.OpenInterest
28 | })]
29 | public PriceType SourcePrices = PriceType.Close;
30 | [InputParameter("Type of moving average", 3, variants: new object[]{
31 | "Simple Moving Average", MaMode.SMA,
32 | "Exponential Moving Average", MaMode.EMA,
33 | "Smoothed Moving Average", MaMode.SMMA,
34 | "Linearly Weighted Moving Average", MaMode.LWMA,
35 | })]
36 | public MaMode MaType = MaMode.SMA;
37 |
38 | [InputParameter("Calculation type", 4, variants: new object[]
39 | {
40 | "All available data", IndicatorCalculationType.AllAvailableData,
41 | "By period", IndicatorCalculationType.ByPeriod,
42 | })]
43 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
44 |
45 | public int MinHistoryDepths => this.Period;
46 | public override string ShortName => $"BB ({this.Period}:{this.D})";
47 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorBollingerBands.cs";
48 |
49 | private Indicator ma;
50 |
51 | ///
52 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
53 | ///
54 | public IndicatorBollingerBands()
55 | : base()
56 | {
57 | // Defines indicator's name and description.
58 | this.Name = "Bollinger Bands";
59 | this.Description = "Provides a relative definition of high and low based on standard deviation and a simple moving average";
60 |
61 | // Defines three lines with particular parameters.
62 | this.AddLineSeries("Upper Band", Color.Red, 2, LineStyle.Solid);
63 | this.AddLineSeries("Middle Band", Color.Gray, 2, LineStyle.Solid);
64 | this.AddLineSeries("Lower Band", Color.Green, 2, LineStyle.Solid);
65 |
66 | this.SeparateWindow = false;
67 | }
68 |
69 | ///
70 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
71 | ///
72 | protected override void OnInit()
73 | {
74 | // Get MA indicator from built-in indicator collection (according to selected 'MaType')
75 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, this.SourcePrices, this.MaType, this.CalculationType);
76 | this.AddIndicator(this.ma);
77 | }
78 |
79 | ///
80 | /// Calculation entry point. This function is called when a price data updates.
81 | /// Will be runing under the HistoricalBar mode during history loading.
82 | /// Under NewTick during realtime.
83 | /// Under NewBar if start of the new bar is required.
84 | ///
85 | /// Provides data of updating reason and incoming price.
86 | protected override void OnUpdate(UpdateArgs args)
87 | {
88 | // Checking, if current amount of bars
89 | // more, than period of moving average. If it is
90 | // then the calculation is possible
91 | if (this.Count < this.MinHistoryDepths)
92 | return;
93 |
94 | // Get MA value of current bar (0 offset by default)
95 | double maValue = this.ma.GetValue();
96 |
97 | // Calulation of the sum
98 | double sum = 0.0;
99 | for (int i = 0; i < this.Period; i++)
100 | sum += Math.Pow(this.GetPrice(this.SourcePrices, i) - maValue, 2);
101 |
102 | // Calculation of deviation value
103 | sum = this.D * Math.Sqrt(sum / this.Period);
104 |
105 | // set values to line buffers
106 | this.SetValue(maValue + sum);
107 | this.SetValue(maValue, 1);
108 | this.SetValue(maValue - sum, 2);
109 | }
110 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorMovingAverageEnvelope.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Channels;
7 |
8 | public sealed class IndicatorMovingAverageEnvelope : Indicator, IWatchlistIndicator
9 | {
10 | // Defines the 'Period' parameter as input field (where 'min' is 1 and 'max' is 999).
11 | [InputParameter("Period of MA for envelopes", 0, 1, 999, 1, 0)]
12 | public int Period = 20;
13 |
14 | // Defines the 'SourcePrice' parameter as dropdown list
15 | [InputParameter("Sources prices for MA", 1, variants: new object[] {
16 | "Close", PriceType.Close,
17 | "Open", PriceType.Open,
18 | "High", PriceType.High,
19 | "Low", PriceType.Low,
20 | "Typical", PriceType.Typical,
21 | "Medium", PriceType.Median,
22 | "Weighted", PriceType.Weighted,
23 | "Volume", PriceType.Volume,
24 | "Open interest", PriceType.OpenInterest
25 | })]
26 | public PriceType SourcePrice = PriceType.Close;
27 |
28 | // Defines the 'MaType' parameter as dropdown list
29 | [InputParameter("Type of moving average", 2, variants: new object[]{
30 | "Simple Moving Average", MaMode.SMA,
31 | "Exponential Moving Average", MaMode.EMA,
32 | "Smoothed Moving Average", MaMode.SMMA,
33 | "Linearly Weighted Moving Average", MaMode.LWMA,
34 | })]
35 | public MaMode MaType = MaMode.SMA;
36 |
37 | [InputParameter("Calculation type", 3, variants: new object[]
38 | {
39 | "All available data", IndicatorCalculationType.AllAvailableData,
40 | "By period", IndicatorCalculationType.ByPeriod,
41 | })]
42 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
43 |
44 | // Defines the 'UpShift' parameter as input field (where 'min' is 0.1 and 'increment' is 0.1).
45 | [InputParameter("Upband deviation in %", 4, 0.01, int.MaxValue, 0.01, 2)]
46 | public double UpShift = 0.1;
47 |
48 | // Defines the 'DownShift' parameter as input field (where 'min' is 0.1 and 'increment' is 0.1).
49 | [InputParameter("Downband deviation in %", 5, 0.01, int.MaxValue, 0.01, 2)]
50 | public double DownShift = 0.1;
51 |
52 | public int MinHistoryDepths => this.Period;
53 | public override string ShortName => $"MAE ({this.Period}:{this.UpShift}:{this.DownShift})";
54 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorMovingAverageEnvelope.cs";
55 |
56 | private Indicator ma;
57 |
58 | ///
59 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
60 | ///
61 | public IndicatorMovingAverageEnvelope()
62 | : base()
63 | {
64 | // Defines indicator's name and description.
65 | this.Name = "Moving Average Envelope";
66 | this.Description = "Demonstrates a range of the prices discrepancy from a Moving Average";
67 |
68 | // Defines two lines with particular parameters.
69 | this.AddLineSeries("Lower Band", Color.Purple, 1, LineStyle.Solid);
70 | this.AddLineSeries("Upper Band", Color.LightSeaGreen, 1, LineStyle.Solid);
71 |
72 | this.SeparateWindow = false;
73 | }
74 |
75 | ///
76 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
77 | ///
78 | protected override void OnInit()
79 | {
80 | // Get MA indicator from built-in indicator collection (according to selected 'MaType').
81 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, this.SourcePrice, this.MaType, this.CalculationType);
82 | this.AddIndicator(this.ma);
83 | }
84 |
85 | ///
86 | /// Calculation entry point. This function is called when a price data updates.
87 | /// Will be runing under the HistoricalBar mode during history loading.
88 | /// Under NewTick during realtime.
89 | /// Under NewBar if start of the new bar is required.
90 | ///
91 | /// Provides data of updating reason and incoming price.
92 | protected override void OnUpdate(UpdateArgs args)
93 | {
94 | // Skip some period for correct calculation.
95 | if (this.Count < this.MinHistoryDepths)
96 | return;
97 |
98 | // Get current close price (0 offset by default)
99 | double maValue = this.ma.GetValue();
100 |
101 | // Set values to 'Lower Band' and 'Upper Band' line buffers.
102 | this.SetValue((1.0 - this.DownShift * 0.01) * maValue, 0);
103 | this.SetValue((1.0 + this.UpShift * 0.01) * maValue, 1);
104 | }
105 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorSmoothedMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace MovingAverages;
7 |
8 | ///
9 | /// The SMMA gives recent prices an equal weighting to historic prices.
10 | ///
11 | public sealed class IndicatorSmoothedMovingAverage : Indicator, IWatchlistIndicator
12 | {
13 | // Period of moving average.
14 | [InputParameter("Period of Smoothed Moving Average", 0, 1, 999, 1, 0)]
15 | public int MaPeriod = 7;
16 |
17 | // Price type of moving average.
18 | [InputParameter("Sources prices for MA", 1, variants: new object[]
19 | {
20 | "Close", PriceType.Close,
21 | "Open", PriceType.Open,
22 | "High", PriceType.High,
23 | "Low", PriceType.Low,
24 | "Typical", PriceType.Typical,
25 | "Median", PriceType.Median,
26 | "Weighted", PriceType.Weighted,
27 | "Volume", PriceType.Volume,
28 | "Open interest", PriceType.OpenInterest
29 | })]
30 | public PriceType SourcePrice = PriceType.Close;
31 |
32 | [InputParameter("Calculation type", 10, variants: new object[]
33 | {
34 | "All available data", IndicatorCalculationType.AllAvailableData,
35 | "By period", IndicatorCalculationType.ByPeriod,
36 | })]
37 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
38 |
39 | ///
40 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
41 | ///
42 | public IndicatorSmoothedMovingAverage()
43 | : base()
44 | {
45 | // Defines indicator's group, name and description.
46 | this.Name = "Smoothed Moving Average";
47 | this.Description = "The SMMA gives recent prices an equal weighting to historic prices.";
48 |
49 | // Defines line on demand with particular parameters.
50 | this.AddLineSeries("SMMA", Color.DodgerBlue, 1, LineStyle.Solid);
51 |
52 | this.SeparateWindow = false;
53 | }
54 |
55 | public int MinHistoryDepths => this.MaPeriod * 2;
56 | public override string ShortName => $"SMMA ({this.MaPeriod}: {this.SourcePrice})";
57 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorSmoothedMovingAverage.cs";
58 |
59 | ///
60 | /// Calculation entry point. This function is called when a price data updates.
61 | /// Will be runing under the HistoricalBar mode during history loading.
62 | /// Under NewTick during realtime.
63 | /// Under NewBar if start of the new bar is required.
64 | ///
65 | /// Provides data of updating reason and incoming price.
66 | protected override void OnUpdate(UpdateArgs args)
67 | {
68 | // Checking, if current amount of bars less, than period of moving average - calculation is impossible.
69 | if (this.Count < this.MinHistoryDepths)
70 | return;
71 |
72 | if (this.CalculationType == IndicatorCalculationType.ByPeriod)
73 | this.CalculateByPeriod();
74 | else
75 | this.CalculateForAllData();
76 | }
77 |
78 | private void CalculateByPeriod(int offset = 0)
79 | {
80 | int startOffset = offset + this.MaPeriod;
81 |
82 | if (this.Count <= startOffset + this.MaPeriod)
83 | return;
84 |
85 | // calcualte start value
86 | double smma = this.CalculateSMA(startOffset);
87 |
88 | for (int i = startOffset - 1; i >= offset; i--)
89 | smma = this.CalculateSMMA(i, smma);
90 |
91 | this.SetValue(smma, offset);
92 | }
93 |
94 | private double CalculateSMMA(int offset, double prevSMMA) => (prevSMMA * (this.MaPeriod - 1) + this.GetPrice(this.SourcePrice, offset)) / this.MaPeriod;
95 |
96 | private void CalculateForAllData()
97 | {
98 | // Calculating the current value of the indicator.
99 | double value;
100 | double prevSMMA = this.GetValue(1);
101 |
102 | if (double.IsNaN(prevSMMA))
103 | {
104 | // Calculates initial value as Simple Moving Average.
105 | value = this.CalculateSMA(0);
106 | }
107 | else
108 | {
109 | value = this.CalculateSMMA(0, prevSMMA);
110 | }
111 |
112 | // Sets value for displaying on the chart.
113 | this.SetValue(value);
114 | }
115 |
116 | private double CalculateSMA(int offset)
117 | {
118 | double sum = 0d;
119 | for (int i = 0; i < this.MaPeriod; i++)
120 | sum += this.GetPrice(this.SourcePrice, offset + i);
121 |
122 | return sum / this.MaPeriod;
123 | }
124 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorMovingAverageOfOscillator.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Oscillators;
8 |
9 | public sealed class IndicatorMovingAverageOfOscillator : Indicator, IWatchlistIndicator
10 | {
11 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
12 | [InputParameter("Period of fast EMA", 0, 1, 999, 1, 0)]
13 | public int FastPeriod = 12;
14 |
15 | [InputParameter("Period of slow EMA", 1, 1, 999, 1, 0)]
16 | public int SlowPeriod = 26;
17 |
18 | [InputParameter("Period of signal EMA", 2, 1, 999, 1, 0)]
19 | public int SignalPeriod = 9;
20 |
21 | //
22 | [InputParameter("Calculation type", 10, variants: new object[]
23 | {
24 | "All available data", IndicatorCalculationType.AllAvailableData,
25 | "By period", IndicatorCalculationType.ByPeriod,
26 | })]
27 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
28 |
29 | private int MaxEMAPeriod => Math.Max(this.FastPeriod, this.SlowPeriod);
30 | public int MinHistoryDepths => this.MaxEMAPeriod + this.SignalPeriod;
31 | public override string ShortName => $"OsMA ({this.FastPeriod}:{this.SlowPeriod}:{this.SignalPeriod})";
32 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorMovingAverageOfOscillator.cs";
33 |
34 | private Indicator fastEMA;
35 | private Indicator slowEMA;
36 | private Indicator sma;
37 | private HistoricalDataCustom customHD;
38 |
39 | ///
40 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
41 | ///
42 | public IndicatorMovingAverageOfOscillator()
43 | : base()
44 | {
45 | // Defines indicator's name and description.
46 | this.Name = "Moving Average of Oscillator";
47 | this.Description = "Reflects the difference between an oscillator (MACD) and its moving average (signal line).";
48 |
49 | // Defines line on demand with particular parameters.
50 | this.AddLineSeries("OsMA", Color.Green, 4, LineStyle.Histogramm);
51 |
52 | this.SeparateWindow = true;
53 | }
54 |
55 | ///
56 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
57 | ///
58 | protected override void OnInit()
59 | {
60 | // Get two EMA and one SMA indicators from built-in indicator collection
61 | this.fastEMA = Core.Indicators.BuiltIn.EMA(this.FastPeriod, PriceType.Typical, this.CalculationType);
62 | this.slowEMA = Core.Indicators.BuiltIn.EMA(this.SlowPeriod, PriceType.Typical, this.CalculationType);
63 | this.sma = Core.Indicators.BuiltIn.SMA(this.SignalPeriod, PriceType.Close);
64 |
65 | // Create a custom HistoricalData and syncronize it with this(MACD) indicator.
66 | this.customHD = new HistoricalDataCustom(this);
67 |
68 | // Attach SMA indicator to custom HistoricalData. The SMA will calculate on the data, which will store in custom HD.
69 | this.customHD.AddIndicator(this.sma);
70 |
71 | // Add auxiliary EMA indicators to the current one.
72 | this.AddIndicator(this.fastEMA);
73 | this.AddIndicator(this.slowEMA);
74 | }
75 |
76 | ///
77 | /// Calculation entry point. This function is called when a price data updates.
78 | /// Will be runing under the HistoricalBar mode during history loading.
79 | /// Under NewTick during realtime.
80 | /// Under NewBar if start of the new bar is required.
81 | ///
82 | /// Provides data of updating reason and incoming price.
83 | protected override void OnUpdate(UpdateArgs args)
84 | {
85 | // Skip max period for correct calculation.
86 | if (this.Count < this.MaxEMAPeriod)
87 | return;
88 |
89 | // Calculate a difference bettwen two EMA indicators.
90 | double differ = this.fastEMA.GetValue() - this.slowEMA.GetValue();
91 |
92 | // The calculated value must be set as close price against the custom HistoricalData,
93 | // because the SMA indicator was initialized with the source price - PriceType.Close.
94 | this.customHD[PriceType.Close, 0] = differ;
95 |
96 | if (this.Count < this.MinHistoryDepths)
97 | return;
98 |
99 | // Get value from SMA indicator, which is calculated based on custom HistoricalData.
100 | double signal = this.sma.GetValue();
101 | if (double.IsNaN(signal))
102 | return;
103 |
104 | // Set value to the 'OsMA' line buffer.
105 | this.SetValue(differ - signal);
106 | }
107 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorQstick.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Oscillators;
7 |
8 | ///
9 | /// Moving average that shows the difference between the prices at which an issue opens and closes.
10 | ///
11 | public sealed class IndicatorQstick : Indicator, IWatchlistIndicator
12 | {
13 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
14 | [InputParameter("Period", 0, 1, 999, 0, 0)]
15 | public int Period = 14;
16 |
17 | // Displays Input Parameter as dropdown list.
18 | [InputParameter("Type of Moving Average", 1, variants: new object[] {
19 | "Simple", MaMode.SMA,
20 | "Exponential", MaMode.EMA,
21 | "Modified", MaMode.SMMA,
22 | "Linear Weighted", MaMode.LWMA}
23 | )]
24 | public MaMode MAType = MaMode.SMA;
25 | [InputParameter("Smoothing period", 0, 1, 999, 0, 0)]
26 | public int SmoothingPeriod = 20;
27 |
28 | // Displays Input Parameter as dropdown list.
29 | [InputParameter("Smoothing Type", 1, variants: new object[] {
30 | "Simple", MaMode.SMA,
31 | "Exponential", MaMode.EMA,
32 | "Modified", MaMode.SMMA,
33 | "Linear Weighted", MaMode.LWMA}
34 | )]
35 | public MaMode SmoothingType = MaMode.SMA;
36 | //
37 | [InputParameter("Calculation type", 5, variants: new object[]
38 | {
39 | "All available data", IndicatorCalculationType.AllAvailableData,
40 | "By period", IndicatorCalculationType.ByPeriod,
41 | })]
42 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
43 |
44 | public int MinHistoryDepths => this.Period;
45 | public override string ShortName => $"Qstick ({this.Period}: {this.MAType})";
46 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorQstick.cs";
47 |
48 | private HistoricalDataCustom customHistData;
49 | private Indicator ma;
50 | private Indicator smoothing;
51 |
52 |
53 | ///
54 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
55 | ///
56 | public IndicatorQstick()
57 | : base()
58 | {
59 | // Defines indicator's group, name and description.
60 | this.Name = "Qstick";
61 | this.Description = "Moving average that shows the difference between the prices at which an issue opens and closes.";
62 |
63 | // Defines line on demand with particular parameters.
64 | this.AddLineSeries("Qstick'Line", Color.Blue, 1, LineStyle.Solid);
65 | this.AddLineLevel(0, "0'Line", Color.Gray, 1, LineStyle.Solid);
66 | this.AddLineSeries("Smoothing line", Color.IndianRed, 1, LineStyle.Solid);
67 |
68 | this.SeparateWindow = true;
69 | }
70 |
71 | ///
72 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
73 | ///
74 | protected override void OnInit()
75 | {
76 | // Creates an instance of the custom historical data which will be syncronized by the current indicator instance.
77 | this.customHistData = new HistoricalDataCustom(this);
78 |
79 | // Creates a smoothing indicator which will keep smoothed custom data.
80 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, PriceType.Close, this.MAType, this.CalculationType);
81 |
82 | // Adds the smoothing indicator to the custom historical data.
83 | this.customHistData.AddIndicator(this.ma);
84 |
85 | this.smoothing = Core.Indicators.BuiltIn.MA(this.SmoothingPeriod, PriceType.Open, this.SmoothingType, this.CalculationType);
86 | this.customHistData.AddIndicator(this.smoothing);
87 | }
88 |
89 | ///
90 | /// Calculation entry point. This function is called when a price data updates.
91 | /// Will be runing under the HistoricalBar mode during history loading.
92 | /// Under NewTick during realtime.
93 | /// Under NewBar if start of the new bar is required.
94 | ///
95 | /// Provides data of updating reason and incoming price.
96 | protected override void OnUpdate(UpdateArgs args)
97 | {
98 | // Populates custom HistoricalData price with the current price difference value.
99 | this.customHistData[PriceType.Close] = this.Close() - this.Open();
100 |
101 | // Skip if count is smaller than period value.
102 | if (this.Count < this.MinHistoryDepths)
103 | return;
104 | var qStickValue = this.ma.GetValue();
105 | this.customHistData[PriceType.Open] = this.Close() - this.Open();
106 | // Sets value (smoothing value on the custom historical data) for displaying on the chart.
107 | this.SetValue(qStickValue);
108 | this.SetValue(this.smoothing.GetValue(), 1);
109 | }
110 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorBollingerBandsFlat.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Channels;
7 |
8 | ///
9 | /// The Bollinger Bands Flat (BBF) indicator provides the same data as BB, but drawn in separate field and easier to recognize whether price is in or out of the band.
10 | ///
11 | public sealed class IndicatorBollingerBandsFlat : Indicator, IWatchlistIndicator
12 | {
13 | #region Parameters
14 |
15 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
16 | [InputParameter("Period", 0, 1, 999, 1, 0)]
17 | public int Period = 9;
18 |
19 | [InputParameter("Type of Moving Average", 1, variants: new object[] {
20 | "Simple", MaMode.SMA,
21 | "Exponential", MaMode.EMA,
22 | "Modified", MaMode.SMMA,
23 | "Linear Weighted", MaMode.LWMA}
24 | )]
25 | public MaMode MAType = MaMode.SMA;
26 |
27 | // Displays Input Parameter as dropdown list.
28 | [InputParameter("Sources prices for MA", 2, variants: new object[] {
29 | "Close", PriceType.Close,
30 | "Open", PriceType.Open,
31 | "High", PriceType.High,
32 | "Low", PriceType.Low,
33 | "Typical", PriceType.Typical,
34 | "Medium", PriceType.Median,
35 | "Weighted", PriceType.Weighted,
36 | "Volume", PriceType.Volume,
37 | "Open interest", PriceType.OpenInterest
38 | })]
39 | public PriceType SourcePrice = PriceType.Close;
40 |
41 | [InputParameter("Deviation", 3, 0.01, 3, 0.01, 2)]
42 | public double Deviation = 1.5;
43 | //
44 | [InputParameter("Calculation type", 4, variants: new object[]
45 | {
46 | "All available data", IndicatorCalculationType.AllAvailableData,
47 | "By period", IndicatorCalculationType.ByPeriod,
48 | })]
49 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
50 |
51 | #endregion
52 |
53 | // Holds additional indicators values.
54 | private Indicator ma;
55 | private Indicator sd;
56 | public int MinHistoryDepths => this.Period;
57 | public override string ShortName => $"BBF ({this.Period}: {this.Deviation})";
58 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorBollingerBandsFlat.cs";
59 |
60 | ///
61 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
62 | ///
63 | public IndicatorBollingerBandsFlat()
64 | : base()
65 | {
66 | // Defines indicator's group, name and description.
67 | this.Name = "Bollinger Bands Flat";
68 | this.Description = "The Bollinger Bands Flat (BBF) indicator provides the same data as BB, but drawn in separate field and easier to recognize whether price is in or out of the band.";
69 |
70 | // Defines line on demand with particular parameters.
71 | this.AddLineSeries("+SD", Color.Red, 1, LineStyle.Solid);
72 | this.AddLineSeries("-SD", Color.Red, 1, LineStyle.Solid);
73 | this.AddLineSeries("BBF'Line", Color.FromArgb(0, 51, 252), 1, LineStyle.Solid);
74 | this.AddLineLevel(0, "0'Line", Color.Aqua, 1, LineStyle.Solid);
75 |
76 | this.SeparateWindow = true;
77 | }
78 |
79 | ///
80 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
81 | ///
82 | protected override void OnInit()
83 | {
84 | // Creates an instances of the proper indicators (MA, SD) from the default indicators list.
85 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, this.SourcePrice, this.MAType, this.CalculationType);
86 | this.sd = Core.Indicators.BuiltIn.SD(this.Period, this.SourcePrice, this.MAType, this.CalculationType);
87 | // Adds auxiliary (MA, SD) indicators to the current one (BBF).
88 | // This will let inner indicators (MA, SD) to be calculated in advance to the current one (BBF).
89 | this.AddIndicator(this.ma);
90 | this.AddIndicator(this.sd);
91 | }
92 |
93 | ///
94 | /// Calculation entry point. This function is called when a price data updates.
95 | /// Will be runing under the HistoricalBar mode during history loading.
96 | /// Under NewTick during realtime.
97 | /// Under NewBar if start of the new bar is required.
98 | ///
99 | /// Provides data of updating reason and incoming price.
100 | protected override void OnUpdate(UpdateArgs args)
101 | {
102 | if (this.Count < this.MinHistoryDepths)
103 | return;
104 |
105 | // Sets value for displaying on the chart.
106 | double std = this.Deviation * this.sd.GetValue();
107 |
108 | this.SetValue(std);
109 | this.SetValue(-std, 1);
110 | this.SetValue(this.GetPrice(PriceType.Close) - this.ma.GetValue(), 2);
111 | }
112 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorCommodityChannelIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Oscillators;
8 |
9 | public sealed class IndicatorCommodityChannelIndex : Indicator, IWatchlistIndicator
10 | {
11 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
12 | [InputParameter("Period", 10, 1, 999, 1, 0)]
13 | public int Period = 14;
14 |
15 | // Displays Input Parameter as dropdown list.
16 | [InputParameter("Sources prices for MA", 20, variants: new object[] {
17 | "Close", PriceType.Close,
18 | "Open", PriceType.Open,
19 | "High", PriceType.High,
20 | "Low", PriceType.Low,
21 | "Typical", PriceType.Typical,
22 | "Medium", PriceType.Median,
23 | "Weighted", PriceType.Weighted,
24 | "Volume", PriceType.Volume,
25 | "Open interest", PriceType.OpenInterest
26 | })]
27 | public PriceType SourcePrice = PriceType.Typical;
28 |
29 | // Displays Input Parameter as dropdown list.
30 | [InputParameter("Type of Moving Average", 30, variants: new object[] {
31 | "Simple", MaMode.SMA,
32 | "Exponential", MaMode.EMA,
33 | "Modified", MaMode.SMMA,
34 | "Linear Weighted", MaMode.LWMA}
35 | )]
36 | public MaMode MAType = MaMode.SMA;
37 |
38 | [InputParameter("Calculation type", 40, variants: new object[]
39 | {
40 | "All available data", IndicatorCalculationType.AllAvailableData,
41 | "By period", IndicatorCalculationType.ByPeriod,
42 | })]
43 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
44 |
45 | public int MinHistoryDepths => this.Period;
46 | public override string ShortName => $"CCI ({this.Period}: {this.SourcePrice})";
47 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/oscillators/commodity-channel-index";
48 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorCommodityChannelIndex.cs";
49 |
50 | private Indicator MA;
51 |
52 | ///
53 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
54 | ///
55 | public IndicatorCommodityChannelIndex()
56 | : base()
57 | {
58 | // Serves for an identification of related indicators with different parameters.
59 | this.Name = "Commodity Channel Index";
60 | this.Description = "Measures the position of price in relation to its moving average";
61 |
62 | // Defines line on demand with particular parameters.
63 | this.AddLineSeries("CCI Line", Color.Red, 1, LineStyle.Solid);
64 | this.AddLineLevel(150, "150", Color.Gray, 1, LineStyle.Solid);
65 | this.AddLineLevel(100, "100", Color.Gray, 1, LineStyle.Solid);
66 | this.AddLineLevel(0, "0", Color.Gray, 1, LineStyle.Solid);
67 | this.AddLineLevel(-100, "-100", Color.Gray, 1, LineStyle.Solid);
68 | this.AddLineLevel(-150, "-150", Color.Gray, 1, LineStyle.Solid);
69 | this.SeparateWindow = true;
70 | }
71 |
72 | ///
73 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
74 | ///
75 | protected override void OnInit()
76 | {
77 | // Creates an instance of the proper indicator from the default indicators list.
78 | this.MA = Core.Indicators.BuiltIn.MA(this.Period, this.SourcePrice, this.MAType, this.CalculationType);
79 | // Adds an auxiliary (MA) indicator to the current one (CCI).
80 | // This will let inner indicator (MA) to be calculated in advance to the current one (CCI).
81 | this.AddIndicator(this.MA);
82 | }
83 | ///
84 | /// Calculation entry point. This function is called when a price data updates.
85 | /// Will be runing under the HistoricalBar mode during history loading.
86 | /// Under NewTick during realtime.
87 | /// Under NewBar if start of the new bar is required.
88 | ///
89 | /// Provides data of updating reason and incoming price.
90 | protected override void OnUpdate(UpdateArgs args)
91 | {
92 | // Skip if count is smaller than period value.
93 | if (this.Count < this.MinHistoryDepths)
94 | return;
95 |
96 | double meanDeviation = 0;
97 | double sma = this.MA.GetValue(0);
98 | for (int i = 0; i < this.Period; i++)
99 | {
100 | double tp = this.GetPrice(this.SourcePrice, i);
101 | meanDeviation += Math.Abs(tp - sma);
102 | }
103 |
104 | meanDeviation = 0.015 * (meanDeviation / this.Period);
105 |
106 | double currentTP = this.GetPrice(this.SourcePrice);
107 | double currentSMA = this.MA.GetValue();
108 |
109 | this.SetValue((currentTP - currentSMA) / meanDeviation);
110 | }
111 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorKeltnerChannel.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace Channels;
7 |
8 | ///
9 | /// Keltner Channels are volatility-based envelopes set above and below an exponential moving average.
10 | ///
11 | public sealed class IndicatorKeltnerChannel : Indicator, IWatchlistIndicator
12 | {
13 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
14 | [InputParameter("Sources prices for MA", 10, variants: new object[] {
15 | "Close", PriceType.Close,
16 | "Open", PriceType.Open,
17 | "High", PriceType.High,
18 | "Low", PriceType.Low,
19 | "Typical", PriceType.Typical,
20 | "Medium", PriceType.Median,
21 | "Weighted", PriceType.Weighted,
22 | "Volume", PriceType.Volume,
23 | "Open interest", PriceType.OpenInterest
24 | })]
25 | public PriceType SourcePrice = PriceType.Close;
26 |
27 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
28 | [InputParameter("Type of Moving Average", 20, variants: new object[] {
29 | "Simple", MaMode.SMA,
30 | "Exponential", MaMode.EMA,
31 | "Modified", MaMode.SMMA,
32 | "Linear Weighted", MaMode.LWMA}
33 | )]
34 | public MaMode MAType = MaMode.SMA;
35 | //
36 | [InputParameter("Calculation type", 30, variants: new object[]
37 | {
38 | "All available data", IndicatorCalculationType.AllAvailableData,
39 | "By period", IndicatorCalculationType.ByPeriod,
40 | })]
41 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
42 |
43 | // Displays Input Parameter as dropdown list.
44 | [InputParameter("Period of MA for Keltner's Channel", 40, 1, 9999, 1)]
45 | public int Period = 20;
46 |
47 | // Displays Input Parameter as dropdown list.
48 | [InputParameter("Coefficient of channel's width", 50, 0.01, 100)]
49 | public double Offset = 2;
50 |
51 | public int MinHistoryDepths => this.Period;
52 | public override string ShortName => $"Keltner ({this.Period}: {this.Offset}: {this.SourcePrice}: {this.MAType})";
53 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorKeltnerChannel.cs";
54 |
55 | private Indicator ma;
56 | private Indicator atr;
57 |
58 | ///
59 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
60 | ///
61 | public IndicatorKeltnerChannel()
62 | : base()
63 | {
64 | // Defines indicator's group, name and description.
65 | this.Name = "Keltner Channel";
66 | this.Description = "Keltner Channels are volatility-based envelopes set above and below an exponential moving average";
67 | this.IsUpdateTypesSupported = false;
68 |
69 | // Defines line on demand with particular parameters.
70 | this.AddLineSeries("MA'Line", Color.Coral, 1, LineStyle.Solid);
71 | this.AddLineSeries("+ATR'Line", Color.Red, 1, LineStyle.Solid);
72 | this.AddLineSeries("-ATR'Line", Color.Purple, 1, LineStyle.Solid);
73 | }
74 |
75 | ///
76 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
77 | ///
78 | protected override void OnInit()
79 | {
80 | // Creates an instances of the proper indicators from the default indicators list.
81 | this.ma = Core.Indicators.BuiltIn.MA(this.Period, this.SourcePrice, this.MAType, this.CalculationType);
82 | this.ma.UpdateType = IndicatorUpdateType.OnTick;
83 |
84 | this.atr = Core.Indicators.BuiltIn.ATR(this.Period, this.MAType, this.CalculationType);
85 |
86 | // Adds an auxiliary (MA, ATR ) indicators to the current one (Keltner).
87 | // This will let inner indicator (MA, ATR) to be calculated in advance to the current one (Keltner).
88 | this.AddIndicator(this.ma);
89 | this.AddIndicator(this.atr);
90 | }
91 |
92 | ///
93 | /// Calculation entry point. This function is called when a price data updates.
94 | /// Will be runing under the HistoricalBar mode during history loading.
95 | /// Under NewTick during realtime.
96 | /// Under NewBar if start of the new bar is required.
97 | ///
98 | /// Provides data of updating reason and incoming price.
99 | protected override void OnUpdate(UpdateArgs args)
100 | {
101 | if (this.Count < this.MinHistoryDepths)
102 | return;
103 |
104 | // Gets calculation values.
105 | double maValue = this.ma.GetValue();
106 | double atrValue = this.Offset * this.atr.GetValue();
107 |
108 | // Sets given values for the displaying on the chart.
109 | this.SetValue(maValue, 0);
110 | this.SetValue(maValue + atrValue, 1);
111 | this.SetValue(maValue - atrValue, 2);
112 | }
113 | }
--------------------------------------------------------------------------------
/Indicators/Indicator3MASignal.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using TradingPlatform.BusinessLayer;
4 | using System.Drawing;
5 | using System.Linq;
6 |
7 | namespace MovingAverages;
8 |
9 | #warning Не використовуйте абревіатури у назвах, особливо якщо якщо вони не загальноприйняті
10 | public sealed class Indicator3MASignal : Indicator, IWatchlistIndicator
11 | {
12 | private const int UP = 1; // Up trend
13 | private const int DOWN = -1; // Down trend
14 | private const int NONE = 0; // No trend
15 |
16 | //Defines input parameters as input fields
17 | [InputParameter("Short Moving Average Period", 0, 1, 999, 1, 0)]
18 | public int ShortMaPeriod;
19 |
20 | [InputParameter("Middle Moving Average Period", 1, 1, 999, 1, 0)]
21 | public int MiddleMaPeriod;
22 |
23 | [InputParameter("Long Moving Average Period", 2, 1, 999, 1, 0)]
24 | public int LongMaPeriod;
25 |
26 | [InputParameter("Amount of bars passed before opening position", 3, 1, 999, 1, 0)]
27 | public int BarsInterval;
28 |
29 | private Indicator shortMa;
30 | private Indicator middleMa;
31 | private Indicator longMa;
32 | private int currentTrend;
33 |
34 | public int MinHistoryDepths => Enumerable.Max(new int[] { this.ShortMaPeriod, this.MiddleMaPeriod, this.LongMaPeriod });
35 | public override string ShortName => $"MAS3 ({this.ShortMaPeriod}:{this.MiddleMaPeriod}:{this.LongMaPeriod}:{this.BarsInterval})";
36 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/Indicator3MASignal.cs";
37 |
38 | ///
39 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
40 | ///
41 | public Indicator3MASignal()
42 | {
43 | // Defines indicator's name and description.
44 | this.Name = "3MASignal";
45 | this.Description = "Offers buy and sell signals according to intersections of three moving averages";
46 |
47 | this.ShortMaPeriod = 5;
48 | this.MiddleMaPeriod = 10;
49 | this.LongMaPeriod = 25;
50 | this.BarsInterval = 1;
51 |
52 | this.SeparateWindow = true;
53 |
54 | // Define one line with particular parameters
55 | this.AddLineSeries("3MASignal", Color.Orange, 5, LineStyle.Histogramm);
56 | }
57 |
58 | ///
59 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
60 | ///
61 | protected override void OnInit()
62 | {
63 | this.currentTrend = NONE;
64 |
65 | // Get SMA indicators from built-in indicator collection
66 | this.shortMa = Core.Indicators.BuiltIn.MA(this.ShortMaPeriod, PriceType.Close, MaMode.SMA);
67 | this.middleMa = Core.Indicators.BuiltIn.MA(this.MiddleMaPeriod, PriceType.Close, MaMode.SMA);
68 | this.longMa = Core.Indicators.BuiltIn.MA(this.LongMaPeriod, PriceType.Close, MaMode.SMA);
69 |
70 | this.AddIndicator(this.shortMa);
71 | this.AddIndicator(this.middleMa);
72 | this.AddIndicator(this.longMa);
73 | }
74 |
75 | ///
76 | /// Calculation entry point. This function is called when a price data updates.
77 | /// Will be runing under the HistoricalBar mode during history loading.
78 | /// Under NewTick during realtime.
79 | /// Under NewBar if start of the new bar is required.
80 | ///
81 | /// Provides data of updating reason and incoming price.
82 | protected override void OnUpdate(UpdateArgs args)
83 | {
84 | // Skip largest period for correct calculation.
85 | if (this.Count < this.MinHistoryDepths)
86 | return;
87 |
88 | // Define the trend on the interval
89 | for (int shift = 0; shift < this.BarsInterval; shift++)
90 | {
91 | if (shift == 0)
92 | {
93 | // Calculate the initial state
94 | this.currentTrend = CompareMA(this.shortMa.GetValue(shift, 0), this.middleMa.GetValue(shift, 0), this.longMa.GetValue(shift, 0));
95 | }
96 | else
97 | {
98 | int trend = CompareMA(this.shortMa.GetValue(shift, 0), this.middleMa.GetValue(shift, 0), this.longMa.GetValue(shift, 0));
99 |
100 | if (trend != this.currentTrend)
101 | {
102 | this.currentTrend = NONE;
103 | break;
104 | }
105 | }
106 | }
107 | // Set price to the line buffer (line index is 0) by offset 0;
108 | this.SetValue(this.currentTrend);
109 | }
110 |
111 | ///
112 | /// Compare SMA values for define current trend
113 | ///
114 | /// ShortMA value
115 | /// MiddleMa value
116 | /// LongMa value
117 | /// Current trend (as int)
118 | private static int CompareMA(double shMa, double midMA, double lgMa)
119 | {
120 | if (midMA > lgMa && midMA < shMa)
121 | return UP;
122 | else if (midMA > shMa && midMA < lgMa)
123 | return DOWN;
124 |
125 | return NONE;
126 | }
127 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorPercentagePriceOscillator.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Oscillators;
8 |
9 | ///
10 | /// Percentage Price Oscillator is a momentum indicator. Signal line is EMA of PPO. Formula: (FastEMA-SlowEMA)/SlowEMA
11 | ///
12 | public sealed class IndicatorPercentagePriceOscillator : Indicator, IWatchlistIndicator
13 | {
14 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
15 | [InputParameter("Fast EMA Period", 0, 1, 999, 1, 0)]
16 | public int fastEmaPeriod = 12;
17 |
18 | [InputParameter("Slow EMA Period", 1, 1, 999, 1, 0)]
19 | public int slowEmaPeriod = 26;
20 |
21 | [InputParameter("Signal EMA Period", 2, 1, 999, 1, 0)]
22 | public int signalEmaPeriod = 9;
23 | //
24 | [InputParameter("Calculation type", 5, variants: new object[]
25 | {
26 | "All available data", IndicatorCalculationType.AllAvailableData,
27 | "By period", IndicatorCalculationType.ByPeriod,
28 | })]
29 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
30 |
31 | private int MaxEMAPeriod => Math.Max(this.fastEmaPeriod, this.slowEmaPeriod);
32 | public int MinHistoryDepths => this.MaxEMAPeriod + this.signalEmaPeriod;
33 | public override string ShortName => $"PPO ({this.fastEmaPeriod}: {this.slowEmaPeriod}: {this.signalEmaPeriod})";
34 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorPercentagePriceOscillator.cs";
35 |
36 | private Indicator fastEma;
37 | private Indicator slowEma;
38 | private Indicator signalEma;
39 | private HistoricalDataCustom customHDsignal;
40 |
41 | ///
42 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
43 | ///
44 | public IndicatorPercentagePriceOscillator()
45 | : base()
46 | {
47 | // Defines indicator's group, name and description.
48 | this.Name = "Percentage Price Oscillator";
49 | this.Description = "Percentage Price Oscillator is a momentum indicator. Signal line is EMA of PPO. Formula: (FastEMA-SlowEMA)/SlowEMA";
50 |
51 | // Defines line on demand with particular parameters.
52 | this.AddLineSeries("PPO'Line", Color.SkyBlue, 2, LineStyle.Solid);
53 | this.AddLineSeries("Signal'Line", Color.Red, 1, LineStyle.Solid);
54 | this.AddLineLevel(0, "0'Line", Color.Gray, 1, LineStyle.Solid);
55 |
56 | this.SeparateWindow = true;
57 | }
58 |
59 | ///
60 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
61 | ///
62 | protected override void OnInit()
63 | {
64 | // Creates an instance of the custom historical data which will be syncronized by the current indicator instance.
65 | this.customHDsignal = new HistoricalDataCustom(this);
66 |
67 | // Creates a smoothing indicator which will keep smoothed custom data (for close prices).
68 | this.signalEma = Core.Indicators.BuiltIn.EMA(this.signalEmaPeriod, PriceType.Close, this.CalculationType);
69 |
70 | // Adds the smoothing indicator to the custom historical data.
71 | this.customHDsignal.AddIndicator(this.signalEma);
72 |
73 | // Creates an instances of the proper indicators from the default indicators list.
74 | this.fastEma = Core.Indicators.BuiltIn.EMA(this.fastEmaPeriod, PriceType.Close, this.CalculationType);
75 | this.slowEma = Core.Indicators.BuiltIn.EMA(this.slowEmaPeriod, PriceType.Close, this.CalculationType);
76 |
77 | // Adds an auxiliary (fastEMA, slowEMA) indicators to the current one (PPO).
78 | // This will let inner indicators (fastEMA, slowEMA) to be calculated in advance to the current one (PPO).
79 | this.AddIndicator(this.fastEma);
80 | this.AddIndicator(this.slowEma);
81 | }
82 |
83 | ///
84 | /// Calculation entry point. This function is called when a price data updates.
85 | /// Will be runing under the HistoricalBar mode during history loading.
86 | /// Under NewTick during realtime.
87 | /// Under NewBar if start of the new bar is required.
88 | ///
89 | /// Provides data of updating reason and incoming price.
90 | protected override void OnUpdate(UpdateArgs args)
91 | {
92 | if (this.Count < this.MaxEMAPeriod)
93 | return;
94 |
95 | // Gets calculation values.
96 | double fastEMA = this.fastEma.GetValue();
97 | double slowEMA = this.slowEma.GetValue();
98 |
99 | // Gets PPO value.
100 | double ppo = (fastEMA - slowEMA) / slowEMA;
101 |
102 | // Populates custom HistoricalData price with the PPO value.
103 | this.customHDsignal[PriceType.Close] = ppo;
104 |
105 | // Skip if count is smaller than period value.
106 | if (this.Count < this.MinHistoryDepths)
107 | return;
108 |
109 | // Sets given values for the displaying on the chart.
110 | this.SetValue(ppo, 0);
111 | this.SetValue(this.signalEma.GetValue(), 1);
112 | }
113 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorExponentialMovingAverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Drawing;
4 | using TradingPlatform.BusinessLayer;
5 |
6 | namespace MovingAverages;
7 |
8 | ///
9 | /// The weighted price calculation for the last N periods.
10 | ///
11 | public sealed class IndicatorExponentialMovingAverage : Indicator, IWatchlistIndicator
12 | {
13 | // Period of moving average.
14 | [InputParameter("Period of Exponential Moving Average", 10, 1, 9999, 1, 0)]
15 | public int MaPeriod = 9;
16 |
17 | // Price type of moving average.
18 | [InputParameter("Sources prices for MA", 20, variants: new object[]
19 | {
20 | "Close", PriceType.Close,
21 | "Open", PriceType.Open,
22 | "High", PriceType.High,
23 | "Low", PriceType.Low,
24 | "Typical", PriceType.Typical,
25 | "Median", PriceType.Median,
26 | "Weighted", PriceType.Weighted,
27 | "Volume", PriceType.Volume,
28 | "Open interest", PriceType.OpenInterest
29 | })]
30 | public PriceType SourcePrice = PriceType.Close;
31 |
32 | //
33 | [InputParameter("Calculation type", 30, variants: new object[]
34 | {
35 | "All available data", IndicatorCalculationType.AllAvailableData,
36 | "By period", IndicatorCalculationType.ByPeriod,
37 | })]
38 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
39 |
40 | public int MinHistoryDepths => this.CalculationType switch
41 | {
42 | IndicatorCalculationType.AllAvailableData => this.MaPeriod,
43 | _ => this.MaPeriod * 2
44 | };
45 | public override string ShortName => $"EMA ({this.MaPeriod}: {this.SourcePrice})";
46 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorExponentialMovingAverage.cs";
47 |
48 | // EMA's calculation coefficient
49 | private double k;
50 |
51 | ///
52 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
53 | ///
54 | public IndicatorExponentialMovingAverage()
55 | : base()
56 | {
57 | // Defines indicator's group, name and description.
58 | this.Name = "Exponential Moving Average";
59 | this.Description = "The weighted price calculation for the last N periods";
60 |
61 | // Defines line on demand with particular parameters.
62 | this.AddLineSeries("EMA", Color.DodgerBlue, 1, LineStyle.Solid);
63 |
64 | this.SeparateWindow = false;
65 | }
66 |
67 | ///
68 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
69 | ///
70 | protected override void OnInit()
71 | {
72 | // Calculation of a coefficient.
73 | this.k = 2.0 / (this.MaPeriod + 1);
74 | }
75 | ///
76 | /// Calculation entry point. This function is called when a price data updates.
77 | /// Will be runing under the HistoricalBar mode during history loading.
78 | /// Under NewTick during realtime.
79 | /// Under NewBar if start of the new bar is required.
80 | ///
81 | /// Provides data of updating reason and incoming price.
82 | protected override void OnUpdate(UpdateArgs args)
83 | {
84 | if (this.CalculationType == IndicatorCalculationType.ByPeriod)
85 | this.CalculateByPeriod();
86 | else
87 | this.CalcualteForAllData();
88 | }
89 |
90 | private void CalcualteForAllData(int offset = 0)
91 | {
92 | if (this.Count <= offset + 1)
93 | return;
94 |
95 | int prevOffset = offset + 1;
96 |
97 | // Getting previous EMA and display value. If it's NaN (start calculation) then get current close price (by default).
98 | double prevEMA = double.IsNaN(this.GetValue(prevOffset))
99 | ? this.GetPrice(this.SourcePrice, prevOffset)
100 | : this.GetValue(prevOffset);
101 |
102 | double ema = this.CalculateEMA(offset, prevEMA);
103 |
104 | if (this.Count <= this.MaPeriod)
105 | return;
106 |
107 | this.SetValue(ema);
108 | }
109 | private void CalculateByPeriod(int offset = 0)
110 | {
111 | int startOffset = offset + this.MaPeriod;
112 |
113 | if (this.Count <= startOffset + this.MaPeriod)
114 | return;
115 |
116 | // Calculate start value
117 | double ema = this.CalculateSMA(startOffset);
118 |
119 | for (int i = startOffset - 1; i >= offset; i--)
120 | ema = this.CalculateEMA(i, ema);
121 |
122 | this.SetValue(ema, 0, offset);
123 | }
124 |
125 | private double CalculateEMA(int offset, double prevEMA)
126 | {
127 | // Getting current price.
128 | double price = this.GetPrice(this.SourcePrice, offset);
129 |
130 | // Sets value for displaying on the chart.
131 | return prevEMA + this.k * (price - prevEMA);
132 | }
133 | private double CalculateSMA(int offset)
134 | {
135 | double sum = 0d;
136 | for (int i = 0; i < this.MaPeriod; i++)
137 | sum += this.GetPrice(this.SourcePrice, offset + i);
138 |
139 | return sum / this.MaPeriod;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/Indicators/IndicatorATRTrailingStopWithFibRetracements.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Volatility;
8 |
9 | public class IndicatorATRTrailingStopWithFibRetracements : Indicator
10 | {
11 | [InputParameter("ATR Period", 0, 1, 9999)]
12 | public int Period = 5;
13 | [InputParameter("ATR Factor", 0, 0.1, 999, 0.1, 1)]
14 | public double ATRFactor = 3.5;
15 | [InputParameter("Fib1", 0, 0.1, 999, 0.1, 1)]
16 | public double Fib1Lvl = 61.8;
17 | [InputParameter("Fib2", 0, 0.1, 999, 0.1, 1)]
18 | public double Fib2Lvl = 78.6;
19 | [InputParameter("Fib3", 0, 0.1, 999, 0.1, 1)]
20 | public double Fib3Lvl = 88.6;
21 | [InputParameter("Type of Moving Average", 3, variants: new object[] {
22 | "Simple", MaMode.SMA,
23 | "Exponential", MaMode.EMA,
24 | "Smoothed Modified", MaMode.SMMA,
25 | "Linear Weighted", MaMode.LWMA})]
26 | public MaMode MaType = MaMode.SMA;
27 |
28 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorATRTrailingStopWithFibRetracements.cs";
29 |
30 |
31 | public double fibLvl1 = 1.618, fibLvl2 = 2.618, fibLvl3 = 4.23, fib1, fib2, fib3, fibTgt1, fibTgt2, fibTgt3;
32 | public double trailStop, trend, trendUp, trendDown, ex, currClose, switchVal, diff, loss;
33 | public bool trendChange;
34 | private Indicator atr;
35 | public override string ShortName => $"ATRTrailStop ({this.Period})";
36 | public IndicatorATRTrailingStopWithFibRetracements()
37 | : base()
38 | {
39 | // Defines indicator's name and description.
40 | Name = "ATR Trailing w/Fib Targets";
41 | Description = "Fib Targets on the ATR trailing stop";
42 |
43 | // Defines line on demand with particular parameters.
44 | AddLineSeries("TrailStop", Color.White, 1, LineStyle.Solid);
45 | AddLineSeries("fibTgtDown1", Color.Red, 1, LineStyle.Solid);
46 | AddLineSeries("fibTgtDown2", Color.Red, 1, LineStyle.Solid);
47 | AddLineSeries("fibTgtDown3", Color.Red, 1, LineStyle.Solid);
48 | AddLineSeries("fibTgtUp1", Color.Green, 1, LineStyle.Solid);
49 | AddLineSeries("fibTgtUp2", Color.Green, 1, LineStyle.Solid);
50 | AddLineSeries("fibTgtUp3", Color.Green, 1, LineStyle.Solid);
51 | AddLineSeries("fib1", Color.Gray, 1, LineStyle.Solid);
52 | AddLineSeries("fib2", Color.Gray, 1, LineStyle.Solid);
53 | AddLineSeries("fib3", Color.Gray, 1, LineStyle.Solid);
54 | // By default indicator will be applied on main window of the chart
55 | SeparateWindow = false;
56 | }
57 |
58 | protected override void OnInit()
59 | {
60 | this.atr = Core.Indicators.BuiltIn.ATR(this.Period, this.MaType, Indicator.DEFAULT_CALCULATION_TYPE);
61 | this.AddIndicator(this.atr);
62 | }
63 |
64 | protected override void OnUpdate(UpdateArgs args)
65 | {
66 | double prevClose = currClose;
67 |
68 | currClose = GetPrice(PriceType.Close);
69 | double currHigh = GetPrice(PriceType.High);
70 | double currLow = GetPrice(PriceType.Low);
71 |
72 | loss = ATRFactor * atr.GetValue();
73 | double up = currClose - loss;
74 | double down = currClose + loss;
75 |
76 | double prevTrend = trend;
77 | double prevTrendUp = trendUp;
78 | double prevTrendDown = trendDown;
79 |
80 | trendUp = prevClose > prevTrendUp ? Math.Max(up, prevTrendUp) : up;
81 | trendDown = prevClose < prevTrendDown ? Math.Min(down, prevTrendDown) : down;
82 | trend = currClose > prevTrendDown ? 1 : currClose < prevTrendUp ? -1 : prevTrend;
83 |
84 | trailStop = trend == 1 ? trendUp : trendDown;
85 |
86 | double prevEx = ex;
87 | ex = (trend > 0 && prevTrend < 0) ? currHigh : (trend < 0 && prevTrend > 0) ? currLow : trend == 1 ? Math.Max(prevEx, currHigh) : trend == -1 ? Math.Min(prevEx, currLow) : prevEx;
88 |
89 | fib1 = ex + (trailStop - ex) * Fib1Lvl / 100;
90 | fib2 = ex + (trailStop - ex) * Fib2Lvl / 100;
91 | fib3 = ex + (trailStop - ex) * Fib3Lvl / 100;
92 |
93 | double prevSwitchVal = switchVal;
94 | double prevDiff = diff;
95 | trendChange = trend == prevTrend ? false : true;
96 | switchVal = trendChange ? trailStop : prevSwitchVal;
97 | diff = trendChange ? currClose - switchVal : prevDiff;
98 |
99 | fibTgt1 = switchVal + (diff * fibLvl1);
100 | fibTgt2 = switchVal + (diff * fibLvl2);
101 | fibTgt3 = switchVal + (diff * fibLvl3);
102 | double prevfibTgt1 = fibTgt1;
103 |
104 | SetValue(trailStop);
105 | if (trend == 1 && fibTgt1 == prevfibTgt1)
106 | {
107 | if (fibTgt1 > trailStop)
108 | SetValue(fibTgt1, 4);
109 | if (fibTgt2 > trailStop)
110 | SetValue(fibTgt2, 5);
111 | if (fibTgt3 > trailStop)
112 | SetValue(fibTgt3, 6);
113 | }
114 | if (trend == -1 && fibTgt1 == prevfibTgt1)
115 | {
116 | if (fibTgt1 < trailStop)
117 | SetValue(fibTgt1, 1);
118 | if (fibTgt2 < trailStop)
119 | SetValue(fibTgt2, 2);
120 | if (fibTgt3 < trailStop)
121 | SetValue(fibTgt3, 3);
122 | }
123 | SetValue(fib1, 7);
124 | SetValue(fib2, 8);
125 | SetValue(fib3, 9);
126 | }
127 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorIchimoku.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Trend;
8 |
9 | public sealed class IndicatorIchimoku : Indicator, IWatchlistIndicator
10 | {
11 | private const int TENKAN = 0;
12 | private const int KIJUN = 1;
13 | private const int SENKOU_SPANA = 2;
14 | private const int SENKOU_SPANB = 3;
15 | private const int CHINKOU_SPAN = 4;
16 |
17 | // Displays Input Parameter as input field (or checkbox if value type is bolean).
18 | [InputParameter("Tenkan Sen", 0, 1, 9999, 1, 0)]
19 | public int TenkanPeriod = 9;
20 |
21 | [InputParameter("Kijun Sen", 1, 1, 9999, 1, 0)]
22 | public int KijunPeriod = 26;
23 |
24 | [InputParameter("Senkou Span B", 2, 1, 9999, 1, 0)]
25 | public int SenkouSpanB = 52;
26 |
27 | [InputParameter("Cloud up color", 3)]
28 | public Color UpColor = Color.FromArgb(50, Color.Green);
29 |
30 | [InputParameter("Cloud down color", 3)]
31 | public Color DownColor = Color.FromArgb(50, Color.Red);
32 |
33 | public override string ShortName => $"ICH ({this.TenkanPeriod}: {this.KijunPeriod}: {this.SenkouSpanB})";
34 | public int MinHistoryDepths => Math.Max(this.TenkanPeriod, Math.Max(this.KijunPeriod, this.SenkouSpanB));
35 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/trend/ichimoku-indicator";
36 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorIchimoku.cs";
37 |
38 | private Trend currentTrend;
39 |
40 | ///
41 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
42 | ///
43 | public IndicatorIchimoku()
44 | : base()
45 | {
46 | // Defines indicator's name and description.
47 | this.Name = "Ichimoku";
48 | this.Description = "Enables to quickly discern and filter 'at a glance' the low-probability trading setups from those of higher probability";
49 |
50 | // Defines line on demand with particular parameters.
51 | this.AddLineSeries("Tenkan", Color.Blue, 1, LineStyle.Solid);
52 | this.AddLineSeries("Kijun", Color.Lime, 1, LineStyle.Solid);
53 | this.AddLineSeries("Senkou Span A", Color.SpringGreen, 1, LineStyle.Solid);
54 | this.AddLineSeries("Senkou Span B", Color.Red, 1, LineStyle.Solid);
55 | this.AddLineSeries("Chinkou Span", Color.FromArgb(255, 153, 0), 1, LineStyle.Solid);
56 |
57 | this.SeparateWindow = false;
58 | }
59 |
60 | ///
61 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
62 | ///
63 | protected override void OnInit()
64 | {
65 | this.LinesSeries[SENKOU_SPANA].TimeShift = this.KijunPeriod;
66 | this.LinesSeries[SENKOU_SPANB].TimeShift = this.KijunPeriod;
67 | this.LinesSeries[CHINKOU_SPAN].TimeShift = -this.KijunPeriod;
68 | }
69 |
70 | ///
71 | /// Calculation entry point. This function is called when a price data updates.
72 | /// Will be runing under the HistoricalBar mode during history loading.
73 | /// Under NewTick during realtime.
74 | /// Under NewBar if start of the new bar is required.
75 | ///
76 | /// Provides data of updating reason and incoming price.
77 | protected override void OnUpdate(UpdateArgs args)
78 | {
79 | if (this.Count < this.MinHistoryDepths)
80 | return;
81 |
82 | //1 line
83 | this.SetValue(this.GetAverage(this.TenkanPeriod), TENKAN);
84 |
85 | //2 line
86 | this.SetValue(this.GetAverage(this.KijunPeriod), KIJUN);
87 |
88 | //5 line
89 | this.SetValue(this.GetPrice(PriceType.Close), CHINKOU_SPAN);
90 |
91 | //3 line
92 | double senkouSpanA = (this.GetValue(0, TENKAN) + this.GetValue(0, KIJUN)) / 2;
93 | this.SetValue(senkouSpanA, SENKOU_SPANA);
94 |
95 | //4 line
96 | double senkouSpanB = this.GetAverage(this.SenkouSpanB);
97 | this.SetValue(senkouSpanB, SENKOU_SPANB);
98 |
99 | var newTrend = senkouSpanA == senkouSpanB ? Trend.Unknown :
100 | senkouSpanA > senkouSpanB ? Trend.Up : Trend.Down;
101 |
102 | if (this.currentTrend != newTrend)
103 | {
104 | this.EndCloud(SENKOU_SPANA, SENKOU_SPANB, this.GetColorByTrend(this.currentTrend));
105 | this.BeginCloud(SENKOU_SPANA, SENKOU_SPANB, this.GetColorByTrend(newTrend));
106 | }
107 |
108 | this.currentTrend = newTrend;
109 | }
110 |
111 | public double GetAverage(int period)
112 | {
113 | double high = this.GetPrice(PriceType.High);
114 | double low = this.GetPrice(PriceType.Low);
115 | for (int i = 1; i < period; i++)
116 | {
117 | double price = this.GetPrice(PriceType.High, i);
118 | if (high < price)
119 | high = price;
120 | price = this.GetPrice(PriceType.Low, i);
121 | if (low > price)
122 | low = price;
123 | }
124 |
125 | return (high + low) / 2.0;
126 | }
127 |
128 | private Color GetColorByTrend(Trend trend) => trend switch
129 | {
130 | Trend.Up => this.UpColor,
131 | Trend.Down => this.DownColor,
132 | _ => Color.Empty
133 | };
134 |
135 | private enum Trend
136 | {
137 | Unknown,
138 | Up,
139 | Down
140 | }
141 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorDeltaFlow.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Drawing;
6 | using TradingPlatform.BusinessLayer;
7 |
8 | namespace VolumeIndicators;
9 |
10 | public class IndicatorDeltaFlow : Indicator, IVolumeAnalysisIndicator, IWatchlistIndicator
11 | {
12 | #region Parameters
13 | public const string COLORING_SCHEME_SI = "Coloring scheme";
14 |
15 | public override string HelpLink => "https://help.quantower.com/analytics-panels/chart/technical-indicators/volume/delta-flow";
16 |
17 | [InputParameter(COLORING_SCHEME_SI, 10, variants: new object[]
18 | {
19 | "By delta", DeltaPaceColoringScheme.ByDelta,
20 | "By bar", DeltaPaceColoringScheme.ByBar
21 | })]
22 | internal DeltaPaceColoringScheme ColoringScheme = DeltaPaceColoringScheme.ByDelta;
23 |
24 | internal PairColor PairColor;
25 |
26 | private bool isVolumeAnalysisProgressSubscribed;
27 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorDeltaFlow.cs";
28 |
29 | #endregion Parameters
30 |
31 | public IndicatorDeltaFlow()
32 | {
33 | this.Name = "Delta Flow";
34 | this.AddLineSeries("Histogram", Color.Gray, 3, LineStyle.Histogramm);
35 | this.IsUpdateTypesSupported = false;
36 |
37 | this.PairColor = new PairColor()
38 | {
39 | Color1 = Color.FromArgb(33, 150, 243),
40 | Color2 = Color.FromArgb(239, 83, 80),
41 | Text1 = loc._("Up"),
42 | Text2 = loc._("Down")
43 | };
44 | this.SeparateWindow = true;
45 | }
46 |
47 | #region Overrides
48 | protected override void OnInit()
49 | {
50 | this.isVolumeAnalysisProgressSubscribed = false;
51 | }
52 | protected override void OnUpdate(UpdateArgs args)
53 | {
54 | //
55 | if (!this.isVolumeAnalysisProgressSubscribed)
56 | {
57 | if (this.HistoricalData?.VolumeAnalysisCalculationProgress != null)
58 | {
59 | this.HistoricalData.VolumeAnalysisCalculationProgress.ProgressChanged += VolumeAnalysisCalculationProgress_ProgressChanged;
60 | this.isVolumeAnalysisProgressSubscribed = true;
61 | }
62 | }
63 |
64 | this.CalculateIndicatorByOffset(offset: 0);
65 | }
66 | public override IList Settings
67 | {
68 | get
69 | {
70 | var settings = base.Settings;
71 |
72 | var inputSepar = settings.GetItemByName(COLORING_SCHEME_SI)?.SeparatorGroup ?? new SettingItemSeparatorGroup();
73 |
74 | settings.Add(new SettingItemPairColor("HistogramColors", this.PairColor, 10)
75 | {
76 | SeparatorGroup = inputSepar,
77 | Text = loc._("Histogram colors")
78 | });
79 |
80 | return settings;
81 | }
82 | set
83 | {
84 | base.Settings = value;
85 |
86 | if (value.GetItemByName("HistogramColors") is SettingItemPairColor pairColorSI)
87 | {
88 | this.PairColor = (PairColor)pairColorSI.Value;
89 | this.Refresh();
90 | }
91 | }
92 | }
93 | protected override void OnClear()
94 | {
95 | if (this.HistoricalData?.VolumeAnalysisCalculationProgress != null)
96 | this.HistoricalData.VolumeAnalysisCalculationProgress.ProgressChanged -= VolumeAnalysisCalculationProgress_ProgressChanged;
97 | }
98 | #endregion Overrides
99 |
100 | #region Misc and Event handlers
101 | private void CalculateIndicatorByOffset(int offset)
102 | {
103 | var index = this.Count - 1 - offset;
104 | if (index < 0)
105 | return;
106 |
107 | var volumeAnalysis = this.HistoricalData[index, SeekOriginHistory.Begin].VolumeAnalysisData;
108 |
109 | if (volumeAnalysis != null)
110 | {
111 | var value = volumeAnalysis.Total.Delta * (this.High(offset) - this.Low(offset));
112 | this.SetValue(Math.Abs(value), 0, offset);
113 |
114 | var isUpColor =
115 | (ColoringScheme == DeltaPaceColoringScheme.ByDelta && volumeAnalysis.Total.Delta > 0) ||
116 | (ColoringScheme == DeltaPaceColoringScheme.ByBar && this.Close(offset) > this.Open(offset));
117 |
118 | if (isUpColor)
119 | this.LinesSeries[0].SetMarker(offset, this.PairColor.Color1);
120 | else
121 | this.LinesSeries[0].SetMarker(offset, this.PairColor.Color2);
122 | }
123 | }
124 | private void RecalculateAllIndicator()
125 | {
126 | for (int i = 0; i < this.Count - 1; i++)
127 | this.CalculateIndicatorByOffset(i);
128 | }
129 |
130 | private void VolumeAnalysisCalculationProgress_ProgressChanged(object sender, VolumeAnalysisTaskEventArgs e)
131 | {
132 | if (e.CalculationState == VolumeAnalysisCalculationState.Processing)
133 | this.RecalculateAllIndicator();
134 | }
135 | #endregion Misc and Event handlers
136 |
137 | #region IVolumeAnalysisIndicator
138 | public bool IsRequirePriceLevelsCalculation => false;
139 | public void VolumeAnalysisData_Loaded()
140 | {
141 | this.RecalculateAllIndicator();
142 | }
143 | #endregion IVolumeAnalysisIndicator
144 |
145 | #region IWatchlistIndicator
146 | public int MinHistoryDepths => 2;
147 | #endregion IWatchlistIndicator
148 |
149 | internal enum DeltaPaceColoringScheme
150 | {
151 | ByDelta = 0,
152 | ByBar = 10,
153 | }
154 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorSeparatedAverageTrueRange.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System.Collections.Generic;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace OscillatorsIndicators;
8 |
9 | public sealed class IndicatorSeparatedAverageTrueRange : Indicator
10 | {
11 | #region Parameters
12 | private const string HISTOGRAM_COLORS_SETTING_NAME = "HistogramColor";
13 | private const string PERIOD_SETTING_NAME = "Period of Moving Average";
14 |
15 | [InputParameter(PERIOD_SETTING_NAME, 0, 1, 999, 1, 0)]
16 | public int Period = 14;
17 |
18 | [InputParameter("Type of Moving Average", 1, variants: new object[] {
19 | "Simple", MaMode.SMA,
20 | "Exponential", MaMode.EMA,
21 | "Smoothed", MaMode.SMMA,
22 | "Linear Weighted", MaMode.LWMA}
23 | )]
24 | public MaMode MAType = MaMode.SMA;
25 |
26 | [InputParameter("Calculation type", 5, variants: new object[]
27 | {
28 | "All available data", IndicatorCalculationType.AllAvailableData,
29 | "By period", IndicatorCalculationType.ByPeriod,
30 | })]
31 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
32 |
33 | private HistoricalDataCustom customHD1;
34 | private HistoricalDataCustom customHD2;
35 | private Indicator atr1;
36 | private Indicator atr2;
37 | private Color upHistogramColor;
38 | private Color downHistogramColor;
39 |
40 | public override string ShortName => $"SATR ({this.Period}: {this.MAType})";
41 |
42 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorSeparatedAverageTrueRange.cs";
43 |
44 | #endregion Parameters
45 |
46 | public IndicatorSeparatedAverageTrueRange()
47 | {
48 | this.Name = "Separated Average True Range";
49 |
50 | this.upHistogramColor = Color.FromArgb(0, 178, 89);
51 | this.downHistogramColor = Color.FromArgb(251, 87, 87);
52 |
53 | this.AddLineSeries("Buy ATR", this.upHistogramColor, 2, LineStyle.Solid);
54 | this.AddLineSeries("Sell ATR", this.downHistogramColor, 2, LineStyle.Solid);
55 | this.AddLineSeries("Delta", Color.DodgerBlue, 2, LineStyle.Histogramm);
56 |
57 | this.LinesSeries[0].Visible = this.LinesSeries[1].Visible = false;
58 |
59 | this.SeparateWindow = true;
60 | }
61 |
62 | protected override void OnInit()
63 | {
64 | base.OnInit();
65 |
66 | this.customHD1 = new HistoricalDataCustom();
67 | this.atr1 = Core.Indicators.BuiltIn.ATR(this.Period, this.MAType, this.CalculationType);
68 | this.customHD1.AddIndicator(this.atr1);
69 |
70 | this.customHD2 = new HistoricalDataCustom();
71 | this.atr2 = Core.Indicators.BuiltIn.ATR(this.Period, this.MAType, this.CalculationType);
72 | this.customHD2.AddIndicator(this.atr2);
73 | }
74 |
75 | public override IList Settings
76 | {
77 | get
78 | {
79 | var settings = base.Settings;
80 |
81 | var separatorGroup = settings.GetItemByName(PERIOD_SETTING_NAME)?.SeparatorGroup ?? new SettingItemSeparatorGroup("");
82 | settings.Add(new SettingItemPairColor(HISTOGRAM_COLORS_SETTING_NAME, new PairColor(this.upHistogramColor, this.downHistogramColor, loc._("Up"), loc._("Down")), 10)
83 | {
84 | Text = loc._("Histogram style"),
85 | SeparatorGroup = separatorGroup
86 | });
87 | return settings;
88 | }
89 | set
90 | {
91 | if (value.GetItemByName(HISTOGRAM_COLORS_SETTING_NAME) is SettingItemPairColor pairColorSI && pairColorSI.Value is PairColor colors)
92 | {
93 | this.upHistogramColor = colors.Color1;
94 | this.downHistogramColor = colors.Color2;
95 |
96 | this.Refresh();
97 | }
98 |
99 | base.Settings = value;
100 | }
101 | }
102 |
103 | protected override void OnUpdate(UpdateArgs args)
104 | {
105 | if (this.customHD1.Count == 0 || !double.IsNaN(this.customHD1[PriceType.Close]) && args.Reason != UpdateReason.NewTick)
106 | this.customHD1.AddValue(double.NaN, double.NaN, double.NaN, double.NaN);
107 |
108 | if (this.customHD2.Count == 0 || !double.IsNaN(this.customHD2[PriceType.Close]) && args.Reason != UpdateReason.NewTick)
109 | this.customHD2.AddValue(double.NaN, double.NaN, double.NaN, double.NaN);
110 |
111 | if (this.Open() < this.Close())
112 | {
113 | this.customHD1.SetValue(this.Open(), this.High(), this.Low(), this.Close());
114 | this.customHD2.SetValue(double.NaN, double.NaN, double.NaN, double.NaN);
115 | }
116 | else
117 | {
118 | this.customHD2.SetValue(this.Open(), this.High(), this.Low(), this.Close());
119 | this.customHD1.SetValue(double.NaN, double.NaN, double.NaN, double.NaN);
120 | }
121 |
122 | if (this.Count < this.Period)
123 | return;
124 |
125 | double v1 = double.IsNaN(this.atr1.GetValue()) ? this.atr1.GetValue(1) : this.atr1.GetValue();
126 | double v2 = double.IsNaN(this.atr2.GetValue()) ? this.atr2.GetValue(1) : this.atr2.GetValue();
127 |
128 | this.SetValue(v1, 0);
129 | this.SetValue(v2, 1);
130 |
131 | double delta = v1 - v2;
132 | this.SetValue(delta, 2);
133 |
134 | if (delta > 0)
135 | this.LinesSeries[2].SetMarker(0, this.upHistogramColor);
136 | else
137 | this.LinesSeries[2].SetMarker(0, this.downHistogramColor);
138 | }
139 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorTrueStrengthIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Drawing;
5 | using TradingPlatform.BusinessLayer;
6 |
7 | namespace Oscillators;
8 |
9 | public sealed class IndicatorTrueStrengthIndex : Indicator, IWatchlistIndicator
10 | {
11 | // Displays Input Parameter as input field.
12 | [InputParameter("First MA period", 0, 1, 999, 1, 0)]
13 | public int FirstPeriod = 5;
14 |
15 | // Displays Input Parameter as input field.
16 | [InputParameter("Second MA period", 1, 1, 999, 1, 0)]
17 | public int SecondPeriod = 8;
18 |
19 | //
20 | [InputParameter("Calculation type", 10, variants: new object[]
21 | {
22 | "All available data", IndicatorCalculationType.AllAvailableData,
23 | "By period", IndicatorCalculationType.ByPeriod,
24 | })]
25 | public IndicatorCalculationType CalculationType = Indicator.DEFAULT_CALCULATION_TYPE;
26 |
27 | private Indicator firstEma;
28 | private Indicator firstEmaAbs;
29 | private Indicator secondEma;
30 | private Indicator secondEmaAbs;
31 |
32 | private HistoricalDataCustom firstEmaHD;
33 | private HistoricalDataCustom firstEmaAbsHD;
34 | private HistoricalDataCustom secondEmaHD;
35 | private HistoricalDataCustom secondEmaAbsHD;
36 |
37 | public int MinHistoryDepths => this.FirstPeriod + this.SecondPeriod;
38 | public override string ShortName => $"TSI ({this.FirstPeriod}:{this.SecondPeriod})";
39 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorTrueStrengthIndex.cs";
40 |
41 | ///
42 | /// Indicator's constructor. Contains general information: name, description, LineSeries etc.
43 | ///
44 | public IndicatorTrueStrengthIndex()
45 | : base()
46 | {
47 | // Defines indicator's name and description.
48 | this.Name = "True Strength Index";
49 | this.Description = "Is a variation of the Relative Strength Indicator which uses a doubly-smoothed exponential moving average of price momentum to eliminate choppy price changes and spot trend changes";
50 |
51 | // Defines lines on demand with particular parameters.
52 | this.AddLineLevel(50, "Upper", Color.Gray, 1, LineStyle.Solid);
53 | this.AddLineLevel(0, "Zero", Color.Gray, 1, LineStyle.Solid);
54 | this.AddLineLevel(-50, "Lower", Color.Gray, 1, LineStyle.Solid);
55 | this.AddLineSeries("TSI", Color.Orange, 1, LineStyle.Solid);
56 |
57 | this.SeparateWindow = true;
58 | }
59 |
60 | ///
61 | /// This function will be called after creating an indicator as well as after its input params reset or chart (symbol or timeframe) updates.
62 | ///
63 | protected override void OnInit()
64 | {
65 | // Get EMA indicators from built-in indicator collection.
66 | this.firstEma = Core.Indicators.BuiltIn.EMA(this.FirstPeriod, PriceType.Close, this.CalculationType);
67 | this.firstEmaAbs = Core.Indicators.BuiltIn.EMA(this.FirstPeriod, PriceType.Close, this.CalculationType);
68 | this.secondEma = Core.Indicators.BuiltIn.EMA(this.SecondPeriod, PriceType.Close, this.CalculationType);
69 | this.secondEmaAbs = Core.Indicators.BuiltIn.EMA(this.SecondPeriod, PriceType.Close, this.CalculationType);
70 |
71 | // Create custom HistoricalData objects for stored custom values and syncronize their with this(TSI) indicator.
72 | this.firstEmaHD = new HistoricalDataCustom(this);
73 | this.firstEmaAbsHD = new HistoricalDataCustom(this);
74 | this.secondEmaHD = new HistoricalDataCustom(this);
75 | this.secondEmaAbsHD = new HistoricalDataCustom(this);
76 |
77 | // Attach EMA indicators to custom HistoricalData.
78 | this.firstEmaHD.AddIndicator(this.firstEma);
79 | this.firstEmaAbsHD.AddIndicator(this.firstEmaAbs);
80 | this.secondEmaHD.AddIndicator(this.secondEma);
81 | this.secondEmaAbsHD.AddIndicator(this.secondEmaAbs);
82 | }
83 |
84 | ///
85 | /// Calculation entry point. This function is called when a price data updates.
86 | /// Will be runing under the HistoricalBar mode during history loading.
87 | /// Under NewTick during realtime.
88 | /// Under NewBar if start of the new bar is required.
89 | ///
90 | /// Provides data of updating reason and incoming price.
91 | protected override void OnUpdate(UpdateArgs args)
92 | {
93 | double mtm = this.GetMTM(0);
94 |
95 | // Store custom value as 'Close' price into custom HD,
96 | // because EMA indicator (which was attached to it) was initialized with PriceType.Close.
97 | this.firstEmaHD[PriceType.Close, 0] = mtm;
98 | this.firstEmaAbsHD[PriceType.Close, 0] = Math.Abs(mtm);
99 |
100 | // Skip some period for correct calculation.
101 | if (this.Count < this.FirstPeriod)
102 | return;
103 |
104 | this.secondEmaHD[PriceType.Close, 0] = this.firstEma.GetValue();
105 | this.secondEmaAbsHD[PriceType.Close, 0] = this.firstEmaAbs.GetValue();
106 |
107 | if (this.Count < this.MinHistoryDepths)
108 | return;
109 |
110 | // Set value to 'TSI' line buffer.
111 | this.SetValue(100 * this.secondEma.GetValue() / this.secondEmaAbs.GetValue());
112 | }
113 |
114 | ///
115 | /// Compute the momentum value.
116 | ///
117 | private double GetMTM(int offset)
118 | {
119 | if (this.Count < 2)
120 | return this.GetPrice(PriceType.Close, offset);
121 |
122 | return this.GetPrice(PriceType.Close, offset) - this.GetPrice(PriceType.Close, offset + 1);
123 | }
124 | }
--------------------------------------------------------------------------------
/Indicators/IndicatorRoundNumbers.cs:
--------------------------------------------------------------------------------
1 | // Copyright QUANTOWER LLC. © 2017-2024. All rights reserved.
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Drawing;
6 | using TradingPlatform.BusinessLayer;
7 | using TradingPlatform.BusinessLayer.Utils;
8 |
9 | namespace ChanneIsIndicators;
10 |
11 | public class IndicatorRoundNumbers : Indicator
12 | {
13 | public const string ROUND_NUMBERS_SI = "Step of lines (ticks)";
14 | public const string NUMBER_OF_LINES_SI = "Number of lines";
15 |
16 | [InputParameter(ROUND_NUMBERS_SI, 10, 1, int.MaxValue, 1, 0)]
17 | public int Step = 50;
18 |
19 | [InputParameter(NUMBER_OF_LINES_SI, 20, 1, int.MaxValue, 1, 0)]
20 | public int NumberOfLines = 20;
21 |
22 | public override string ShortName => $"{this.Name} ({this.Step})";
23 |
24 | public LineOptions LineOptions
25 | {
26 | get => this.lineOptions;
27 | set
28 | {
29 | this.lineOptions = value;
30 | this.currentPen = ProcessPen(this.currentPen, value);
31 | }
32 | }
33 | private LineOptions lineOptions;
34 | private Pen currentPen;
35 |
36 | public override string SourceCodeLink => "https://github.com/Quantower/Scripts/blob/main/Indicators/IndicatorRoundNumbers.cs";
37 |
38 | public IndicatorRoundNumbers()
39 | {
40 | this.Name = "Round numbers";
41 |
42 | this.LineOptions = new LineOptions()
43 | {
44 | LineStyle = LineStyle.Solid,
45 | Color = Color.Orange,
46 | Width = 2,
47 | WithCheckBox = false,
48 | Enabled = true
49 | };
50 |
51 | this.OnBackGround = true;
52 | this.SeparateWindow = false;
53 | }
54 |
55 | #region Overrides
56 |
57 | public override void OnPaintChart(PaintChartEventArgs args)
58 | {
59 | var gr = args.Graphics;
60 |
61 | float deltaPriceY = (float)(this.Step * this.CurrentChart.TickSize * this.CurrentChart.MainWindow.YScaleFactor);
62 | if (deltaPriceY <= 0)
63 | return;
64 |
65 | int bottom = this.CurrentChart.MainWindow.ClientRectangle.Bottom;
66 | int top = this.CurrentChart.MainWindow.ClientRectangle.Top;
67 | int right = this.CurrentChart.MainWindow.ClientRectangle.Right;
68 |
69 | double middlePrice = this.Close();
70 | double correctedMiddleLevel = (int)(middlePrice / (this.Step * this.CurrentChart.TickSize)) * (this.Step * this.CurrentChart.TickSize);
71 |
72 | float startLevel = (float)(this.CurrentChart.MainWindow.CoordinatesConverter.GetChartY(correctedMiddleLevel) - System.Math.Ceiling(this.NumberOfLines / 2d) * deltaPriceY);
73 |
74 | for (int i = 0; i < this.NumberOfLines; i++)
75 | {
76 | if (startLevel >= top && startLevel <= bottom)
77 | gr.DrawLine(this.currentPen, 0f, startLevel, right, startLevel);
78 |
79 | startLevel += deltaPriceY;
80 | }
81 | }
82 | public override IList Settings
83 | {
84 | get
85 | {
86 | var settings = base.Settings;
87 |
88 | var inputParametersSepar = settings.GetItemByName(ROUND_NUMBERS_SI) is SettingItem si
89 | ? si.SeparatorGroup
90 | : new SettingItemSeparatorGroup("", 10);
91 |
92 | settings.Add(new SettingItemLineOptions("LineStyle", this.LineOptions, 10)
93 | {
94 | Text = loc._("Line style"),
95 | SeparatorGroup = inputParametersSepar
96 | });
97 |
98 | return settings;
99 | }
100 | set
101 | {
102 | base.Settings = value;
103 |
104 | if (value.GetItemByName("LineStyle") is SettingItemLineOptions si)
105 | this.LineOptions = si.Value as LineOptions;
106 | }
107 | }
108 |
109 | #endregion Overrides
110 |
111 | private static Pen ProcessPen(Pen pen, LineOptions lineOptions)
112 | {
113 | if (pen == null)
114 | pen = new Pen(Color.Empty);
115 |
116 | pen.Color = lineOptions.Color;
117 | pen.Width = lineOptions.Width;
118 |
119 | try
120 | {
121 | switch (lineOptions.LineStyle)
122 | {
123 | case LineStyle.Solid:
124 | {
125 | pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
126 | break;
127 | }
128 | case LineStyle.Dot:
129 | {
130 | pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
131 | break;
132 | }
133 | case LineStyle.Dash:
134 | {
135 | pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
136 | break;
137 | }
138 | case LineStyle.DashDot:
139 | {
140 | pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
141 | float[] dp = new float[] { 2, 4, 7, 4 };
142 | pen.DashPattern = dp;
143 | break;
144 | }
145 | case LineStyle.Histogramm:
146 | {
147 | pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
148 | float[] dp = new float[] { 0.25F, 1 };
149 | pen.DashPattern = dp;
150 | pen.Width = 4;
151 | break;
152 | }
153 | }
154 | }
155 | catch (Exception ex)
156 | {
157 | Core.Loggers.Log(ex);
158 | }
159 | return pen;
160 | }
161 | }
--------------------------------------------------------------------------------