mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-04 12:07:44 +00:00
refresh with new QT DLL
This commit is contained in:
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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
@@ -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}
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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" : "")})";
|
||||
}
|
||||
|
||||
@@ -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" : "")})";
|
||||
}
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user