New version merge

This commit is contained in:
Miha Kralj
2024-09-22 17:31:24 -07:00
parent 1b719fa94e
commit d475bcd19a
405 changed files with 56573 additions and 12440 deletions
+25
View File
@@ -0,0 +1,25 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class EntropyIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 50;
private Entropy? entropy;
protected override AbstractBase QuanTAlib => entropy!;
public override string ShortName => $"ENTROPY {Period} : {SourceName}";
public EntropyIndicator() : base()
{
Name = "ENTROPY - Entropy";
SeparateWindow = true;
}
protected override void InitIndicator()
{
entropy = new(Period);
MinHistoryDepths = entropy.WarmupPeriod;
base.InitIndicator();
}
}
+25
View File
@@ -0,0 +1,25 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class KurtosisIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 4, 2000, 1, 0)]
public int Period { get; set; } = 20;
private Kurtosis? kurtosis;
protected override AbstractBase QuanTAlib => kurtosis!;
public override string ShortName => $"KURTOSIS {Period} : {SourceName}";
public KurtosisIndicator() : base()
{
Name = "KURTOSIS - Relative Flatness";
SeparateWindow = true;
}
protected override void InitIndicator()
{
kurtosis = new(Period);
MinHistoryDepths = kurtosis.WarmupPeriod;
base.InitIndicator();
}
}
+28
View File
@@ -0,0 +1,28 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class MaxIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Decay to mean", sortIndex: 1, minimum: 0.00, maximum: 100.0, increment: 0.01, decimalPlaces: 2)]
public double Decay { get; set; } = 0.1;
private Max? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"MAX {Period} : {Decay:F2} : {SourceName}";
public MaxIndicator() : base()
{
Name = "MAX - Maximum value (with decay) ";
}
protected override void InitIndicator()
{
ma = new Max(Period, Decay);
MinHistoryDepths = ma.WarmupPeriod;
Source = 2;
base.InitIndicator();
}
}
+23
View File
@@ -0,0 +1,23 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class MedianIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
private Median? med;
protected override AbstractBase QuanTAlib => med!;
public override string ShortName => $"MEDIAN {Period} : {SourceName}";
public MedianIndicator() : base()
{
Name = "MEDIAN - Median historical value";
}
protected override void InitIndicator()
{
med = new Median(Period);
MinHistoryDepths = med.WarmupPeriod;
base.InitIndicator();
}
}
+27
View File
@@ -0,0 +1,27 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class MinIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Decay to mean", sortIndex: 1, minimum: 0.00, maximum: 100.0, increment: 0.01, decimalPlaces: 2)]
public double Decay { get; set; } = 0.1;
private Min? mi;
protected override AbstractBase QuanTAlib => mi!;
public override string ShortName => $"MIN {Period} : {Decay:F2} : {SourceName}";
public MinIndicator() : base()
{
Name = "MIN - Minimum value (with decay)";
}
protected override void InitIndicator()
{
mi = new Min(Period, Decay);
MinHistoryDepths = mi.WarmupPeriod;
Source = 3;
base.InitIndicator();
}
}
+23
View File
@@ -0,0 +1,23 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class ModeIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
private Mode? mode;
protected override AbstractBase QuanTAlib => mode!;
public override string ShortName => $"MODE {Period} : {SourceName}";
public ModeIndicator() : base()
{
Name = "MODE - Most frequent historical value";
}
protected override void InitIndicator()
{
mode = new Mode(Period);
MinHistoryDepths = mode.WarmupPeriod;
base.InitIndicator();
}
}
@@ -0,0 +1,28 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class PercentileIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Percent", sortIndex: 2, 0, 100, 1, 0)]
public double Percent { get; set; } = 50;
private Percentile? percentile;
protected override AbstractBase QuanTAlib => percentile!;
public override string ShortName => $"PERCENTILE {Period} {Percent:F0}% : {SourceName}";
public PercentileIndicator() : base()
{
Name = "PERCENTILE - n-th Percentile ";
SeparateWindow = false;
}
protected override void InitIndicator()
{
percentile = new(Period, Percent);
MinHistoryDepths = percentile.WarmupPeriod;
base.InitIndicator();
}
}
+26
View File
@@ -0,0 +1,26 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class SkewIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 3, 2000, 1, 0)]
public int Period { get; set; } = 20;
private Skew? skew;
protected override AbstractBase QuanTAlib => skew!;
public override string ShortName => $"SKEW {Period} : {SourceName}";
public SkewIndicator() : base()
{
Name = "SKEW - Skewness";
SeparateWindow = true;
}
protected override void InitIndicator()
{
skew = new(Period);
MinHistoryDepths = skew.WarmupPeriod;
base.InitIndicator();
}
}
+18
View File
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AlgoType>Indicator</AlgoType>
<OutputPath>bin\$(Configuration)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
<PackageReference Include="Microsoft.DotNet.Interactive.Formatting" Version="1.0.0-beta.21459.1" />
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\obj\**">
<Link>lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</ItemGroup>
<Target Name="CopyCustomContent" AfterTargets="AfterBuild">
<Copy SourceFiles="$(OutputPath)\Statistics.dll" DestinationFolder="$(QuantowerRoot)\Settings\Scripts\Indicators\QuanTAlib\Statistics" />
</Target>
</Project>
+27
View File
@@ -0,0 +1,27 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class StddevIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Population", sortIndex: 2)]
public bool IsPopulation { get; set; } = false;
private Stddev? stddev;
protected override AbstractBase QuanTAlib => stddev!;
public override string ShortName => $"STDDEV {Period} : {SourceName}";
public StddevIndicator() : base()
{
Name = "STDDEV - Standard Deviation";
SeparateWindow = true;
}
protected override void InitIndicator()
{
stddev = new(Period, IsPopulation);
MinHistoryDepths = stddev.WarmupPeriod;
base.InitIndicator();
}
}
+28
View File
@@ -0,0 +1,28 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class VarianceIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, minimum: 2, maximum: 2000, increment: 1, decimalPlaces: 0)]
public int Period { get; set; } = 20;
[InputParameter("Population", sortIndex: 2)]
public bool IsPopulation { get; set; } = false;
private Variance? variance;
protected override AbstractBase QuanTAlib => variance!;
public override string ShortName => $"VAR {Period} : {SourceName}";
public VarianceIndicator() : base()
{
Name = "VAR - Variance";
SeparateWindow = true;
}
protected override void InitIndicator()
{
SeparateWindow = true;
variance = new(Period, IsPopulation);
MinHistoryDepths = variance.WarmupPeriod;
base.InitIndicator();
}
}
+26
View File
@@ -0,0 +1,26 @@
using TradingPlatform.BusinessLayer;
using QuanTAlib;
public class ZScoreIndicator : IndicatorBase
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 20;
private Zscore? zScore;
protected override AbstractBase QuanTAlib => zScore!;
public override string ShortName => $"ZSCORE {Period} : {SourceName}";
public ZScoreIndicator() : base()
{
Name = "ZSCORE - Standard Score";
SeparateWindow = true;
}
protected override void InitIndicator()
{
zScore = new(Period);
MinHistoryDepths = zScore.WarmupPeriod;
base.InitIndicator();
}
}
+189
View File
@@ -0,0 +1,189 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
using TradingPlatform.BusinessLayer.Chart;
using System.Runtime.CompilerServices;
using System.Drawing.Drawing2D;
using QuanTAlib;
using System.Collections;
using TradingPlatform.BusinessLayer.TimeSync;
#pragma warning disable CA1416 // Validate platform compatibility
public abstract class IndicatorBase : Indicator, IWatchlistIndicator
{
[InputParameter("Data source", sortIndex: 17, variants: [
"Open", 1,
"High", 2,
"Low", 3,
"Close", 4,
"HL/2 (Median)", 5,
"OC/2 (Midpoint)", 6,
"OHL/3 (Mean)", 7,
"HLC/3 (Typical)", 8,
"OHLC/4 (Average)", 9,
"HLCC/4 (Weighted)", 10
])]
public int Source { get; set; } = 4;
[InputParameter("Show cold values", sortIndex: 20)]
public bool ShowColdValues { get; set; } = true;
public int MinHistoryDepths;
// LineSeries.LineSeries(string, Color, int, LineStyle)'
protected LineSeries? Series;
protected string SourceName;
protected abstract AbstractBase QuanTAlib { get; }
int IWatchlistIndicator.MinHistoryDepths => 0;
protected IndicatorBase() : base()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = GetName(Source);
Series = new(name: $"{Name}", color: Color.RoyalBlue, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
InitIndicator();
}
protected virtual void InitIndicator()
{
SourceName = GetName(Source);
}
protected override void OnInit()
{
InitIndicator();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TBar bar = new(Time: Time(),
Open: GetPrice(PriceType.Open),
High: GetPrice(PriceType.High),
Low: GetPrice(PriceType.Low),
Close: GetPrice(PriceType.Close),
Volume: GetPrice(PriceType.Volume),
IsNew: args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar);
double price = Source switch
{
1 => bar.Open,
2 => bar.High,
3 => bar.Low,
4 => bar.Close,
5 => bar.HL2,
6 => bar.OC2,
7 => bar.OHL3,
8 => bar.HLC3,
9 => bar.OHLC4,
10 => bar.HLCC4,
_ => bar.Close
};
TValue input = new TValue(bar.Time, price, bar.IsNew);
TValue result = QuanTAlib.Calc(input);
Series!.SetValue(result.Value);
Series!.SetMarker(0, Color.Transparent);
}
public override void OnPaintChart(PaintChartEventArgs args)
{
base.OnPaintChart(args);
List<Point> allPoints = new List<Point>();
if (CurrentChart == null) return;
Graphics gr = args.Graphics;
var mainWindow = this.CurrentChart.Windows[args.WindowIndex];
var converter = mainWindow.CoordinatesConverter;
var clientRect = mainWindow.ClientRectangle;
gr.SetClip(clientRect);
DateTime leftTime = new[] { converter.GetTime(clientRect.Left), Time(this.Count - 1) }.Max();
DateTime rightTime = new[] { converter.GetTime(clientRect.Right), Time(0) }.Min();
int leftIndex = (int)HistoricalData.GetIndexByTime(leftTime.Ticks) + 1;
int rightIndex = (int)HistoricalData.GetIndexByTime(rightTime.Ticks);
for (int i = rightIndex; i < leftIndex; i++)
{
int barX = (int)converter.GetChartX(Time(i));
int barY = (int)converter.GetChartY(Series![i]);
int halfBarWidth = CurrentChart.BarsWidth / 2;
Point point = new Point(barX + halfBarWidth, barY);
allPoints.Add(point);
}
if (allPoints.Count > 1)
{
DrawSmoothCombinedCurve(gr, allPoints, this.Count - QuanTAlib.WarmupPeriod - rightIndex);
}
}
private void DrawSmoothCombinedCurve(Graphics gr, List<Point> allPoints, int hotCount)
{
if (allPoints.Count < 2) return;
using (Pen defaultPen = new(Series!.Color, Series.Width) { DashStyle = ConvertLineStyleToDashStyle(Series.Style) })
using (Pen coldPen = new(Series!.Color, Series.Width) { DashStyle = DashStyle.Dot })
{
// Draw the hot part
if (hotCount > 0)
{
var hotPoints = allPoints.Take(Math.Min(hotCount + 1, allPoints.Count)).ToArray();
gr.DrawCurve(defaultPen, hotPoints, 0, hotPoints.Length - 1, (float)0.1);
}
// Draw the cold part
if (ShowColdValues && hotCount < allPoints.Count)
{
var coldPoints = allPoints.Skip(Math.Max(0, hotCount)).ToArray();
gr.DrawCurve(coldPen, coldPoints, 0, coldPoints.Length - 1, (float)0.1);
}
}
}
private DashStyle ConvertLineStyleToDashStyle(LineStyle lineStyle)
{
return lineStyle switch
{
LineStyle.Solid => DashStyle.Solid,
LineStyle.Dash => DashStyle.Dash,
LineStyle.Dot => DashStyle.Dot,
LineStyle.DashDot => DashStyle.DashDot,
_ => DashStyle.Solid,
};
}
protected void DrawText(Graphics gr, string text, Rectangle clientRect)
{
Font font = new Font("Inter", 8);
SizeF textSize = gr.MeasureString(text, font);
RectangleF textRect = new RectangleF(clientRect.Left + 5,
clientRect.Bottom - textSize.Height - 10,
textSize.Width + 10, textSize.Height + 10);
gr.FillRectangle(SystemBrushes.ControlDarkDark, textRect);
gr.DrawString(text, font, Brushes.White, new PointF(textRect.X + 6, textRect.Y + 5));
}
protected string GetName(int pType)
{
return pType switch
{
1 => "Open",
2 => "High",
3 => "Low",
4 => "Close",
5 => "Median",
6 => "Midpoint",
7 => "Mean",
8 => "Typical",
9 => "Average",
10 => "Weighted",
_ => "N/A"
};
}
}