refresh with new QT DLL

This commit is contained in:
Miha Kralj
2024-10-12 20:36:37 -07:00
parent cc45cebeb4
commit b3b3b24a25
65 changed files with 2593 additions and 1189 deletions
Binary file not shown.
+1 -26
View File
@@ -377,21 +377,6 @@
Mediates a history meta data with available data types and intervals on vendor side
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.Integration.HistoryMetadata.AllowedHistoryTypes">
<summary>
History data types
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.Integration.HistoryMetadata.AllowedBasePeriods">
<summary>
History intervals
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.Integration.HistoryMetadata.AllowedPeriods">
<summary>
History intervals
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.Integration.MessageAsset.Id">
<summary>
Asset id bearer
@@ -1948,7 +1933,7 @@
<param name="toTime"></param>
<returns></returns>
</member>
<member name="M:TradingPlatform.BusinessLayer.Symbol.GetHistory(TradingPlatform.BusinessLayer.HistoryAggregation,TradingPlatform.BusinessLayer.HistoryType,System.DateTime,System.DateTime)">
<member name="M:TradingPlatform.BusinessLayer.Symbol.GetHistory(TradingPlatform.BusinessLayer.HistoryAggregation,System.DateTime,System.DateTime)">
<summary>
Gets historical data according to aggregation and other parameters
</summary>
@@ -2965,21 +2950,11 @@
Gets HistoricalData symbol
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.HistoricalData.Period">
<summary>
Gets HistoricalData Period
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.HistoricalData.Aggregation">
<summary>
Gets HistoricalData aggregation
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.HistoricalData.HistoryType">
<summary>
Gets HistoricalData history type
</summary>
</member>
<member name="P:TradingPlatform.BusinessLayer.HistoricalData.FromTime">
<summary>
Gets HistoricalData left time boundary
+18 -2
View File
@@ -43,15 +43,28 @@ jobs:
- name: SonarCloud Scanner Start
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
PR_PARAMS="/d:sonar.pullrequest.key=${{ github.event.pull_request.number }} \
/d:sonar.pullrequest.branch=${{ github.head_ref }} \
/d:sonar.pullrequest.base=${{ github.base_ref }}"
elif [[ ${{ github.event_name }} == 'push' ]]; then
BRANCH_PARAMS="/d:sonar.branch.name=${{ github.ref_name }}"
else
BRANCH_PARAMS="/d:sonar.branch.name=${{ github.ref_name }}"
fi
dotnet sonarscanner begin \
/k:"mihakralj_QuanTAlib" \
/o:"mihakralj" \
/d:sonar.token="${{ secrets.SONAR_TOKEN }}" \
/d:sonar.host.url="https://sonarcloud.io" \
/d:sonar.cs.dotcover.reportsPaths=dotcover* \
/d:sonar.scanner.scanAll=false
/d:sonar.scanner.scanAll=false \
/d:sonar.scm.provider=git \
$PR_PARAMS $BRANCH_PARAMS
- name: Build
run: |
@@ -216,7 +229,10 @@ jobs:
build_publish:
needs: [SonarCloud, Code_Coverage, CodeQL, Codacy_Scan, SecurityCodeScan]
if: success()
if: |
success() &&
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')) ||
github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
+15 -15
View File
@@ -1,5 +1,4 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
@@ -7,15 +6,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "quantalib", "lib\quantalib.
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "quantower", "quantower", "{1B9AC248-76F8-44DD-958D-F1DC08EE1E87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Statistics", "quantower\Statistics\Statistics.csproj", "{2E9427C7-144F-488E-A29D-789ACC1C32AE}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Statistics", "quantower\Statistics\_Statistics.csproj", "{2E9427C7-144F-488E-A29D-789ACC1C32AE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Averages", "quantower\Averages\Averages.csproj", "{6BE10C39-4127-446C-818B-7976FCDD51D5}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Averages", "quantower\Averages\_Averages.csproj", "{6BE10C39-4127-446C-818B-7976FCDD51D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volatility", "quantower\Volatility\Volatility.csproj", "{B7DC44F7-D3A3-4C70-9025-513E0182B646}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volatility", "quantower\Volatility\_Volatility.csproj", "{B7DC44F7-D3A3-4C70-9025-513E0182B646}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntheticVendor", "SyntheticVendor\SyntheticVendor.csproj", "{1CF111D9-33E6-4A11-8FEC-F23300A78D15}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{E204F173-5840-4AA3-BED1-98C8D2F813E3}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{2D97C971-20BF-40DB-94AA-3279F787D3CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -41,15 +40,16 @@ Global
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release|Any CPU.Build.0 = Release|Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release|Any CPU.Build.0 = Release|Any CPU
{E204F173-5840-4AA3-BED1-98C8D2F813E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E204F173-5840-4AA3-BED1-98C8D2F813E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E204F173-5840-4AA3-BED1-98C8D2F813E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E204F173-5840-4AA3-BED1-98C8D2F813E3}.Release|Any CPU.Build.0 = Release|Any CPU
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release | Any CPU.ActiveCfg = Release | Any CPU
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release | Any CPU.Build.0 = Release | Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug | Any CPU.ActiveCfg = Debug | Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug | Any CPU.Build.0 = Debug | Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release | Any CPU.ActiveCfg = Release | Any CPU
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release | Any CPU.Build.0 = Release | Any CPU
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2E9427C7-144F-488E-A29D-789ACC1C32AE} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
+63 -75
View File
@@ -5,10 +5,7 @@ using TradingPlatform.BusinessLayer;
using TradingPlatform.BusinessLayer.Integration;
using System.Diagnostics.CodeAnalysis;
namespace SyntheticVendorNamespace;
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
public class SyntheticVendor : Vendor
{
@@ -101,6 +98,25 @@ public class SyntheticVendor : Vendor
}
public static VendorMetaData GetVendorMetaData()
{
return new VendorMetaData()
{
VendorName = "Synthetic Vendor",
VendorDescription = "A synthetic vendor for testing and demonstration purposes",
GetDefaultConnections = () =>
{
var defaultConnection = Vendor.CreateDefaultConnectionInfo(
"Synthetic Connection",
"Synthetic Vendor",
"", // Replace with actual path if you have a logo
allowCreateCustomConnections: true
);
return new List<ConnectionInfo> { defaultConnection };
}
};
}
private MessageSymbol CreateMessageSymbol(
string id,
string name,
@@ -131,24 +147,7 @@ public class SyntheticVendor : Vendor
return messageSymbol;
}
public static VendorMetaData GetVendorMetaData()
{
return new VendorMetaData()
{
VendorName = "Synthetic Vendor",
VendorDescription = "A synthetic vendor for testing and demonstration purposes",
GetDefaultConnections = () =>
{
var defaultConnection = Vendor.CreateDefaultConnectionInfo(
"Synthetic Connection",
"Synthetic Vendor",
"", // Replace with actual path if you have a logo
allowCreateCustomConnections: true
);
return new List<ConnectionInfo> { defaultConnection };
}
};
}
private MessageSymbol CreateMessageSymbol(string id, string name, string exchangeId, string assetId, SymbolType type)
@@ -226,20 +225,6 @@ public class SyntheticVendor : Vendor
}
public override void OnConnected(CancellationToken token)
{
// This method is called after a successful connection
// You can initialize resources or start any necessary processes here
base.OnConnected(token);
// For example, you might want to push some initial messages or data
// PushMessage(new MessageVendorEvent("SyntheticVendor connected successfully"));
}
public override IList<MessageExchange> GetExchanges(CancellationToken token)
{
return exchanges;
@@ -310,7 +295,6 @@ public class SyntheticVendor : Vendor
{
switch (symbolId)
{
//case "W0": return GenerateConstant;
case "W1": return GenerateSpike;
case "W2": return GenerateDiracDelta;
case "W3": return GenerateSquareWave;
@@ -333,36 +317,52 @@ public class SyntheticVendor : Vendor
}
}
/*
public override HistoryMetadata GetHistoryMetadata(CancellationToken cancellationToken)
{
return new HistoryMetadata()
return new HistoryMetadata
{
AllowedHistoryTypes = new HistoryType[]
AllowedAggregations = new string[] { "Time", "Tick" },
AllowedPeriodsHistoryAggregationTime = new Period[]
{
HistoryType.Bid,
HistoryType.Ask,
HistoryType.Midpoint,
HistoryType.Last,
HistoryType.BidAsk,
HistoryType.Mark,
Period.SECOND1, Period.SECOND5, Period.SECOND10, Period.SECOND15, Period.SECOND30,
Period.MIN1, Period.MIN2, Period.MIN3, Period.MIN4, Period.MIN5,
Period.MIN10, Period.MIN15, Period.MIN30,
Period.HOUR1, Period.HOUR2, Period.HOUR3, Period.HOUR4,
Period.HOUR6, Period.HOUR8, Period.HOUR12,
Period.DAY1,
Period.WEEK1,
Period.MONTH1,
Period.YEAR1
},
AllowedPeriods = new Period[]
AllowedBasePeriodsHistoryAggregationTime = new BasePeriod[]
{
Period.TICK1,
Period.SECOND1, Period.SECOND5, Period.SECOND10, Period.SECOND15, Period.SECOND30,
Period.MIN1, Period.MIN2, Period.MIN3, Period.MIN4, Period.MIN5,
Period.MIN10, Period.MIN15, Period.MIN30,
Period.HOUR1, Period.HOUR2, Period.HOUR3, Period.HOUR4,
Period.HOUR6, Period.HOUR8, Period.HOUR12,
Period.DAY1,
Period.WEEK1,
Period.MONTH1,
Period.YEAR1
BasePeriod.Second, BasePeriod.Minute, BasePeriod.Hour, BasePeriod.Day, BasePeriod.Week, BasePeriod.Month, BasePeriod.Year
},
UseHistoryLocalCache = false
AllowedHistoryTypesHistoryAggregationTime = new HistoryType[]
{
HistoryType.Bid,
HistoryType.Ask,
HistoryType.Midpoint,
HistoryType.Last,
HistoryType.BidAsk,
HistoryType.Mark
},
AllowedHistoryTypesHistoryAggregationTick = new HistoryType[]
{
HistoryType.Bid,
HistoryType.Ask,
HistoryType.Midpoint,
HistoryType.Last,
HistoryType.BidAsk,
HistoryType.Mark
},
DegreeOfParallelism = 1,
UseHistoryLocalCache = false,
BuildUncompletedBars = true
};
}
*/
/*******************************************************************************************************************************************/
/*******************************************************************************************************************************************/
@@ -418,18 +418,6 @@ public class SyntheticVendor : Vendor
private static readonly double[] distributionValues = new double[]
{
0.010, // Extreme left tail
0.050, // Left tail
0.200, // Left of center
0.480, // Center (peak)
0.200, // Right of center
0.050, // Right tail
0.010 // Extreme right tail
};
private HistoryItemBar GenerateDiracDelta(DateTime time, TimeSpan slice)
{
// Ensure we're working with UTC time
@@ -972,7 +960,7 @@ public class SyntheticVendor : Vendor
private const int NumOctaves = 6;
private double[] pinkNoiseState = new double[NumOctaves];
private readonly double[] pinkNoiseState = new double[NumOctaves];
private double GeneratePinkNoiseValue()
{
double total = 0;
@@ -1033,8 +1021,8 @@ public class SyntheticVendor : Vendor
private double GBMLastClose = 100; // Starting price
private double GBMMu = 0.05; // Annual drift
private double GBMSigma = 0.2; // Annual volatility
private readonly double GBMMu = 0.05; // Annual drift
private readonly double GBMSigma = 0.2; // Annual volatility
private HistoryItemBar GenerateGBM(DateTime time, TimeSpan slice)
{
@@ -1081,9 +1069,9 @@ public class SyntheticVendor : Vendor
}
private double FBMLastClose = 100; // Starting price
private double FBMHurst = 0.85; // Hurst parameter (0.5 < H < 1 for persistent fBm)
private double FBMSigma = 0.25; // Volatility parameter
private double FBMDrift = 0.001; // drift
private readonly double FBMHurst = 0.85; // Hurst parameter (0.5 < H < 1 for persistent fBm)
private readonly double FBMSigma = 0.25; // Volatility parameter
private readonly double FBMDrift = 0.001; // drift
private HistoryItemBar GenerateFBM(DateTime time, TimeSpan slice)
{
+4 -1
View File
@@ -37,7 +37,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\quantower\**\*.csproj" />
<ProjectReference Include="..\lib\*.csproj" />
<ProjectReference Include="..\quantower\Volatility\_Volatility.csproj" Aliases="volatility" />
<ProjectReference Include="..\quantower\Averages\_Averages.csproj" Aliases="averages" />
<ProjectReference Include="..\quantower\Statistics\_Statistics.csproj" Aliases="statistics" />
</ItemGroup>
</Project>
+8 -2
View File
@@ -1,7 +1,13 @@
extern alias volatility;
extern alias averages;
extern alias statistics;
using Xunit;
using System;
using System.Reflection;
using TradingPlatform.BusinessLayer;
using statistics::QuanTAlib;
using averages::QuanTAlib;
using volatility::QuanTAlib;
namespace QuanTAlib
{
@@ -83,7 +89,7 @@ namespace QuanTAlib
[Fact] public void Slope() => TestIndicator<SlopeIndicator>("slope");
[Fact] public void Stddev() => TestIndicator<StddevIndicator>("stddev");
[Fact] public void Variance() => TestIndicator<VarianceIndicator>("variance");
[Fact] public void Zscore() => TestIndicator<ZScoreIndicator>("zScore");
[Fact] public void Zscore() => TestIndicator<ZscoreIndicator>("zScore");
// Volatility Indicators
[Fact] public void Atr() => TestIndicator<AtrIndicator>("atr");
-148
View File
@@ -1,148 +0,0 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
using TradingPlatform.BusinessLayer.Chart;
using System.Runtime.CompilerServices;
using System.Drawing.Drawing2D;
namespace QuanTAlib;
#pragma warning disable CA1416 // Validate platform compatibility
public abstract class AbstractIndicatorBase : Indicator
{
[InputParameter("Data source", sortIndex: 18, variants: new object[]{
"Close", PriceType.Close,
"Open", PriceType.Open,
"High", PriceType.High,
"Low", PriceType.Low,
"Typical", PriceType.Typical,
"Median", PriceType.Median,
"Weighted", PriceType.Weighted
})]
public PriceType SourcePrice { get; set; } = PriceType.Close;
[InputParameter(name: "Line smoothing", sortIndex: 19, minimum: 0.0, maximum: 1.0, increment: 0.1, decimalPlaces: 2)]
public double Tension = 0.2;
[InputParameter("Show cold values", sortIndex: 20)]
public bool ShowColdValues { get; set; } = true;
// LineSeries.LineSeries(string, Color, int, LineStyle)'
protected LineSeries? Series;
protected abstract AbstractBase MovingAverage { get; }
protected AbstractIndicatorBase() : base()
{
OnBackGround = true;
SeparateWindow = false;
Series = new(name: $"Name", color: Color.Orange, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
InitIndicator();
}
protected virtual void InitIndicator()
{
}
protected override void OnInit()
{
InitIndicator();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
base.OnUpdate(args);
bool isNew = this.HistoricalData.Aggregation.GetPeriod == Period.TICK1
? args.Reason == UpdateReason.NewTick || args.Reason == UpdateReason.HistoricalBar
: args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar;
double price = GetPrice(SourcePrice);
TValue input = new TValue(Time(), price, isNew);
TValue result = MovingAverage.Calc(input);
Series!.SetMarker(0, Color.Transparent);
Series.SetValue(result.Value);
}
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 = CurrentChart.MainWindow;
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 - MovingAverage.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)Tension);
}
// 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)Tension);
}
}
}
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));
}
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,
};
}
}
+43 -9
View File
@@ -1,7 +1,9 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class AfirmaIndicator : IndicatorBase
public class AfirmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Taps (number of weights)", sortIndex: 1, 1, 2000, 1, 0)]
public int Taps { get; set; } = 6;
@@ -11,27 +13,59 @@ public class AfirmaIndicator : IndicatorBase
[InputParameter("Window Type", sortIndex: 3, variants: [
"Rectangular", Afirma.WindowType.Rectangular,
"Hanning", Afirma.WindowType.Hanning1,
"Hamming", Afirma.WindowType.Hanning2,
"Blackman", Afirma.WindowType.Blackman,
"Blackman-Harris", Afirma.WindowType.BlackmanHarris
"Hanning", Afirma.WindowType.Hanning1,
"Hamming", Afirma.WindowType.Hanning2,
"Blackman", Afirma.WindowType.Blackman,
"Blackman-Harris", Afirma.WindowType.BlackmanHarris
])]
public Afirma.WindowType Window { get; set; } = Afirma.WindowType.Hanning1;
[InputParameter("Data source", sortIndex: 4, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Afirma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"AFIRMA {Taps}:{Periods}:{Window} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods + Taps;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public AfirmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "AFIRMA - Adaptive Finite Impulse Response Moving Average";
Description = "Adaptive Finite Impulse Response Moving Average with ARMA component";
Series = new(name: $"AFIRMA {Taps}:{Periods}:{Window}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Afirma(periods: Periods, taps: Taps, window: Window);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"AFIRMA {Taps}:{Periods}:{Window}:{SourceName}";
}
+45 -11
View File
@@ -1,30 +1,64 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class AlmaIndicator : IndicatorBase
public class AlmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Offset", sortIndex: 5)]
[InputParameter("Offset", sortIndex: 2)]
public double Offset { get; set; } = 0.85;
[InputParameter("Sigma", sortIndex: 6)]
[InputParameter("Sigma", sortIndex: 3)]
public double Sigma { get; set; } = 6.0;
private Alma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"ALMA {Period} : {Offset:F2} : {Sigma:F0} : {SourceName}";
public AlmaIndicator() : base()
[InputParameter("Data source", sortIndex: 4, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Alma? ma;
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Period;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public AlmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "ALMA - Arnaud Legoux Moving Average";
Description = "Arnaud Legoux Moving Average";
Series = new(name: $"ALMA {Period}:{Offset:F2}:{Sigma:F0}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Alma(period: Period, offset: Offset, sigma: Sigma);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"ALMA {Period}:{Offset:F2}:{Sigma:F0}:{SourceName}";
}
+43 -8
View File
@@ -1,23 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class DemaIndicator : IndicatorBase
public class DemaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
private Dema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"DEMA {Period} : {SourceName}";
public DemaIndicator() : base()
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Dema? ma;
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Period;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public DemaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "DEMA - Double Exponential Moving Average";
Description = "A faster-responding moving average that reduces lag by applying the EMA twice.";
Series = new(name: $"DEMA {Period}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Dema(period: Period);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"DEMA {Period}:{SourceName}";
}
+44 -8
View File
@@ -1,27 +1,63 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class DsmaIndicator : IndicatorBase
public class DsmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Scale factor", sortIndex: 2, minimum: 0.01, maximum: 1.0, increment: 0.01, decimalPlaces: 2)]
public double Scale { get; set; } = 0.5;
private Dsma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"DSMA {Period} : {Scale:F2} : {SourceName}";
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
public DsmaIndicator() : base()
private Dsma? ma;
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths { get; private set; }
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public DsmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "DSMA - Deviation Scaled Moving Average";
Description = "A moving average that adjusts its responsiveness based on price deviations from the mean.";
Series = new(name: $"DSMA {Period}:{Scale:F2}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Dsma(Period, Scale);
MinHistoryDepths = ma.WarmupPeriod;
base.InitIndicator();
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"DSMA {Period}:{Scale:F2}:{SourceName}";
}
+43 -8
View File
@@ -1,24 +1,59 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class DwmaIndicator : IndicatorBase
public class DwmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
private Dwma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"DWMA {Period} : {SourceName}";
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
public DwmaIndicator() : base()
private Dwma? ma;
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Period;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public DwmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "DWMA - Double Weighted Moving Average";
Description = "A moving average that applies double weighting to recent prices for increased responsiveness.";
Series = new(name: $"DWMA {Period}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Dwma(Period);
base.InitIndicator();
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"DWMA {Period}:{SourceName}";
}
+44 -13
View File
@@ -1,27 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class EmaIndicator : IndicatorBase
public class EmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Use SMA for warmup", sortIndex: 5)]
public bool UseSma { get; set; } = false;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Ema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"EMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public EmaIndicator() : base()
public EmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "EMA - Exponential Moving Average";
Description = "Moving average that gives more weight to recent prices, reducing lag in trend following.";
Description = "Exponential Moving Average";
Series = new(name: $"EMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Ema(period: Period, useSma: UseSma);
ma = new Ema(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"EMA {Periods}:{SourceName}";
}
+46 -12
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class EpmaIndicator : IndicatorBase
public class EpmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Epma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"EPMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public EpmaIndicator() : base()
public EpmaIndicator()
{
Name = "EPMA - Endpoint Moving Average";
Description = "Moving average that emphasizes the most recent data point, useful for identifying trend changes.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "EPMA - Exponential Percentage Moving Average";
Description = "Exponential Percentage Moving Average";
Series = new(name: $"EPMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Epma(period: Period);
ma = new Epma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"EPMA {Periods}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class FramaIndicator : IndicatorBase
public class FramaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Frama? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"FRAMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods * 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public FramaIndicator() : base()
public FramaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "FRAMA - Fractal Adaptive Moving Average";
Description = "Adaptive moving average that adjusts its smoothing based on market fractal dimension.";
Description = "Fractal Adaptive Moving Average";
Series = new(name: $"FRAMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Frama(Period);
base.InitIndicator();
ma = new Frama(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"FRAMA {Periods}:{SourceName}";
}
+46 -12
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class FwmaIndicator : IndicatorBase
public class FwmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Fwma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"FWMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public FwmaIndicator() : base()
public FwmaIndicator()
{
Name = "FWMA - Fibonacci-Weighted Moving Average";
Description = "Moving average that uses Fibonacci sequence for weighting, emphasizing recent and key historical prices.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "FWMA - Fibonacci Weighted Moving Average";
Description = "Fibonacci Weighted Moving Average";
Series = new(name: $"FWMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Fwma(Period);
base.InitIndicator();
ma = new Fwma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"FWMA {Periods}:{SourceName}";
}
+49 -12
View File
@@ -1,24 +1,61 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class GmaIndicator : IndicatorBase
public class GmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Sigma", sortIndex: 2, 0.1, 10, 0.1, 1)]
public double Sigma { get; set; } = 1.0;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Gma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"GMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public GmaIndicator() : base()
public GmaIndicator()
{
Name = "GMA - Gaussian-Weighted Moving Average";
Description = "Moving average using Gaussian distribution for weighting, balancing recent and historical data.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "GMA - Gaussian Moving Average";
Description = "Gaussian Moving Average";
Series = new(name: $"GMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Gma(Period);
base.InitIndicator();
ma = new Gma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"GMA {Periods}:{Sigma}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class HmaIndicator : IndicatorBase
public class HmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Hma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"HMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods + (int)Math.Sqrt(Periods) - 1;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public HmaIndicator() : base()
public HmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "HMA - Hull Moving Average";
Description = "Responsive moving average that reduces lag while maintaining smoothness in price action.";
Description = "Hull Moving Average";
Series = new(name: $"HMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Hma(Period);
base.InitIndicator();
ma = new Hma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"HMA {Periods}:{SourceName}";
}
+43 -10
View File
@@ -1,22 +1,55 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class HtitIndicator : IndicatorBase
public class HtitIndicator : Indicator, IWatchlistIndicator
{
private Htit? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"HTIT : {SourceName}";
[InputParameter("Data source", sortIndex: 1, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
public HtitIndicator() : base()
private Htit? ma;
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => 12; // Based on WarmupPeriod in Htit
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public HtitIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "HTIT - Hilbert Transform Instantaneous Trendline";
Description = "Uses Hilbert Transform to identify the dominant cycle and generate a smooth, lag-free trendline.";
Description = "Hilbert Transform Instantaneous Trendline (Note: This indicator may not be fully functional)";
Series = new(name: "HTIT", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Htit();
MinHistoryDepths = ma.WarmupPeriod;
base.InitIndicator();
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"HTIT:{SourceName}";
}
+59 -15
View File
@@ -1,30 +1,74 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class HwmaIndicator : IndicatorBase
public class HwmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("nA - smoothed series", sortIndex: 5, minimum: 0.0, maximum: 1.0, increment: 0.1, decimalPlaces: 2)]
public double nA { get; set; } = 0.18;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("nB - assess the trend (from 0 to 1)", sortIndex: 6, minimum: 0.0, maximum: 1.0, increment: 0.1, decimalPlaces: 2)]
public double nB { get; set; } = 0.1;
[InputParameter("nA", sortIndex: 2, 0, 1, 0.01, 2)]
public double NA { get; set; } = 0;
[InputParameter("nC - assess seasonality (from 0 to 1)", sortIndex: 7, minimum: 0.0, maximum: 1.0, increment: 0.1, decimalPlaces: 2)]
public double nC { get; set; } = 0.1;
[InputParameter("nB", sortIndex: 3, 0, 1, 0.01, 2)]
public double NB { get; set; } = 0;
[InputParameter("nC", sortIndex: 4, 0, 1, 0.01, 2)]
public double NC { get; set; } = 0;
[InputParameter("Data source", sortIndex: 5, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Hwma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"HWMA {nA:F2} : {nB:F2} : {nC:F2} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public HwmaIndicator() : base()
public HwmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "HWMA - Holt-Winter Moving Average";
Description = "Triple exponential moving average that accounts for level, trend, and seasonal components.";
Description = "Holt-Winter Moving Average";
Series = new(name: $"HWMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Hwma(nA: nA, nB: nB, nC: nC);
base.InitIndicator();
if (NA == 0 && NB == 0 && NC == 0)
{
ma = new Hwma(Periods);
}
else
{
ma = new Hwma(Periods, NA, NB, NC);
}
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"HWMA {Periods}:{NA}:{NB}:{NC}:{SourceName}";
}
+50 -12
View File
@@ -1,26 +1,64 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class JmaIndicator : IndicatorBase
public class JmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Phase", sortIndex: 2, -100, 100, 1, 0)]
public int Phase { get; set; } = 0;
public double Phase { get; set; } = 0;
[InputParameter("VShort", sortIndex: 3, 1, 100, 1, 0)]
public int VShort { get; set; } = 10;
[InputParameter("Data source", sortIndex: 4, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Jma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"JMA {Period} : {Phase} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods * 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public JmaIndicator() : base()
public JmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "JMA - Jurik Moving Average";
Description = "Adaptive moving average with reduced lag and noise, adjustable smoothness and phase shift.";
Description = "Jurik Moving Average (Note: This indicator may have consistency issues)";
Series = new(name: $"JMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Jma(period: Period, phase: (double)Phase);
base.InitIndicator();
ma = new Jma(Periods, Phase, VShort);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"JMA {Periods}:{Phase}:{VShort}:{SourceName}";
}
+49 -13
View File
@@ -1,28 +1,64 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class KamaIndicator : IndicatorBase
public class KamaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Fast", sortIndex: 2, 1, 2000, 1, 0)]
[InputParameter("Fast", sortIndex: 2, 1, 100, 1, 0)]
public int Fast { get; set; } = 2;
[InputParameter("Slow", sortIndex: 3, 1, 2000, 1, 0)]
[InputParameter("Slow", sortIndex: 3, 1, 100, 1, 0)]
public int Slow { get; set; } = 30;
[InputParameter("Data source", sortIndex: 4, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Kama? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"KAMA {Period} : {Fast} : {Slow} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public KamaIndicator() : base()
public KamaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "KAMA - Kaufman's Adaptive Moving Average";
Description = "Adaptive moving average that adjusts to market volatility, reducing lag in trending markets.";
Description = "Kaufman's Adaptive Moving Average";
Series = new(name: $"KAMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Kama(Period, Fast, Slow);
base.InitIndicator();
ma = new Kama(Periods, Fast, Slow);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"KAMA {Periods}:{Fast}:{Slow}:{SourceName}";
}
+46 -12
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class LtmaIndicator : IndicatorBase
public class LtmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Gamma", sortIndex: 1, 0, 1, 0.01, 2)]
public double Gamma { get; set; } = 0.10;
[InputParameter("Gamma", sortIndex: 1, 0.01, 1, 0.01, 2)]
public double Gamma { get; set; } = 0.1;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Ltma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"Laguerre {Gamma:F2} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => 4; // Based on WarmupPeriod in Ltma
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public LtmaIndicator() : base()
public LtmaIndicator()
{
Name = "LTMA - Laguerre Transform Moving Average";
Description = "Moving average using Laguerre polynomials, offering adjustable smoothing and lag reduction.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "LTMA - Laguerre Time Moving Average";
Description = "Laguerre Time Moving Average";
Series = new(name: $"LTMA {Gamma}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Ltma(gamma: Gamma);
base.InitIndicator();
ma = new Ltma(Gamma);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"LTMA {Gamma}:{SourceName}";
}
+48 -14
View File
@@ -1,27 +1,61 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MaafIndicator : IndicatorBase
public class MaafIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 39;
[InputParameter("Periods", sortIndex: 1, 3, 1000, 1, 0)]
public int Periods { get; set; } = 39;
[InputParameter("Threshold", sortIndex: 5, minimum: 0, maximum: 1, increment: 0.001, decimalPlaces: 3)]
private double Threshold { get; set; } = 0.002;
[InputParameter("Threshold", sortIndex: 2, 0.0001, 0.1, 0.0001, 4)]
public double Threshold { get; set; } = 0.002;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Maaf? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"MAAF {Period} : {Threshold:F2} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MaafIndicator() : base()
public MaafIndicator()
{
Name = "MAAF - Median-Average Adaptive Filter";
Description = "Adaptive filter combining median and average, reducing noise while preserving trend responsiveness.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "MAAF - Median Adaptive Averaging Filter";
Description = "Median Adaptive Averaging Filter (Note: This indicator may have consistency issues)";
Series = new(name: $"MAAF {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Maaf(period: Period, threshold: Threshold);
ma = new Maaf(Periods, Threshold);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"MAAF {Periods}:{Threshold}:{SourceName}";
}
+53 -13
View File
@@ -1,25 +1,65 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MamaIndicator : IndicatorBase
public class MamaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Fast limit", sortIndex: 2, 0, 1, 0.01, 2)]
public double Fast { get; set; } = 0.4;
[InputParameter("Slow limit", sortIndex: 3, 0, 1, 0.01, 2)]
public double Slow { get; set; } = 0.04;
[InputParameter("Fast Limit", sortIndex: 1, 0.01, 1, 0.01, 2)]
public double FastLimit { get; set; } = 0.5;
[InputParameter("Slow Limit", sortIndex: 2, 0.01, 1, 0.01, 2)]
public double SlowLimit { get; set; } = 0.05;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Mama? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"MAMA : {Fast} : {Slow} : {SourceName}";
protected LineSeries? MamaSeries;
protected LineSeries? FamaSeries;
protected string? SourceName;
public int MinHistoryDepths => 6;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MamaIndicator() : base()
public MamaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "MAMA - MESA Adaptive Moving Average";
Description = "Adaptive moving average using MESA algorithm to adjust to market cycles and reduce lag.";
Description = "MESA Adaptive Moving Average";
MamaSeries = new(name: "MAMA", color: Color.Yellow, width: 2, style: LineStyle.Solid);
FamaSeries = new(name: "FAMA", color: Color.Red, width: 2, style: LineStyle.Solid);
AddLineSeries(MamaSeries);
AddLineSeries(FamaSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Mama(Fast, Slow);
base.InitIndicator();
ma = new Mama(FastLimit, SlowLimit);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
MamaSeries!.SetValue(result.Value);
FamaSeries!.SetValue(ma.Fama.Value);
}
public override string ShortName => $"MAMA {FastLimit}:{SlowLimit}:{SourceName}";
}
+48 -14
View File
@@ -1,27 +1,61 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MgdiIndicator : IndicatorBase
public class MgdiIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("k Factor", sortIndex: 2, minimum: 0.0, maximum: 1.0, increment: 0.1, decimalPlaces: 2)]
public double kfactor { get; set; } = 0.6;
[InputParameter("K-Factor", sortIndex: 2, 0.1, 2, 0.1, 1)]
public double KFactor { get; set; } = 0.6;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Mgdi? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"MGDI {Period} : {kfactor:F2} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MgdiIndicator() : base()
public MgdiIndicator()
{
Name = "MGDI - McGinley Dynamic Index";
Description = "Adaptive moving average that adjusts to market speed, reducing whipsaws in trending markets.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "MGDI - McGinley Dynamic Indicator";
Description = "McGinley Dynamic Indicator";
Series = new(name: $"MGDI {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Mgdi(period: Period, kFactor: kfactor);
base.InitIndicator();
ma = new Mgdi(Periods, KFactor);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"MGDI {Periods}:{KFactor}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MmaIndicator : IndicatorBase
public class MmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Mma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"MMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MmaIndicator() : base()
public MmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "MMA - Modified Moving Average";
Description = "Variation of EMA that reduces lag and smooths price action, balancing responsiveness and stability.";
Description = "Modified Moving Average";
Series = new(name: $"MMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Mma(period: Period);
ma = new Mma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"MMA {Periods}:{SourceName}";
}
+44 -10
View File
@@ -1,24 +1,58 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class PwmaIndicator : IndicatorBase
public class PwmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Pwma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"PWMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public PwmaIndicator() : base()
public PwmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "PWMA - Pascal's Weighted Moving Average";
Description = "Moving average using Pascal's triangle coefficients, emphasizing recent data with smooth transitions.";
Description = "Pascal's Weighted Moving Average";
Series = new(name: $"PWMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Pwma(period: Period);
ma = new Pwma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"PWMA {Periods}:{SourceName}";
}
+55 -18
View File
@@ -1,30 +1,67 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class QemaIndicator : IndicatorBase
public class QemaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("alpha 1", sortIndex: 1, minimum: 0.01, maximum: 1.0, increment: 0.01, decimalPlaces: 2)]
public double k1 { get; set; } = 0.2;
[InputParameter("K1", sortIndex: 1, 0.01, 1, 0.01, 2)]
public double K1 { get; set; } = 0.2;
[InputParameter("K2", sortIndex: 2, 0.01, 1, 0.01, 2)]
public double K2 { get; set; } = 0.2;
[InputParameter("K3", sortIndex: 3, 0.01, 1, 0.01, 2)]
public double K3 { get; set; } = 0.2;
[InputParameter("K4", sortIndex: 4, 0.01, 1, 0.01, 2)]
public double K4 { get; set; } = 0.2;
[InputParameter("Data source", sortIndex: 5, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
[InputParameter("alpha 2", sortIndex: 2, minimum: 0.01, maximum: 1.0, increment: 0.01, decimalPlaces: 2)]
public double k2 { get; set; } = 0.3;
[InputParameter("alpha 3", sortIndex: 3, minimum: 0.01, maximum: 1.0, increment: 0.01, decimalPlaces: 2)]
public double k3 { get; set; } = 0.4;
[InputParameter("alpha 4", sortIndex: 4, minimum: 0.01, maximum: 1.0, increment: 0.01, decimalPlaces: 2)]
public double k4 { get; set; } = 0.5;
private Qema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"QEMA {k1:F2} : {k2:F2} : {k3:F2} : {k4:F2} :{SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => (int)((2 - Math.Min(Math.Min(K1, K2), Math.Min(K3, K4))) / Math.Min(Math.Min(K1, K2), Math.Min(K3, K4)));
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public QemaIndicator() : base()
public QemaIndicator()
{
Name = "QEMA - Quad Exponential Moving Average";
Description = "Combines four EMAs with different smoothing factors to reduce lag and improve trend following.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "QEMA - Quadruple Exponential Moving Average";
Description = "Quadruple Exponential Moving Average";
Series = new(name: $"QEMA {K1},{K2},{K3},{K4}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Qema(k1, k2, k3, k4);
ma = new Qema(K1, K2, K3, K4);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"QEMA {K1},{K2},{K3},{K4}:{SourceName}";
}
+46 -12
View File
@@ -1,27 +1,61 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class RemaIndicator : IndicatorBase
public class RemaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Regularization Factor", sortIndex: 2, minimum: 0, maximum: 2.5, increment: 0.1, decimalPlaces: 1)]
[InputParameter("Lambda", sortIndex: 2, 0, 1, 0.01, 2)]
public double Lambda { get; set; } = 0.5;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Rema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"REMA {Period} : {Lambda:F2} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public RemaIndicator() : base()
public RemaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "REMA - Regularized Exponential Moving Average";
Description = "EMA variant with regularization to reduce noise and improve stability in volatile markets.";
Description = "Regularized Exponential Moving Average";
Series = new(name: $"REMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Rema(period: Period, lambda: Lambda);
ma = new Rema(Periods, Lambda);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"REMA {Periods}:{Lambda}:{SourceName}";
}
+46 -12
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class RmaIndicator : IndicatorBase
public class RmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Rma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"RMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods * 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public RmaIndicator() : base()
public RmaIndicator()
{
Name = "RMA - Wilder's Moving Average";
Description = "Smoothed moving average that reduces whipsaws, commonly used in RSI calculations.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "RMA - Relative Moving Average (Wilder's Moving Average)";
Description = "Relative Moving Average, also known as Wilder's Moving Average";
Series = new(name: $"RMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Rma(Period);
base.InitIndicator();
ma = new Rma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"RMA {Periods}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class SinemaIndicator : IndicatorBase
public class SinemaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Sinema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"SINEMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public SinemaIndicator() : base()
public SinemaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "SINEMA - Sine-Weighted Moving Average";
Description = "Moving average using sine function for weighting, balancing recent and historical price data.";
Description = "Sine-Weighted Moving Average";
Series = new(name: $"SINEMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Sinema(Period);
base.InitIndicator();
ma = new Sinema(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"SINEMA {Periods}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class SmaIndicator : IndicatorBase
public class SmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Sma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"SMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public SmaIndicator() : base()
public SmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "SMA - Simple Moving Average";
Description = "Basic moving average that calculates the arithmetic mean of prices over a specified period.";
Description = "Simple Moving Average";
Series = new(name: $"SMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Sma(Period);
base.InitIndicator();
ma = new Sma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"SMA {Periods}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class SmmaIndicator : IndicatorBase
public class SmmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Smma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"SMMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public SmmaIndicator() : base()
public SmmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "SMMA - Smoothed Moving Average";
Description = "Moving average that gives more weight to recent data while retaining all historical data.";
Description = "Smoothed Moving Average";
Series = new(name: $"SMMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Smma(Period);
base.InitIndicator();
ma = new Smma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"SMMA {Periods}:{SourceName}";
}
+49 -15
View File
@@ -1,30 +1,64 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class T3Indicator : IndicatorBase
public class T3Indicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Vfactor", sortIndex: 2, 0, 1, 0.01, 2)]
public double Vfactor { get; set; } = 0.62;
[InputParameter("Volume Factor", sortIndex: 2, 0, 1, 0.01, 2)]
public double VolumeFactor { get; set; } = 0.7;
[InputParameter("Use SMA for warmup", sortIndex: 3)]
public bool UseSma { get; set; } = false;
[InputParameter("Use SMA", sortIndex: 3)]
public bool UseSma { get; set; } = true;
[InputParameter("Data source", sortIndex: 4, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private T3? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"T3 {Period} : {Vfactor:F2} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public T3Indicator() : base()
public T3Indicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "T3 - Tillson T3 Moving Average";
Description = "Triple exponential moving average with reduced lag and smoothing, adjustable via volume factor.";
Description = "Tillson T3 Moving Average";
Series = new(name: $"T3 {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new T3(period: Period, vfactor: Vfactor, useSma: UseSma);
base.InitIndicator();
ma = new T3(Periods, VolumeFactor, UseSma);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"T3 {Periods}:{VolumeFactor}:{UseSma}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class TemaIndicator : IndicatorBase
public class TemaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Tema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"TEMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => (int)Math.Ceiling(-Periods * Math.Log(1 - 0.85));
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public TemaIndicator() : base()
public TemaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "TEMA - Triple Exponential Moving Average";
Description = "Moving average that applies EMA three times to reduce lag and improve responsiveness to trends.";
Description = "Triple Exponential Moving Average";
Series = new(name: $"TEMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Tema(period: Period);
ma = new Tema(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"TEMA {Periods}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class TrimaIndicator : IndicatorBase
public class TrimaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Trima? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"TRIMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public TrimaIndicator() : base()
public TrimaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "TRIMA - Triangular Moving Average";
Description = "Weighted moving average giving more importance to the middle of the period for smoother output.";
Description = "Triangular Moving Average";
Series = new(name: $"TRIMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Trima(Period);
base.InitIndicator();
ma = new Trima(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"TRIMA {Periods}:{SourceName}";
}
+51 -15
View File
@@ -1,28 +1,64 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class VidyaIndicator : IndicatorBase
public class VidyaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Short Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Long Period", sortIndex: 2, 1, 2000, 1, 0)]
public int LPeriod { get; set; } = 40;
[InputParameter("Alpha", sortIndex: 3, 0, 1, 0.1, 1)]
public double Alpha { get; set; } = 0.4;
[InputParameter("Short Period", sortIndex: 1, 1, 1000, 1, 0)]
public int ShortPeriod { get; set; } = 14;
[InputParameter("Long Period", sortIndex: 2, 0, 1000, 1, 0)]
public int LongPeriod { get; set; } = 0;
[InputParameter("Alpha", sortIndex: 3, 0.01, 1, 0.01, 2)]
public double Alpha { get; set; } = 0.2;
[InputParameter("Data source", sortIndex: 4, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Vidya? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"VIDYA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => LongPeriod == 0 ? ShortPeriod * 4 : LongPeriod;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public VidyaIndicator() : base()
public VidyaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "VIDYA - Variable Index Dynamic Average";
Description = "Adaptive moving average that adjusts based on market volatility for improved trend following.";
Description = "Variable Index Dynamic Average";
Series = new(name: $"VIDYA {ShortPeriod}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Vidya(Period, LPeriod, Alpha);
base.InitIndicator();
ma = new Vidya(ShortPeriod, LongPeriod, Alpha);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"VIDYA {ShortPeriod}:{LongPeriod}:{Alpha}:{SourceName}";
}
+45 -11
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class WmaIndicator : IndicatorBase
public class WmaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Wma? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"WMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public WmaIndicator() : base()
public WmaIndicator()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "WMA - Weighted Moving Average";
Description = "Moving average that assigns higher weights to recent data points for improved responsiveness.";
Description = "Weighted Moving Average";
Series = new(name: $"WMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Wma(Period);
base.InitIndicator();
ma = new Wma(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"WMA {Periods}:{SourceName}";
}
+46 -12
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class ZlemaIndicator : IndicatorBase
public class ZlemaIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 14;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Zlema? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"ZLEMA {Period} : {SourceName}";
protected LineSeries? Series;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public ZlemaIndicator() : base()
public ZlemaIndicator()
{
Name = "ZLEMA - Zero-Lag Exponential Moving Average";
Description = "EMA variant that reduces lag by using linear extrapolation, providing faster response to price changes.";
OnBackGround = true;
SeparateWindow = false;
SourceName = Source.ToString();
Name = "ZLEMA - Zero Lag Exponential Moving Average";
Description = "Zero Lag Exponential Moving Average";
Series = new(name: $"ZLEMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void InitIndicator()
protected override void OnInit()
{
base.InitIndicator();
ma = new Zlema(Period);
ma = new Zlema(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetValue(result.Value);
}
public override string ShortName => $"ZLEMA {Periods}:{SourceName}";
}
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Averages</AssemblyName>
<AlgoType>Indicator</AlgoType>
<OutputPath>bin\$(Configuration)\</OutputPath>
<IsLocalBuild Condition="'$(GITHUB_ACTIONS)' == ''">true</IsLocalBuild>
@@ -14,7 +15,8 @@
<ItemGroup>
<Compile Include="..\*.cs" />
<Compile Include="*.cs" />
<ProjectReference Include="..\..\lib\quantalib.csproj" Private="true" IncludeAssets="all" />
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\bin\**;..\..\lib\obj\**" />
<Reference Include="TradingPlatform.BusinessLayer">
<HintPath>..\..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
</Reference>
+148
View File
@@ -0,0 +1,148 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace QuanTAlib;
public enum SourceType
{
Open, High, Low, Close, HL2, OC2, OHL3, HLC3, OHLC4, HLCC4
}
public static class IndicatorExtensions
{
public static TValue GetInputValue(this Indicator indicator, UpdateArgs args, SourceType source)
{
var historicalData = indicator.HistoricalData;
TBar bar = new TBar(
Time: historicalData.Time(),
Open: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Open],
High: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.High],
Low: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Low],
Close: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Close],
Volume: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Volume],
IsNew: args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar
);
double price = source switch
{
SourceType.Open => bar.Open,
SourceType.High => bar.High,
SourceType.Low => bar.Low,
SourceType.Close => bar.Close,
SourceType.HL2 => bar.HL2,
SourceType.OC2 => bar.OC2,
SourceType.OHL3 => bar.OHL3,
SourceType.HLC3 => bar.HLC3,
SourceType.OHLC4 => bar.OHLC4,
SourceType.HLCC4 => bar.HLCC4,
_ => bar.Close
};
return new TValue(bar.Time, price, bar.IsNew);
}
public static TBar GetInputBar(this Indicator indicator, UpdateArgs args)
{
var historicalData = indicator.HistoricalData;
return new TBar(
Time: historicalData.Time(),
Open: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Open],
High: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.High],
Low: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Low],
Close: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Close],
Volume: historicalData[indicator.Count - 1, SeekOriginHistory.Begin][PriceType.Volume],
IsNew: args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar
);
}
#pragma warning disable CA1416 // Validate platform compatibility
public static void PaintSmoothCurve(this Indicator indicator, PaintChartEventArgs args, LineSeries series, int warmupPeriod, bool showColdValues = true, double tension = 0.2)
{
if (!series.Visible || indicator.CurrentChart == null)
return;
Graphics gr = args.Graphics;
var mainWindow = indicator.CurrentChart.MainWindow;
var converter = mainWindow.CoordinatesConverter;
var clientRect = mainWindow.ClientRectangle;
gr.SetClip(clientRect);
DateTime leftTime = new[] { converter.GetTime(clientRect.Left), indicator.HistoricalData.Time(indicator!.Count - 1) }.Max();
DateTime rightTime = new[] { converter.GetTime(clientRect.Right), indicator.HistoricalData.Time(0) }.Min();
int leftIndex = (int)indicator.HistoricalData.GetIndexByTime(leftTime.Ticks) + 1;
int rightIndex = (int)indicator.HistoricalData.GetIndexByTime(rightTime.Ticks);
List<Point> allPoints = new List<Point>();
for (int i = rightIndex; i < leftIndex; i++)
{
int barX = (int)converter.GetChartX(indicator.HistoricalData.Time(i));
int barY = (int)converter.GetChartY(series[i]);
int halfBarWidth = indicator.CurrentChart.BarsWidth / 2;
Point point = new Point(barX + halfBarWidth, barY);
allPoints.Add(point);
}
if (allPoints.Count > 1)
{
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 })
{
int hotCount = indicator.Count - warmupPeriod - rightIndex;
// 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)tension);
}
// 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)tension);
}
}
}
}
public static void DrawText(this Indicator indicator, PaintChartEventArgs args, string text)
{
if (indicator.CurrentChart == null)
return;
Graphics gr = args.Graphics;
var clientRect = indicator.CurrentChart.MainWindow.ClientRectangle;
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(Brushes.DarkBlue, textRect);
gr.DrawString(text, font, Brushes.White, new PointF(textRect.X + 6, textRect.Y + 5));
}
private static 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,
};
}
}
+48 -10
View File
@@ -1,25 +1,63 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class CurvatureIndicator : IndicatorBase
public class CurvatureIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 3, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Curvature? curvature;
protected override AbstractBase QuanTAlib => curvature!;
public override string ShortName => $"CURVATURE {Period} : {SourceName}";
protected LineSeries? CurvatureSeries;
protected LineSeries? LineSeries;
protected string? SourceName;
public int MinHistoryDepths => Periods * 2 - 1;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public CurvatureIndicator()
{
Name = "CURVATURE - Rate of Change of Slope";
Description = "Measures the rate of change of the slope, indicating acceleration or deceleration in price movement.";
Name = "Curvature";
Description = "Calculates the rate of change of the slope over a specified period";
SeparateWindow = true;
SourceName = Source.ToString();
CurvatureSeries = new("Curvature", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(CurvatureSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
curvature = new(Period);
MinHistoryDepths = curvature.WarmupPeriod;
curvature = new Curvature(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = curvature!.Calc(input);
CurvatureSeries!.SetValue(result.Value);
if (curvature.Line.HasValue)
{
LineSeries!.SetValue(curvature.Line.Value);
}
}
public override string ShortName => $"Curvature ({Periods}:{SourceName})";
}
+44 -12
View File
@@ -1,26 +1,58 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class EntropyIndicator : IndicatorBase
public class EntropyIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Entropy? entropy;
protected override AbstractBase QuanTAlib => entropy!;
public override string ShortName => $"ENTROPY {Period} : {SourceName}";
protected LineSeries? EntropySeries;
protected string? SourceName;
public int MinHistoryDepths => 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public EntropyIndicator() : base()
public EntropyIndicator()
{
Name = "ENTROPY - Entropy";
Description = "Measures the randomness or uncertainty in price movements, useful for identifying market phases.";
Name = "Entropy";
Description = "Measures the unpredictability of data using Shannon's Entropy";
SeparateWindow = true;
SourceName = Source.ToString();
EntropySeries = new("Entropy", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(EntropySeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
entropy = new(Period);
MinHistoryDepths = entropy.WarmupPeriod;
base.InitIndicator();
entropy = new Entropy(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = entropy!.Calc(input);
EntropySeries!.SetValue(result.Value);
}
public override string ShortName => $"Entropy ({Periods}:{SourceName})";
}
+44 -12
View File
@@ -1,26 +1,58 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class KurtosisIndicator : IndicatorBase
public class KurtosisIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 4, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 4, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Kurtosis? kurtosis;
protected override AbstractBase QuanTAlib => kurtosis!;
public override string ShortName => $"KURTOSIS {Period} : {SourceName}";
protected LineSeries? KurtosisSeries;
protected string? SourceName;
public int MinHistoryDepths => Periods - 1;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public KurtosisIndicator() : base()
public KurtosisIndicator()
{
Name = "KURTOSIS - Relative Flatness";
Description = "Measures the 'tailedness' of price distribution, indicating potential for extreme market movements.";
Name = "Kurtosis";
Description = "Measures the 'tailedness' of the probability distribution of a real-valued random variable";
SeparateWindow = true;
SourceName = Source.ToString();
KurtosisSeries = new("Kurtosis", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(KurtosisSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
kurtosis = new(Period);
MinHistoryDepths = kurtosis.WarmupPeriod;
base.InitIndicator();
kurtosis = new Kurtosis(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = kurtosis!.Calc(input);
KurtosisSeries!.SetValue(result.Value);
}
public override string ShortName => $"Kurtosis ({Periods}:{SourceName})";
}
+48 -16
View File
@@ -1,29 +1,61 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MaxIndicator : IndicatorBase
public class MaxIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Decay to mean", sortIndex: 1, minimum: 0.00, maximum: 100.0, increment: 0.01, decimalPlaces: 2)]
public double Decay { get; set; } = 0.1;
[InputParameter("Decay", sortIndex: 2, 0, 10, 0.01, 2)]
public double Decay { get; set; } = 0;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.High;
private Max? ma;
protected override AbstractBase QuanTAlib => ma!;
public override string ShortName => $"MAX {Period} : {Decay:F2} : {SourceName}";
protected LineSeries? MaxSeries;
protected string? SourceName;
public int MinHistoryDepths => 0;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MaxIndicator() : base()
public MaxIndicator()
{
Name = "MAX - Maximum value (with decay)";
Description = "Tracks the maximum value over a period, with a decay factor to gradually adjust to new highs.";
Name = "Max";
Description = "Calculates the maximum value over a specified period, with an optional decay factor";
SeparateWindow = false;
SourceName = Source.ToString();
MaxSeries = new("Max", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(MaxSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
ma = new Max(Period, Decay);
MinHistoryDepths = ma.WarmupPeriod;
Source = 2;
base.InitIndicator();
ma = new Max(Periods, Decay);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
MaxSeries!.SetValue(result.Value);
}
public override string ShortName => $"Max ({Periods}, {Decay:F2}:{SourceName})";
}
+47 -13
View File
@@ -1,24 +1,58 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MedianIndicator : IndicatorBase
public class MedianIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Median? med;
protected override AbstractBase QuanTAlib => med!;
public override string ShortName => $"MEDIAN {Period} : {SourceName}";
public MedianIndicator() : base()
protected LineSeries? MedianSeries;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MedianIndicator()
{
Name = "MEDIAN - Median historical value";
Description = "Calculates the middle value of price data over a specified period, less affected by outliers than mean.";
Name = "Median";
Description = "Calculates the median value over a specified period";
SeparateWindow = false;
SourceName = Source.ToString();
MedianSeries = new("Median", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(MedianSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
med = new Median(Period);
MinHistoryDepths = med.WarmupPeriod;
base.InitIndicator();
med = new Median(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = med!.Calc(input);
MedianSeries!.SetValue(result.Value);
}
public override string ShortName => $"Median ({Periods}:{SourceName})";
}
+49 -16
View File
@@ -1,28 +1,61 @@
using TradingPlatform.BusinessLayer;
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class MinIndicator : IndicatorBase
public class MinIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Decay to mean", sortIndex: 1, minimum: 0.00, maximum: 100.0, increment: 0.01, decimalPlaces: 2)]
public double Decay { get; set; } = 0.1;
[InputParameter("Decay", sortIndex: 2, 0, 10, 0.01, 2)]
public double Decay { get; set; } = 0;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Low;
private Min? mi;
protected override AbstractBase QuanTAlib => mi!;
public override string ShortName => $"MIN {Period} : {Decay:F2} : {SourceName}";
public MinIndicator() : base()
protected LineSeries? MinSeries;
protected string? SourceName;
public int MinHistoryDepths => 0;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public MinIndicator()
{
Name = "MIN - Minimum value (with decay)";
Description = "Tracks the minimum value over a period, with a decay factor to gradually adjust to new lows.";
Name = "Min";
Description = "Calculates the minimum value over a specified period, with an optional decay factor";
SeparateWindow = false;
SourceName = Source.ToString();
MinSeries = new("Min", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(MinSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
mi = new Min(Period, Decay);
MinHistoryDepths = mi.WarmupPeriod;
Source = 3;
base.InitIndicator();
mi = new Min(Periods, Decay);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = mi!.Calc(input);
MinSeries!.SetValue(result.Value);
}
public override string ShortName => $"Min ({Periods}, {Decay:F2}:{SourceName})";
}
+46 -12
View File
@@ -1,24 +1,58 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class ModeIndicator : IndicatorBase
public class ModeIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 50;
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Mode? mode;
protected override AbstractBase QuanTAlib => mode!;
public override string ShortName => $"MODE {Period} : {SourceName}";
public ModeIndicator() : base()
protected LineSeries? ModeSeries;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public ModeIndicator()
{
Name = "MODE - Most frequent historical value";
Description = "Identifies the most frequently occurring price value over a specified period, indicating price clusters.";
Name = "Mode";
Description = "Calculates the most frequent value in a specified period";
SeparateWindow = false;
SourceName = Source.ToString();
ModeSeries = new("Mode", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(ModeSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
mode = new Mode(Period);
MinHistoryDepths = mode.WarmupPeriod;
base.InitIndicator();
mode = new Mode(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = mode!.Calc(input);
ModeSeries!.SetValue(result.Value);
}
public override string ShortName => $"Mode ({Periods}:{SourceName})";
}
+49 -16
View File
@@ -1,28 +1,61 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace 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;
namespace QuanTAlib;
public class PercentileIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Percentile", sortIndex: 2, 0, 100, 0.1, 1)]
public double PercentileValue { get; set; } = 50;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Percentile? percentile;
protected override AbstractBase QuanTAlib => percentile!;
public override string ShortName => $"PERCENTILE {Period} {Percent:F0}% : {SourceName}";
protected LineSeries? PercentileSeries;
protected string? SourceName;
public int MinHistoryDepths => 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public PercentileIndicator() : base()
public PercentileIndicator()
{
Name = "PERCENTILE - n-th Percentile";
Description = "Calculates the value below which a given percentage of observations falls within a specified period.";
Name = "Percentile";
Description = "Calculates the value at a specified percentile in a given period of data points";
SeparateWindow = false;
SourceName = Source.ToString();
PercentileSeries = new("Percentile", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(PercentileSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
percentile = new(Period, Percent);
MinHistoryDepths = percentile.WarmupPeriod;
base.InitIndicator();
percentile = new Percentile(Periods, PercentileValue);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = percentile!.Calc(input);
PercentileSeries!.SetValue(result.Value);
}
public override string ShortName => $"Percentile ({Periods}, {PercentileValue}%:{SourceName})";
}
+44 -12
View File
@@ -1,26 +1,58 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class SkewIndicator : IndicatorBase
public class SkewIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 3, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 3, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Skew? skew;
protected override AbstractBase QuanTAlib => skew!;
public override string ShortName => $"SKEW {Period} : {SourceName}";
protected LineSeries? SkewSeries;
protected string? SourceName;
public int MinHistoryDepths => 3;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public SkewIndicator() : base()
public SkewIndicator()
{
Name = "SKEW - Skewness";
Description = "Measures the asymmetry of price distribution, indicating potential trend direction or reversal.";
Name = "Skew";
Description = "Measures the asymmetry of the probability distribution of a real-valued random variable about its mean";
SeparateWindow = true;
SourceName = Source.ToString();
SkewSeries = new("Skew", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(SkewSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
skew = new(Period);
MinHistoryDepths = skew.WarmupPeriod;
base.InitIndicator();
skew = new Skew(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = skew!.Calc(input);
SkewSeries!.SetValue(result.Value);
}
public override string ShortName => $"Skew ({Periods}:{SourceName})";
}
+67 -10
View File
@@ -1,25 +1,82 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class SlopeIndicator : IndicatorBase
public class SlopeIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Slope? slope;
protected override AbstractBase QuanTAlib => slope!;
public override string ShortName => $"SLOPE {Period} : {SourceName}";
protected LineSeries? SlopeSeries;
protected LineSeries? LineSeries;
protected string? SourceName;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public SlopeIndicator()
{
Name = "SLOPE - Trend Slope";
Description = "Measures the rate of change in price over a specified period, indicating trend strength and direction.";
Name = "Slope";
Description = "Calculates the slope of a linear regression line for the specified period";
SeparateWindow = true;
SourceName = Source.ToString();
SlopeSeries = new("Slope", Color.Blue, 2, LineStyle.Solid);
LineSeries = new("Regression Line", Color.Red, 1, LineStyle.Solid);
AddLineSeries(SlopeSeries);
AddLineSeries(LineSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
slope = new(Period);
MinHistoryDepths = slope.WarmupPeriod;
slope = new Slope(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = slope!.Calc(input);
SlopeSeries!.SetValue(result.Value);
if (slope.Line.HasValue)
{
LineSeries!.SetValue(slope.Line.Value);
}
}
public override string ShortName
{
get
{
var result = $"Slope ({Periods}:{SourceName})";
if (slope != null)
{
result += $" Slope: {Math.Round(SlopeSeries!.GetValue(), 6)}";
if (slope.Line.HasValue)
result += $", Line: {Math.Round(slope.Line.Value, 6)}";
if (slope.Intercept.HasValue)
result += $", Intercept: {Math.Round(slope.Intercept.Value, 6)}";
if (slope.RSquared.HasValue)
result += $", R²: {Math.Round(slope.RSquared.Value, 6)}";
}
return result;
}
}
}
+45 -12
View File
@@ -1,28 +1,61 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class StddevIndicator : IndicatorBase
public class StddevIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Population", sortIndex: 2)]
public bool IsPopulation { get; set; } = false;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Stddev? stddev;
protected override AbstractBase QuanTAlib => stddev!;
public override string ShortName => $"STDDEV {Period} : {SourceName}";
public StddevIndicator() : base()
protected LineSeries? StddevSeries;
protected string? SourceName;
public int MinHistoryDepths => 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public StddevIndicator()
{
Name = "STDDEV - Standard Deviation";
Description = "Measures price volatility by calculating the dispersion of prices from their average over a period.";
Name = "Standard Deviation";
Description = "Measures the amount of variation or dispersion of a set of values";
SeparateWindow = true;
SourceName = Source.ToString();
StddevSeries = new("StdDev", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(StddevSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
stddev = new(Period, IsPopulation);
MinHistoryDepths = stddev.WarmupPeriod;
base.InitIndicator();
stddev = new Stddev(Periods, IsPopulation);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = stddev!.Calc(input);
StddevSeries!.SetValue(result.Value);
}
public override string ShortName => $"StdDev ({Periods}, {(IsPopulation ? "Pop" : "Sample")}:{SourceName})";
}
+45 -13
View File
@@ -1,29 +1,61 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class VarianceIndicator : IndicatorBase
public class VarianceIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, minimum: 2, maximum: 2000, increment: 1, decimalPlaces: 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 2, 1000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Population", sortIndex: 2)]
public bool IsPopulation { get; set; } = false;
[InputParameter("Data source", sortIndex: 3, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Variance? variance;
protected override AbstractBase QuanTAlib => variance!;
public override string ShortName => $"VAR {Period} : {SourceName}";
public VarianceIndicator() : base()
protected LineSeries? VarianceSeries;
protected string? SourceName;
public int MinHistoryDepths => 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public VarianceIndicator()
{
Name = "VAR - Variance";
Description = "Measures the spread of price data around its mean, indicating volatility and potential trend changes.";
Name = "Variance";
Description = "Measures the spread of a set of numbers from their average value";
SeparateWindow = true;
SourceName = Source.ToString();
VarianceSeries = new("Variance", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(VarianceSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
SeparateWindow = true;
variance = new(Period, IsPopulation);
MinHistoryDepths = variance.WarmupPeriod;
base.InitIndicator();
variance = new Variance(Periods, IsPopulation);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = variance!.Calc(input);
VarianceSeries!.SetValue(result.Value);
}
public override string ShortName => $"Variance ({Periods}, {(IsPopulation ? "Pop" : "Sample")}:{SourceName})";
}
+43 -11
View File
@@ -1,26 +1,58 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class ZScoreIndicator : IndicatorBase
public class ZscoreIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 2, 2000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Data source", sortIndex: 2, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
private Zscore? zScore;
protected override AbstractBase QuanTAlib => zScore!;
public override string ShortName => $"ZSCORE {Period} : {SourceName}";
protected LineSeries? ZscoreSeries;
protected string? SourceName;
public int MinHistoryDepths => 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public ZScoreIndicator() : base()
public ZscoreIndicator()
{
Name = "ZSCORE - Standard Score";
Name = "Z-Score";
Description = "Measures how many standard deviations a price is from the mean, indicating overbought/oversold levels.";
SeparateWindow = true;
SourceName = Source.ToString();
ZscoreSeries = new("Z-Score", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(ZscoreSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
zScore = new(Period);
MinHistoryDepths = zScore.WarmupPeriod;
base.InitIndicator();
zScore = new Zscore(Periods);
SourceName = Source.ToString();
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = zScore!.Calc(input);
ZscoreSeries!.SetValue(result.Value);
}
public override string ShortName => $"Z-Score ({Periods}:{SourceName})";
}
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Statistics</AssemblyName>
<AlgoType>Indicator</AlgoType>
<OutputPath>bin\$(Configuration)\</OutputPath>
<IsLocalBuild Condition="'$(GITHUB_ACTIONS)' == ''">true</IsLocalBuild>
@@ -14,7 +15,7 @@
<ItemGroup>
<Compile Include="..\*.cs" />
<Compile Include="*.cs" />
<ProjectReference Include="..\..\lib\quantalib.csproj" Private="true" IncludeAssets="all" />
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\bin\**;..\..\lib\obj\**" />
<Reference Include="TradingPlatform.BusinessLayer">
<HintPath>..\..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
</Reference>
+25 -8
View File
@@ -1,24 +1,41 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class AtrIndicator : IndicatorBarBase
public class AtrIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 1, 2000, 1, 0)]
public int Periods { get; set; } = 20;
private Atr? atr;
protected override AbstractBase QuanTAlib => atr!;
public override string ShortName => $"ATR {Period}";
protected LineSeries? AtrSeries;
public int MinHistoryDepths => 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public AtrIndicator()
{
Name = "ATR - Average True Range";
Description = "Measures market volatility by calculating the average range between high and low prices.";
SeparateWindow = true;
AtrSeries = new("ATR", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(AtrSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
atr = new(Period);
MinHistoryDepths = atr!.WarmupPeriod;
atr = new Atr(Periods);
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TBar input = IndicatorExtensions.GetInputBar(this, args);
TValue result = atr!.Calc(input);
AtrSeries!.SetValue(result.Value);
}
public override string ShortName => $"ATR ({Periods})";
}
+25 -10
View File
@@ -1,29 +1,44 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class HistoricalIndicator : IndicatorBase
public class HistoricalIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 1, 2000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Annualized", sortIndex: 2)]
public bool IsAnnualized { get; set; } = true;
private Historical? historical;
protected override AbstractBase QuanTAlib => historical!;
public override string ShortName => $"Historical Volatility {Period}{(IsAnnualized ? " - Annualized" : "")} : {SourceName}";
protected LineSeries? HvSeries;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public HistoricalIndicator() : base()
public HistoricalIndicator()
{
Name = "HV - Historical Volatility";
Description = "Measures price fluctuations over time, indicating market volatility based on past price movements.";
SeparateWindow = true;
HvSeries = new("HV", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(HvSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
historical = new(Period, IsAnnualized);
MinHistoryDepths = historical.WarmupPeriod;
base.InitIndicator();
historical = new Historical(Periods, IsAnnualized);
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TBar input = IndicatorExtensions.GetInputBar(this, args);
TValue result = historical!.Calc(input);
HvSeries!.SetValue(result.Value);
}
public override string ShortName => $"HV ({Periods}{(IsAnnualized ? " - Annualized" : "")})";
}
+25 -10
View File
@@ -1,29 +1,44 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class RealizedIndicator : IndicatorBase
public class RealizedIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 20;
[InputParameter("Periods", sortIndex: 1, 1, 2000, 1, 0)]
public int Periods { get; set; } = 20;
[InputParameter("Annualized", sortIndex: 2)]
public bool IsAnnualized { get; set; } = true;
private Realized? realized;
protected override AbstractBase QuanTAlib => realized!;
public override string ShortName => $"Realized Volatility {Period}{(IsAnnualized ? " - Annualized" : "")} : {SourceName}";
protected LineSeries? RvSeries;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public RealizedIndicator() : base()
public RealizedIndicator()
{
Name = "RV - Realized Volatility";
Description = "Measures actual price volatility over a specific period, useful for risk assessment and forecasting.";
SeparateWindow = true;
RvSeries = new("RV", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(RvSeries);
}
protected override void InitIndicator()
protected override void OnInit()
{
realized = new(Period, IsAnnualized);
MinHistoryDepths = realized.WarmupPeriod;
base.InitIndicator();
realized = new Realized(Periods, IsAnnualized);
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TBar input = IndicatorExtensions.GetInputBar(this, args);
TValue result = realized!.Calc(input);
RvSeries!.SetValue(result.Value);
}
public override string ShortName => $"RV ({Periods}{(IsAnnualized ? " - Annualized" : "")})";
}
+27 -12
View File
@@ -1,26 +1,41 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class RviIndicator : IndicatorBase
public class RviIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 2, 100, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Periods", sortIndex: 1, 2, 100, 1, 0)]
public int Periods { get; set; } = 10;
private Rvi? rvi;
protected override AbstractBase QuanTAlib => rvi!;
public override string ShortName => $"RVI {Period} : {SourceName}";
protected LineSeries? RviSeries;
public int MinHistoryDepths => Periods;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public RviIndicator() : base()
public RviIndicator()
{
Name = "RVI - Relative Volatility Index";
Description = "Measures the direction of volatility, helping to identify overbought or oversold conditions in price.";
SeparateWindow = true;
}
protected override void InitIndicator()
{
rvi = new Rvi(Period);
MinHistoryDepths = rvi.WarmupPeriod;
base.InitIndicator();
RviSeries = new("RVI", Color.Blue, 2, LineStyle.Solid);
AddLineSeries(RviSeries);
}
protected override void OnInit()
{
rvi = new Rvi(Periods);
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TBar input = IndicatorExtensions.GetInputBar(this, args);
TValue result = rvi!.Calc(input);
RviSeries!.SetValue(result.Value);
}
public override string ShortName => $"RVI ({Periods})";
}
+66
View File
@@ -0,0 +1,66 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class TestIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
public int Period { get; set; } = 10;
[InputParameter("Data source", sortIndex: 20, variants: [
"Open", SourceType.Open,
"High", SourceType.High,
"Low", SourceType.Low,
"Close", SourceType.Close,
"HL/2 (Median)", SourceType.HL2,
"OC/2 (Midpoint)", SourceType.OC2,
"OHL/3 (Mean)", SourceType.OHL3,
"HLC/3 (Typical)", SourceType.HLC3,
"OHLC/4 (Average)", SourceType.OHLC4,
"HLCC/4 (Weighted)", SourceType.HLCC4
])]
public SourceType Source { get; set; } = SourceType.Close;
[InputParameter("Show cold values", sortIndex: 21)]
public bool ShowColdValues { get; set; } = true;
private Sma? ma;
protected LineSeries? Series;
//protected string? SourceName;
public int MinHistoryDepths { get; set; }
int IWatchlistIndicator.MinHistoryDepths => 0; //QuanTAlib indicators generate value immediately
public TestIndicator()
{
OnBackGround = true;
SeparateWindow = false;
Name = "TEST";
Description = "test and test and test and more test.";
Series = new(name: $"{Name}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected override void OnInit()
{
ma = new Sma(Period);
base.OnInit();
}
protected override void OnUpdate(UpdateArgs args)
{
TValue input = this.GetInputValue(args, Source);
TValue result = ma!.Calc(input);
Series!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
Series!.SetValue(result);
}
public override void OnPaintChart(PaintChartEventArgs args)
{
base.OnPaintChart(args);
this.PaintSmoothCurve(args, Series!, ma!.WarmupPeriod, ShowColdValues, tension: 0.2);
this.DrawText(args, Description);
}
}
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>Volatility</AssemblyName>
<AlgoType>Indicator</AlgoType>
<OutputPath>bin\$(Configuration)\</OutputPath>
<IsLocalBuild Condition="'$(GITHUB_ACTIONS)' == ''">true</IsLocalBuild>
@@ -14,7 +15,8 @@
<ItemGroup>
<Compile Include="..\*.cs" />
<Compile Include="*.cs" />
<ProjectReference Include="..\..\lib\quantalib.csproj" Private="true" IncludeAssets="all" />
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\bin\**;..\..\lib\obj\**" />
<Reference Include="TradingPlatform.BusinessLayer">
<HintPath>..\..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
</Reference>
-135
View File
@@ -1,135 +0,0 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
using TradingPlatform.BusinessLayer.Chart;
using System.Runtime.CompilerServices;
using System.Drawing.Drawing2D;
using System.Collections;
using TradingPlatform.BusinessLayer.TimeSync;
namespace QuanTAlib;
#pragma warning disable CA1416 // Validate platform compatibility
public abstract class IndicatorBarBase : Indicator, IWatchlistIndicator
{
[InputParameter("Show cold values", sortIndex: 20)]
public bool ShowColdValues { get; set; } = true;
public int MinHistoryDepths { get; set; }
// LineSeries.LineSeries(string, Color, int, LineStyle)'
protected LineSeries? Series;
protected abstract AbstractBase QuanTAlib { get; }
int IWatchlistIndicator.MinHistoryDepths => 0;
protected IndicatorBarBase()
{
OnBackGround = true;
SeparateWindow = false;
Series = new(name: $"{Name}", color: Color.RoyalBlue, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
protected abstract void InitIndicator();
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);
TValue result = QuanTAlib.Calc(bar);
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(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 static 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 static void DrawText(Graphics gr, string text, Rectangle clientRect)
{
Font font = new("Inter", 8);
SizeF textSize = gr.MeasureString(text, font);
RectangleF textRect = new(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));
}
}
-188
View File
@@ -1,188 +0,0 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
using TradingPlatform.BusinessLayer.Chart;
using System.Runtime.CompilerServices;
using System.Drawing.Drawing2D;
using System.Collections;
using TradingPlatform.BusinessLayer.TimeSync;
namespace QuanTAlib;
#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 { get; set; }
// LineSeries.LineSeries(string, Color, int, LineStyle)'
protected LineSeries? Series;
protected string SourceName;
protected abstract AbstractBase QuanTAlib { get; }
int IWatchlistIndicator.MinHistoryDepths => 0;
protected IndicatorBase()
{
OnBackGround = true;
SeparateWindow = false;
SourceName = GetName(Source);
Series = new(name: $"{Name}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
AddLineSeries(Series);
}
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.2);
}
// 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.2);
}
}
}
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"
};
}
}