Files
2026-01-28 13:47:53 +01:00

123 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace Myc.HmaSma
{
/// <summary>
/// DTO representing a single row in the HMA/SMA configuration file.
/// </summary>
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}";
}
}
/// <summary>
/// Handles parsing and caching of HMA/SMA configuration files.
/// </summary>
public class HmaSmaLoader
{
// Key: "SYMBOL_TIMEFRAME" (Normalized to UpperCase)
private readonly Dictionary<string, HmaSmaParameters> _cache = new Dictionary<string, HmaSmaParameters>();
private readonly string _filePath;
public HmaSmaLoader(string filePath)
{
_filePath = filePath;
}
/// <summary>
/// Reads the file and populates the internal cache.
/// Throws FileNotFoundException if file is missing.
/// Returns number of successfully loaded entries.
/// </summary>
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;
}
/// <summary>
/// Retrieves configuration for a specific symbol and timeframe.
/// Returns null if not found.
/// </summary>
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()}";
}
}
}