Files
2025-04-24 16:51:09 -04:00

194 lines
15 KiB
C#
Executable File

using MarketData.Utils;
namespace MarketData.Generator.CMMomentum
{
public class CMParams
{
public CMParams()
{
DayCount = 90; // The lookback period
AnalysisDate = DateTime.Now.Date; // The analysis date of the run
TradeDate = DateTime.Now; // The current trade date
DailyReturnLimit = .25; // .15 was producing a lot unqualified candidates, this test to .25. Reject candidates that exceed DailyReturnLimit within the lookback period
MovingAverageConstraintDays = 100; // If current price of a candidate is below the DMA(MovingAverageConstraintDays) then it is rejected
FallbackCandidateBestOf = "SHV,NEAR,BIL,GSY,AGG,ACWX,GSY,SCHF,IXUS,DBEF,IEFA"; // if set then the fallback candidate is selected as the best 252 day return in this comma seperated list (i.e.) "SHV,ACWX,AGG"
FallbackMaxAlloc = 1000; // Max Allocation for Fallback candidate.
Benchmark = "SPY"; // This is the benchmark security
BenchmarkMovingAverageDays = 200; // If the latest benchmark Close is below DMA(BenchmarkMovingAverageDays) then we switch the strategy to the fallback candidates
HoldingPeriod = 3; // 3 is the default. This is in months.
MaxPositions = 3; // 3 is the default
NoTradeSymbols = "GBTC,YOKU,PNY,RFMD,ASAZY"; // ASAZY came up as candidate during 3/30 run but not available on Robinhood
InitialCash = 10000; // The initial cash
TargetBeta = 1.00; // The target Beta used to perform allocation for risk
BetaMonths = 6; // The number of months to use for Beta
MarketCapLowerLimit = 1000000000; // MarketCap lower limit 1,000,000,000
UseMaxBeta = false; // Utilize the MaxBeta filter
MaxBeta = 10.00; // Candidates with Beta that exceed this are rejected.
UseMaxPositionBucketWeight=false; // When set to true then ensure that no single position within a bucket can exceed UseMaxPositionBucketWeightMaxWeight percent
UseMaxPositionBucketWeightMaxWeight=.60; // The maximum weight any single position can be allocated within a bucket. .60 is 60%
UseOverExtendedIndicator=false; // The OverExtendedIndicator uses the upper K band of the Bollinger Band and compares that to the Price.Close on that day. It does this comparison across dayCount days start at TradeDate and going back through time
UseOverExtendedIndicatorDays=10; // This is the number of days of history to scan for OverExtension detetction. 10 gives best results in backtest
UseOverExtendedIndicatorViolationThreshhold=1; // This is the number of items that constitute an upper band break. (i.e.) if this is set to 1 then a single band break is a violation... if 2 then >=2 band breaks are a violation etc., 1.00 gives the best results in backtest
UseOverExtendedIndicatorMarginPercent=1.00; // Add this in so we can control the margin. The best value is 1.00 from backtest results
UseCNN=false; // If set to true then use convolutional network to assist in ranking the candidates
UseCNNHost="http://127.0.0.1:5000"; // The url for the UseCNNHost
UseCNNDayCount=270; // The daycount to use for the image data to present to the convolutional network
UseCNNRewardPercentDecimal=.20; // If a prediction is positive then Score is increased by the specified percentage. Tests using 20% reward show 25% improvement in gains versus not running the CNN
}
public int DayCount { get; set; }
public DateTime AnalysisDate { get; set; }
public DateTime TradeDate { get; set; }
public double DailyReturnLimit { get; set; }
public int MovingAverageConstraintDays { get; set; }
public String FallbackCandidateBestOf { get; set; }
public double FallbackMaxAlloc { get; set; }
public String Benchmark { get; set; }
public int BenchmarkMovingAverageDays { get; set; }
public int HoldingPeriod { get; set; }
public int MaxPositions { get; set; }
public String NoTradeSymbols{ get; set; }
public List<String> NoTradeSymbolsList { get { return null==NoTradeSymbols?null:Utility.ToList(NoTradeSymbols); } }
public double InitialCash { get; set; }
public double TargetBeta { get; set; }
public int BetaMonths { get; set; }
public double MaxBeta { get; set; }
public bool UseMaxBeta { get; set; }
public double MarketCapLowerLimit { get; set; }
public bool UseOverExtendedIndicator{get;set;}
public int UseOverExtendedIndicatorDays { get; set; }
public int UseOverExtendedIndicatorViolationThreshhold { get; set; }
public double UseOverExtendedIndicatorMarginPercent { get; set; }
public bool UseMaxPositionBucketWeight{get;set;}
public double UseMaxPositionBucketWeightMaxWeight{get;set;}
public bool UseCNN{get;set;}
public String UseCNNHost{get;set;}
public int UseCNNDayCount{get;set;}
public double UseCNNRewardPercentDecimal{get;set;}
public void DisplayHeader()
{
MDTrace.WriteLine(LogLevel.DEBUG, "Setting,Value");
}
public NVPCollection ToNVPCollection()
{
NVPCollection nvpCollection = new NVPCollection();
nvpCollection.Add(new NVP("DayCount", DayCount.ToString()));
nvpCollection.Add(new NVP("AnalysisDate", AnalysisDate.ToShortDateString()));
nvpCollection.Add(new NVP("TradeDate", TradeDate.ToShortDateString()));
nvpCollection.Add(new NVP("DailyReturnLimit", DailyReturnLimit.ToString()));
nvpCollection.Add(new NVP("MovingAverageConstraintDays", MovingAverageConstraintDays.ToString()));
nvpCollection.Add(new NVP("FallbackCandidateBestOf", FallbackCandidateBestOf.ToString()));
nvpCollection.Add(new NVP("Benchmark", Benchmark.ToString()));
nvpCollection.Add(new NVP("BenchmarkMovingAverageDays", BenchmarkMovingAverageDays.ToString()));
nvpCollection.Add(new NVP("HoldingPeriod", HoldingPeriod.ToString()));
nvpCollection.Add(new NVP("MaxPositions", MaxPositions.ToString()));
nvpCollection.Add(new NVP("NoTradeSymbols", NoTradeSymbols.ToString()));
nvpCollection.Add(new NVP("InitialCash", InitialCash.ToString()));
nvpCollection.Add(new NVP("TargetBeta", TargetBeta.ToString()));
nvpCollection.Add(new NVP("BetaMonths", BetaMonths.ToString()));
nvpCollection.Add(new NVP("MarketCapLowerLimit", MarketCapLowerLimit.ToString()));
nvpCollection.Add(new NVP("MaxBeta", MaxBeta.ToString()));
nvpCollection.Add(new NVP("UseMaxBeta", UseMaxBeta.ToString()));
nvpCollection.Add(new NVP("FallbackMaxAlloc", FallbackMaxAlloc.ToString()));
nvpCollection.Add(new NVP("UseOverExtendedIndicator",UseOverExtendedIndicator.ToString()));
nvpCollection.Add(new NVP("UseOverExtendedIndicatorDays",UseOverExtendedIndicatorDays.ToString()));
nvpCollection.Add(new NVP("UseOverExtendedIndicatorViolationThreshhold",UseOverExtendedIndicatorViolationThreshhold.ToString()));
nvpCollection.Add(new NVP("UseOverExtendedIndicatorMarginPercent",UseOverExtendedIndicatorMarginPercent.ToString()));
nvpCollection.Add(new NVP("UseMaxPositionBucketWeight",UseMaxPositionBucketWeight.ToString()));
nvpCollection.Add(new NVP("UseMaxPositionBucketWeightMaxWeight",UseMaxPositionBucketWeightMaxWeight.ToString()));
nvpCollection.Add(new NVP("UseCNN",UseCNN.ToString()));
nvpCollection.Add(new NVP("UseCNNHost",UseCNNHost.ToString()));
nvpCollection.Add(new NVP("UseCNNDayCount",UseCNNDayCount.ToString()));
nvpCollection.Add(new NVP("UseCNNRewardPercentDecimal",UseCNNRewardPercentDecimal.ToString()));
return nvpCollection;
}
public static CMParams FromNVPCollection(NVPCollection nvpCollection)
{
CMParams cmParams=new CMParams();
NVPDictionary nvpDictionary = nvpCollection.ToDictionary();
cmParams.DayCount = nvpDictionary["DayCount"].Get<int>();
cmParams.AnalysisDate = nvpDictionary["AnalysisDate"].Get<DateTime>();
cmParams.AnalysisDate = nvpDictionary["TradeDate"].Get<DateTime>();
cmParams.DailyReturnLimit = nvpDictionary["DailyReturnLimit"].Get<double>();
cmParams.MovingAverageConstraintDays = nvpDictionary["MovingAverageConstraintDays"].Get<int>();
cmParams.FallbackCandidateBestOf = nvpDictionary["FallbackCandidateBestOf"].Get<String>();
cmParams.Benchmark = nvpDictionary["Benchmark"].Get<String>();
cmParams.BenchmarkMovingAverageDays = nvpDictionary["BenchmarkMovingAverageDays"].Get<int>();
cmParams.HoldingPeriod = nvpDictionary["HoldingPeriod"].Get<int>();
cmParams.MaxPositions = nvpDictionary["MaxPositions"].Get<int>();
cmParams.NoTradeSymbols = nvpDictionary["NoTradeSymbols"].Get<String>();
cmParams.InitialCash = nvpDictionary["InitialCash"].Get<Double>();
cmParams.TargetBeta = nvpDictionary["TargetBeta"].Get<Double>();
cmParams.BetaMonths = nvpDictionary["BetaMonths"].Get<int>();
cmParams.MarketCapLowerLimit = nvpDictionary["MarketCapLowerLimit"].Get<double>();
cmParams.MaxBeta = nvpDictionary["MaxBeta"].Get<double>();
cmParams.UseMaxBeta = nvpDictionary["UseMaxBeta"].Get<bool>();
cmParams.FallbackMaxAlloc = nvpDictionary["FallbackMaxAlloc"].Get<double>();
if(nvpDictionary.ContainsKey("UseOverExtendedIndicator"))
{
cmParams.UseOverExtendedIndicator=nvpDictionary["UseOverExtendedIndicator"].Get<bool>();
cmParams.UseOverExtendedIndicatorDays=nvpDictionary["UseOverExtendedIndicatorDays"].Get<int>();
cmParams.UseOverExtendedIndicatorViolationThreshhold=nvpDictionary["UseOverExtendedIndicatorViolationThreshhold"].Get<int>();
cmParams.UseOverExtendedIndicatorMarginPercent=nvpDictionary["UseOverExtendedIndicatorMarginPercent"].Get<double>();
}
else
{
cmParams.UseOverExtendedIndicator=false;
cmParams.UseOverExtendedIndicatorDays=0;
cmParams.UseOverExtendedIndicatorViolationThreshhold=1;
cmParams.UseOverExtendedIndicatorMarginPercent=1;
}
if(nvpDictionary.ContainsKey("UseMaxPositionBucketWeight"))
{
cmParams.UseMaxPositionBucketWeight=nvpDictionary["UseMaxPositionBucketWeight"].Get<bool>();
cmParams.UseMaxPositionBucketWeightMaxWeight=nvpDictionary["UseMaxPositionBucketWeightMaxWeight"].Get<double>();
}
else
{
cmParams.UseMaxPositionBucketWeight=true;
cmParams.UseMaxPositionBucketWeightMaxWeight=0.65;
}
if(nvpDictionary.ContainsKey("UseCNN"))
{
cmParams.UseCNN=nvpDictionary["UseCNN"].Get<bool>();
if(nvpDictionary.ContainsKey("UseCNNHost"))cmParams.UseCNNHost=nvpDictionary["UseCNNHost"].Get<String>();
if(nvpDictionary.ContainsKey("UseCNNDayCount"))cmParams.UseCNNDayCount=nvpDictionary["UseCNNDayCount"].Get<int>();
if(nvpDictionary.ContainsKey("UseCNNRewardPercentDecimal"))cmParams.UseCNNRewardPercentDecimal=nvpDictionary["UseCNNRewardPercentDecimal"].Get<double>();
}
return cmParams;
}
public void DisplayConfiguration()
{
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("DayCount,{0}", DayCount));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("AnalysisDate,{0}", AnalysisDate));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("TradeDate,{0}", TradeDate));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("DailyReturnLimit,{0}", DailyReturnLimit));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("MovingAverageConstraintDays,{0}", MovingAverageConstraintDays));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("FallbackCandidateBestOf,{0}", FallbackCandidateBestOf));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Benchmark,{0}", Benchmark));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("BenchmarkMovingAverageDays,{0}", BenchmarkMovingAverageDays));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("HoldingPeriod,{0}", HoldingPeriod));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("MaxPositions,{0}", MaxPositions));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("NoTradeSymbols,{0}", NoTradeSymbols));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("InitialCash,{0}", InitialCash));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("TargetBeta,{0}", TargetBeta.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("BetaMonths,{0}", BetaMonths.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("MarketCapLowerLimit,{0}", MarketCapLowerLimit.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("UseMaxBeta,{0}", UseMaxBeta.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("MaxBeta,{0}", MaxBeta.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG, String.Format("FallbackMaxAlloc,{0}", FallbackMaxAlloc.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseOverExtendedIndicator,{0}",UseOverExtendedIndicator.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseOverExtendedIndicatorDays,{0}",UseOverExtendedIndicatorDays.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseOverExtendedIndicatorViolationThreshhold,{0}",UseOverExtendedIndicatorViolationThreshhold.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseOverExtendedIndicatorMarginPercent,{0}",UseOverExtendedIndicatorMarginPercent.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseMaxPositionBucketWeight,{0}",UseMaxPositionBucketWeight.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseMaxPositionBucketWeightMaxWeight,{0}",UseMaxPositionBucketWeightMaxWeight.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseCNN,{0}",UseCNN.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseCNNHost,{0}",UseCNNHost.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseCNNDayCount,{0}",UseCNNDayCount.ToString()));
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseCNNRewardPercentDecimal,{0}",UseCNNRewardPercentDecimal.ToString()));
}
}
}