diff --git a/Sources/Common/MSLib/HmaSma.cs b/Sources/Common/MSLib/HmaSma.cs
new file mode 100644
index 0000000..2e8d88a
--- /dev/null
+++ b/Sources/Common/MSLib/HmaSma.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+
+namespace Myc.HmaSma
+{
+ ///
+ /// DTO representing a single row in the HMA/SMA configuration file.
+ ///
+ public class HmaSmaParameters
+ {
+ // Initialized to string.Empty to satisfy CS8618
+ public string Symbol { get; set; } = string.Empty;
+ public string Timeframe { get; set; } = string.Empty;
+ public double EntrySig { get; set; }
+ public double SlSig { get; set; }
+ public int SmaBias { get; set; }
+ public int HmaBias { get; set; }
+ public int HmaCluster { get; set; }
+ public bool BiasFilter { get; set; }
+ public int BiasAvg { get; set; }
+ public bool DynMgmt { get; set; }
+ public bool TelegramOnly { get; set; }
+
+ public override string ToString()
+ {
+ return $"{Symbol} {Timeframe}: SMA={SmaBias}, HMA={HmaBias}, Cluster={HmaCluster}";
+ }
+ }
+
+ ///
+ /// Handles parsing and caching of HMA/SMA configuration files.
+ ///
+ public class HmaSmaLoader
+ {
+ // Key: "SYMBOL_TIMEFRAME" (Normalized to UpperCase)
+ private readonly Dictionary _cache = new Dictionary();
+ private readonly string _filePath;
+
+ public HmaSmaLoader(string filePath)
+ {
+ _filePath = filePath;
+ }
+
+ ///
+ /// Reads the file and populates the internal cache.
+ /// Throws FileNotFoundException if file is missing.
+ /// Returns number of successfully loaded entries.
+ ///
+ public int Load()
+ {
+ _cache.Clear();
+
+ if (!File.Exists(_filePath))
+ throw new FileNotFoundException($"Config file not found: {_filePath}");
+
+ var lines = File.ReadAllLines(_filePath);
+ int loadedCount = 0;
+
+ foreach (var line in lines)
+ {
+ var trimmed = line.Trim();
+ if (string.IsNullOrWhiteSpace(trimmed) || trimmed.StartsWith("#"))
+ continue;
+
+ // Split by whitespace (tabs or spaces)
+ var cols = trimmed.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
+
+ // Ensure we have at least 11 columns based on specification
+ if (cols.Length < 11)
+ continue;
+
+ try
+ {
+ var param = new HmaSmaParameters
+ {
+ Symbol = cols[0],
+ Timeframe = cols[1],
+ EntrySig = double.Parse(cols[2], CultureInfo.InvariantCulture),
+ SlSig = double.Parse(cols[3], CultureInfo.InvariantCulture),
+ SmaBias = int.Parse(cols[4], CultureInfo.InvariantCulture),
+ HmaBias = int.Parse(cols[5], CultureInfo.InvariantCulture),
+ HmaCluster = int.Parse(cols[6], CultureInfo.InvariantCulture),
+ BiasFilter = bool.Parse(cols[7]),
+ BiasAvg = int.Parse(cols[8], CultureInfo.InvariantCulture),
+ DynMgmt = bool.Parse(cols[9]),
+ TelegramOnly = bool.Parse(cols[10])
+ };
+
+ string key = BuildKey(param.Symbol, param.Timeframe);
+
+ // Overwrite duplicates if they exist lower in the file
+ _cache[key] = param;
+ loadedCount++;
+ }
+ catch (Exception)
+ {
+ // Fail silently for single bad lines, or log if logger provided.
+ // For library code, we skip invalid lines to ensure robustness.
+ continue;
+ }
+ }
+
+ return loadedCount;
+ }
+
+ ///
+ /// Retrieves configuration for a specific symbol and timeframe.
+ /// Returns null if not found.
+ ///
+ public HmaSmaParameters? GetParameters(string symbol, string timeframe)
+ {
+ string key = BuildKey(symbol, timeframe);
+ return _cache.TryGetValue(key, out var parameters) ? parameters : null;
+ }
+
+ private static string BuildKey(string symbol, string timeframe)
+ {
+ return $"{symbol.ToUpperInvariant()}_{timeframe.ToUpperInvariant()}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Common/MSLib/MSLib.sln b/Sources/Common/MSLib/MSLib.sln
new file mode 100644
index 0000000..79faa5c
--- /dev/null
+++ b/Sources/Common/MSLib/MSLib.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSLib", "MSLib.csproj", "{35379097-39C9-E3AB-CA26-4A355536E164}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {35379097-39C9-E3AB-CA26-4A355536E164}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {35379097-39C9-E3AB-CA26-4A355536E164}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {35379097-39C9-E3AB-CA26-4A355536E164}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {35379097-39C9-E3AB-CA26-4A355536E164}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {63787C32-34FC-4DC2-99AD-98BEA2F486EC}
+ EndGlobalSection
+EndGlobal
diff --git a/Sources/Common/MSLib/SRCluster.cs b/Sources/Common/MSLib/SRCluster.cs
new file mode 100644
index 0000000..fc8f9f5
--- /dev/null
+++ b/Sources/Common/MSLib/SRCluster.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Generic;
+
+namespace Myc
+{
+ public enum PointType { Peak, Trough }
+
+ public struct ExtremumPoint
+ {
+ public double Price;
+ public int Index;
+ public PointType Type;
+ }
+
+ public struct ClusterZone
+ {
+ public double Price;
+ public double Score;
+ }
+
+ ///
+ /// Hochoptimierte Engine. Hält den State im Speicher, um GC-Allocations zu vermeiden.
+ /// Nutzt eine permanent preis-sortierte Liste für extrem schnelle Range-Abfragen.
+ ///
+ public class ClusterCalculator
+ {
+ // Permanente Buffer verhindern "new List<>" Zuweisungen pro Tick
+ private readonly List _priceSortedPoints;
+ private readonly List _candidatesBuffer;
+ private readonly List _resultsBuffer;
+
+ private readonly CandidateComparer _candidateComparer = new CandidateComparer();
+
+ // Status für effizientes Aufräumen (Pruning)
+ private int _lastPruneIndex = 0;
+ private const int PruneInterval = 100; // Nur alle 100 Bars aufräumen spart CPU
+
+ public ClusterCalculator(int capacity = 2000)
+ {
+ _priceSortedPoints = new List(capacity);
+ _candidatesBuffer = new List(capacity);
+ _resultsBuffer = new List(100);
+ }
+
+ ///
+ /// Fügt einen Punkt via BinarySearch ein, um die Sortierung beizubehalten (O(log N)).
+ ///
+ public void AddPoint(ExtremumPoint point)
+ {
+ int low = 0;
+ int high = _priceSortedPoints.Count - 1;
+
+ while (low <= high)
+ {
+ int mid = low + (high - low) / 2;
+ if (_priceSortedPoints[mid].Price < point.Price)
+ low = mid + 1;
+ else
+ high = mid - 1;
+ }
+
+ _priceSortedPoints.Insert(low, point);
+ }
+
+ ///
+ /// Entfernt alte Punkte. Nutzt einen effizienten "Swap-and-Cut" Algorithmus (O(N)),
+ /// statt langsamem RemoveAt in einer Schleife (O(N^2)).
+ ///
+ private void PruneOldPoints(int currentIndex, int decayPeriod)
+ {
+ int cutoffIndex = currentIndex - decayPeriod;
+ int writeIndex = 0;
+
+ // In-Place Filterung (vermeidet Array-Copies)
+ for (int i = 0; i < _priceSortedPoints.Count; i++)
+ {
+ if (_priceSortedPoints[i].Index >= cutoffIndex)
+ {
+ _priceSortedPoints[writeIndex] = _priceSortedPoints[i];
+ writeIndex++;
+ }
+ }
+
+ // Den Rest der Liste abschneiden
+ if (writeIndex < _priceSortedPoints.Count)
+ {
+ _priceSortedPoints.RemoveRange(writeIndex, _priceSortedPoints.Count - writeIndex);
+ }
+ }
+
+ public (List Zones, double TotalWeight) Calculate(
+ int currentIndex,
+ double currentPrice,
+ double range,
+ int decayPeriod,
+ int maxZones)
+ {
+ // 1. Internes Auto-Pruning (gedrosselt)
+ if (currentIndex - _lastPruneIndex >= PruneInterval)
+ {
+ PruneOldPoints(currentIndex, decayPeriod);
+ _lastPruneIndex = currentIndex;
+ }
+
+ _candidatesBuffer.Clear();
+ _resultsBuffer.Clear();
+
+ int count = _priceSortedPoints.Count;
+ if (count < 2) return (_resultsBuffer, 0.0);
+
+ double totalWeightSum = 0.0;
+
+ // 2. Sliding Window auf der sortierten Liste
+ // Da die Liste nach Preis sortiert ist, können wir Fenster [Center-Range, Center+Range] effizient finden.
+ int left = 0;
+ int right = 0;
+
+ for (int i = 0; i < count; i++)
+ {
+ var centerPt = _priceSortedPoints[i];
+ double centerWeight = GetWeight(centerPt, currentIndex, currentPrice, decayPeriod);
+
+ // Tote Punkte ignorieren (Micro-Optimierung)
+ if (centerWeight <= 0.001) continue;
+
+ totalWeightSum += centerWeight;
+
+ double minPrice = centerPt.Price - range;
+ double maxPrice = centerPt.Price + range;
+
+ // Fenster nach rechts erweitern
+ while (right < count && _priceSortedPoints[right].Price <= maxPrice)
+ {
+ right++;
+ }
+
+ // Fenster von links verkleinern
+ while (left < right && _priceSortedPoints[left].Price < minPrice)
+ {
+ left++;
+ }
+
+ // Gewichtung im Fenster summieren
+ double localScore = 0;
+ for (int k = left; k < right; k++)
+ {
+ localScore += GetWeight(_priceSortedPoints[k], currentIndex, currentPrice, decayPeriod);
+ }
+
+ if (localScore > 0.01)
+ {
+ _candidatesBuffer.Add(new ClusterZone
+ {
+ Price = centerPt.Price,
+ Score = localScore
+ });
+ }
+ }
+
+ // 3. Kandidaten sortieren (Allocation Free via Comparer)
+ _candidatesBuffer.Sort(_candidateComparer);
+
+ // 4. Überlappungen filtern
+ int candCount = _candidatesBuffer.Count;
+ for (int i = 0; i < candCount; i++)
+ {
+ if (_resultsBuffer.Count >= maxZones) break;
+
+ var cand = _candidatesBuffer[i];
+ bool overlaps = false;
+
+ int resCount = _resultsBuffer.Count;
+ for (int j = 0; j < resCount; j++)
+ {
+ if (Math.Abs(_resultsBuffer[j].Price - cand.Price) < range)
+ {
+ overlaps = true;
+ break;
+ }
+ }
+
+ if (!overlaps)
+ {
+ _resultsBuffer.Add(cand);
+ }
+ }
+
+ return (_resultsBuffer, totalWeightSum);
+ }
+
+ private double GetWeight(ExtremumPoint p, int currentIndex, double currentPrice, int decayPeriod)
+ {
+ double age = currentIndex - p.Index;
+ if (age > decayPeriod) return 0.0;
+
+ double w = 1.0 - (age / decayPeriod);
+ if (w < 0) return 0.0;
+
+ // Role Reversal Logic
+ if ((p.Type == PointType.Peak && p.Price < currentPrice) ||
+ (p.Type == PointType.Trough && p.Price > currentPrice))
+ {
+ w *= 2.0;
+ }
+ return w;
+ }
+
+ private class CandidateComparer : IComparer
+ {
+ public int Compare(ClusterZone x, ClusterZone y) => y.Score.CompareTo(x.Score);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.dll b/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.dll
index acf6f9a..cd7721a 100644
Binary files a/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.dll and b/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.dll differ
diff --git a/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.pdb b/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.pdb
index d1c06a6..227563f 100644
Binary files a/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.pdb and b/Sources/Common/MSLib/bin/Debug/net6.0/MSLib.pdb differ
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.GeneratedMSBuildEditorConfig.editorconfig b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.GeneratedMSBuildEditorConfig.editorconfig
index 4db8300..2387edc 100644
--- a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.GeneratedMSBuildEditorConfig.editorconfig
+++ b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.GeneratedMSBuildEditorConfig.editorconfig
@@ -7,4 +7,4 @@ build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = MSLib
-build_property.ProjectDir = C:\Users\Brummel\Documents\cAlgo\Sources\Common\MSLib\
+build_property.ProjectDir = c:\Users\Brummel\Documents\cAlgo\Sources\Common\MSLib\
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.assets.cache b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.assets.cache
index d7e1628..a98a7ac 100644
Binary files a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.assets.cache and b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.assets.cache differ
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.CoreCompileInputs.cache b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.CoreCompileInputs.cache
index 5a1c6bb..9bcdebf 100644
--- a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.CoreCompileInputs.cache
+++ b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-375eb7427a13a6a1a036f49ce73cc2a66452e118
+3ad9fabd4c4d10fabf7ae747a073d85bece381b1
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.FileListAbsolute.txt b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.FileListAbsolute.txt
index 71d3a6b..e94742d 100644
--- a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.FileListAbsolute.txt
+++ b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.csproj.FileListAbsolute.txt
@@ -10,3 +10,15 @@ C:\Users\Brummel\Documents\cAlgo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.dll
C:\Users\Brummel\Documents\cAlgo\Sources\Common\MSLib\obj\Debug\net6.0\refint\MSLib.dll
C:\Users\Brummel\Documents\cAlgo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.pdb
C:\Users\Brummel\Documents\cAlgo\Sources\Common\MSLib\obj\Debug\net6.0\ref\MSLib.dll
+t:\cTrader-Algo\Sources\Common\MSLib\bin\Debug\net6.0\MSLib.deps.json
+t:\cTrader-Algo\Sources\Common\MSLib\bin\Debug\net6.0\MSLib.dll
+t:\cTrader-Algo\Sources\Common\MSLib\bin\Debug\net6.0\MSLib.pdb
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.csproj.AssemblyReference.cache
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.GeneratedMSBuildEditorConfig.editorconfig
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.AssemblyInfoInputs.cache
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.AssemblyInfo.cs
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.csproj.CoreCompileInputs.cache
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.dll
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\refint\MSLib.dll
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\MSLib.pdb
+t:\cTrader-Algo\Sources\Common\MSLib\obj\Debug\net6.0\ref\MSLib.dll
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.dll b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.dll
index acf6f9a..cd7721a 100644
Binary files a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.dll and b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.dll differ
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.pdb b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.pdb
index d1c06a6..227563f 100644
Binary files a/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.pdb and b/Sources/Common/MSLib/obj/Debug/net6.0/MSLib.pdb differ
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/ref/MSLib.dll b/Sources/Common/MSLib/obj/Debug/net6.0/ref/MSLib.dll
index 00ff9d3..5a0174e 100644
Binary files a/Sources/Common/MSLib/obj/Debug/net6.0/ref/MSLib.dll and b/Sources/Common/MSLib/obj/Debug/net6.0/ref/MSLib.dll differ
diff --git a/Sources/Common/MSLib/obj/Debug/net6.0/refint/MSLib.dll b/Sources/Common/MSLib/obj/Debug/net6.0/refint/MSLib.dll
index 00ff9d3..5a0174e 100644
Binary files a/Sources/Common/MSLib/obj/Debug/net6.0/refint/MSLib.dll and b/Sources/Common/MSLib/obj/Debug/net6.0/refint/MSLib.dll differ
diff --git a/Sources/Common/MSLib/obj/MSLib.csproj.nuget.dgspec.json b/Sources/Common/MSLib/obj/MSLib.csproj.nuget.dgspec.json
index 103cb00..67ecc79 100644
--- a/Sources/Common/MSLib/obj/MSLib.csproj.nuget.dgspec.json
+++ b/Sources/Common/MSLib/obj/MSLib.csproj.nuget.dgspec.json
@@ -1,17 +1,17 @@
{
"format": 1,
"restore": {
- "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj": {}
+ "c:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj": {}
},
"projects": {
- "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj": {
+ "c:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj": {
"version": "1.0.0",
"restore": {
- "projectUniqueName": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj",
+ "projectUniqueName": "c:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj",
"projectName": "MSLib",
- "projectPath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj",
+ "projectPath": "c:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj",
"packagesPath": "C:\\Users\\Brummel\\.nuget\\packages\\",
- "outputPath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\obj\\",
+ "outputPath": "c:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\Brummel\\AppData\\Roaming\\NuGet\\NuGet.Config"
diff --git a/Sources/Common/MSLib/obj/project.nuget.cache b/Sources/Common/MSLib/obj/project.nuget.cache
index 701bd15..caa3c6c 100644
--- a/Sources/Common/MSLib/obj/project.nuget.cache
+++ b/Sources/Common/MSLib/obj/project.nuget.cache
@@ -1,8 +1,8 @@
{
"version": 2,
- "dgSpecHash": "Oo9DgV2PMMwBLALF97djBTxT9Wgbo3xT86Zo8aWAwrxLBxF4zrxrwtxR5/TCIXpFczNFbEDKftQZxvjl9Y6BHQ==",
+ "dgSpecHash": "QUjfNVpQVakrJnZ6ikXioBqXAAQSJGbdswDDGq/346m+iKBsBuuIGU7p4bNk4ScgIgCDP9J76j1QkbDrbUrkrg==",
"success": true,
- "projectFilePath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj",
+ "projectFilePath": "c:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Common\\MSLib\\MSLib.csproj",
"expectedPackageFiles": [],
"logs": []
}
\ No newline at end of file
diff --git a/Sources/Indicators/Candlestick Patterns DEMO.algo b/Sources/Indicators/Candlestick Patterns DEMO.algo
deleted file mode 100644
index 84ced26..0000000
Binary files a/Sources/Indicators/Candlestick Patterns DEMO.algo and /dev/null differ
diff --git a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO.sln b/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO.sln
deleted file mode 100644
index b7a72d8..0000000
--- a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Candlestick Patterns DEMO", "Candlestick Patterns DEMO\Candlestick Patterns DEMO.csproj", "{B9F710D0-7DD5-4E04-B2E9-98C1878E7674}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {B9F710D0-7DD5-4E04-B2E9-98C1878E7674}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B9F710D0-7DD5-4E04-B2E9-98C1878E7674}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B9F710D0-7DD5-4E04-B2E9-98C1878E7674}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B9F710D0-7DD5-4E04-B2E9-98C1878E7674}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Candlestick Patterns DEMO.cs b/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Candlestick Patterns DEMO.cs
deleted file mode 100644
index 0b8fa89..0000000
--- a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Candlestick Patterns DEMO.cs
+++ /dev/null
@@ -1,504 +0,0 @@
-using System;
-using System.IO;
-using cAlgo.API;
-using cAlgo.API.Internals;
-using cAlgo.API.Indicators;
-using cAlgo.Indicators;
-
-namespace cAlgo
-{
- [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
- public class CP : Indicator
- {
- #region Parameters
-
- [Parameter("Show names", DefaultValue = false)]
- public bool Name_Status { get; set; }
-
- [Parameter("Show more info", DefaultValue = true)]
- public bool Add_info { get; set; }
-
- [Parameter("Show Doji", DefaultValue = true)]
- public bool Show_Doji { get; set; }
-
- [Parameter("Show Hammer", DefaultValue = true)]
- public bool Show_Hammer { get; set; }
-
- [Parameter("MACD Long Cycle", DefaultValue = 26)]
- public int LongCycle { get; set; }
-
- [Parameter("MACD Short Cycle", DefaultValue = 12)]
- public int ShortCycle { get; set; }
-
- [Parameter("MACD Signal Periods", DefaultValue = 9)]
- public int Periods { get; set; }
-
- [Parameter("Doji", DefaultValue = "✝")]
- public string Doji_s { get; set; }
- [Parameter("Hammer", DefaultValue = "☨")]
- public string Hammer_s { get; set; }
-
- #endregion Parameters
-
- private MacdHistogram macd;
-
- private const VerticalAlignment vAlign = VerticalAlignment.Top;
- private const HorizontalAlignment hAlign = HorizontalAlignment.Center;
-
- private const double n = 0.618;
-
- private const string UpArrow = "▲";
- private const string DownArrow = "▼";
-
- private string Pattern_name;
-
- private double offset;
-
- private struct Candle
- {
- #region Data
-
- public double High;
- public double Close;
- public double Open;
- public double Low;
-
- #endregion Data
-
- #region Functions
-
- public bool IsFallCandle()
- {
- if (Close < Open)
- return true;
- else
- return false;
- }
- public bool IsRiseCandle()
- {
- if (Open < Close)
- return true;
- else
- return false;
- }
-
- public double Median()
- {
- return (High + Low) / 2;
- }
-
- #endregion Functions
- }
-
- private enum PatternType : int
- {
- Doji = 1,
- Hammer = 2
- }
-
- protected override void Initialize()
- {
- macd = Indicators.MacdHistogram(MarketSeries.Close, LongCycle, ShortCycle, Periods);
- offset = Symbol.PipSize * 5;
- }
-
- private void DrawText(int index, int _Type)
- {
- var high = MarketSeries.High[index];
- var low = MarketSeries.Low[index];
-
- int x = index;
-
- double h_y = high + offset;
- double h_d_y = h_y + offset * 2.5;
- double h_t_y = h_d_y + offset;
-
- double l_y = low - offset * 2.5;
- double l_d_y = l_y - offset;
-
-
- if (TimeFrame == TimeFrame.Minute)
- {
- h_y = high + offset / 2;
- h_d_y = h_y + offset / 2;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset / 2;
- l_d_y = l_y - offset / 2;
- }
-
-
-
- if (TimeFrame == TimeFrame.Minute15)
- {
- h_y = high + offset / 1.5;
- h_d_y = h_y + offset;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 1.5;
- l_d_y = l_y - offset * 1.1;
- }
-
-
- if (TimeFrame == TimeFrame.Hour)
- {
- h_y = high + offset;
- h_d_y = h_y + offset * 3;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 3;
- l_d_y = l_y - offset * 3;
- }
-
- if (TimeFrame == TimeFrame.Hour4)
- {
- h_y = high + offset;
- h_d_y = h_y + offset * 5;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 5;
- l_d_y = l_y - offset * 5;
- }
-
- if (TimeFrame == TimeFrame.Daily)
- {
- h_y = high + offset * 3;
- h_d_y = h_y + offset * 12;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 12;
- l_d_y = l_y - offset * 12;
- }
-
- if (TimeFrame == TimeFrame.Weekly)
- {
- h_y = high + offset * 6;
- h_d_y = h_y + offset * 24;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 24;
- l_d_y = l_y - offset * 24;
- }
-
- if (TimeFrame == TimeFrame.Monthly)
- {
- h_y = high + offset * 24;
- h_d_y = h_y + offset * 64;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 64;
- l_d_y = l_y - offset * 64;
- }
-
- string f_ObjName;
- string s_ObjName;
-
- switch (_Type)
- {
- case (int)PatternType.Doji:
-
- f_ObjName = string.Format("Doji {0}", index);
- s_ObjName = string.Format("Doji | {0}", index);
-
- ChartObjects.DrawText(f_ObjName, "Doji", x, h_d_y, vAlign, hAlign, Colors.White);
- ChartObjects.DrawText(s_ObjName, "\n|", x, h_y, vAlign, hAlign, Colors.White);
-
- break;
-
- case (int)PatternType.Hammer:
-
- f_ObjName = string.Format("Hammer {0}", index);
- s_ObjName = string.Format("Hammer | {0}", index);
-
- ChartObjects.DrawText(f_ObjName, "Hammer", x, h_d_y, vAlign, hAlign, Colors.White);
- ChartObjects.DrawText(s_ObjName, "\n|", x, h_y, vAlign, hAlign, Colors.White);
-
- break;
-
- }
- }
-
- private void DrawSymbols(int index, int _Type)
- {
- var high = MarketSeries.High[index];
- var low = MarketSeries.Low[index];
-
- int x = index;
-
- double h_y = high + offset;
- double h_d_y = h_y + offset * 2.5;
- double h_t_y = h_d_y + offset;
-
- double l_y = low - offset * 2.5;
- double l_d_y = l_y - offset;
-
-
- if (TimeFrame == TimeFrame.Minute)
- {
- h_y = high + offset / 2;
- h_d_y = h_y + offset / 2;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset / 2;
- l_d_y = l_y - offset / 2;
- }
-
-
-
- if (TimeFrame == TimeFrame.Minute15)
- {
- h_y = high + offset / 1.5;
- h_d_y = h_y + offset;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 1.5;
- l_d_y = l_y - offset * 1.1;
- }
-
-
- if (TimeFrame == TimeFrame.Hour)
- {
- h_y = high + offset;
- h_d_y = h_y + offset * 3;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 3;
- l_d_y = l_y - offset * 3;
- }
-
- if (TimeFrame == TimeFrame.Hour4)
- {
- h_y = high + offset;
- h_d_y = h_y + offset * 5;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 5;
- l_d_y = l_y - offset * 5;
- }
-
- if (TimeFrame == TimeFrame.Daily)
- {
- h_y = high + offset * 3;
- h_d_y = h_y + offset * 12;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 12;
- l_d_y = l_y - offset * 12;
- }
-
- if (TimeFrame == TimeFrame.Weekly)
- {
- h_y = high + offset * 6;
- h_d_y = h_y + offset * 24;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 24;
- l_d_y = l_y - offset * 24;
- }
-
- if (TimeFrame == TimeFrame.Monthly)
- {
- h_y = high + offset * 24;
- h_d_y = h_y + offset * 64;
- h_t_y = h_d_y + offset;
-
- l_y = low - offset * 64;
- l_d_y = l_y - offset * 64;
- }
-
- string f_ObjName;
- string s_ObjName;
-
- switch (_Type)
- {
- case (int)PatternType.Doji:
-
- f_ObjName = string.Format("Doji {0}", index);
- s_ObjName = string.Format("Doji | {0}", index);
-
- ChartObjects.DrawText(f_ObjName, Doji_s, x, h_d_y, vAlign, hAlign, Colors.White);
- ChartObjects.DrawText(s_ObjName, "\n|", x, h_y, vAlign, hAlign, Colors.White);
-
- break;
-
- case (int)PatternType.Hammer:
-
- f_ObjName = string.Format("Hammer {0}", index);
- s_ObjName = string.Format("Hammer | {0}", index);
-
- ChartObjects.DrawText(f_ObjName, Hammer_s, x, h_d_y, vAlign, hAlign, Colors.DarkOrange);
- ChartObjects.DrawText(s_ObjName, "\n|", x, h_y, vAlign, hAlign, Colors.White);
-
- break;
-
- }
- }
-
-
- private bool Size(Candle candle)
- {
- if (candle.IsFallCandle())
- {
- if ((candle.Open - candle.Close) > (candle.High - candle.Low) * n)
- return true;
- }
- else if (candle.IsRiseCandle())
- {
- if ((candle.Close - candle.Open) > (candle.High - candle.Low) * n)
- return true;
- }
-
- return false;
- }
-
- private void Text_Info(int index, string Pattern_name)
- {
- if (Add_info == true)
- {
-
- #region Pattern
-
- ChartObjects.DrawText("PATTERN", "LAST PATTERN : " + Pattern_name, StaticPosition.TopLeft, Colors.White);
-
- #endregion Pattern
-
- #region MACD
-
- if (MACD_Info(index) == "UP")
- {
- ChartObjects.DrawText("MACD", "\nMACD : ", StaticPosition.TopLeft, Colors.White);
- ChartObjects.DrawText("ARROW MACD", "\n\t" + UpArrow, StaticPosition.TopLeft, Colors.DodgerBlue);
-
- }
- else if (MACD_Info(index) == "DOWN")
- {
- ChartObjects.DrawText("MACD", "\nMACD : ", StaticPosition.TopLeft, Colors.White);
- ChartObjects.DrawText("ARROW MACD", "\n\t" + DownArrow, StaticPosition.TopLeft, Colors.Crimson);
- }
-
- #endregion MACD
-
- }
- }
-
- private string MACD_Info(int index)
- {
- if (macd.Histogram[index] > 0)
- {
- return "UP";
- }
-
- if (macd.Histogram[index] < 0)
- {
- return "DOWN";
- }
- return "ZERO";
- }
-
-
- private bool Doji(Candle candle)
- {
-
- if (candle.IsFallCandle() & (candle.Close != candle.Low))
- {
- if ((candle.High - candle.Low) > 12 * (candle.Open - candle.Close))
- return true;
- }
- if (candle.IsRiseCandle() & (candle.Close != candle.High))
- {
- if ((candle.High - candle.Low) > 12 * (candle.Close - candle.Open))
- return true;
- }
- return false;
- }
-
- private bool Hammer(Candle candle)
- {
- if (candle.IsFallCandle() & (candle.Close == candle.Low))
- {
- if ((candle.Median() > candle.Open) & (candle.Median() > candle.Close))
- {
- if ((candle.Median() - candle.Low) > 1.618 * (candle.Open - candle.Close))
- return true;
- }
- }
-
- if (candle.IsRiseCandle() & (candle.Close == candle.High))
- {
- if ((candle.Median() < candle.Open) & (candle.Median() < candle.Close))
- {
- if ((candle.High - candle.Median()) > 1.618 * (candle.Close - candle.Open))
- return true;
- }
- }
-
- return false;
- }
-
- public override void Calculate(int index)
- {
- #region structs
-
- Candle candle = new Candle();
-
- #endregion structs
-
- #region variables
-
- int candle_index = 0;
-
- candle.High = MarketSeries.High.Last(candle_index);
- candle.Open = MarketSeries.Open.Last(candle_index);
- candle.Close = MarketSeries.Close.Last(candle_index);
- candle.Low = MarketSeries.Low.Last(candle_index);
-
- #endregion variables
-
- #region Patterns
-
- // Doji
-
- if (Doji(candle))
- {
- if (Show_Doji == true)
- {
- Pattern_name = "Doji";
- if (Name_Status == true)
- {
- DrawText(index, (int)PatternType.Doji);
- }
- else
- {
- DrawSymbols(index, (int)PatternType.Doji);
- }
- }
- }
-
- //Hammer
-
- if (Hammer(candle))
- {
- if (Show_Hammer == true)
- {
- Pattern_name = "Hammer";
- if (Name_Status == true)
- {
- DrawText(index, (int)PatternType.Hammer);
- }
- else
- {
- DrawSymbols(index, (int)PatternType.Hammer);
- }
- }
- }
-
- #endregion Patterns
-
- #region Text
-
- Text_Info(index, Pattern_name);
-
- #endregion Text
- }
- }
-}
diff --git a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Candlestick Patterns DEMO.csproj b/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Candlestick Patterns DEMO.csproj
deleted file mode 100644
index bfeb7d6..0000000
--- a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Candlestick Patterns DEMO.csproj
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {B9F710D0-7DD5-4E04-B2E9-98C1878E7674}
- {DD87C1B2-3799-4CA2-93B6-5288EE928820};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- cAlgo
- Candlestick Patterns DEMO
- v4.0
- Client
- 512
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
- False
- ..\..\..\..\API\cAlgo.API.dll
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Properties/AssemblyInfo.cs b/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Properties/AssemblyInfo.cs
deleted file mode 100644
index 814d8b2..0000000
--- a/Sources/Indicators/Candlestick Patterns DEMO/Candlestick Patterns DEMO/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Candlestick Patterns DEMO")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyProduct("Candlestick Patterns DEMO")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: ComVisible(false)]
-
-[assembly: Guid("35f19c43-c7cc-4f53-b8e0-61caaf9cd8e8")]
-
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/Sources/Indicators/Correlation with angle v1.1.algo b/Sources/Indicators/Correlation with angle v1.1.algo
deleted file mode 100644
index 4f167e9..0000000
Binary files a/Sources/Indicators/Correlation with angle v1.1.algo and /dev/null differ
diff --git a/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1.sln b/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1.sln
deleted file mode 100644
index f4ad4f5..0000000
--- a/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1.sln
+++ /dev/null
@@ -1,22 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30011.22
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Correlation with angle v1.1", "Correlation with angle v1.1\Correlation with angle v1.1.csproj", "{0e2c43ed-8f8d-446b-848e-ed1fe9ef49a2}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0e2c43ed-8f8d-446b-848e-ed1fe9ef49a2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0e2c43ed-8f8d-446b-848e-ed1fe9ef49a2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0e2c43ed-8f8d-446b-848e-ed1fe9ef49a2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0e2c43ed-8f8d-446b-848e-ed1fe9ef49a2}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1/Correlation with angle v1.1.cs b/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1/Correlation with angle v1.1.cs
deleted file mode 100644
index 901975e..0000000
--- a/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1/Correlation with angle v1.1.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading;
-using cAlgo.API;
-using cAlgo.API.Indicators;
-using cAlgo.API.Internals;
-using cAlgo.Indicators;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace cAlgo
-{
- [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
- public class Correlationwithanglev11 : Indicator
- {
- [Parameter("Symbol Selection Method", DefaultValue = SymbolSelectionMethodType.SymbolList, Group = "Symbole Choice \n(Uncomment code for more than 6 Symbole)")]
- public SymbolSelectionMethodType SymbolSelectionMethod { get; set; }
- public enum SymbolSelectionMethodType
- {
- WatchList,
- SymbolList
- }
-
- [Parameter("Symbol List 1 / WatchList Name 1:", DefaultValue = "XAUUSD", Group = "Symbol Management (5 Symbol / List Maximum)")]
- public string TradedSymbols1 { get; set; }
- [Parameter("Symbol List 2 / WatchList Name 2:", DefaultValue = "SpotBrent", Group = "Symbol Management (5 Symbol / List Maximum)")]
- public string TradedSymbols2 { get; set; }
-
- [Parameter("ExtraLevel", DefaultValue = 50, Group = "Angle Level")]
- public int ExtraLevel { get; set; }
-
- [Parameter("PeriodA ngle", DefaultValue = 14, Group = "Angle Setting")]
- public int PeriodAngle { get; set; }
- [Parameter("Loockback Periods Angle", DefaultValue = 1, Group = "Angle Setting")]
- public int LookbackAngle { get; set; }
- [Parameter("Price Smooth Type", DefaultValue = MovingAverageType.Weighted, Group = "Angle Setting")]
- public MovingAverageType MaTypeAngle { get; set; }
-
- [Parameter("History Diff Angle", DefaultValue = 1, Group = "Base Setting")]
- public int HistoryTextLookback { get; set; }
-
- [Parameter("ShowSignals", DefaultValue = true, Group = "Histogram Setting")]
- public bool ShowSignal { get; set; }
- [Parameter("Sensibility Histogram", DefaultValue = 0.3, Group = "Histogram Setting")]
- public double SensibilityHisto { get; set; }
-
- [Parameter("Signal Periods", DefaultValue = 55, Group = "Histogram Setting")]
- public int SignalPeriods { get; set; }
- [Parameter("Price Smooth Type", DefaultValue = MovingAverageType.Weighted, Group = "Histogram Setting")]
- public MovingAverageType MaTypeSignal { get; set; }
-
- [Output("List 1 : Symb n° 1", LineColor = "Lime", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN1 { get; set; }
- [Output("List 1 : Symb n° 2", LineColor = "Lime", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN2 { get; set; }
- [Output("List 1 : Symb n° 3", LineColor = "Lime", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN3 { get; set; }
- [Output("List 1 : Symb n° 4", LineColor = "Lime", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN4 { get; set; }
- [Output("List 1 : Symb n° 5", LineColor = "Lime", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN5 { get; set; }
-
- [Output("List 2 : Symb n° 6", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN6 { get; set; }
- [Output("List 2 : Symb n° 7", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN7 { get; set; }
- [Output("List 2 : Symb n° 8", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN8 { get; set; }
- [Output("List 2 : Symb n° 9", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN9 { get; set; }
- [Output("List 2 : Symb n° 10", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN10 { get; set; }
-
- [Output("LevelHigh", LineColor = "Gold", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries LevelHigh { get; set; }
- [Output("LevelMid", LineColor = "White", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries LevelMid { get; set; }
- [Output("LevelLow", LineColor = "Gold", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries LevelLow { get; set; }
-
- private MovingAverage[] angleIndex1, angleIndex2;
- private AverageTrueRange[] atrIndex1, atrIndex2;
-
- private Symbol[] TradeList1, TradeList2;
- private Bars[] bars1, bars2;
- private IndicatorDataSeries[] ResPaireWatchlist1, ResPaireWatchlist2;
- private int[] indexBars1, indexBars2;
-
- protected override void Initialize()
- {
- if (SymbolSelectionMethod == SymbolSelectionMethodType.WatchList)
- {
- // Get the trade list from the watchlist 1 provided by the user
- foreach (Watchlist w in Watchlists)
- {
- if (w.Name == TradedSymbols1)
- {
- TradeList1 = Symbols.GetSymbols(w.SymbolNames.ToArray());
- }
- }
- // Get the trade list from the watchlist 2 provided by the user
- foreach (Watchlist w in Watchlists)
- {
- if (w.Name == TradedSymbols2)
- {
- TradeList2 = Symbols.GetSymbols(w.SymbolNames.ToArray());
- }
- }
- Print();
- Print("Watchlist 1 : [ {0} ] = {1} symbols || Watchlist 2 : [ {2} ] = {3} symbols", Bars.ToString().Substring(0, 3), TradeList1.Length, Bars.ToString().Substring(3, 3), TradeList2.Length);
- Print();
- }
- else if (SymbolSelectionMethod == SymbolSelectionMethodType.SymbolList)
- {
- // Get the trade list from the SymbolList provided by the user
- string[] SymbolList = TradedSymbols1.Split(' ');
- TradeList1 = Symbols.GetSymbols(SymbolList);
-
- // Get the trade list from the SymbolList provided by the user
- string[] SymbolList2 = TradedSymbols2.Split(' ');
- TradeList2 = Symbols.GetSymbols(SymbolList2);
- }
-
- //Create Indicators for Watchlist 1
- angleIndex1 = new MovingAverage[TradeList1.Length];
- atrIndex1 = new AverageTrueRange[TradeList1.Length];
- bars1 = new Bars[TradeList1.Length];
- indexBars1 = new int[TradeList1.Length];
- ResPaireWatchlist1 = new IndicatorDataSeries[TradeList1.Length];
-
- //Create Indicators for Watchlist 2
- angleIndex2 = new MovingAverage[TradeList2.Length];
- atrIndex2 = new AverageTrueRange[TradeList2.Length];
- bars2 = new Bars[TradeList2.Length];
- indexBars2 = new int[TradeList2.Length];
- ResPaireWatchlist2 = new IndicatorDataSeries[TradeList2.Length];
-
- //Initialize Indicators for Watchlist 1
- int i = 0;
- foreach (var symbol in TradeList1)
- {
- Print("Watchlist : [ {0} ] => {1} symbols = {2}", Bars.SymbolName, (i + 1), symbol.Name);
- //Load bars of watchlist 1
- bars1[i] = MarketData.GetBars(TimeFrame, symbol.Name);
- while (bars1[i].OpenTimes[0] > Bars.OpenTimes[0])
- bars1[i].LoadMoreHistory();
-
- //Load Futurs DataSerie watchlist 1 (calculation in Calculate(int index))
- ResPaireWatchlist1[i] = CreateDataSeries();
-
- //Load Indicators watchlist 1
-
- atrIndex1[i] = Indicators.AverageTrueRange(bars1[i], 500, MovingAverageType.Simple);
- angleIndex1[i] = Indicators.MovingAverage(bars1[i].ClosePrices, PeriodAngle, MaTypeAngle);
- i++;
- }
- //Initialize Indicators for Watchlist 2
- Print();
-
- int j = 0;
- foreach (var symbol2 in TradeList2)
- {
- Print("Watchlist : [ {0} ] => {1} symbols = {2}", Bars.SymbolName, (j + 1), symbol2.Name);
- //Load bars of watchlist 2
- bars2[j] = MarketData.GetBars(TimeFrame, symbol2.Name);
- while (bars2[j].OpenTimes[0] > Bars.OpenTimes[0])
- bars2[j].LoadMoreHistory();
-
- //Load Futurs DataSerie watchlist 2 (calculation in Calculate(int index))
- ResPaireWatchlist2[j] = CreateDataSeries();
-
- //Load Indicators watchlist 2
- atrIndex2[j] = Indicators.AverageTrueRange(bars2[j], 500, MovingAverageType.Simple);
- angleIndex2[j] = Indicators.MovingAverage(bars2[j].ClosePrices, PeriodAngle, MaTypeAngle);
- j++;
- }
- Print();
- }
- public override void Calculate(int index)
- {
- //Plot Static level on indicator
- LevelHigh[index] = ExtraLevel;
- LevelMid[index] = 0;
- LevelLow[index] = 0 - ExtraLevel;
-
- if (index < PeriodAngle)
- return;
-
- //Calculate angle by symbol list 1
- for (int i = 0; i < TradeList1.Length; i++)
- {
- indexBars1[i] = bars1[i].OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
- ResPaireWatchlist1[i][index] = GetCalculationAngle(angleIndex1[i].Result[indexBars1[i]], angleIndex1[i].Result[indexBars1[i] - LookbackAngle], atrIndex1[i].Result[indexBars1[i]]);
- }
-
- //Remove Static text of difference into index and index - HistoryTextLookback
- if (IndicatorArea.FindAllObjects(ChartObjectType.Text).Length > 0)
- IndicatorArea.RemoveAllObjects();
- //Calculate difference into index and index - HistoryTextLookback list 1
- for (int i = 0; i < TradeList1.Length; i++)
- IndicatorArea.DrawText((TradeList1[i]).ToString() + index, TradeList1[i] + " : " + ResPaireWatchlist1[i][index].ToString("F2"), index + 2, double.IsNaN(ResPaireWatchlist1[i][index]) ? 0 : ResPaireWatchlist1[i][index], ResPaireWatchlist1[i][index] > ResPaireWatchlist1[i][index - HistoryTextLookback] ? Color.Lime : Color.Red);
-
- //Output the result like symbolList number != output number list 1
- int j = TradeList1.Length - 1;
- SymbN1[index] = ResPaireWatchlist1[0 < j ? 0 : j][index];
- SymbN2[index] = ResPaireWatchlist1[1 < j ? 1 : j][index];
- SymbN3[index] = ResPaireWatchlist1[2 < j ? 2 : j][index];
- SymbN4[index] = ResPaireWatchlist1[3 < j ? 3 : j][index];
- SymbN5[index] = ResPaireWatchlist1[4 < j ? 4 : j][index];
-
- //Calculate angle by symbol list 2
- for (int i = 0; i < TradeList2.Length; i++)
- {
- indexBars2[i] = bars2[i].OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
- ResPaireWatchlist2[i][index] = GetCalculationAngle(angleIndex2[i].Result[indexBars2[i]], angleIndex2[i].Result[indexBars2[i] - LookbackAngle], atrIndex2[i].Result[indexBars2[i]]);
- }
-
- //Calculate difference into index and index - HistoryTextLookback list 2
- for (int i = 0; i < TradeList2.Length; i++)
- IndicatorArea.DrawText((TradeList2[i]).ToString() + index, TradeList2[i] + " : " + ResPaireWatchlist2[i][index].ToString("F2"), index + 2, double.IsNaN(ResPaireWatchlist2[i][index]) ? 0 : ResPaireWatchlist2[i][index], ResPaireWatchlist2[i][index] > ResPaireWatchlist2[i][index - HistoryTextLookback] ? Color.Lime : Color.Red);
-
- //Output the result like symbolList number != output number list 2
- int k = TradeList2.Length - 1;
- SymbN6[index] = ResPaireWatchlist2[0 < k ? 0 : k][index];
- SymbN7[index] = ResPaireWatchlist2[1 < k ? 1 : k][index];
- SymbN8[index] = ResPaireWatchlist2[2 < k ? 2 : k][index];
- SymbN9[index] = ResPaireWatchlist2[3 < k ? 3 : k][index];
- SymbN10[index] = ResPaireWatchlist2[4 < k ? 4 : k][index];
-
- }
-
- //Function for angle calculation with atr normalization
- public double GetCalculationAngle(double priceSmooth, double priceSmoothLoockBack, double atr)
- {
- var _momentumpositive = priceSmooth - priceSmoothLoockBack;
- var _momentumnegative = priceSmoothLoockBack - priceSmooth;
- var _momentum = priceSmooth > priceSmoothLoockBack
- ? _momentumpositive / atr
- : _momentumnegative / atr;
- var _hypothenuse = Math.Sqrt((_momentum * _momentum) + (LookbackAngle * LookbackAngle));
- var _cos = (LookbackAngle / _hypothenuse);
- var _angle = priceSmooth > priceSmoothLoockBack
- ? (0 + (Math.Acos(_cos) * 100))
- : (0 - (Math.Acos(_cos) * 100));
- return _angle;
- }
- }
-}
diff --git a/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1/Correlation with angle v1.1.csproj b/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1/Correlation with angle v1.1.csproj
deleted file mode 100644
index 4040d8c..0000000
--- a/Sources/Indicators/Correlation with angle v1.1/Correlation with angle v1.1/Correlation with angle v1.1.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
- net6.0
-
-
-
-
-
-
diff --git a/Sources/Indicators/Correlation with angle v1.1/msAngle of MultiSymbol.cs b/Sources/Indicators/Correlation with angle v1.1/msAngle of MultiSymbol.cs
deleted file mode 100644
index c1cd75e..0000000
--- a/Sources/Indicators/Correlation with angle v1.1/msAngle of MultiSymbol.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading;
-using cAlgo.API;
-using cAlgo.API.Indicators;
-using cAlgo.API.Internals;
-using cAlgo.Indicators;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace cAlgo
-{
- //[Cloud("Fast Smooth", "Slow Smooth", FirstColor = "Green", SecondColor = "Red", Opacity = 0.1)]
- [Levels(0)]
- [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
- public class AngleOfMultiSymbol : Indicator
- {
- [Parameter("Symbol Selection Method", DefaultValue = SymbolSelectionMethodType.SymbolList, Group = "Symbole Choice \n(Uncomment code for more than 6 Symbole)")]
- public SymbolSelectionMethodType SymbolSelectionMethod { get; set; }
- [Parameter("Symbol List", DefaultValue = "EURUSD GBPUSD AUDUSD USDCHF", Group = "Symbole Choice \n(Uncomment code for more than 6 Symbole)")]
- public string TradedSymbols { get; set; }
- [Parameter("Watchlist Name", DefaultValue = "My Watchlist", Group = "Symbole Choice \n(Uncomment code for more than 6 Symbole)")]
- public string WatchlistName { get; set; }
-
- public enum SymbolSelectionMethodType
- {
- CurrentChart,
- SymbolList,
- WatchList
- }
-
- [Parameter("History Diff Angle", DefaultValue = 1, Group = "Base Setting")]
- public int HistoryTextLookback { get; set; }
- [Parameter("Tf", DefaultValue = "Hour1", Group = "Base Setting")]
- public TimeFrame Tf { get; set; }
- [Parameter("Price Smooth Period (255)", DefaultValue = 255, Group = "Angle Setting")]
- public int SmoothPeriods { get; set; }
- [Parameter("Price Smooth Type", DefaultValue = MovingAverageType.Weighted, Group = "Angle Setting")]
- public MovingAverageType MaType { get; set; }
- [Parameter("Loockback Periods Angle", DefaultValue = 1, Group = "Angle Setting")]
- public int LookbackPeriodsAngle { get; set; }
- [Parameter("Sensitivity (1.0)", DefaultValue = 1, Group = "Angle Setting")]
- public double Sensitivity { get; set; }
-
- [Output("Symb n° 1", LineColor = "White", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN1 { get; set; }
- [Output("Symb n° 2", LineColor = "Lime", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN2 { get; set; }
- [Output("Symb n° 3", LineColor = "Green", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN3 { get; set; }
- [Output("Symb n° 4", LineColor = "DeepSkyBlue", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN4 { get; set; }
- [Output("Symb n° 5", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN5 { get; set; }
- [Output("Symb n° 6", LineColor = "Magenta", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN6 { get; set; }
-
- /*Uncomment For more Symbole on the chart
- [Output("Symb n° 7", LineColor = "Green", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN7 { get; set; }
- [Output("Symb n° 8", LineColor = "DeepSkyBlue", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN8 { get; set; }
- [Output("Symb n° 9", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN9 { get; set; }
- [Output("Symb n° 10", LineColor = "Magenta", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 1)]
- public IndicatorDataSeries SymbN10 { get; set; }
- */
-
- private MovingAverage[] ma;
- private AverageTrueRange[] atr;
-
- private Symbol[] TradeList;
- private Bars[] bars;
- private IndicatorDataSeries[] Sources, ResSymbol;
- private int[] indexBars;
-
- protected override void Initialize()
- {
- if (SymbolSelectionMethod == SymbolSelectionMethodType.WatchList)
- {
- // Get the trade list from the watchlist provided by the user
- foreach (Watchlist w in Watchlists)
- {
- if (w.Name == WatchlistName)
- {
- TradeList = Symbols.GetSymbols(w.SymbolNames.ToArray());
- }
- }
- }
- else if (SymbolSelectionMethod == SymbolSelectionMethodType.SymbolList)
- {
- // Get the trade list from the sysmbol list provided by the user
- string[] SymbolList = TradedSymbols.ToUpper().Split(' ');
-
- TradeList = Symbols.GetSymbols(SymbolList);
- }
- else
- {
- TradeList = new Symbol[1];
- TradeList[0] = Symbol;
- }
-
- atr = new AverageTrueRange[TradeList.Length];
- ma = new MovingAverage[TradeList.Length];
- bars = new Bars[TradeList.Length];
- indexBars = new int[TradeList.Length];
- Sources = new IndicatorDataSeries[TradeList.Length];
- ResSymbol = new IndicatorDataSeries[TradeList.Length];
-
- Print("{0} traded symbols: ", TradeList.Length);
-
- int i = 0;
- foreach (var symbol in TradeList)
- {
- Print(symbol.Name);
-
- bars[i] = MarketData.GetBars(Tf, symbol.Name);
- if (bars[i].OpenTimes[0] > Bars.OpenTimes[0])
- bars[i].LoadMoreHistory();
- //Load indicators on start up EP5-ATR
- Sources[i] = CreateDataSeries();
- ResSymbol[i] = CreateDataSeries();
- atr[i] = Indicators.AverageTrueRange(bars[i], 500, MovingAverageType.Simple);
-
- ma[i] = Indicators.MovingAverage(Sources[i], SmoothPeriods, MaType);
- i++;
- }
- }
-
- public override void Calculate(int index)
- {
- if (index < SmoothPeriods)
- return;
-
- for (int i = 0; i < TradeList.Length; i++)
- {
- //indexBars[i] = GetIndexByDate(bars[i], Bars.OpenTimes[index]);
-
- indexBars[i] = bars[i].OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
- Sources[i][index] = bars[i].ClosePrices[indexBars[i]];
- ResSymbol[i][index] = GetCalculationSymbol(ma[i].Result[index], ma[i].Result[index - LookbackPeriodsAngle], atr[i].Result[indexBars[i]]);
- }
-
- SymbN1[index] = ResSymbol[0][index];
- SymbN2[index] = ResSymbol[1][index];
- SymbN3[index] = ResSymbol[2][index];
- SymbN4[index] = ResSymbol[3][index];
- SymbN5[index] = ResSymbol[4][index];
- SymbN6[index] = ResSymbol[5][index];
-
- /* Uncomment For More Symbols on chart
- SymbN7[index] = ResSymbol[2][index];
- SymbN8[index] = ResSymbol[3][index];
- SymbN9[index] = ResSymbol[4][index];
- SymbN10[index] = ResSymbol[5][index];
- */
-
- IndicatorArea.RemoveAllObjects();
-
- for (int i = 0; i < TradeList.Length; i++)
- {
- IndicatorArea.DrawText((TradeList[i]).ToString() + index, TradeList[i] + " : " + ResSymbol[i][index].ToString("F2"), index, ResSymbol[i][index], ResSymbol[i][index] > ResSymbol[i][index - HistoryTextLookback] ? Color.Lime : Color.Red);
- }
-
- }
- public double GetCalculationSymbol(double priceSmooth, double priceSmoothLoockBack, double atr)
- {
- var _momentumpositive = priceSmooth - priceSmoothLoockBack;
- var _momentumnegative = priceSmoothLoockBack - priceSmooth;
- var _momentum = priceSmooth > priceSmoothLoockBack
- ? _momentumpositive / atr
- : _momentumnegative / atr;
- var _hypothenuse = Math.Sqrt((_momentum * _momentum) + (LookbackPeriodsAngle * LookbackPeriodsAngle));
- var _cos = (LookbackPeriodsAngle / _hypothenuse);
- var _angle = priceSmooth > priceSmoothLoockBack
- ? (0 + (Math.Acos(_cos) * 100)) * Sensitivity
- : (0 - (Math.Acos(_cos) * 100)) * Sensitivity;
- return _angle;
- }
- }
-}
diff --git a/Sources/Indicators/Correlation with angle v1.1/msAngle of MultiSymbol.csproj b/Sources/Indicators/Correlation with angle v1.1/msAngle of MultiSymbol.csproj
deleted file mode 100644
index 4040d8c..0000000
--- a/Sources/Indicators/Correlation with angle v1.1/msAngle of MultiSymbol.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
- net6.0
-
-
-
-
-
-
diff --git a/Sources/Indicators/Economic Events On Chart.algo b/Sources/Indicators/Economic Events On Chart.algo
deleted file mode 100644
index bd94e70..0000000
Binary files a/Sources/Indicators/Economic Events On Chart.algo and /dev/null differ
diff --git a/Sources/Indicators/Economic Events On Chart/.gitattributes b/Sources/Indicators/Economic Events On Chart/.gitattributes
deleted file mode 100644
index 1ff0c42..0000000
--- a/Sources/Indicators/Economic Events On Chart/.gitattributes
+++ /dev/null
@@ -1,63 +0,0 @@
-###############################################################################
-# Set default behavior to automatically normalize line endings.
-###############################################################################
-* text=auto
-
-###############################################################################
-# Set default behavior for command prompt diff.
-#
-# This is need for earlier builds of msysgit that does not have it on by
-# default for csharp files.
-# Note: This is only used by command line
-###############################################################################
-#*.cs diff=csharp
-
-###############################################################################
-# Set the merge driver for project and solution files
-#
-# Merging from the command prompt will add diff markers to the files if there
-# are conflicts (Merging from VS is not affected by the settings below, in VS
-# the diff markers are never inserted). Diff markers may cause the following
-# file extensions to fail to load in VS. An alternative would be to treat
-# these files as binary and thus will always conflict and require user
-# intervention with every merge. To do so, just uncomment the entries below
-###############################################################################
-#*.sln merge=binary
-#*.csproj merge=binary
-#*.vbproj merge=binary
-#*.vcxproj merge=binary
-#*.vcproj merge=binary
-#*.dbproj merge=binary
-#*.fsproj merge=binary
-#*.lsproj merge=binary
-#*.wixproj merge=binary
-#*.modelproj merge=binary
-#*.sqlproj merge=binary
-#*.wwaproj merge=binary
-
-###############################################################################
-# behavior for image files
-#
-# image files are treated as binary by default.
-###############################################################################
-#*.jpg binary
-#*.png binary
-#*.gif binary
-
-###############################################################################
-# diff behavior for common document formats
-#
-# Convert binary document formats to text before diffing them. This feature
-# is only available from the command line. Turn it on by uncommenting the
-# entries below.
-###############################################################################
-#*.doc diff=astextplain
-#*.DOC diff=astextplain
-#*.docx diff=astextplain
-#*.DOCX diff=astextplain
-#*.dot diff=astextplain
-#*.DOT diff=astextplain
-#*.pdf diff=astextplain
-#*.PDF diff=astextplain
-#*.rtf diff=astextplain
-#*.RTF diff=astextplain
diff --git a/Sources/Indicators/Economic Events On Chart/.gitignore b/Sources/Indicators/Economic Events On Chart/.gitignore
deleted file mode 100644
index 9491a2f..0000000
--- a/Sources/Indicators/Economic Events On Chart/.gitignore
+++ /dev/null
@@ -1,363 +0,0 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-##
-## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
-
-# User-specific files
-*.rsuser
-*.suo
-*.user
-*.userosscache
-*.sln.docstates
-
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
-# Mono auto generated files
-mono_crash.*
-
-# Build results
-[Dd]ebug/
-[Dd]ebugPublic/
-[Rr]elease/
-[Rr]eleases/
-x64/
-x86/
-[Ww][Ii][Nn]32/
-[Aa][Rr][Mm]/
-[Aa][Rr][Mm]64/
-bld/
-[Bb]in/
-[Oo]bj/
-[Oo]ut/
-[Ll]og/
-[Ll]ogs/
-
-# Visual Studio 2015/2017 cache/options directory
-.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
-
-# Visual Studio 2017 auto generated files
-Generated\ Files/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-# NUnit
-*.VisualState.xml
-TestResult.xml
-nunit-*.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-# Benchmark Results
-BenchmarkDotNet.Artifacts/
-
-# .NET Core
-project.lock.json
-project.fragment.lock.json
-artifacts/
-
-# ASP.NET Scaffolding
-ScaffoldingReadMe.txt
-
-# StyleCop
-StyleCopReport.xml
-
-# Files built by Visual Studio
-*_i.c
-*_p.c
-*_h.h
-*.ilk
-*.meta
-*.obj
-*.iobj
-*.pch
-*.pdb
-*.ipdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*_wpftmp.csproj
-*.log
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-*.VC.VC.opendb
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-*.sap
-
-# Visual Studio Trace Files
-*.e2e
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# AxoCover is a Code Coverage Tool
-.axoCover/*
-!.axoCover/settings.json
-
-# Coverlet is a free, cross platform Code Coverage Tool
-coverage*.json
-coverage*.xml
-coverage*.info
-
-# Visual Studio code coverage results
-*.coverage
-*.coveragexml
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-nCrunchTemp_*
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-# Note: Comment the next line if you want to checkin your web deploy settings,
-# but database connection strings (with potential passwords) will be unencrypted
-*.pubxml
-*.publishproj
-
-# Microsoft Azure Web App publish settings. Comment the next line if you want to
-# checkin your Azure Web App publish settings, but sensitive information contained
-# in these scripts will be unencrypted
-PublishScripts/
-
-# NuGet Packages
-*.nupkg
-# NuGet Symbol Packages
-*.snupkg
-# The packages folder can be ignored because of Package Restore
-**/[Pp]ackages/*
-# except build/, which is used as an MSBuild target.
-!**/[Pp]ackages/build/
-# Uncomment if necessary however generally it will be regenerated when needed
-#!**/[Pp]ackages/repositories.config
-# NuGet v3's project.json files produces more ignorable files
-*.nuget.props
-*.nuget.targets
-
-# Microsoft Azure Build Output
-csx/
-*.build.csdef
-
-# Microsoft Azure Emulator
-ecf/
-rcf/
-
-# Windows Store app package directories and files
-AppPackages/
-BundleArtifacts/
-Package.StoreAssociation.xml
-_pkginfo.txt
-*.appx
-*.appxbundle
-*.appxupload
-
-# Visual Studio cache files
-# files ending in .cache can be ignored
-*.[Cc]ache
-# but keep track of directories ending in .cache
-!?*.[Cc]ache/
-
-# Others
-ClientBin/
-~$*
-*~
-*.dbmdl
-*.dbproj.schemaview
-*.jfm
-*.pfx
-*.publishsettings
-orleans.codegen.cs
-
-# Including strong name files can present a security risk
-# (https://github.com/github/gitignore/pull/2483#issue-259490424)
-#*.snk
-
-# Since there are multiple workflows, uncomment next line to ignore bower_components
-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
-#bower_components/
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-ServiceFabricBackup/
-*.rptproj.bak
-
-# SQL Server files
-*.mdf
-*.ldf
-*.ndf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-*.rptproj.rsuser
-*- [Bb]ackup.rdl
-*- [Bb]ackup ([0-9]).rdl
-*- [Bb]ackup ([0-9][0-9]).rdl
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# GhostDoc plugin setting file
-*.GhostDoc.xml
-
-# Node.js Tools for Visual Studio
-.ntvs_analysis.dat
-node_modules/
-
-# Visual Studio 6 build log
-*.plg
-
-# Visual Studio 6 workspace options file
-*.opt
-
-# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
-*.vbw
-
-# Visual Studio LightSwitch build output
-**/*.HTMLClient/GeneratedArtifacts
-**/*.DesktopClient/GeneratedArtifacts
-**/*.DesktopClient/ModelManifest.xml
-**/*.Server/GeneratedArtifacts
-**/*.Server/ModelManifest.xml
-_Pvt_Extensions
-
-# Paket dependency manager
-.paket/paket.exe
-paket-files/
-
-# FAKE - F# Make
-.fake/
-
-# CodeRush personal settings
-.cr/personal
-
-# Python Tools for Visual Studio (PTVS)
-__pycache__/
-*.pyc
-
-# Cake - Uncomment if you are using it
-# tools/**
-# !tools/packages.config
-
-# Tabs Studio
-*.tss
-
-# Telerik's JustMock configuration file
-*.jmconfig
-
-# BizTalk build output
-*.btp.cs
-*.btm.cs
-*.odx.cs
-*.xsd.cs
-
-# OpenCover UI analysis results
-OpenCover/
-
-# Azure Stream Analytics local run output
-ASALocalRun/
-
-# MSBuild Binary and Structured Log
-*.binlog
-
-# NVidia Nsight GPU debugger configuration file
-*.nvuser
-
-# MFractors (Xamarin productivity tool) working folder
-.mfractor/
-
-# Local History for Visual Studio
-.localhistory/
-
-# BeatPulse healthcheck temp database
-healthchecksdb
-
-# Backup folder for Package Reference Convert tool in Visual Studio 2017
-MigrationBackup/
-
-# Ionide (cross platform F# VS Code tools) working folder
-.ionide/
-
-# Fody - auto-generated XML schema
-FodyWeavers.xsd
\ No newline at end of file
diff --git a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart.sln b/Sources/Indicators/Economic Events On Chart/Economic Events On Chart.sln
deleted file mode 100644
index d5b245c..0000000
--- a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Economic Events On Chart", "Economic Events On Chart\Economic Events On Chart.csproj", "{7D9A4560-D021-4B46-8D58-83DCBEBBE654}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {7D9A4560-D021-4B46-8D58-83DCBEBBE654}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7D9A4560-D021-4B46-8D58-83DCBEBBE654}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7D9A4560-D021-4B46-8D58-83DCBEBBE654}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7D9A4560-D021-4B46-8D58-83DCBEBBE654}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Economic Events On Chart.cs b/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Economic Events On Chart.cs
deleted file mode 100644
index b831773..0000000
--- a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Economic Events On Chart.cs
+++ /dev/null
@@ -1,345 +0,0 @@
-using System;
-using cAlgo.API;
-using System.Collections.Generic;
-using System.Xml;
-using System.Net;
-using System.Xml.Serialization;
-using System.IO;
-using System.Text;
-using System.Linq;
-using System.Globalization;
-
-namespace cAlgo
-{
- [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.Internet)]
- public class EconomicEventsOnChart : Indicator
- {
- private Color _colorHighImpact, _colorMediumImpact, _colorLowImpact, _colorOthers;
-
- private TextBlock _textBlock;
-
- [Parameter("Data URI", DefaultValue = "https://nfs.faireconomy.media/ff_calendar_thisweek.xml", Group = "General")]
- public string DataUri { get; set; }
-
- [Parameter("Only Symbol Events", DefaultValue = true, Group = "General")]
- public bool OnlySymbolEvents { get; set; }
-
- [Parameter("Show Past Events", DefaultValue = true, Group = "General")]
- public bool ShowPastEvents { get; set; }
-
- [Parameter("Show", DefaultValue = true, Group = "High Impact")]
- public bool ShowHighImpact { get; set; }
-
- [Parameter("Color", DefaultValue = "Red", Group = "High Impact")]
- public string ColorHighImpact { get; set; }
-
- [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "High Impact")]
- public LineStyle LineStyleHighImpact { get; set; }
-
- [Parameter("Thickness", DefaultValue = 1, Group = "High Impact")]
- public int ThicknessHighImpact { get; set; }
-
- [Parameter("Show", DefaultValue = true, Group = "Medium Impact")]
- public bool ShowMediumImpact { get; set; }
-
- [Parameter("Color", DefaultValue = "Gold", Group = "Medium Impact")]
- public string ColorMediumImpact { get; set; }
-
- [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "Medium Impact")]
- public LineStyle LineStyleMediumImpact { get; set; }
-
- [Parameter("Thickness", DefaultValue = 1, Group = "Medium Impact")]
- public int ThicknessMediumImpact { get; set; }
-
- [Parameter("Show", DefaultValue = true, Group = "Low Impact")]
- public bool ShowLowImpact { get; set; }
-
- [Parameter("Color", DefaultValue = "Yellow", Group = "Low Impact")]
- public string ColorLowImpact { get; set; }
-
- [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "Low Impact")]
- public LineStyle LineStyleLowImpact { get; set; }
-
- [Parameter("Thickness", DefaultValue = 1, Group = "Low Impact")]
- public int ThicknessLowImpact { get; set; }
-
- [Parameter("Show", DefaultValue = false, Group = "Others")]
- public bool ShowOthers { get; set; }
-
- [Parameter("Color", DefaultValue = "Gray", Group = "Others")]
- public string ColorOthers { get; set; }
-
- [Parameter("Style", DefaultValue = LineStyle.Solid, Group = "Others")]
- public LineStyle LineStyleOthers { get; set; }
-
- [Parameter("Thickness", DefaultValue = 1, Group = "Others")]
- public int ThicknessOthers { get; set; }
-
- [Parameter("Show", DefaultValue = true, Group = "Text Block")]
- public bool ShowTextBlock { get; set; }
-
- [Parameter("Background Color", DefaultValue = "#969696", Group = "Text Block")]
- public string TextBlockBackgroundColor { get; set; }
-
- [Parameter("Color", DefaultValue = "White", Group = "Text Block")]
- public string TextBlockColor { get; set; }
-
- [Parameter("Horizontal Alignment", DefaultValue = HorizontalAlignment.Center, Group = "Text Block")]
- public HorizontalAlignment TextBlockHorizontalAlignment { get; set; }
-
- [Parameter("Vertical Alignment", DefaultValue = VerticalAlignment.Bottom, Group = "Text Block")]
- public VerticalAlignment TextBlockVerticalAlignment { get; set; }
-
- [Parameter("Text Alignment", DefaultValue = TextAlignment.Center, Group = "Text Block")]
- public TextAlignment TextBlockTextAlignment { get; set; }
-
- [Parameter("Font Weight", DefaultValue = FontWeight.Bold, Group = "Text Block")]
- public FontWeight TextBlockFontWeight { get; set; }
-
- protected override void Initialize()
- {
- RemoveEventLines();
-
- if (ShowTextBlock)
- {
- _textBlock = new TextBlock
- {
- IsVisible = false,
- HorizontalAlignment = TextBlockHorizontalAlignment,
- VerticalAlignment = TextBlockVerticalAlignment,
- BackgroundColor = GetColor(TextBlockBackgroundColor),
- ForegroundColor = GetColor(TextBlockColor),
- TextAlignment = TextBlockTextAlignment,
- FontWeight = TextBlockFontWeight,
- Padding = 5
- };
-
- Chart.AddControl(_textBlock);
-
- Chart.ObjectHoverChanged += Chart_ObjectHoverChanged;
- }
-
- _colorHighImpact = GetColor(ColorHighImpact);
- _colorMediumImpact = GetColor(ColorMediumImpact);
- _colorLowImpact = GetColor(ColorLowImpact);
- _colorOthers = GetColor(ColorOthers);
-
- var events = GetNewsEvents();
-
- DisplayEvents(events);
- }
-
- private void Chart_ObjectHoverChanged(ChartObjectHoverChangedEventArgs obj)
- {
- if (!obj.IsObjectHovered || obj.ChartObject == null || string.IsNullOrWhiteSpace(obj.ChartObject.Name) || !obj.ChartObject.Name.EndsWith("Event", StringComparison.OrdinalIgnoreCase))
- {
- _textBlock.IsVisible = false;
-
- return;
- }
-
- _textBlock.Text = string.Format("{0} | {1}", obj.ChartObject.Name.Replace(" | Event", string.Empty), obj.ChartObject.Comment);
-
- _textBlock.IsVisible = true;
- }
-
- public override void Calculate(int index)
- {
- }
-
- private IEnumerable GetNewsEvents()
- {
- using (var webClient = new WebClient())
- {
- var data = webClient.DownloadString(DataUri);
-
- return GetNewsEventsFromXml(data);
- }
- }
-
- private IEnumerable GetNewsEventsFromXml(string xml)
- {
- var xmlSerializer = new XmlSerializer(typeof(WeeklyEvents));
-
- var stream = new StringReader(xml);
-
- var weeklyEvents = xmlSerializer.Deserialize(stream) as WeeklyEvents;
-
- foreach (var newsEvent in weeklyEvents.Events)
- {
- var timeString = string.Format("{0} {1}", newsEvent.UtcDate, newsEvent.UtcTime);
-
- DateTimeOffset time;
-
- if (DateTimeOffset.TryParseExact(timeString, "MM-dd-yyyy h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out time))
- {
- newsEvent.Time = time;
- }
- }
-
- return weeklyEvents.Events;
- }
-
- private void DisplayEvents(IEnumerable events)
- {
- foreach (var newsEvent in events)
- {
- if (!newsEvent.Time.HasValue
- || (newsEvent.Impact == NewsEventImpact.High && !ShowHighImpact)
- || (newsEvent.Impact == NewsEventImpact.Medium && !ShowMediumImpact)
- || (newsEvent.Impact == NewsEventImpact.Low && !ShowLowImpact)
- || ((newsEvent.Impact == NewsEventImpact.None || newsEvent.Impact == NewsEventImpact.Holiday) && !ShowOthers)
- || (OnlySymbolEvents && !IsEventRelatedToSymbol(newsEvent.Currency))
- || (!ShowPastEvents && newsEvent.Time < Server.TimeInUtc)) continue;
-
- var lineSettings = GetLineSettings(newsEvent.Impact);
-
- var eventLine = Chart.DrawVerticalLine(string.Format("{0} | {1} | {2} | Event", newsEvent.Title, newsEvent.Currency, newsEvent.Impact), newsEvent.Time.Value.UtcDateTime, lineSettings.Color, lineSettings.Thickness, lineSettings.Style);
-
- var stringBuilder = new StringBuilder();
-
- if (!string.IsNullOrWhiteSpace(newsEvent.Forecast))
- {
- stringBuilder.Append(string.Format("Forecast: {0} | ", newsEvent.Forecast));
- }
-
- if (!string.IsNullOrWhiteSpace(newsEvent.Previous))
- {
- stringBuilder.Append(string.Format("Previous: {0} | ", newsEvent.Previous));
- }
-
- if (newsEvent.Time.HasValue)
- {
- var time = newsEvent.Time.Value.ToOffset(Application.UserTimeOffset);
-
- stringBuilder.Append(string.Format("Time: {0:s}", time));
- }
-
- eventLine.Comment = stringBuilder.ToString();
- eventLine.IsInteractive = true;
- eventLine.IsLocked = true;
- }
- }
-
- private bool IsEventRelatedToSymbol(string eventCurrency)
- {
- return SymbolName.StartsWith(eventCurrency, StringComparison.OrdinalIgnoreCase) || SymbolName.EndsWith(eventCurrency, StringComparison.OrdinalIgnoreCase);
- }
-
- private Color GetColor(string colorString, int alpha = 255)
- {
- var color = colorString[0] == '#' ? Color.FromHex(colorString) : Color.FromName(colorString);
-
- return Color.FromArgb(alpha, color);
- }
-
- private LineSettings GetLineSettings(NewsEventImpact impact)
- {
- switch (impact)
- {
- case NewsEventImpact.High:
- return new LineSettings
- {
- Color = _colorHighImpact,
- Style = LineStyleHighImpact,
- Thickness = ThicknessHighImpact
- };
-
- case NewsEventImpact.Medium:
- return new LineSettings
- {
- Color = _colorMediumImpact,
- Style = LineStyleMediumImpact,
- Thickness = ThicknessMediumImpact
- };
-
- case NewsEventImpact.Low:
- return new LineSettings
- {
- Color = _colorLowImpact,
- Style = LineStyleLowImpact,
- Thickness = ThicknessLowImpact
- };
-
- default:
- return new LineSettings
- {
- Color = _colorOthers,
- Style = LineStyleOthers,
- Thickness = ThicknessOthers
- };
- }
- }
-
- private void RemoveEventLines()
- {
- var chartObjects = Chart.Objects.ToArray();
-
- foreach (var chartObject in chartObjects)
- {
- if (chartObject.ObjectType != ChartObjectType.VerticalLine || !chartObject.IsInteractive || string.IsNullOrEmpty(chartObject.Name) || !chartObject.Name.EndsWith("Event", StringComparison.OrdinalIgnoreCase))
- {
- continue;
- }
-
- Chart.RemoveObject(chartObject.Name);
- }
- }
- }
-
- [XmlRoot("weeklyevents")]
- public class WeeklyEvents
- {
- [XmlElement("event")]
- public List Events { get; set; }
- }
-
- public class NewsEvent
- {
- [XmlElement("title")]
- public string Title { get; set; }
-
- [XmlElement("country")]
- public string Currency { get; set; }
-
- [XmlElement("date")]
- public string UtcDate { get; set; }
-
- [XmlElement("time")]
- public string UtcTime { get; set; }
-
- [XmlIgnore]
- public DateTimeOffset? Time { get; set; }
-
- [XmlElement("impact")]
- public NewsEventImpact Impact { get; set; }
-
- [XmlElement("previous")]
- public string Previous { get; set; }
-
- [XmlElement("forecast")]
- public string Forecast { get; set; }
- }
-
- public enum NewsEventImpact
- {
- None,
-
- High,
-
- Medium,
-
- Low,
-
- Holiday
- }
-
- public struct LineSettings
- {
- public Color Color { get; set; }
-
- public LineStyle Style { get; set; }
-
- public int Thickness { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Economic Events On Chart.csproj b/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Economic Events On Chart.csproj
deleted file mode 100644
index b2d03cf..0000000
--- a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Economic Events On Chart.csproj
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
- 7.2
- Debug
- AnyCPU
- {7D9A4560-D021-4B46-8D58-83DCBEBBE654}
- {DD87C1B2-3799-4CA2-93B6-5288EE928820};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- cAlgo
- Economic Events On Chart
- v4.0
- Client
- 512
- True
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
- False
- ..\..\..\..\API\cAlgo.API.dll
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Properties/AssemblyInfo.cs b/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Properties/AssemblyInfo.cs
deleted file mode 100644
index 5334d9f..0000000
--- a/Sources/Indicators/Economic Events On Chart/Economic Events On Chart/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Diagnostics;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Economic Events On Chart")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyProduct("Economic Events On Chart")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: ComVisible(false)]
-
-[assembly: Guid("35f19c43-c7cc-4f53-b8e0-61caaf9cd8e8")]
-
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-#if DEBUG
- [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations)]
-#endif
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterDisplay.algo b/Sources/Indicators/HmaClusterDisplay.algo
index 17e0f49..a6155d4 100644
Binary files a/Sources/Indicators/HmaClusterDisplay.algo and b/Sources/Indicators/HmaClusterDisplay.algo differ
diff --git a/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.cs b/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.cs
index 390e899..46d8a11 100644
--- a/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.cs
+++ b/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.cs
@@ -1,9 +1,8 @@
using System;
-using System.IO;
-using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
+using Myc.HmaSma;
namespace cAlgo
{
@@ -39,7 +38,7 @@ namespace cAlgo
private HullMovingAverage _hmaBiasIndicator;
private HullMovingAverage _hmaClusterIndicator;
- // Default values from prompt header
+ // Default values
private int _smaBiasLength = 200;
private int _hmaBiasLength = 250;
private int _hmaClusterLength = 25;
@@ -48,7 +47,7 @@ namespace cAlgo
protected override void Initialize()
{
- LoadConfiguration();
+ ApplyExternalConfiguration();
// Initialize indicators with loaded or default values
_smaBiasIndicator = Indicators.SimpleMovingAverage(Bars.ClosePrices, _smaBiasLength);
@@ -62,73 +61,39 @@ namespace cAlgo
{
if (_smaBiasIndicator != null)
SmaBiasOutput[index] = _smaBiasIndicator.Result[index];
-
+
if (_hmaBiasIndicator != null)
HmaBiasOutput[index] = _hmaBiasIndicator.Result[index];
-
+
if (_hmaClusterIndicator != null)
HmaClusterOutput[index] = _hmaClusterIndicator.Result[index];
}
- private void LoadConfiguration()
+ private void ApplyExternalConfiguration()
{
- if (!File.Exists(ConfigFilePath))
- {
- Print($"Config file not found at {ConfigFilePath}. Using defaults.");
- return;
- }
-
try
{
- var lines = File.ReadAllLines(ConfigFilePath);
- var currentSymbol = SymbolName;
- // cTrader ShortName returns "m5", "h1", etc. which matches your file format
- var currentTimeframe = TimeFrame.ShortName;
+ var loader = new HmaSmaLoader(ConfigFilePath);
+ loader.Load();
- foreach (var line in lines)
+ // cTrader TimeFrame.ShortName returns values like "m5", "h1" which match the library expectation
+ var parameters = loader.GetParameters(SymbolName, TimeFrame.ShortName);
+
+ if (parameters != null)
{
- var trimmedLine = line.Trim();
-
- // Skip comments and empty lines
- if (string.IsNullOrWhiteSpace(trimmedLine) || trimmedLine.StartsWith("#"))
- continue;
-
- // Split by whitespace
- var columns = trimmedLine.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
-
- // Ensure we have enough columns (need at least up to index 6)
- if (columns.Length < 7)
- continue;
-
- var cfgSymbol = columns[0];
- var cfgTimeframe = columns[1];
-
- // Check for match (case-insensitive)
- if (string.Equals(cfgSymbol, currentSymbol, StringComparison.OrdinalIgnoreCase) &&
- string.Equals(cfgTimeframe, currentTimeframe, StringComparison.OrdinalIgnoreCase))
- {
- // Parse values
- // Col 4: SmaBias
- // Col 5: HmaBias
- // Col 6: HmaCluster
- if (int.TryParse(columns[4], out int sBias) &&
- int.TryParse(columns[5], out int hBias) &&
- int.TryParse(columns[6], out int hCluster))
- {
- _smaBiasLength = sBias;
- _hmaBiasLength = hBias;
- _hmaClusterLength = hCluster;
- Print($"Configuration found for {currentSymbol} {currentTimeframe}");
- return; // Stop searching after match
- }
- }
+ _smaBiasLength = parameters.SmaBias;
+ _hmaBiasLength = parameters.HmaBias;
+ _hmaClusterLength = parameters.HmaCluster;
+ Print($"Configuration loaded for {SymbolName} {TimeFrame.ShortName}");
+ }
+ else
+ {
+ Print($"No specific config found for {SymbolName} {TimeFrame.ShortName}. Using defaults.");
}
-
- Print($"No specific config found for {currentSymbol} {currentTimeframe}. Using defaults.");
}
catch (Exception ex)
{
- Print($"Error reading config file: {ex.Message}. Using defaults.");
+ Print($"Error loading configuration: {ex.Message}. Using defaults.");
}
}
}
diff --git a/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.csproj b/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.csproj
index da1fef1..866383b 100644
--- a/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.csproj
+++ b/Sources/Indicators/HmaClusterDisplay/HmaClusterDisplay/HmaClusterDisplay.csproj
@@ -1,9 +1,14 @@
+
net6.0
-
-
+
+
+ ..\..\..\Common\MSLib\obj\Debug\net6.0\MSLib.dll
+
+
+
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR.algo b/Sources/Indicators/HmaClusterSR.algo
index 329c2c4..d1d1a03 100644
Binary files a/Sources/Indicators/HmaClusterSR.algo and b/Sources/Indicators/HmaClusterSR.algo differ
diff --git a/Sources/Indicators/HmaClusterSR/.vscode/tasks.json b/Sources/Indicators/HmaClusterSR/.vscode/tasks.json
new file mode 100644
index 0000000..215166e
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/.vscode/tasks.json
@@ -0,0 +1 @@
+{"version":"2.0.0","tasks":[{"label":"build","command":"dotnet","type":"process","args":["build","${workspaceFolder}","/property:GenerateFullPaths=true","/consoleLoggerParameters:NoSummary"],"problemMatcher":"$msCompile"}]}
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.cs b/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.cs
index 5495496..c421f70 100644
--- a/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.cs
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.cs
@@ -1,777 +1,72 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
-using System.Net.Http;
-using System.Threading.Tasks;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
+using Myc;
-namespace cAlgo.Robots
+namespace cAlgo.Indicators
{
- [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
- public class HmaClusterBot : Robot
+ [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
+ public class HmaClusterSR : Indicator
{
#region Parameters
+ [Parameter("HMA Period", DefaultValue = 25, MinValue = 2)]
+ public int HmaPeriod { get; set; }
- [Parameter("Symbols (CSV)", DefaultValue = "", Group = "Multi Symbol")]
- public string SymbolsCsv { get; set; }
+ [Parameter("Amplitude Period (Swings)", DefaultValue = 50, MinValue = 1)]
+ public int AmplitudePeriod { get; set; }
- [Parameter("Risk % of Balance", DefaultValue = 1.0, MinValue = 0.1, MaxValue = 10.0, Group = "Risk")]
- public double RiskPercent { get; set; }
+ [Parameter("Auto Range Multiplier", DefaultValue = 0.5, MinValue = 0.05, MaxValue = 1.0)]
+ public double RangeMultiplier { get; set; }
- [Parameter("Entry Significance %", DefaultValue = 20.0, MinValue = 1.0, Group = "Thresholds")]
- public double EntrySigThreshold { get; set; }
-
- [Parameter("Stop Loss Significance %", DefaultValue = 10.0, MinValue = 1.0, Group = "Thresholds")]
- public double SlSigThreshold { get; set; }
-
- [Parameter("SMA Bias Period", DefaultValue = 200, Group = "Bias")]
- public int SmaBiasPeriod { get; set; }
-
- [Parameter("HMA Bias Period", DefaultValue = 250, Group = "Bias")]
- public int HmaBiasPeriod { get; set; }
-
- [Parameter("Use Bias Deviation Filter", DefaultValue = true, Group = "Bias Filter")]
- public bool UseBiasDeviationFilter { get; set; }
-
- [Parameter("Bias Deviation Avg Period", DefaultValue = 500, Group = "Bias Filter")]
- public int BiasDeviationAvgPeriod { get; set; }
-
- [Parameter("Use Dynamic Position Management", DefaultValue = true, Group = "Management")]
- public bool UseDynamicPositionManagement { get; set; }
-
- [Parameter("Close Profit on Bias Flip", DefaultValue = false, Group = "Management")]
- public bool CloseProfitOnBiasFlip { get; set; }
-
- [Parameter("HMA Cluster Period", DefaultValue = 25, Group = "Clusters")]
- public int HmaClusterPeriod { get; set; }
-
- [Parameter("Cluster Max Points", DefaultValue = 2000, Group = "Clusters")]
+ [Parameter("Buffer Size (Points)", DefaultValue = 2000, MinValue = 10)]
public int MaxPoints { get; set; }
- [Parameter("Cluster Decay (Bars)", DefaultValue = 1000, Group = "Clusters")]
+ [Parameter("Decay Period (Bars)", DefaultValue = 1000, MinValue = 100)]
public int DecayPeriod { get; set; }
- // --- Telegram Parameters ---
- [Parameter("Send Telegram Only", DefaultValue = false, Group = "Telegram")]
- public bool SendTelegramOnly { get; set; }
-
- [Parameter("Telegram Bot Token", DefaultValue = "8569913524:AAE9RGsvkBPa0yhTFCKBjVeST0fuzdOx5w0", Group = "Telegram")]
- public string TelegramBotToken { get; set; }
-
- [Parameter("Telegram Chat ID", DefaultValue = "5171721381", Group = "Telegram")]
- public string TelegramChatId { get; set; }
-
+ [Parameter("Max Zones", DefaultValue = 100, MinValue = 1)]
+ public int MaxZones { get; set; }
#endregion
- private readonly List _strategies = new List();
- private static readonly HttpClient _httpClient = new HttpClient();
-
- protected override void OnStart()
- {
- try
- {
- if (string.IsNullOrWhiteSpace(SymbolsCsv))
- {
- Print("CSV is empty. Running in Single-Symbol Mode on Chart Symbol.");
-
- var config = new StrategyConfig
- {
- SymbolName = SymbolName,
- EntrySigThreshold = EntrySigThreshold,
- SlSigThreshold = SlSigThreshold,
- SmaBiasPeriod = SmaBiasPeriod,
- HmaBiasPeriod = HmaBiasPeriod,
- HmaClusterPeriod = HmaClusterPeriod,
- UseBiasDeviationFilter = UseBiasDeviationFilter,
- BiasDeviationAvgPeriod = BiasDeviationAvgPeriod,
- UseDynamicPositionManagement = UseDynamicPositionManagement,
- CloseProfitOnBiasFlip = CloseProfitOnBiasFlip,
- SendTelegramOnly = SendTelegramOnly,
- RiskPercent = RiskPercent,
- MaxPoints = MaxPoints,
- DecayPeriod = DecayPeriod
- };
-
- var strategy = new ClusterStrategy(this, Symbol, Bars, config, _httpClient, TelegramBotToken, TelegramChatId, BroadcastError);
- _strategies.Add(strategy);
- strategy.Start();
- }
- else
- {
- Print("CSV detected. Running in Multi-Symbol Mode.");
- ParseCsvAndCreateStrategies();
- }
- }
- catch (Exception ex)
- {
- BroadcastError($"CRITICAL STARTUP ERROR: {ex.Message}");
- Stop();
- }
- }
-
- protected override void OnStop()
- {
- foreach (var strategy in _strategies)
- {
- strategy.Stop();
- }
- }
-
- protected override void OnError(Error error)
- {
- BroadcastError($"TRADING ERROR [{error.Code}]: {error.ToString}");
- }
-
- public void BroadcastError(string message)
- {
- Print(message);
-
- if (!string.IsNullOrWhiteSpace(TelegramBotToken) && !string.IsNullOrWhiteSpace(TelegramChatId))
- {
- string formattedMsg = $"⚠️ ERROR @ {DateTime.UtcNow:HH:mm:ss} UTC\n\n{message}";
- _ = SendTelegramRawAsync(TelegramBotToken, TelegramChatId, formattedMsg);
- }
- }
-
- private async Task SendTelegramRawAsync(string token, string chatId, string message)
- {
- try
- {
- string url = $"https://api.telegram.org/bot{token}/sendMessage?chat_id={chatId}&text={Uri.EscapeDataString(message)}&parse_mode=HTML";
- await _httpClient.GetAsync(url);
- }
- catch (Exception ex)
- {
- Print("FAILED TO SEND TELEGRAM ERROR: " + ex.Message);
- }
- }
-
- private void ParseCsvAndCreateStrategies()
- {
- var normalizedCsv = SymbolsCsv.Replace("\n", ",").Replace("\r", ",");
-
- var tokens = normalizedCsv.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
- .Select(t => t.Trim())
- .Where(t => !string.IsNullOrEmpty(t))
- .ToArray();
-
- int paramsPerSymbol = 10;
-
- if (tokens.Length % paramsPerSymbol != 0)
- {
- string err = $"CSV Token count ({tokens.Length}) is not a multiple of {paramsPerSymbol}. Check format.";
- BroadcastError(err);
- }
-
- for (int i = 0; i < tokens.Length; i += paramsPerSymbol)
- {
- if (i + paramsPerSymbol > tokens.Length) break;
-
- string symName = tokens[i];
-
- try
- {
- Symbol symbol = Symbols.GetSymbol(symName);
- if (symbol == null)
- {
- BroadcastError($"Symbol '{symName}' not found in cTrader.");
- continue;
- }
-
- Bars bars = MarketData.GetBars(TimeFrame, symName);
-
- var config = new StrategyConfig
- {
- SymbolName = symName,
- EntrySigThreshold = double.Parse(tokens[i + 1], CultureInfo.InvariantCulture),
- SlSigThreshold = double.Parse(tokens[i + 2], CultureInfo.InvariantCulture),
- SmaBiasPeriod = int.Parse(tokens[i + 3], CultureInfo.InvariantCulture),
- HmaBiasPeriod = int.Parse(tokens[i + 4], CultureInfo.InvariantCulture),
- HmaClusterPeriod = int.Parse(tokens[i + 5], CultureInfo.InvariantCulture),
- UseBiasDeviationFilter = bool.Parse(tokens[i + 6]),
- BiasDeviationAvgPeriod = int.Parse(tokens[i + 7], CultureInfo.InvariantCulture),
- UseDynamicPositionManagement = bool.Parse(tokens[i + 8]),
- SendTelegramOnly = bool.Parse(tokens[i + 9]),
-
- // Default values for parameters not in CSV yet
- CloseProfitOnBiasFlip = CloseProfitOnBiasFlip,
- RiskPercent = RiskPercent,
- MaxPoints = MaxPoints,
- DecayPeriod = DecayPeriod
- };
-
- var strategy = new ClusterStrategy(this, symbol, bars, config, _httpClient, TelegramBotToken, TelegramChatId, BroadcastError);
- _strategies.Add(strategy);
- strategy.Start();
-
- Print("Initialized Strategy for {0}", symName);
- }
- catch (Exception ex)
- {
- BroadcastError($"Config Error for '{symName}': {ex.Message}");
- }
- }
- }
- }
-
- public class StrategyConfig
- {
- public string SymbolName { get; set; }
- public double EntrySigThreshold { get; set; }
- public double SlSigThreshold { get; set; }
- public int SmaBiasPeriod { get; set; }
- public int HmaBiasPeriod { get; set; }
- public int HmaClusterPeriod { get; set; }
- public bool UseBiasDeviationFilter { get; set; }
- public int BiasDeviationAvgPeriod { get; set; }
- public bool UseDynamicPositionManagement { get; set; }
- public bool CloseProfitOnBiasFlip { get; set; }
- public bool SendTelegramOnly { get; set; }
- public double RiskPercent { get; set; }
- public int MaxPoints { get; set; }
- public int DecayPeriod { get; set; }
- }
-
- public class ClusterStrategy
- {
- #region Types & Fields
-
- private enum PointType { Peak, Trough }
- private enum Bias { Long, Short, Neutral }
-
- private struct ExtremumPoint
- {
- public double Price;
- public int Index;
- public PointType Type;
- }
-
- public struct ClusterLevel
- {
- public double Price;
- public double Significance;
- }
-
- private readonly Robot _robot;
- private readonly Symbol _symbol;
- private readonly Bars _bars;
- private readonly StrategyConfig _config;
- private readonly HttpClient _httpClient;
- private readonly string _botToken;
- private readonly string _chatId;
- private readonly Action _errorCallback;
-
- private SimpleMovingAverage _smaBias;
- private HullMovingAverage _hmaBias;
- private HullMovingAverage _hmaCluster;
-
- private readonly Queue _deviationQueue = new Queue();
- private double _runningDeviationSum;
+ #region Fields
+ private HullMovingAverage _hma;
- private bool _deviationConditionMetInCurrentCycle;
- private bool _isTradingAllowedBasedOnPrevCycle;
+ // Neue optimierte Engine
+ private ClusterCalculator _calculator;
- private readonly List _extremaPoints = new();
+ // Lokaler State für Trend
private readonly List _amplitudes = new();
-
private double _trendExtremum;
private int _trendExtremumIndex;
private double _lastExtremumPrice;
private bool? _isUpTrend;
private double _currentDynamicRange;
-
- private const string Label = "HmaClusterBot";
-
#endregion
- public ClusterStrategy(
- Robot robot,
- Symbol symbol,
- Bars bars,
- StrategyConfig config,
- HttpClient httpClient,
- string token,
- string chatId,
- Action errorCallback)
+ protected override void Initialize()
{
- _robot = robot;
- _symbol = symbol;
- _bars = bars;
- _config = config;
- _httpClient = httpClient;
- _botToken = token;
- _chatId = chatId;
- _errorCallback = errorCallback;
- }
-
- public void Start()
- {
- int requiredBars = Math.Max(_config.SmaBiasPeriod, _config.HmaBiasPeriod);
- requiredBars = Math.Max(requiredBars, _config.BiasDeviationAvgPeriod) + 10;
-
- while (_bars.Count < requiredBars)
- {
- int loaded = _bars.LoadMoreHistory();
- if (loaded == 0)
- {
- _errorCallback?.Invoke($"Not enough history for {_config.SymbolName}. Loaded: {_bars.Count}, Req: {requiredBars}");
- return;
- }
- }
-
- _smaBias = _robot.Indicators.SimpleMovingAverage(_bars.ClosePrices, _config.SmaBiasPeriod);
- _hmaBias = _robot.Indicators.HullMovingAverage(_bars.ClosePrices, _config.HmaBiasPeriod);
- _hmaCluster = _robot.Indicators.HullMovingAverage(_bars.ClosePrices, _config.HmaClusterPeriod);
-
- _currentDynamicRange = 5.0 * _symbol.PipSize;
- _deviationConditionMetInCurrentCycle = false;
- _isTradingAllowedBasedOnPrevCycle = false;
-
- int startIndex = Math.Max(_config.SmaBiasPeriod, _config.HmaBiasPeriod);
- startIndex = Math.Max(startIndex, _config.BiasDeviationAvgPeriod);
+ Print("Initializing HmaClusterSR with Optimized Engine. Symbol: {0}", Symbol.Name);
- for (int i = startIndex; i < _bars.Count; i++)
- {
- UpdateFilterState(i);
- UpdateClusterData(i);
- }
-
- _bars.BarOpened += OnBarOpened;
- }
-
- public void Stop()
- {
- _bars.BarOpened -= OnBarOpened;
- }
-
- private void OnBarOpened(BarOpenedEventArgs obj)
- {
- try
- {
- int index = _bars.Count - 2;
- if (index < _config.BiasDeviationAvgPeriod) return;
-
- UpdateFilterState(index);
- UpdateClusterData(index);
-
- var clusters = CalculateClusters(index);
-
- // 1. Dynamic SL/TP Management
- if (!_config.SendTelegramOnly && _config.UseDynamicPositionManagement && clusters.Count >= 2)
- {
- ManagePositions(clusters);
- }
-
- var currentBias = GetCurrentBias(index);
-
- // 2. Check for Profit Close on Bias Flip
- if (!_config.SendTelegramOnly && _config.CloseProfitOnBiasFlip)
- {
- CloseReversedPositions(currentBias);
- }
-
- // 3. New Entry Logic
- ManageOrders(currentBias, index, clusters);
- }
- catch (Exception ex)
- {
- _errorCallback?.Invoke($"Runtime Error ({_config.SymbolName}): {ex.Message}\n{ex.StackTrace}");
- }
- }
-
- private void CloseReversedPositions(Bias currentBias)
- {
- if (currentBias == Bias.Neutral) return;
-
- foreach (var pos in _robot.Positions)
- {
- if (pos.SymbolName != _config.SymbolName || pos.Label != Label) continue;
- if (pos.NetProfit <= 0) continue;
-
- bool close = false;
-
- if (currentBias == Bias.Short && pos.TradeType == TradeType.Buy)
- close = true;
- else if (currentBias == Bias.Long && pos.TradeType == TradeType.Sell)
- close = true;
-
- if (close)
- {
- var result = _robot.ClosePosition(pos);
- if (result.IsSuccessful)
- {
- string msg = $"🔒 CLOSE PROFIT (Bias Flip) @ {_config.SymbolName}\n" +
- $"Profit: {pos.NetProfit:F2}";
- _ = SendTelegramMessageAsync(msg);
- }
- }
- }
- }
-
- private void UpdateFilterState(int index)
- {
- double currHma = _hmaBias.Result[index];
- double currSma = _smaBias.Result[index];
- double prevHma = _hmaBias.Result[index - 1];
- double prevSma = _smaBias.Result[index - 1];
-
- double currentBiasDeviation = Math.Abs(currHma - currSma);
+ _hma = Indicators.HullMovingAverage(Bars.ClosePrices, HmaPeriod);
- _deviationQueue.Enqueue(currentBiasDeviation);
- _runningDeviationSum += currentBiasDeviation;
-
- if (_deviationQueue.Count > _config.BiasDeviationAvgPeriod)
- {
- double removed = _deviationQueue.Dequeue();
- _runningDeviationSum -= removed;
- }
-
- double averageDeviation = (_deviationQueue.Count > 0)
- ? _runningDeviationSum / _deviationQueue.Count
- : 0.0;
-
- bool currHmaAbove = currHma > currSma;
- bool prevHmaAbove = prevHma > prevSma;
-
- if (currHmaAbove != prevHmaAbove)
- {
- _isTradingAllowedBasedOnPrevCycle = _deviationConditionMetInCurrentCycle;
- _deviationConditionMetInCurrentCycle = false;
- }
-
- if (currentBiasDeviation > averageDeviation)
- {
- _deviationConditionMetInCurrentCycle = true;
- }
- }
-
- private Bias GetCurrentBias(int index)
- {
- double hma = _hmaBias.Result[index];
- double sma = _smaBias.Result[index];
- double prevSma = _smaBias.Result[index - 1];
-
- if ((hma > sma) && (sma > prevSma)) return Bias.Long;
- if ((hma < sma) && (sma < prevSma)) return Bias.Short;
-
- return Bias.Neutral;
- }
-
- private void ManagePositions(List clusters)
- {
- double pNow = _symbol.Bid;
-
- foreach (var pos in _robot.Positions)
- {
- if (pos.Label != Label || pos.SymbolName != _config.SymbolName) continue;
-
- ClusterLevel? newSl = null;
- ClusterLevel? newTp = null;
-
- if (pos.TradeType == TradeType.Buy)
- {
- double highestSlPrice = double.MinValue;
- double highestTpPrice = double.MinValue;
-
- foreach (var c in clusters)
- {
- if (c.Price < pNow && c.Significance < _config.SlSigThreshold && c.Price > highestSlPrice)
- {
- newSl = c;
- highestSlPrice = c.Price;
- }
- if (c.Price > pNow && c.Significance >= _config.EntrySigThreshold && c.Price > highestTpPrice)
- {
- newTp = c;
- highestTpPrice = c.Price;
- }
- }
-
- double proposedSl = (newSl.HasValue) ? newSl.Value.Price : (pos.StopLoss ?? 0);
- double proposedTp = (newTp.HasValue) ? newTp.Value.Price : (pos.TakeProfit ?? 0);
-
- bool modifySl = pos.StopLoss.HasValue && (proposedSl > pos.StopLoss.Value + _symbol.TickSize);
- if (!pos.StopLoss.HasValue && newSl.HasValue) modifySl = true;
-
- bool modifyTp = newTp.HasValue && Math.Abs(proposedTp - (pos.TakeProfit ?? 0)) > _symbol.TickSize;
-
- if (modifySl || modifyTp)
- {
- double finalSl = modifySl ? proposedSl : pos.StopLoss ?? 0;
- double finalTp = modifyTp ? proposedTp : pos.TakeProfit ?? 0;
-
- if (finalSl < _symbol.Bid && (finalTp == 0 || finalTp > _symbol.Bid))
- {
- _robot.ModifyPosition(pos, finalSl, finalTp, ProtectionType.Absolute);
- }
- }
- }
- else // Sell
- {
- double lowestSlPrice = double.MaxValue;
- double lowestTpPrice = double.MaxValue;
-
- foreach (var c in clusters)
- {
- if (c.Price > pNow && c.Significance < _config.SlSigThreshold && c.Price < lowestSlPrice)
- {
- newSl = c;
- lowestSlPrice = c.Price;
- }
- if (c.Price < pNow && c.Significance >= _config.EntrySigThreshold && c.Price < lowestTpPrice)
- {
- newTp = c;
- lowestTpPrice = c.Price;
- }
- }
-
- double proposedSl = (newSl.HasValue) ? newSl.Value.Price : (pos.StopLoss ?? 0);
- double proposedTp = (newTp.HasValue) ? newTp.Value.Price : (pos.TakeProfit ?? 0);
-
- bool modifySl = pos.StopLoss.HasValue && (proposedSl < pos.StopLoss.Value - _symbol.TickSize);
- if (!pos.StopLoss.HasValue && newSl.HasValue) modifySl = true;
-
- bool modifyTp = newTp.HasValue && Math.Abs(proposedTp - (pos.TakeProfit ?? 0)) > _symbol.TickSize;
-
- if (modifySl || modifyTp)
- {
- double finalSl = modifySl ? proposedSl : pos.StopLoss ?? 0;
- double finalTp = modifyTp ? proposedTp : pos.TakeProfit ?? 0;
-
- if (finalSl > _symbol.Ask && (finalTp == 0 || finalTp < _symbol.Ask))
- {
- _robot.ModifyPosition(pos, finalSl, finalTp, ProtectionType.Absolute);
- }
- }
- }
- }
- }
-
- private void ManageOrders(Bias bias, int index, List clusters)
- {
- CleanupOrders(bias);
-
- if (_config.UseBiasDeviationFilter && !_isTradingAllowedBasedOnPrevCycle)
- return;
-
- if (bias == Bias.Neutral) return;
-
- if (!_config.SendTelegramOnly)
- {
- bool hasLong = _robot.Positions.Any(p => p.SymbolName == _config.SymbolName && p.Label == Label && p.TradeType == TradeType.Buy);
- bool hasShort = _robot.Positions.Any(p => p.SymbolName == _config.SymbolName && p.Label == Label && p.TradeType == TradeType.Sell);
-
- if ((bias == Bias.Long && hasLong) || (bias == Bias.Short && hasShort))
- return;
- }
-
- if (clusters.Count < 2) return;
-
- double pNow = _bars.ClosePrices[index];
-
- if (bias == Bias.Short)
- ProcessShortSetup(clusters, pNow);
- else if (bias == Bias.Long)
- ProcessLongSetup(clusters, pNow);
- }
-
- private void CleanupOrders(Bias currentBias)
- {
- if (_config.SendTelegramOnly) return;
-
- foreach (var order in _robot.PendingOrders)
- {
- if (order.Label != Label || order.SymbolName != _config.SymbolName) continue;
-
- if (currentBias == Bias.Long && order.TradeType == TradeType.Sell)
- _robot.CancelPendingOrder(order);
- else if (currentBias == Bias.Short && order.TradeType == TradeType.Buy)
- _robot.CancelPendingOrder(order);
- else if (currentBias == Bias.Neutral)
- _robot.CancelPendingOrder(order);
- }
- }
-
- private void ProcessShortSetup(List clusters, double pNow)
- {
- ClusterLevel? entry = null;
- ClusterLevel? sl = null;
- ClusterLevel? tp = null;
-
- double highestEntryPrice = double.MinValue;
- double lowestSlPrice = double.MaxValue;
- double lowestTpPrice = double.MaxValue;
-
- foreach (var c in clusters)
- {
- if (c.Price > pNow)
- {
- if ((c.Significance >= _config.EntrySigThreshold) && (c.Price > highestEntryPrice))
- {
- entry = c;
- highestEntryPrice = c.Price;
- }
- if ((c.Significance < _config.SlSigThreshold) && (c.Price < lowestSlPrice))
- {
- sl = c;
- lowestSlPrice = c.Price;
- }
- }
- }
-
- if (entry == null || sl == null) return;
-
- foreach (var c in clusters)
- {
- if ((c.Price < entry.Value.Price) && (c.Significance >= _config.EntrySigThreshold))
- {
- if (c.Price < lowestTpPrice)
- {
- tp = c;
- lowestTpPrice = c.Price;
- }
- }
- }
-
- if (tp != null && (sl.Value.Price > entry.Value.Price))
- {
- double risk = sl.Value.Price - entry.Value.Price;
- double reward = entry.Value.Price - tp.Value.Price;
-
- if (risk <= reward)
- UpdateOrPlaceLimitOrder(TradeType.Sell, entry.Value.Price, sl.Value.Price, tp.Value.Price);
- }
- }
-
- private void ProcessLongSetup(List clusters, double pNow)
- {
- ClusterLevel? entry = null;
- ClusterLevel? sl = null;
- ClusterLevel? tp = null;
-
- double lowestEntryPrice = double.MaxValue;
- double highestSlPrice = double.MinValue;
- double highestTpPrice = double.MinValue;
-
- foreach (var c in clusters)
- {
- if (c.Price < pNow)
- {
- if ((c.Significance >= _config.EntrySigThreshold) && (c.Price < lowestEntryPrice))
- {
- entry = c;
- lowestEntryPrice = c.Price;
- }
- if ((c.Significance < _config.SlSigThreshold) && (c.Price > highestSlPrice))
- {
- sl = c;
- highestSlPrice = c.Price;
- }
- }
- }
-
- if (entry == null || sl == null) return;
-
- foreach (var c in clusters)
- {
- if ((c.Price > entry.Value.Price) && (c.Significance >= _config.EntrySigThreshold))
- {
- if (c.Price > highestTpPrice)
- {
- tp = c;
- highestTpPrice = c.Price;
- }
- }
- }
-
- if (tp != null && (sl.Value.Price < entry.Value.Price))
- {
- double risk = entry.Value.Price - sl.Value.Price;
- double reward = tp.Value.Price - entry.Value.Price;
-
- if (risk <= reward)
- UpdateOrPlaceLimitOrder(TradeType.Buy, entry.Value.Price, sl.Value.Price, tp.Value.Price);
- }
- }
-
- private void UpdateOrPlaceLimitOrder(TradeType type, double entry, double sl, double tp)
- {
- double slDistPips = Math.Abs(entry - sl) / _symbol.PipSize;
- if (slDistPips <= 0) return;
-
- double riskAmount = _robot.Account.Balance * (_config.RiskPercent / 100.0);
- double volume = _symbol.VolumeForFixedRisk(riskAmount, slDistPips);
+ // Calculator initialisieren mit der Kapazität aus den Parametern
+ _calculator = new ClusterCalculator(MaxPoints);
- volume = _symbol.NormalizeVolumeInUnits(volume, RoundingMode.Down);
- if (volume < _symbol.VolumeInUnitsMin) return;
-
- double lots = _symbol.VolumeInUnitsToQuantity(volume);
-
- if (_config.SendTelegramOnly)
- {
- string directionStr = type == TradeType.Buy ? "BUY" : "SELL";
- string directionIcon = type == TradeType.Buy ? "📈" : "📉";
- string msg = $"{directionIcon} {directionStr} Signal @ {_config.SymbolName}\n\n" +
- $"Entry: {entry}\n" +
- $"SL: {sl}\n" +
- $"TP: {tp}\n" +
- $"Vol: {lots:F2} Lots";
-
- _ = SendTelegramMessageAsync(msg);
- return;
- }
-
- var existingOrder = _robot.PendingOrders.FirstOrDefault(o => o.SymbolName == _config.SymbolName && o.Label == Label && o.TradeType == type);
-
- if (existingOrder != null)
- {
- bool volumeChanged = Math.Abs(existingOrder.VolumeInUnits - volume) > _symbol.VolumeInUnitsStep;
- bool entryChanged = Math.Abs(existingOrder.TargetPrice - entry) > _symbol.TickSize;
- bool slChanged = Math.Abs((existingOrder.StopLoss ?? 0) - sl) > _symbol.TickSize;
- bool tpChanged = Math.Abs((existingOrder.TakeProfit ?? 0) - tp) > _symbol.TickSize;
-
- if (volumeChanged || entryChanged || slChanged || tpChanged)
- {
- _robot.ModifyPendingOrder(existingOrder, entry, sl, tp, ProtectionType.Absolute, null, volume);
- }
- }
- else
- {
- _robot.Print("[SIGNAL] {0} {1} | Entry: {2} | SL: {3} | TP: {4} | Vol: {5:F2} Lots",
- (type == TradeType.Buy ? "BUY" : "SELL"), _config.SymbolName, entry, sl, tp, lots);
-
- _robot.PlaceLimitOrder(type, _config.SymbolName, volume, entry, Label, sl, tp, ProtectionType.Absolute);
- }
+ _currentDynamicRange = 5.0 * Symbol.PipSize;
}
- private async Task SendTelegramMessageAsync(string message)
+ public override void Calculate(int index)
{
- if (_robot.IsBacktesting) return;
- if (string.IsNullOrWhiteSpace(_botToken) || string.IsNullOrWhiteSpace(_chatId)) return;
+ if (index < 1) return;
- try
- {
- string url = $"https://api.telegram.org/bot{_botToken}/sendMessage?chat_id={_chatId}&text={Uri.EscapeDataString(message)}&parse_mode=HTML";
- HttpResponseMessage response = await _httpClient.GetAsync(url);
-
- if (!response.IsSuccessStatusCode)
- {
- _errorCallback?.Invoke($"Telegram Error: {response.StatusCode}");
- }
- }
- catch (Exception ex)
- {
- _errorCallback?.Invoke($"Telegram Exception: {ex.Message}");
- }
- }
+ double currentHma = _hma.Result[index];
+ double prevHma = _hma.Result[index - 1];
+
+ if (double.IsNaN(currentHma)) return;
- private void UpdateClusterData(int index)
- {
- double currentHma = _hmaCluster.Result[index];
- double prevHma = _hmaCluster.Result[index - 1];
bool currentDirectionUp = (currentHma > prevHma);
if (_isUpTrend == null)
@@ -784,22 +79,7 @@ namespace cAlgo.Robots
if (currentDirectionUp != _isUpTrend)
{
- double amp = Math.Abs(_trendExtremum - _lastExtremumPrice);
- if (amp > 0)
- {
- _amplitudes.Add(amp);
- if (_amplitudes.Count > 50) _amplitudes.RemoveAt(0);
-
- double sum = 0;
- for (int i = 0; i < _amplitudes.Count; i++) sum += _amplitudes[i];
- _currentDynamicRange = (sum / _amplitudes.Count) * 0.5;
- }
- _extremaPoints.Add(new ExtremumPoint { Price = _trendExtremum, Index = _trendExtremumIndex, Type = _isUpTrend.Value ? PointType.Peak : PointType.Trough });
- if (_extremaPoints.Count > _config.MaxPoints) _extremaPoints.RemoveAt(0);
-
- _lastExtremumPrice = _trendExtremum;
- _isUpTrend = currentDirectionUp;
- SetExtremum(index);
+ HandleTrendReversal(index, currentDirectionUp);
}
else
{
@@ -807,69 +87,132 @@ namespace cAlgo.Robots
}
}
+ private void HandleTrendReversal(int index, bool currentDirectionUp)
+ {
+ // 1. Amplitude berechnen & Dynamische Range updaten
+ double amplitude = Math.Abs(_trendExtremum - _lastExtremumPrice);
+ if (amplitude > 0)
+ {
+ _amplitudes.Add(amplitude);
+ if (_amplitudes.Count > AmplitudePeriod) _amplitudes.RemoveAt(0);
+
+ // Simples Average hier direkt berechnen, da es nur ein UI-Scaling ist
+ double avgAmp = _amplitudes.Count > 0 ? _amplitudes.Average() : 5.0 * Symbol.PipSize;
+ _currentDynamicRange = avgAmp * RangeMultiplier;
+ }
+
+ // 2. Punkt in die optimierte Engine pushen
+ // ACHTUNG: AddPoint sortiert automatisch ein (BinarySearch)
+ _calculator.AddPoint(new ExtremumPoint
+ {
+ Price = _trendExtremum,
+ Index = _trendExtremumIndex,
+ Type = _isUpTrend.Value ? PointType.Peak : PointType.Trough
+ });
+
+ _lastExtremumPrice = _trendExtremum;
+
+ // 3. Cluster neu berechnen & Zeichnen
+ UpdateClusters();
+
+ // 4. Reset für neuen Trend
+ _isUpTrend = currentDirectionUp;
+ SetExtremum(index);
+ }
+
private void SetExtremum(int index)
{
- _trendExtremum = _isUpTrend.Value ? _bars.HighPrices[index] : _bars.LowPrices[index];
+ _trendExtremum = _isUpTrend.Value ? Bars.HighPrices[index] : Bars.LowPrices[index];
_trendExtremumIndex = index;
}
private void UpdateExtremum(int index)
{
- if (_isUpTrend.Value && (_bars.HighPrices[index] > _trendExtremum))
+ if (_isUpTrend.Value && Bars.HighPrices[index] > _trendExtremum)
{
- _trendExtremum = _bars.HighPrices[index];
+ _trendExtremum = Bars.HighPrices[index];
_trendExtremumIndex = index;
}
- else if (!_isUpTrend.Value && (_bars.LowPrices[index] < _trendExtremum))
+ else if (!_isUpTrend.Value && Bars.LowPrices[index] < _trendExtremum)
{
- _trendExtremum = _bars.LowPrices[index];
+ _trendExtremum = Bars.LowPrices[index];
_trendExtremumIndex = index;
}
}
- private List CalculateClusters(int currentIndex)
+ private void UpdateClusters()
{
- int count = _extremaPoints.Count;
- if (count < 2) return new List();
+ // Abrufen der aktuellen Markt-Situation
+ int currentIndex = Bars.Count - 1;
+ double currentPrice = Bars.ClosePrices[currentIndex];
- double currentPrice = _bars.ClosePrices[currentIndex];
- double range = _currentDynamicRange;
+ // Engine aufrufen
+ // DecayPeriod ist wichtig für das interne Pruning der Engine
+ var result = _calculator.Calculate(
+ currentIndex,
+ currentPrice,
+ _currentDynamicRange,
+ DecayPeriod,
+ MaxZones
+ );
- // Score-First / Global Density Approach (Matches Indicator)
- var candidates = _extremaPoints
- .Select(p => {
- double weightedScore = _extremaPoints
- .Where(other => Math.Abs(other.Price - p.Price) <= range)
- .Sum(other => GetWeight(other, currentIndex, currentPrice));
-
- return new { Price = p.Price, Score = weightedScore };
- })
- .OrderByDescending(z => z.Score)
- .ToList();
-
- var topZones = new List();
- foreach (var zone in candidates)
+ if (result.Zones.Count == 0)
{
- // Filter Overlap
- if (!topZones.Any(z => Math.Abs(z.Price - zone.Price) < range))
+ ClearLines();
+ return;
+ }
+
+ DrawSignificance(result.Zones, result.TotalWeight);
+ }
+
+ private void DrawSignificance(List zones, double totalWeightSum)
+ {
+ Color baseColor = Color.Aqua;
+
+ // Wir iterieren bis MaxZones oder Listen-Ende.
+ // Die Engine gibt maximal 'MaxZones' zurück, aber sicher ist sicher.
+ int count = Math.Min(zones.Count, MaxZones);
+
+ for (int i = 0; i < MaxZones; i++)
+ {
+ string lineId = $"SR_Line_{i}";
+ string textId = $"SR_Text_{i}";
+
+ if (i < count && zones[i].Score > 0)
{
- // Normalize Score relative to total Weight of all points (Matches Indicator Normalization)
- double totalWeightSum = _extremaPoints.Sum(p => GetWeight(p, currentIndex, currentPrice));
- double sigPercent = (totalWeightSum > 0) ? (zone.Score / totalWeightSum) * 100.0 : 0;
+ var zone = zones[i];
- topZones.Add(new ClusterLevel { Price = zone.Price, Significance = sigPercent });
+ // Verhindere Division durch Null
+ double absSignificance = totalWeightSum > 0 ? zone.Score / totalWeightSum : 0;
+
+ // Transparenz basierend auf Stärke
+ int alpha = (int)(Math.Sqrt(absSignificance) * 255);
+ alpha = Math.Clamp(alpha, 40, 255);
+
+ Color sigColor = Color.FromArgb(alpha, baseColor.R, baseColor.G, baseColor.B);
+
+ // Zeichnen
+ Chart.DrawHorizontalLine(lineId, zone.Price, sigColor, 2, LineStyle.Solid);
+
+ string label = $" {absSignificance:P1}";
+ Chart.DrawText(textId, label, Chart.LastVisibleBarIndex, zone.Price, sigColor);
+ }
+ else
+ {
+ // Aufräumen nicht benutzter Linien-Slots
+ Chart.RemoveObject(lineId);
+ Chart.RemoveObject(textId);
}
}
-
- return topZones;
}
- private double GetWeight(ExtremumPoint point, int currentIndex, double currentPrice)
+ private void ClearLines()
{
- double weight = Math.Max(0.0, 1.0 - ((double)(currentIndex - point.Index) / _config.DecayPeriod));
- if ((point.Type == PointType.Peak) && (point.Price < currentPrice)) weight *= 2.0;
- else if ((point.Type == PointType.Trough) && (point.Price > currentPrice)) weight *= 2.0;
- return weight;
+ for (int i = 0; i < MaxZones; i++)
+ {
+ Chart.RemoveObject($"SR_Line_{i}");
+ Chart.RemoveObject($"SR_Text_{i}");
+ }
}
}
}
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.csproj b/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.csproj
index da1fef1..866383b 100644
--- a/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.csproj
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/HmaClusterSR.csproj
@@ -1,9 +1,14 @@
+
net6.0
-
-
+
+
+ ..\..\..\Common\MSLib\obj\Debug\net6.0\MSLib.dll
+
+
+
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs
new file mode 100644
index 0000000..32c95f9
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs
@@ -0,0 +1,4 @@
+//
+using System;
+using System.Reflection;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.AssemblyInfo.cs b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.AssemblyInfo.cs
new file mode 100644
index 0000000..ff2bfe8
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.AssemblyInfo.cs
@@ -0,0 +1,22 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+
+[assembly: System.Reflection.AssemblyCompanyAttribute("HmaClusterSR")]
+[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
+[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
+[assembly: System.Reflection.AssemblyProductAttribute("HmaClusterSR")]
+[assembly: System.Reflection.AssemblyTitleAttribute("HmaClusterSR")]
+[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
+
+// Generated by the MSBuild WriteCodeFragment class.
+
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.AssemblyInfoInputs.cache b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.AssemblyInfoInputs.cache
new file mode 100644
index 0000000..81b1cbc
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.AssemblyInfoInputs.cache
@@ -0,0 +1 @@
+9e01ea14fd7f1cf3abff0b8c1e9bec07e427b59e
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.GeneratedMSBuildEditorConfig.editorconfig b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.GeneratedMSBuildEditorConfig.editorconfig
new file mode 100644
index 0000000..04fe673
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.GeneratedMSBuildEditorConfig.editorconfig
@@ -0,0 +1,10 @@
+is_global = true
+build_property.TargetFramework = net6.0
+build_property.TargetPlatformMinVersion =
+build_property.UsingMicrosoftNETSdkWeb =
+build_property.ProjectTypeGuids =
+build_property.InvariantGlobalization =
+build_property.PlatformNeutralAssembly =
+build_property._SupportedPlatformList = Linux,macOS,Windows
+build_property.RootNamespace = HmaClusterSR
+build_property.ProjectDir = C:\Users\Brummel\Documents\cAlgo\Sources\Indicators\HmaClusterSR\HmaClusterSR\
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.assets.cache b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.assets.cache
new file mode 100644
index 0000000..b1b7b3c
Binary files /dev/null and b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.assets.cache differ
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.csproj.AssemblyReference.cache b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.csproj.AssemblyReference.cache
new file mode 100644
index 0000000..50043b7
Binary files /dev/null and b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/Debug/net6.0/HmaClusterSR.csproj.AssemblyReference.cache differ
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.dgspec.json b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.dgspec.json
new file mode 100644
index 0000000..5046328
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.dgspec.json
@@ -0,0 +1,66 @@
+{
+ "format": 1,
+ "restore": {
+ "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj": {}
+ },
+ "projects": {
+ "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj": {
+ "version": "1.0.0",
+ "restore": {
+ "projectUniqueName": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj",
+ "projectName": "HmaClusterSR",
+ "projectPath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj",
+ "packagesPath": "C:\\Users\\Brummel\\.nuget\\packages\\",
+ "outputPath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\obj\\",
+ "projectStyle": "PackageReference",
+ "configFilePaths": [
+ "C:\\Users\\Brummel\\AppData\\Roaming\\NuGet\\NuGet.Config"
+ ],
+ "originalTargetFrameworks": [
+ "net6.0"
+ ],
+ "sources": {
+ "https://api.nuget.org/v3/index.json": {}
+ },
+ "frameworks": {
+ "net6.0": {
+ "targetAlias": "net6.0",
+ "projectReferences": {}
+ }
+ },
+ "warningProperties": {
+ "warnAsError": [
+ "NU1605"
+ ]
+ }
+ },
+ "frameworks": {
+ "net6.0": {
+ "targetAlias": "net6.0",
+ "dependencies": {
+ "cTrader.Automate": {
+ "target": "Package",
+ "version": "[*, )"
+ }
+ },
+ "imports": [
+ "net461",
+ "net462",
+ "net47",
+ "net471",
+ "net472",
+ "net48"
+ ],
+ "assetTargetFallback": true,
+ "warn": true,
+ "frameworkReferences": {
+ "Microsoft.NETCore.App": {
+ "privateAssets": "all"
+ }
+ },
+ "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\6.0.200\\RuntimeIdentifierGraph.json"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.g.props b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.g.props
new file mode 100644
index 0000000..0b161ac
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.g.props
@@ -0,0 +1,21 @@
+
+
+
+ True
+ NuGet
+ $(MSBuildThisFileDirectory)project.assets.json
+ $(UserProfile)\.nuget\packages\
+ C:\Users\Brummel\.nuget\packages\
+ PackageReference
+ 6.1.0
+
+
+
+
+
+
+
+
+ C:\Users\Brummel\.nuget\packages\ctrader.automate\1.0.14
+
+
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.g.targets b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.g.targets
new file mode 100644
index 0000000..46f142c
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/HmaClusterSR.csproj.nuget.g.targets
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/project.assets.json b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/project.assets.json
new file mode 100644
index 0000000..de99536
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/project.assets.json
@@ -0,0 +1,139 @@
+{
+ "version": 3,
+ "targets": {
+ "net6.0": {
+ "cTrader.Automate/1.0.14": {
+ "type": "package",
+ "compile": {
+ "lib/net6.0/cAlgo.API.dll": {}
+ },
+ "runtime": {
+ "lib/net6.0/cAlgo.API.dll": {}
+ },
+ "build": {
+ "build/cTrader.Automate.props": {},
+ "build/cTrader.Automate.targets": {}
+ }
+ }
+ }
+ },
+ "libraries": {
+ "cTrader.Automate/1.0.14": {
+ "sha512": "eNwE7WL90MGBKb5MuLAtZLdQy0vxkI5EVhLWAQ9S83EAdYkGAzdccvGFLk2oqmtSGBtD+gEpyrJUW/ej4dI4jw==",
+ "type": "package",
+ "path": "ctrader.automate/1.0.14",
+ "hasTools": true,
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "build/cTrader.Automate.props",
+ "build/cTrader.Automate.targets",
+ "ctrader.automate.1.0.14.nupkg.sha512",
+ "ctrader.automate.nuspec",
+ "eula.md",
+ "icon.png",
+ "lib/net40/cAlgo.API.dll",
+ "lib/net40/cAlgo.API.xml",
+ "lib/net6.0/cAlgo.API.dll",
+ "lib/net6.0/cAlgo.API.xml",
+ "tools/net472/Core.AlgoFormat.Compose.Reflection.dll",
+ "tools/net472/Core.AlgoFormat.Writer.dll",
+ "tools/net472/Core.AlgoFormat.dll",
+ "tools/net472/Core.Domain.Primitives.dll",
+ "tools/net472/Newtonsoft.Json.dll",
+ "tools/net472/System.Buffers.dll",
+ "tools/net472/System.Collections.Immutable.dll",
+ "tools/net472/System.Memory.dll",
+ "tools/net472/System.Numerics.Vectors.dll",
+ "tools/net472/System.Reflection.Metadata.dll",
+ "tools/net472/System.Reflection.MetadataLoadContext.dll",
+ "tools/net472/System.Runtime.CompilerServices.Unsafe.dll",
+ "tools/net472/cTrader.Automate.Sdk.Tasks.dll",
+ "tools/net6.0/Core.AlgoFormat.Compose.Reflection.dll",
+ "tools/net6.0/Core.AlgoFormat.Writer.dll",
+ "tools/net6.0/Core.AlgoFormat.dll",
+ "tools/net6.0/Core.Connection.Protobuf.Common.dll",
+ "tools/net6.0/Core.Domain.Primitives.dll",
+ "tools/net6.0/Microsoft.Win32.SystemEvents.dll",
+ "tools/net6.0/Newtonsoft.Json.dll",
+ "tools/net6.0/System.Drawing.Common.dll",
+ "tools/net6.0/System.Reflection.MetadataLoadContext.dll",
+ "tools/net6.0/System.Security.Permissions.dll",
+ "tools/net6.0/System.Windows.Extensions.dll",
+ "tools/net6.0/cTrader.Automate.Sdk.Tasks.dll",
+ "tools/net6.0/protobuf-net.Core.dll",
+ "tools/net6.0/protobuf-net.dll",
+ "tools/net6.0/runtimes/unix/lib/net6.0/System.Drawing.Common.dll",
+ "tools/net6.0/runtimes/win/lib/net6.0/Microsoft.Win32.SystemEvents.dll",
+ "tools/net6.0/runtimes/win/lib/net6.0/System.Drawing.Common.dll",
+ "tools/net6.0/runtimes/win/lib/net6.0/System.Windows.Extensions.dll"
+ ]
+ }
+ },
+ "projectFileDependencyGroups": {
+ "net6.0": [
+ "cTrader.Automate >= *"
+ ]
+ },
+ "packageFolders": {
+ "C:\\Users\\Brummel\\.nuget\\packages\\": {}
+ },
+ "project": {
+ "version": "1.0.0",
+ "restore": {
+ "projectUniqueName": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj",
+ "projectName": "HmaClusterSR",
+ "projectPath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj",
+ "packagesPath": "C:\\Users\\Brummel\\.nuget\\packages\\",
+ "outputPath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\obj\\",
+ "projectStyle": "PackageReference",
+ "configFilePaths": [
+ "C:\\Users\\Brummel\\AppData\\Roaming\\NuGet\\NuGet.Config"
+ ],
+ "originalTargetFrameworks": [
+ "net6.0"
+ ],
+ "sources": {
+ "https://api.nuget.org/v3/index.json": {}
+ },
+ "frameworks": {
+ "net6.0": {
+ "targetAlias": "net6.0",
+ "projectReferences": {}
+ }
+ },
+ "warningProperties": {
+ "warnAsError": [
+ "NU1605"
+ ]
+ }
+ },
+ "frameworks": {
+ "net6.0": {
+ "targetAlias": "net6.0",
+ "dependencies": {
+ "cTrader.Automate": {
+ "target": "Package",
+ "version": "[*, )"
+ }
+ },
+ "imports": [
+ "net461",
+ "net462",
+ "net47",
+ "net471",
+ "net472",
+ "net48"
+ ],
+ "assetTargetFallback": true,
+ "warn": true,
+ "frameworkReferences": {
+ "Microsoft.NETCore.App": {
+ "privateAssets": "all"
+ }
+ },
+ "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\6.0.200\\RuntimeIdentifierGraph.json"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/project.nuget.cache b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/project.nuget.cache
new file mode 100644
index 0000000..e377815
--- /dev/null
+++ b/Sources/Indicators/HmaClusterSR/HmaClusterSR/obj/project.nuget.cache
@@ -0,0 +1,10 @@
+{
+ "version": 2,
+ "dgSpecHash": "44vzUq/Lw+XLcrX6CWh7QZnxKTbL7SBSGBbM9ijWJIaHajpDybp1KWXAjmIYPIEKiHbzs2dgB4Wmenl5+uQxng==",
+ "success": true,
+ "projectFilePath": "C:\\Users\\Brummel\\Documents\\cAlgo\\Sources\\Indicators\\HmaClusterSR\\HmaClusterSR\\HmaClusterSR.csproj",
+ "expectedPackageFiles": [
+ "C:\\Users\\Brummel\\.nuget\\packages\\ctrader.automate\\1.0.14\\ctrader.automate.1.0.14.nupkg.sha512"
+ ],
+ "logs": []
+}
\ No newline at end of file
diff --git a/Sources/Robots/HmaClusterBot.algo b/Sources/Robots/HmaClusterBot.algo
index c70f58c..0bc74a9 100644
Binary files a/Sources/Robots/HmaClusterBot.algo and b/Sources/Robots/HmaClusterBot.algo differ
diff --git a/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.cs b/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.cs
index 6a1f1b9..bb96d2a 100644
--- a/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.cs
+++ b/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
+using Myc; // Referenz auf die extrahierte Cluster-Logik
namespace cAlgo.Robots
{
@@ -71,12 +72,12 @@ namespace cAlgo.Robots
protected override void OnStart()
{
- try
+ try
{
if (string.IsNullOrWhiteSpace(SymbolsCsv))
{
Print("CSV is empty. Running in Single-Symbol Mode on Chart Symbol.");
-
+
var config = new StrategyConfig
{
SymbolName = SymbolName,
@@ -129,6 +130,10 @@ namespace cAlgo.Robots
{
Print(message);
+ // WICHTIG: Im Backtest NIEMALS Netzwerk-Calls machen, auch nicht bei Fehlern.
+ // Das führt bei vielen Fehlern zum Stillstand der Simulation.
+ if (IsBacktesting) return;
+
if (!string.IsNullOrWhiteSpace(TelegramBotToken) && !string.IsNullOrWhiteSpace(TelegramChatId))
{
string formattedMsg = $"⚠️ ERROR @ {DateTime.UtcNow:HH:mm:ss} UTC\n\n{message}";
@@ -138,6 +143,8 @@ namespace cAlgo.Robots
private async Task SendTelegramRawAsync(string token, string chatId, string message)
{
+ if (IsBacktesting) return;
+
try
{
string url = $"https://api.telegram.org/bot{token}/sendMessage?chat_id={chatId}&text={Uri.EscapeDataString(message)}&parse_mode=HTML";
@@ -152,7 +159,7 @@ namespace cAlgo.Robots
private void ParseCsvAndCreateStrategies()
{
var normalizedCsv = SymbolsCsv.Replace("\n", ",").Replace("\r", ",");
-
+
var tokens = normalizedCsv.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.Trim())
.Where(t => !string.IsNullOrEmpty(t))
@@ -195,9 +202,8 @@ namespace cAlgo.Robots
BiasDeviationAvgPeriod = int.Parse(tokens[i + 7], CultureInfo.InvariantCulture),
UseDynamicPositionManagement = bool.Parse(tokens[i + 8]),
SendTelegramOnly = bool.Parse(tokens[i + 9]),
-
- // Defaults from global params
- CloseProfitOnBiasFlip = CloseProfitOnBiasFlip,
+
+ CloseProfitOnBiasFlip = CloseProfitOnBiasFlip,
RiskPercent = RiskPercent,
MaxPoints = MaxPoints,
DecayPeriod = DecayPeriod
@@ -239,16 +245,8 @@ namespace cAlgo.Robots
{
#region Types & Fields
- private enum PointType { Peak, Trough }
private enum Bias { Long, Short, Neutral }
- private struct ExtremumPoint
- {
- public double Price;
- public int Index;
- public PointType Type;
- }
-
public struct ClusterLevel
{
public double Price;
@@ -270,13 +268,14 @@ namespace cAlgo.Robots
private readonly Queue _deviationQueue = new Queue();
private double _runningDeviationSum;
-
+
private bool _deviationConditionMetInCurrentCycle;
private bool _isTradingAllowedBasedOnPrevCycle;
- private readonly List _extremaPoints = new();
+ // --- OPTIMIERUNG: Nutzt Calculator statt Liste ---
+ private readonly Myc.ClusterCalculator _clusterCalculator;
private readonly List _amplitudes = new();
-
+
private double _trendExtremum;
private int _trendExtremumIndex;
private double _lastExtremumPrice;
@@ -288,12 +287,12 @@ namespace cAlgo.Robots
#endregion
public ClusterStrategy(
- Robot robot,
- Symbol symbol,
- Bars bars,
- StrategyConfig config,
- HttpClient httpClient,
- string token,
+ Robot robot,
+ Symbol symbol,
+ Bars bars,
+ StrategyConfig config,
+ HttpClient httpClient,
+ string token,
string chatId,
Action errorCallback)
{
@@ -305,17 +304,20 @@ namespace cAlgo.Robots
_botToken = token;
_chatId = chatId;
_errorCallback = errorCallback;
+
+ // Calculator mit Reserve initialisieren
+ _clusterCalculator = new Myc.ClusterCalculator(_config.MaxPoints + 200);
}
public void Start()
{
int requiredBars = Math.Max(_config.SmaBiasPeriod, _config.HmaBiasPeriod);
- requiredBars = Math.Max(requiredBars, _config.BiasDeviationAvgPeriod) + 10;
+ requiredBars = Math.Max(requiredBars, _config.BiasDeviationAvgPeriod) + 10;
while (_bars.Count < requiredBars)
{
int loaded = _bars.LoadMoreHistory();
- if (loaded == 0)
+ if (loaded == 0)
{
_errorCallback?.Invoke($"Not enough history for {_config.SymbolName}. Loaded: {_bars.Count}, Req: {requiredBars}");
return;
@@ -332,11 +334,11 @@ namespace cAlgo.Robots
int startIndex = Math.Max(_config.SmaBiasPeriod, _config.HmaBiasPeriod);
startIndex = Math.Max(startIndex, _config.BiasDeviationAvgPeriod);
-
+
for (int i = startIndex; i < _bars.Count; i++)
{
UpdateFilterState(i);
- UpdateClusterData(i);
+ UpdateClusterData(i);
}
_bars.BarOpened += OnBarOpened;
@@ -356,24 +358,21 @@ namespace cAlgo.Robots
UpdateFilterState(index);
UpdateClusterData(index);
-
+
var clusters = CalculateClusters(index);
- // 1. Dynamic SL/TP Management
if (!_config.SendTelegramOnly && _config.UseDynamicPositionManagement && clusters.Count >= 2)
{
ManagePositions(clusters);
}
-
+
var currentBias = GetCurrentBias(index);
- // 2. Check for Profit Close on Bias Flip
if (!_config.SendTelegramOnly && _config.CloseProfitOnBiasFlip)
{
CloseReversedPositions(currentBias);
}
- // 3. New Entry Logic with FIXED Orphan-Cleanup and Validations
ManageOrders(currentBias, index, clusters);
}
catch (Exception ex)
@@ -389,7 +388,7 @@ namespace cAlgo.Robots
foreach (var pos in _robot.Positions)
{
if (pos.SymbolName != _config.SymbolName || pos.Label != Label) continue;
- if (pos.NetProfit <= 0) continue;
+ if (pos.NetProfit <= 0) continue;
bool close = false;
@@ -405,7 +404,7 @@ namespace cAlgo.Robots
{
string msg = $"🔒 CLOSE PROFIT (Bias Flip) @ {_config.SymbolName}\n" +
$"Profit: {pos.NetProfit:F2}";
- _ = SendTelegramMessageAsync(msg);
+ _ = SendTelegramMessageAsync(msg);
}
}
}
@@ -419,7 +418,7 @@ namespace cAlgo.Robots
double prevSma = _smaBias.Result[index - 1];
double currentBiasDeviation = Math.Abs(currHma - currSma);
-
+
_deviationQueue.Enqueue(currentBiasDeviation);
_runningDeviationSum += currentBiasDeviation;
@@ -429,8 +428,8 @@ namespace cAlgo.Robots
_runningDeviationSum -= removed;
}
- double averageDeviation = (_deviationQueue.Count > 0)
- ? _runningDeviationSum / _deviationQueue.Count
+ double averageDeviation = (_deviationQueue.Count > 0)
+ ? _runningDeviationSum / _deviationQueue.Count
: 0.0;
bool currHmaAbove = currHma > currSma;
@@ -462,7 +461,7 @@ namespace cAlgo.Robots
private void ManagePositions(List clusters)
{
- double pNow = _symbol.Bid;
+ double pNow = _symbol.Bid;
foreach (var pos in _robot.Positions)
{
@@ -509,7 +508,7 @@ namespace cAlgo.Robots
}
}
}
- else // Sell
+ else
{
double lowestSlPrice = double.MaxValue;
double lowestTpPrice = double.MaxValue;
@@ -552,10 +551,9 @@ namespace cAlgo.Robots
private void ManageOrders(Bias bias, int index, List clusters)
{
- // Standard Cleanup: Orders in wrong direction (Bias Change)
CleanupWrongBiasOrders(bias);
- if (_config.UseBiasDeviationFilter && !_isTradingAllowedBasedOnPrevCycle)
+ if (_config.UseBiasDeviationFilter && !_isTradingAllowedBasedOnPrevCycle)
return;
if (bias == Bias.Neutral) return;
@@ -565,11 +563,9 @@ namespace cAlgo.Robots
bool hasLong = _robot.Positions.Any(p => p.SymbolName == _config.SymbolName && p.Label == Label && p.TradeType == TradeType.Buy);
bool hasShort = _robot.Positions.Any(p => p.SymbolName == _config.SymbolName && p.Label == Label && p.TradeType == TradeType.Sell);
- // --- FIX 1: Open Positions Cleanup ---
- // If we are already invested, we ensure no pending orders for the same direction are lingering around.
if (bias == Bias.Long && hasLong)
{
- CancelPendingOrders(TradeType.Buy);
+ CancelPendingOrders(TradeType.Buy);
return;
}
if (bias == Bias.Short && hasShort)
@@ -723,38 +719,18 @@ namespace cAlgo.Robots
{
var existingOrder = _robot.PendingOrders.FirstOrDefault(o => o.SymbolName == _config.SymbolName && o.Label == Label && o.TradeType == type);
- // --- FIX 4: Market Proximity Check ---
- // If the limit price is invalid (e.g. Buy Limit above Ask), we must abort/cancel.
- bool priceInvalid = false;
- double buffer = _symbol.PipSize;
+ double buffer = _symbol.PipSize;
+ if (type == TradeType.Buy && entry >= (_symbol.Ask - buffer)) return;
+ if (type == TradeType.Sell && entry <= (_symbol.Bid + buffer)) return;
- if (type == TradeType.Buy && entry >= (_symbol.Ask - buffer)) priceInvalid = true;
- if (type == TradeType.Sell && entry <= (_symbol.Bid + buffer)) priceInvalid = true;
-
- if (priceInvalid)
- {
- if (existingOrder != null) _robot.CancelPendingOrder(existingOrder);
- return;
- }
-
- // --- FIX 3: SL Distance Check ---
double slDistPips = Math.Abs(entry - sl) / _symbol.PipSize;
- if (slDistPips <= 0)
- {
- if (existingOrder != null) _robot.CancelPendingOrder(existingOrder);
- return;
- }
+ if (slDistPips <= 0) return;
- // --- FIX 2: Volume Check ---
double riskAmount = _robot.Account.Balance * (_config.RiskPercent / 100.0);
double volume = _symbol.VolumeForFixedRisk(riskAmount, slDistPips);
volume = _symbol.NormalizeVolumeInUnits(volume, RoundingMode.Down);
- if (volume < _symbol.VolumeInUnitsMin)
- {
- if (existingOrder != null) _robot.CancelPendingOrder(existingOrder);
- return;
- }
+ if (volume < _symbol.VolumeInUnitsMin) return;
double lots = _symbol.VolumeInUnitsToQuantity(volume);
@@ -763,11 +739,11 @@ namespace cAlgo.Robots
string directionStr = type == TradeType.Buy ? "BUY" : "SELL";
string directionIcon = type == TradeType.Buy ? "📈" : "📉";
string msg = $"{directionIcon} {directionStr} Signal @ {_config.SymbolName}\n\n" +
- $"Entry: {entry}\n" +
- $"SL: {sl}\n" +
- $"TP: {tp}\n" +
- $"Vol: {lots:F2} Lots";
-
+ $"Entry: {entry}\n" +
+ $"SL: {sl}\n" +
+ $"TP: {tp}\n" +
+ $"Vol: {lots:F2} Lots";
+
_ = SendTelegramMessageAsync(msg);
return;
}
@@ -784,16 +760,13 @@ namespace cAlgo.Robots
var result = _robot.ModifyPendingOrder(existingOrder, entry, sl, tp, ProtectionType.Absolute, null, volume);
if (!result.IsSuccessful)
{
- // Fallback: If modify fails (e.g. spread jump), cancel it to avoid stale orders
+ // Falls Modifikation fehlschlägt (z.B. Spread), löschen wir die Order, um keine veralteten Levels zu handeln
_robot.CancelPendingOrder(existingOrder);
}
}
}
else
{
- _robot.Print("[SIGNAL] {0} {1} | Entry: {2} | SL: {3} | TP: {4} | Vol: {5:F2} Lots",
- (type == TradeType.Buy ? "BUY" : "SELL"), _config.SymbolName, entry, sl, tp, lots);
-
_robot.PlaceLimitOrder(type, _config.SymbolName, volume, entry, Label, sl, tp, ProtectionType.Absolute);
}
}
@@ -807,7 +780,7 @@ namespace cAlgo.Robots
{
string url = $"https://api.telegram.org/bot{_botToken}/sendMessage?chat_id={_chatId}&text={Uri.EscapeDataString(message)}&parse_mode=HTML";
HttpResponseMessage response = await _httpClient.GetAsync(url);
-
+
if (!response.IsSuccessStatusCode)
{
_errorCallback?.Invoke($"Telegram Error: {response.StatusCode}");
@@ -842,11 +815,18 @@ namespace cAlgo.Robots
if (_amplitudes.Count > 50) _amplitudes.RemoveAt(0);
double sum = 0;
- for (int i = 0; i < _amplitudes.Count; i++) sum += _amplitudes[i];
+ for(int i=0; i<_amplitudes.Count; i++) sum += _amplitudes[i];
_currentDynamicRange = (sum / _amplitudes.Count) * 0.5;
+ if (_currentDynamicRange < _symbol.PipSize) _currentDynamicRange = _symbol.PipSize;
}
- _extremaPoints.Add(new ExtremumPoint { Price = _trendExtremum, Index = _trendExtremumIndex, Type = _isUpTrend.Value ? PointType.Peak : PointType.Trough });
- if (_extremaPoints.Count > _config.MaxPoints) _extremaPoints.RemoveAt(0);
+
+ // Neuen Punkt in den optimierten Calculator einspeisen
+ _clusterCalculator.AddPoint(new Myc.ExtremumPoint
+ {
+ Price = _trendExtremum,
+ Index = _trendExtremumIndex,
+ Type = _isUpTrend.Value ? Myc.PointType.Peak : Myc.PointType.Trough
+ });
_lastExtremumPrice = _trendExtremum;
_isUpTrend = currentDirectionUp;
@@ -880,57 +860,23 @@ namespace cAlgo.Robots
private List CalculateClusters(int currentIndex)
{
- int count = _extremaPoints.Count;
- if (count == 0) return new List();
-
double currentPrice = _bars.ClosePrices[currentIndex];
- double[] weights = new double[count];
- double totalWeightSum = 0;
- for (int i = 0; i < count; i++)
+ var result = _clusterCalculator.Calculate(
+ currentIndex,
+ currentPrice,
+ _currentDynamicRange,
+ _config.DecayPeriod,
+ 100
+ );
+
+ if (result.TotalWeight == 0 || result.Zones.Count == 0) return new List();
+
+ return result.Zones.Select(z => new ClusterLevel
{
- weights[i] = GetWeight(_extremaPoints[i], currentIndex, currentPrice);
- totalWeightSum += weights[i];
- }
-
- if (totalWeightSum == 0) return new List();
-
- var zones = new List();
- for (int i = count - 1; i >= 0; i--)
- {
- var p = _extremaPoints[i];
-
- bool exists = false;
- for (int j = 0; j < zones.Count; j++)
- {
- if (Math.Abs(zones[j].Price - p.Price) < _currentDynamicRange)
- {
- exists = true;
- break;
- }
- }
- if (exists) continue;
-
- double score = 0;
- for (int k = 0; k < count; k++)
- {
- if (Math.Abs(_extremaPoints[k].Price - p.Price) <= _currentDynamicRange)
- {
- score += weights[k];
- }
- }
-
- zones.Add(new ClusterLevel { Price = p.Price, Significance = (score / totalWeightSum) * 100.0 });
- }
- return zones;
- }
-
- private double GetWeight(ExtremumPoint point, int currentIndex, double currentPrice)
- {
- double weight = Math.Max(0.0, 1.0 - ((double)(currentIndex - point.Index) / _config.DecayPeriod));
- if ((point.Type == PointType.Peak) && (point.Price < currentPrice)) weight *= 2.0;
- else if ((point.Type == PointType.Trough) && (point.Price > currentPrice)) weight *= 2.0;
- return weight;
+ Price = z.Price,
+ Significance = (z.Score / result.TotalWeight) * 100.0
+ }).ToList();
}
}
}
\ No newline at end of file
diff --git a/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.csproj b/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.csproj
index c8ec96f..866383b 100644
--- a/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.csproj
+++ b/Sources/Robots/HmaClusterBot/HmaClusterBot/HmaClusterBot.csproj
@@ -6,4 +6,9 @@
+
+
+ ..\..\..\Common\MSLib\obj\Debug\net6.0\MSLib.dll
+
+
\ No newline at end of file