Files
marketdata/MarketDataLib/Generator/MGSHMomentum/SlopeManager.cs
2025-02-06 16:46:27 -05:00

208 lines
9.3 KiB
C#

using System;
using System.Collections.Generic;
using MarketData.MarketDataModel;
using MarketData.Utils;
using System.Linq;
using MarketData.Numerical;
using System.Text;
namespace MarketData.Generator.MGSHMomentum
{
public class SlopeManager
{
private double bandSlopeSpreadKL5;
private double bandSlopeSpreadKL10;
private double bandSlopeSpreadKL30;
private double bandSlopeSpreadKL60;
private double bandSlopeSpreadKL90;
public SlopeManager(BollingerBandElementsByDate bollingerBandElementsByDate, DateTime analysisDate)
{
bandSlopeSpreadKL5 = GetKLBandSpreadSlope(bollingerBandElementsByDate, analysisDate, 5);
bandSlopeSpreadKL10 = GetKLBandSpreadSlope(bollingerBandElementsByDate, analysisDate, 10);
bandSlopeSpreadKL30 = GetKLBandSpreadSlope(bollingerBandElementsByDate, analysisDate, 30);
bandSlopeSpreadKL60 = GetKLBandSpreadSlope(bollingerBandElementsByDate, analysisDate, 60);
bandSlopeSpreadKL90 = GetKLBandSpreadSlope(bollingerBandElementsByDate, analysisDate, 90);
}
public bool Verbose { get; set; } = true;
/// <summary>
/// The pattern follows.. 90, 60, 30, 10 ,5
/// </summary>
/// <param name="bandStringKLSpread">++0-0</param>
/// <returns></returns>
public bool IsMatchKLSpread(String bandStringKLSpread)
{
StringBuilder sbKLSPread = new StringBuilder();
sbKLSPread.Append(GetValue(bandSlopeSpreadKL90)).Append(GetValue(bandSlopeSpreadKL60)).Append(GetValue(bandSlopeSpreadKL30)).Append(GetValue(bandSlopeSpreadKL10)).Append(GetValue(bandSlopeSpreadKL5));
return AreEqual(bandStringKLSpread, sbKLSPread.ToString());
}
public String GetKLSpread()
{
StringBuilder sbKLSPread = new StringBuilder();
sbKLSPread.Append(GetValue(bandSlopeSpreadKL90)).Append(GetValue(bandSlopeSpreadKL60)).Append(GetValue(bandSlopeSpreadKL30)).Append(GetValue(bandSlopeSpreadKL10)).Append(GetValue(bandSlopeSpreadKL5));
return sbKLSPread.ToString();
}
public int FindFirstMatchRtoL(String bandString, char match)
{
for (int index = bandString.Length - 1; index >= 0; index--)
{
if (bandString[index].Equals(match)) {
switch (index) {
case 0:
return 90;
case 1:
return 60;
case 2:
return 30;
case 3:
return 10;
case 4:
return 5;
default:
return 10;
}
}
}
return 10;
}
/// <summary>
/// Where str1 may have a wild card '?'
/// </summary>
/// <param name="str1"></param>
/// <param name="str2"></param>
/// <returns></returns>
private bool AreEqual(String str1,String str2)
{
if(str1.Length!=str2.Length)return false;
for(int index=0;index<str1.Length;index++)
{
char ch1 = str1[index];
char ch2 = str2[index];
if(ch1.Equals('?'))continue;
if(!ch1.Equals(ch2))return false;
}
return true;
}
private String GetValue(double value)
{
if(Math.Abs(value)<.0001)value=0.00;
if(value==0.00)return "0";
else if(value>0.00)return "+";
return "-";
}
private double GetKLBandSpreadSlope(BollingerBandElementsByDate bollingerBandElementsByDate, DateTime fromDate, int dayCount)
{
List<BollingerBandElement> bollingerBandElements = new List<BollingerBandElement>();
DateGenerator dateGenerator = new DateGenerator();
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(fromDate, dayCount);
foreach (DateTime historicalDate in historicalDates) {
if (!bollingerBandElementsByDate.ContainsKey(historicalDate)) {
continue;
}
bollingerBandElements.Add(bollingerBandElementsByDate[historicalDate]);
}
List<double> spreadElements = new List<double>();
foreach (BollingerBandElement bollingerBandElement in bollingerBandElements) {
spreadElements.Add(bollingerBandElement.K - bollingerBandElement.L);
}
double[] elements = spreadElements.ToArray<double>();
elements = Numerics.Reverse(ref elements);
double[] logElements = new double[elements.Length];
for (int index = 0; index < elements.Length; index++) {
logElements[index] = Math.Log(elements[index]);
}
LeastSquaresResultWithR2 leastSquaresResult = LeastSquaresHelper.CalculateLeastSquaresWithR2(logElements);
return leastSquaresResult.Slope;
}
private double GetKBandSlope(BollingerBandElementsByDate bollingerBandElementsByDate,DateTime fromDate, int dayCount)
{
List<BollingerBandElement> bollingerBandElements = new List<BollingerBandElement>();
DateGenerator dateGenerator = new DateGenerator();
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(fromDate, dayCount);
foreach(DateTime historicalDate in historicalDates)
{
if(!bollingerBandElementsByDate.ContainsKey(historicalDate))
{
continue;
}
bollingerBandElements.Add(bollingerBandElementsByDate[historicalDate]);
}
List<double> bandElements = new List<double>();
foreach(BollingerBandElement bollingerBandElement in bollingerBandElements)
{
bandElements.Add(bollingerBandElement.K);
}
double[] elements = bandElements.ToArray<double>();
elements = Numerics.Reverse(ref elements);
double[] logElements = new double[elements.Length];
for(int index=0;index<elements.Length;index++)
{
logElements[index] = Math.Log(elements[index]);
}
LeastSquaresResultWithR2 leastSquaresResult = LeastSquaresHelper.CalculateLeastSquaresWithR2(logElements);
return leastSquaresResult.Slope;
}
private double GetLBandSlope(BollingerBandElementsByDate bollingerBandElementsByDate,DateTime fromDate, int dayCount)
{
List<BollingerBandElement> bollingerBandElements = new List<BollingerBandElement>();
DateGenerator dateGenerator = new DateGenerator();
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(fromDate, dayCount);
foreach(DateTime historicalDate in historicalDates)
{
if(!bollingerBandElementsByDate.ContainsKey(historicalDate))
{
continue;
}
bollingerBandElements.Add(bollingerBandElementsByDate[historicalDate]);
}
List<double> bandElements = new List<double>();
foreach(BollingerBandElement bollingerBandElement in bollingerBandElements)
{
bandElements.Add(bollingerBandElement.L);
}
double[] elements = bandElements.ToArray<double>();
elements = Numerics.Reverse(ref elements);
double[] logElements = new double[elements.Length];
for(int index=0;index<elements.Length;index++)
{
logElements[index] = Math.Log(elements[index]);
}
LeastSquaresResultWithR2 leastSquaresResult = LeastSquaresHelper.CalculateLeastSquaresWithR2(logElements);
return leastSquaresResult.Slope;
}
public void DisplaySlopes()
{
Display($" 90 60 30 10 5");
//Display($"K {GetValue(bandSlopeK90)} {GetValue(bandSlopeK60)} {GetValue(bandSlopeK30)} {GetValue(bandSlopeK10)} {GetValue(bandSlopeK5)} ");
//Display($"L {GetValue(bandSlopeL90)} {GetValue(bandSlopeL60)} {GetValue(bandSlopeL30)} {GetValue(bandSlopeL10)} {GetValue(bandSlopeL5)} ");
Display($"K-L {GetValue(bandSlopeSpreadKL90)} {GetValue(bandSlopeSpreadKL60)} {GetValue(bandSlopeSpreadKL30)} {GetValue(bandSlopeSpreadKL10)} {GetValue(bandSlopeSpreadKL5)} ");
}
public void DisplaySlopesNumeric()
{
Display($" 90 60 30 10 5");
//Display($"K {Utility.FormatNumber(bandSlopeK90,10)} {Utility.FormatNumber(bandSlopeK60,10)} {Utility.FormatNumber(bandSlopeK30,10)} {Utility.FormatNumber(bandSlopeK10,10)} {Utility.FormatNumber(bandSlopeK5,10)} ");
//Display($"L {Utility.FormatNumber(bandSlopeL90,10)} {Utility.FormatNumber(bandSlopeL60,10)} {Utility.FormatNumber(bandSlopeL30,10)} {Utility.FormatNumber(bandSlopeL10,10)} {Utility.FormatNumber(bandSlopeL5,10)} ");
Display($"L-L {Utility.FormatNumber(bandSlopeSpreadKL90,10)} {Utility.FormatNumber(bandSlopeSpreadKL60,10)} {Utility.FormatNumber(bandSlopeSpreadKL30,10)} {Utility.FormatNumber(bandSlopeSpreadKL10,10)} {Utility.FormatNumber(bandSlopeSpreadKL5,10)} ");
}
private void Display(String message)
{
if(Verbose)
{
MDTrace.WriteLine(LogLevel.DEBUG,message);
}
}
}
}