123 lines
4.6 KiB
C#
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()}";
|
|
}
|
|
}
|
|
} |