using MarketData.Utils;
using System;
using System.Collections.Generic;

namespace MarketData.Generator.CMTrend
{
  public class CMTParams
  {
    public CMTParams()
    {
      SuspendTrading=false;                                     // If this flag is set to true then no new positions will be opned.
			UsePriceSlopeIndicator=true;                              // If this flag is set to true then enforce positive slope on prices over UserPriceSlopeIndicatorDays
			UsePriceSlopeIndicatorDays=252;                           // The number of pricing days to use for the slope.
      BetaMonths=6;                                             // The number of months to use for Beta
      AnalysisDate=DateTime.Now.Date;                           // The analysis date of the run
      MarketCapLowerLimit=500000000;                            // MarketCap lower limit 50,0000,000
      TradeDate=DateTime.Now;                                   // The current trade date
      SidewaysDetection=false;                                  // Detect stock that are going nowhere.  If we've held the stock for SidewaysAfterDays AND we've never adjusted the stop AND we can break even THEN we sell.
      SidewaysAfterDays=30;                                     // Sideways detection days.
      MaxDailyPositions=3;                                      // This is the maximum number of positions to pick up per analysis date.  The default is 3
      MaxOpenPositions=3;                                       // This is the maximum number of open positions.  I have tested this with 3 and had good results.
      NoTradeSymbols="CLCT,PRSC,CMD,STAY,GBTC,YOKU,PNY,RFMD,ASAZY,USMO,VNR,STB,XIV,SYNT"; // ASAZY came up as candidate during 3/30 run but not available on Robinhood
      OnlyTradeSymbols="";                                      // This should be a comma separated list of symbols which would serve as the universe of symbols to trade. If null or empty then we trade everything in security master
      InitialCash=10000;                                         // The initial cash 
      TotalRiskPercentDecimal=.05;                                 // Total Risk of Initial Cash.  The default is .02.  I've been testing with .05
      PositionRiskPercentDecimal=.12;                              // Risk per position  - This will determine where the stop is placed.  The default is .12
      CheckOutliersInReturnStream=true;                            // If enabled then we check the return and ensure that no daily return exceeds DailyReturnLimit
      DailyReturnLimit=.25;                                        // If any single day return in the price stream exceeds this amount we toss it out.  The default is .25
      MinRSI=70;                                                   // The minimum RSI in order to consider the candidate.  Default is 70
      MinDaysBetweenReholding=30;                                  // After selling a security we must wait this number of days before acting on a new buy signal .  The default is 15
      EquityOnly=false;                                            // If set to true then ETFs are excluded
      MinPercentReturnProximityTo52WeekHigh=30;                    // The minimum acceptable percent proximity to the 52 week high.  The default is within 30 percent (i.e.) current price can be  below the 52 week high by this margin. The larger the number , the wider the margin
      MinPercentReturnOver52WeekLow=80;                            // The minimum acceptable percent return over the 52 week low.  Marc recommends 80,90,100,200,300
      ProfitMarginCheck=true;                                      // If TRUE then profit margin time series must be present and slope must be increasing
      EPSCheck=true;                                               // If TRUE then eps time series must be present and slope must be increasing
      LiquidityCheck=true;                                         // If TRUE then the price history is checked against MinVolume
      MinVolume=1000;                                             // The minimum day volume in order to consider a security.  This is used if LiquidityCheck is TRUE.  Default is 5000
      DMA200Horizon=15;                                            // Number of days to examine when evaluating the slope of 200 day moving averages.  Default is 20 days of DMA200's
      MinDaysBetweenStopAdjustments=30;                            // We won't adjust a stop if the number of days between previous adjustment is less than this.  Default is 60
      MinDaysBetweenInitialStopAdjustment=5;                       // We won't change the initial stop until this number of days has elapsed.  Default is 60.
      MaxPricingExceptions=3;                                      // This is the pricing exception limit.  If we have this many of exceptions then we will sell the security at the last known good price.
      UseMarketIndicator=true;                                     // If true then we gauge the market based upon the benchmark's moving average
      Benchmark="SPY";                                             // This is the benchmark security
      BenchmarkMovingAverageDays=200;                              // If the latest benchmark Close is below DMA(BenchmarkMovingAverageDays) then we do not purchase new securities.  I tested this with 200 and then with 55.  55 was 56% better over the period tested which was 01/06/2019-05/07/2021. so I am setting this to 100.. just because.
      BenchmarkMovingAverageHorizon=5;                             // This is the horizon for the benchmark indicator.  it must be trading above BenchmarkMovingAverageDays for BenchmarkMovingAverageHorizon days
      UseMarketIndicatorVolatility=true;                           // If this is true then we detect volatile market by examing lower L band breaks on the ~VIX
      UseMarketIndicatorVolatilityHorizon=60;                      // The horizon over which to examine lower L band breaks in ~VIX
      UseMarketIndicatorVolatilityBenchmark="^VIX";                // The benchmark to use for volatility
      UseStopLimitScaling=true;                                    // When set to true this will scale (tighten) the stop limit as time progresses based upon an anticipated holding period of StopLimitScalingDays.
      StopLimitScalingType="AverageTrueRange";                     // Acceptable types are "AverageTrueRange". 
      StopLimitScalingVolatilityDays=30;                           // StopLimitScalingVolatilityDays=5 The StopLimitScaling takes volatility into account.  This parameter specifies how many days of pricing to use for the volatility calculation.
      EvaluateStopOnUpTrend=false;                                 // If set to true then the stop limit is only evaluated if prices are trending up.
      SellOnDMABreak=true;                                         // If true then we look lok for breaks of all DMAs listed under DMABreak
      DMABreakValues="200";                                        // The defaut value is 200.  This can be a comma separated list.  For instance 50,100,200
      DMABreakForceBreak=false;                                    // If this flag is set to true then we will sell a security on DMA break even if it means taking a loss on the position.  
      EntryType="OverExtended,MVP,PriceTrend,VolumeTrend";         // The entry type indictor.  NarrowRange, Swing, MACD, PriceTRend, VolumeTrend, ChannelBreakout.  Default is "MVP,NarrowRange,MACD,PriceTrend,VolumeTrend". 
      PriceTrendDays=20;                                           // If PriceTrend is in the EntryType list then We want to see a series of higher highs and higher lows.  This is the horizon for those observations.  Default is 10.
      EntryHorizon=30;                                             // For the NarrowRange entry indicator this is the number of days to consider
      MACDSetup="(12,26,9)";                                       // setup for MACD Entry.  Default is (12,26,9)
      MACDSignalDays=5;                                            // Number of signal days to consider.  Default is 12
      MACDRejectStrongSells=true;                                  // MACD reject.  Default is false. **Used only if MACD is in the EntryType list
      MACDRejectWeakSells=true;                                    // MACD reject.  Default is true.  **Used only if MACD is in the EntryType list
      VolumeTrendDays=10;                                          // Volume trend can be used as an entry indicator.  The default value is 10 days of increasing volume
      CandidateExpiryDays=180;                                     // Candidates will be kept in the candidate pool for entry search for this many days after which they will be removed and no longer available for consideration
      ChannelBreakoutHorizon=40;                                   // Horizon for ChannelBreakout entry
      UseOverExtendedIndicatorDays=45;                             // 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;                     // Add this in so we can control the margin.  The best value is 1.00 from backtest results
      MaxBeta=10.00;                                               // Candidates with Beta that exceed this are rejected.
      UseMaxBeta=false;                                            // Utilize the MaxBeta filter
      UseProfitMaximization=true;                                  // Maximize profits when setting stop limits.  What this does is to instead of using 3*ATR(20) it will use   UseProfitMaximizationATRMultiplier*ATR(20) to set the stop limit for R's greater than or equal to UseProfitMaximizationRs
      UseProfitMaximizationExpression="R_THRESSHOLD=4;MAX_ATR=3;MULTIPLIER=MAX_ATR;IF(RMultiple>=R_THRESSHOLD){MULTIPLIER=1.2;}";       // The default ATR multiplier is 3 which will maintain a wider gap.  1.2 will follow more closely
			UseTradeOnlySectors=false;                                     // If set to true then only consider companies in specified sectors
			UseTradeOnlySectorsSectors="Healthcare,Technology,Basic Materials,Consumer Defensive,Industrials";
    }
    public bool SuspendTrading{get;set;}
		public bool UsePriceSlopeIndicator{get;set;}
		public int UsePriceSlopeIndicatorDays{get;set;}
    public bool UseMarketIndicatorVolatility{get;set;}
    public int UseMarketIndicatorVolatilityHorizon{get;set;}
    public string UseMarketIndicatorVolatilityBenchmark{get;set;}
    public int BetaMonths { get; set; }
    public DateTime AnalysisDate { get; set; }
    public DateTime TradeDate { get; set; }
    public double MarketCapLowerLimit { get; set; }
    public bool SidewaysDetection { get; set; }
    public int SidewaysAfterDays { get; set; }
    public int PriceTrendDays { get; set; }
    public bool CheckOutliersInReturnStream { get; set; }
    public double DailyReturnLimit { get; set; }
    public int MaxDailyPositions { get; set; }
    public int MaxOpenPositions { get; set; }
    public String NoTradeSymbols { get; set; }
    public String OnlyTradeSymbols { get; set; }
    public double MinRSI { get; set; }
    public List<String> NoTradeSymbolsList { get { return null==NoTradeSymbols?null:Utility.ToList(NoTradeSymbols); } }
    public List<String> OnlyTradeSymbolsList { get { return null==OnlyTradeSymbols?null:Utility.ToList(OnlyTradeSymbols); } }
    public double InitialCash { get; set; }
    public double TotalRiskPercentDecimal { get; set; }
    public double PositionRiskPercentDecimal { get; set; }
    public bool EquityOnly { get; set; }
    public double MinPercentReturnProximityTo52WeekHigh { get; set; }
    public double MinPercentReturnOver52WeekLow { get; set; }
    public bool ProfitMarginCheck { get; set; }
    public bool EPSCheck { get; set; }
    public int MinDaysBetweenReholding { get; set; }
    public bool LiquidityCheck { get; set; }
    public int MinVolume { get; set; }
    public int DMA200Horizon { get; set; }
    public int MinDaysBetweenStopAdjustments { get; set; }
    public int MinDaysBetweenInitialStopAdjustment { get; set; }
    public int MaxPricingExceptions { get; set; }
    public String MACDSetup { get; set; }
    public int MACDSignalDays { get; set; }
    public bool MACDRejectStrongSells { get; set; }
    public bool MACDRejectWeakSells { get; set; }
    public bool UseMarketIndicator { get; set; }
    public String Benchmark { get; set; }
    public int BenchmarkMovingAverageDays { get; set; }
    public int BenchmarkMovingAverageHorizon { get; set; }
    public bool UseStopLimitScaling { get; set; }
    public String StopLimitScalingType { get; set; }
    public int StopLimitScalingVolatilityDays { get; set; }
    public bool SellOnDMABreak { get; set; }
    public String DMABreakValues { get; set; }
    public bool DMABreakForceBreak { get; set; }
    public List<String> DMABreakValuesCollection { get { return (!SellOnDMABreak)||(null==DMABreakValues)?new List<String>():Utility.ToList(DMABreakValues); } }
    public String EntryType { get; set; }
    public List<String> EntryTypesCollection { get { return null==EntryType?new List<String>():Utility.ToList(EntryType); } }
    public int EntryHorizon { get; set; }
    public int CandidateExpiryDays { get; set; }
    public int VolumeTrendDays { get; set; }
    public int ChannelBreakoutHorizon { get; set; }
    public int UseOverExtendedIndicatorDays { get; set; }
    public int UseOverExtendedIndicatorViolationThreshhold { get; set; }
    public double UseOverExtendedIndicatorMarginPercent { get; set; }
    public bool UseMaxBeta { get; set; }
    public double MaxBeta { get; set; }
    public bool UseProfitMaximization{get;set;}
    public string UseProfitMaximizationExpression{get;set;}
		public bool UseTradeOnlySectors{get;set;}
		public String UseTradeOnlySectorsSectors{get;set;}
    public bool EvaluateStopOnUpTrend { get; set; }

    public void DisplayHeader()
    {
      MDTrace.WriteLine(LogLevel.DEBUG,"Setting,Value");
    }
    public NVPCollection ToNVPCollection()
    {
      NVPCollection nvpCollection=new NVPCollection();
      nvpCollection.Add(new NVP("SuspendTrading",SuspendTrading.ToString()));
      nvpCollection.Add(new NVP("UsePriceSlopeIndicator",UsePriceSlopeIndicator.ToString()));
      nvpCollection.Add(new NVP("UsePriceSlopeIndicatorDays",UsePriceSlopeIndicatorDays.ToString()));
      nvpCollection.Add(new NVP("AnalysisDate",AnalysisDate.ToShortDateString()));
      nvpCollection.Add(new NVP("BetaMonths",BetaMonths.ToString()));
      nvpCollection.Add(new NVP("TradeDate",TradeDate.ToShortDateString()));
      nvpCollection.Add(new NVP("MarketCapLowerLimit",MarketCapLowerLimit.ToString()));
      nvpCollection.Add(new NVP("SidewaysDetection",SidewaysDetection.ToString()));
      nvpCollection.Add(new NVP("SidewaysAfterDays",SidewaysAfterDays.ToString()));
      nvpCollection.Add(new NVP("PriceTrendDays",PriceTrendDays.ToString()));
      nvpCollection.Add(new NVP("CheckOutliersInReturnStream",CheckOutliersInReturnStream.ToString()));
      nvpCollection.Add(new NVP("DailyReturnLimit",DailyReturnLimit.ToString()));
      nvpCollection.Add(new NVP("MaxDailyPositions",MaxDailyPositions.ToString()));
      nvpCollection.Add(new NVP("MaxOpenPositions",MaxOpenPositions.ToString()));
      nvpCollection.Add(new NVP("NoTradeSymbols",NoTradeSymbols.ToString()));
      nvpCollection.Add(new NVP("OnlyTradeSymbols",OnlyTradeSymbols.ToString()));
      nvpCollection.Add(new NVP("MinRSI",MinRSI.ToString()));
      nvpCollection.Add(new NVP("InitialCash",InitialCash.ToString()));
      nvpCollection.Add(new NVP("TotalRiskPercentDecimal",TotalRiskPercentDecimal.ToString()));
      nvpCollection.Add(new NVP("PositionRiskPercentDecimal",PositionRiskPercentDecimal.ToString()));
      nvpCollection.Add(new NVP("EquityOnly",EquityOnly.ToString()));
      nvpCollection.Add(new NVP("MinPercentReturnProximityTo52WeekHigh",MinPercentReturnProximityTo52WeekHigh.ToString()));
      nvpCollection.Add(new NVP("MinPercentReturnOver52WeekLow",MinPercentReturnOver52WeekLow.ToString()));
      nvpCollection.Add(new NVP("ProfitMarginCheck",ProfitMarginCheck.ToString()));
      nvpCollection.Add(new NVP("EPSCheck",EPSCheck.ToString()));
      nvpCollection.Add(new NVP("MinDaysBetweenReholding",MinDaysBetweenReholding.ToString()));
      nvpCollection.Add(new NVP("LiquidityCheck",LiquidityCheck.ToString()));
      nvpCollection.Add(new NVP("MinVolume",MinVolume.ToString()));
      nvpCollection.Add(new NVP("DMA200Horizon",DMA200Horizon.ToString()));
      nvpCollection.Add(new NVP("MinDaysBetweenStopAdjustments",MinDaysBetweenStopAdjustments.ToString()));
      nvpCollection.Add(new NVP("MinDaysBetweenInitialStopAdjustment",MinDaysBetweenInitialStopAdjustment.ToString()));
      nvpCollection.Add(new NVP("MaxPricingExceptions",MaxPricingExceptions.ToString()));
      nvpCollection.Add(new NVP("MACDSetup",MACDSetup.ToString()));
      nvpCollection.Add(new NVP("MACDSignalDays",MACDSignalDays.ToString()));
      nvpCollection.Add(new NVP("MACDRejectStrongSells",MACDRejectStrongSells.ToString()));
      nvpCollection.Add(new NVP("MACDRejectWeakSells",MACDRejectWeakSells.ToString()));
      nvpCollection.Add(new NVP("UseMarketIndicator",UseMarketIndicator.ToString()));
      nvpCollection.Add(new NVP("Benchmark",Benchmark.ToString()));
      nvpCollection.Add(new NVP("BenchmarkMovingAverageDays",BenchmarkMovingAverageDays.ToString()));
      nvpCollection.Add(new NVP("BenchmarkMovingAverageHorizon",BenchmarkMovingAverageHorizon.ToString()));
      nvpCollection.Add(new NVP("UseMarketIndicatorVolatility",UseMarketIndicatorVolatility.ToString()));
      nvpCollection.Add(new NVP("UseMarketIndicatorVolatilityHorizon",UseMarketIndicatorVolatilityHorizon.ToString()));
      nvpCollection.Add(new NVP("UseMarketIndicatorVolatilityBenchmark",UseMarketIndicatorVolatilityBenchmark.ToString()));
      nvpCollection.Add(new NVP("UseStopLimitScaling",UseStopLimitScaling.ToString()));
      nvpCollection.Add(new NVP("StopLimitScalingType",StopLimitScalingType.ToString()));
      nvpCollection.Add(new NVP("StopLimitScalingVolatilityDays",StopLimitScalingVolatilityDays.ToString()));
      nvpCollection.Add(new NVP("SellOnDMABreak",SellOnDMABreak.ToString()));
      nvpCollection.Add(new NVP("DMABreakValues",DMABreakValues.ToString()));
      nvpCollection.Add(new NVP("DMABreakForceBreak",DMABreakForceBreak.ToString()));
      nvpCollection.Add(new NVP("EntryType",EntryType.ToString()));
      nvpCollection.Add(new NVP("EntryHorizon",EntryHorizon.ToString()));
      nvpCollection.Add(new NVP("CandidateExpiryDays",CandidateExpiryDays.ToString()));
      nvpCollection.Add(new NVP("VolumeTrendDays",VolumeTrendDays.ToString()));
      nvpCollection.Add(new NVP("ChannelBreakoutHorizon",ChannelBreakoutHorizon.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("MaxBeta",MaxBeta.ToString()));
      nvpCollection.Add(new NVP("UseMaxBeta",UseMaxBeta.ToString()));
      nvpCollection.Add(new NVP("UseProfitMaximization",UseProfitMaximization.ToString()));
      nvpCollection.Add(new NVP("UseProfitMaximizationExpression",UseProfitMaximizationExpression.ToString()));
      nvpCollection.Add(new NVP("UseTradeOnlySectors",UseTradeOnlySectors.ToString()));
      nvpCollection.Add(new NVP("UseTradeOnlySectorsSectors",UseTradeOnlySectorsSectors.ToString()));
      nvpCollection.Add(new NVP("EvaluateStopOnUpTrend",EvaluateStopOnUpTrend.ToString()));
      return nvpCollection;
    }
    public static CMTParams FromNVPCollection(NVPCollection nvpCollection)
    {
      CMTParams cmtParams=new CMTParams();
      NVPDictionary nvpDictionary=nvpCollection.ToDictionary();

      if(nvpDictionary.ContainsKey("SuspendTrading"))
      {
        cmtParams.SuspendTrading=nvpDictionary["SuspendTrading"].Get<bool>();
      }
			if(nvpDictionary.ContainsKey("UsePriceSlopeIndicator"))
			{
			  cmtParams.UsePriceSlopeIndicator=nvpDictionary["UsePriceSlopeIndicator"].Get<bool>();
				cmtParams.UsePriceSlopeIndicatorDays=nvpDictionary["UsePriceSlopeIndicatorDays"].Get<int>();
			}
      if(nvpDictionary.ContainsKey("UseMarketIndicatorVolatility"))
      {
        cmtParams.UseMarketIndicatorVolatility=nvpDictionary["UseMarketIndicatorVolatility"].Get<bool>();
        cmtParams.UseMarketIndicatorVolatilityHorizon=nvpDictionary["UseMarketIndicatorVolatilityHorizon"].Get<int>();
        cmtParams.UseMarketIndicatorVolatilityBenchmark=nvpDictionary["UseMarketIndicatorVolatilityBenchmark"].Get<String>();
      }
      cmtParams.AnalysisDate=nvpDictionary["AnalysisDate"].Get<DateTime>();
      cmtParams.BetaMonths=nvpDictionary["BetaMonths"].Get<int>();
      cmtParams.TradeDate=nvpDictionary["TradeDate"].Get<DateTime>();
      cmtParams.MarketCapLowerLimit=nvpDictionary["MarketCapLowerLimit"].Get<double>();
      cmtParams.SidewaysDetection=nvpDictionary["SidewaysDetection"].Get<bool>();
      cmtParams.SidewaysAfterDays=nvpDictionary["SidewaysAfterDays"].Get<int>();
      cmtParams.PriceTrendDays=nvpDictionary["PriceTrendDays"].Get<int>();
      cmtParams.CheckOutliersInReturnStream=nvpDictionary["CheckOutliersInReturnStream"].Get<bool>();
      cmtParams.DailyReturnLimit=nvpDictionary["DailyReturnLimit"].Get<double>();
      cmtParams.MaxDailyPositions=nvpDictionary["MaxDailyPositions"].Get<int>();
      cmtParams.MaxOpenPositions=nvpDictionary["MaxOpenPositions"].Get<int>();
      cmtParams.NoTradeSymbols=nvpDictionary["NoTradeSymbols"].Get<String>();
      if(nvpDictionary.ContainsKey("OnlyTradeSymbols")) cmtParams.OnlyTradeSymbols=nvpDictionary["OnlyTradeSymbols"].Get<String>();
      cmtParams.MinRSI=nvpDictionary["MinRSI"].Get<double>();
      cmtParams.InitialCash=nvpDictionary["InitialCash"].Get<Double>();
      cmtParams.TotalRiskPercentDecimal=nvpDictionary["TotalRiskPercentDecimal"].Get<double>();
      cmtParams.PositionRiskPercentDecimal=nvpDictionary["PositionRiskPercentDecimal"].Get<double>();
      cmtParams.EquityOnly=nvpDictionary["EquityOnly"].Get<bool>();
      cmtParams.MinPercentReturnProximityTo52WeekHigh=nvpDictionary["MinPercentReturnProximityTo52WeekHigh"].Get<double>();
      cmtParams.MinPercentReturnOver52WeekLow=nvpDictionary["MinPercentReturnOver52WeekLow"].Get<double>();
      cmtParams.ProfitMarginCheck=nvpDictionary["ProfitMarginCheck"].Get<bool>();
      cmtParams.EPSCheck=nvpDictionary["EPSCheck"].Get<bool>();
      cmtParams.MinDaysBetweenReholding=nvpDictionary["MinDaysBetweenReholding"].Get<int>();
      cmtParams.LiquidityCheck=nvpDictionary["LiquidityCheck"].Get<bool>();
      cmtParams.MinVolume=nvpDictionary["MinVolume"].Get<int>();
      cmtParams.DMA200Horizon=nvpDictionary["DMA200Horizon"].Get<int>();
      cmtParams.MinDaysBetweenStopAdjustments=nvpDictionary["MinDaysBetweenStopAdjustments"].Get<int>();
      cmtParams.MinDaysBetweenInitialStopAdjustment=nvpDictionary["MinDaysBetweenInitialStopAdjustment"].Get<int>();
      cmtParams.MaxPricingExceptions=nvpDictionary["MaxPricingExceptions"].Get<int>();
      cmtParams.MACDSetup=nvpDictionary["MACDSetup"].Get<String>();
      cmtParams.MACDSignalDays=nvpDictionary["MACDSignalDays"].Get<int>();
      cmtParams.MACDRejectStrongSells=nvpDictionary["MACDRejectStrongSells"].Get<bool>();
      cmtParams.MACDRejectWeakSells=nvpDictionary["MACDRejectWeakSells"].Get<bool>();
      cmtParams.UseMarketIndicator=nvpDictionary["UseMarketIndicator"].Get<bool>();
      cmtParams.Benchmark=nvpDictionary["Benchmark"].Get<String>();
      cmtParams.BenchmarkMovingAverageDays=nvpDictionary["BenchmarkMovingAverageDays"].Get<int>();
      cmtParams.BenchmarkMovingAverageHorizon=nvpDictionary["BenchmarkMovingAverageHorizon"].Get<int>();
      cmtParams.UseStopLimitScaling=nvpDictionary["UseStopLimitScaling"].Get<bool>();
      if(nvpDictionary.ContainsKey("StopLimitScalingType")) cmtParams.StopLimitScalingType=nvpDictionary["StopLimitScalingType"].Get<String>();
      cmtParams.StopLimitScalingVolatilityDays=nvpDictionary["StopLimitScalingVolatilityDays"].Get<int>();
      cmtParams.SellOnDMABreak=nvpDictionary["SellOnDMABreak"].Get<bool>();
      cmtParams.DMABreakValues=nvpDictionary["DMABreakValues"].Get<String>();
      if(nvpDictionary.ContainsKey("DMABreakForceBreak")) cmtParams.DMABreakForceBreak=nvpDictionary["DMABreakForceBreak"].Get<bool>();
      cmtParams.EntryType=nvpDictionary["EntryType"].Get<String>();
      cmtParams.EntryHorizon=nvpDictionary["EntryHorizon"].Get<int>();
      cmtParams.CandidateExpiryDays=nvpDictionary["CandidateExpiryDays"].Get<int>();
      if(nvpDictionary.ContainsKey("VolumeTrendDays")) cmtParams.VolumeTrendDays=nvpDictionary["VolumeTrendDays"].Get<int>();
      if(nvpDictionary.ContainsKey("ChannelBreakoutHorizon")) cmtParams.ChannelBreakoutHorizon=nvpDictionary["ChannelBreakoutHorizon"].Get<int>();
      cmtParams.UseOverExtendedIndicatorDays=nvpDictionary["UseOverExtendedIndicatorDays"].Get<int>();
      cmtParams.UseOverExtendedIndicatorViolationThreshhold=nvpDictionary["UseOverExtendedIndicatorViolationThreshhold"].Get<int>();
      cmtParams.UseOverExtendedIndicatorMarginPercent=nvpDictionary["UseOverExtendedIndicatorMarginPercent"].Get<double>();
      cmtParams.UseMaxBeta=nvpDictionary["UseMaxBeta"].Get<bool>();
      cmtParams.MaxBeta=nvpDictionary["MaxBeta"].Get<double>();
      if(nvpDictionary.ContainsKey("UseProfitMaximization"))
      {
        cmtParams.UseProfitMaximization=nvpDictionary["UseProfitMaximization"].Get<bool>();
        cmtParams.UseProfitMaximizationExpression=nvpDictionary["UseProfitMaximizationExpression"].Get<String>();
      }
      if(nvpDictionary.ContainsKey("UseTradeOnlySectors"))
			{
			  cmtParams.UseTradeOnlySectors=nvpDictionary["UseTradeOnlySectors"].Get<bool>();
				cmtParams.UseTradeOnlySectorsSectors=nvpDictionary["UseTradeOnlySectorsSectors"].Get<String>();
			}
      if(nvpDictionary.ContainsKey("EvaluateStopOnUpTrend"))
      {
        cmtParams.EvaluateStopOnUpTrend=nvpDictionary["EvaluateStopOnUpTrend"].Get<bool>();
      }
      return cmtParams;
    }
    public void DisplayConfiguration()
    {
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("SuspendTrading,{0}",SuspendTrading));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UsePriceSlopeIndicator,{0}",UsePriceSlopeIndicator));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UsePriceSlopeIndicatorDays,{0}",UsePriceSlopeIndicatorDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("AnalysisDate,{0}",AnalysisDate));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TradeDate,{0}",TradeDate));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("SidewaysDetection,{0}",SidewaysDetection));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("SidewaysAfterDays,{0}",SidewaysAfterDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("PriceTrendDays,{0}",PriceTrendDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MaxDailyPositions,{0}",MaxDailyPositions));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MaxOpenPositions,{0}",MaxOpenPositions));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("NoTradeSymbols,{0}",NoTradeSymbols));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("OnlyTradeSymbols,{0}",OnlyTradeSymbols));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("InitialCash,{0}",InitialCash));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TotalRiskPercentDecimal,{0}",TotalRiskPercentDecimal));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("PositionRiskPercentDecimal,{0}",PositionRiskPercentDecimal));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("CheckOutliersInReturnStream,{0}",CheckOutliersInReturnStream));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DailyReturnLimit,{0}",DailyReturnLimit));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinRSI,{0}",MinRSI));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinDaysBetweenReholding,{0}",MinDaysBetweenReholding));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("EquityOnly,{0}",EquityOnly));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinPercentReturnProximityTo52WeekHigh,{0}",MinPercentReturnProximityTo52WeekHigh));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinPercentReturnOver52WeekLow,{0}",MinPercentReturnOver52WeekLow));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("ProfitMarginCheck,{0}",ProfitMarginCheck));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("EPSCheck,{0}",EPSCheck));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("LiquidityCheck,{0}",LiquidityCheck));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinVolume,{0}",MinVolume));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMA200Horizon,{0}",DMA200Horizon));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinDaysBetweenStopAdjustments,{0}",MinDaysBetweenStopAdjustments));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MinDaysBetweenInitialStopAdjustment,{0}",MinDaysBetweenInitialStopAdjustment));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MaxPricingExceptions,{0}",MaxPricingExceptions));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MACDSetup,{0}",MACDSetup));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MACDSignalDays,{0}",MACDSignalDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MACDRejectStrongSells,{0}",MACDRejectStrongSells));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MACDRejectWeakSells,{0}",MACDRejectWeakSells));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseMarketIndicator,{0}",UseMarketIndicator));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Benchmark,{0}",Benchmark));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("BenchmarkMovingAverageDays,{0}",BenchmarkMovingAverageDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("BenchmarkMovingAverageHorizon,{0}",BenchmarkMovingAverageHorizon));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseMarketIndicatorVolatility,{0}",UseMarketIndicatorVolatility));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseMarketIndicatorVolatilityHorizon,{0}",UseMarketIndicatorVolatilityHorizon));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseMarketIndicatorVolatilityBenchmark,{0}",UseMarketIndicatorVolatilityBenchmark));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseStopLimitScaling,{0}",UseStopLimitScaling));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("StopLimitScalingType,{0}",StopLimitScalingType));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("StopLimitScalingVolatilityDays,{0}",StopLimitScalingVolatilityDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("SellOnDMABreak,{0}",SellOnDMABreak));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMABreakValues,{0}",DMABreakValues));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMABreakForceBreak,{0}",DMABreakForceBreak));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("EntryType,{0}",EntryType));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("EntryHorizon,{0}",EntryHorizon));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("CandidateExpiryDays,{0}",CandidateExpiryDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("VolumeTrendDays,{0}",VolumeTrendDays));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("ChannelBreakoutHorizon,{0}",ChannelBreakoutHorizon));
      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("UseMaxBeta,{0}",UseMaxBeta.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MaxBeta,{0}",MaxBeta.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("MarketCapLowerLimit,{0}",MarketCapLowerLimit.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("BetaMonths,{0}",BetaMonths.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseProfitMaximization,{0}",UseProfitMaximization.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseProfitMaximizationExpression,{0}",UseProfitMaximizationExpression.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseTradeOnlySectors,{0}",UseTradeOnlySectors.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("UseTradeOnlySectorsSectors,{0}",UseTradeOnlySectorsSectors.ToString()));
      MDTrace.WriteLine(LogLevel.DEBUG,String.Format("EvaluateStopOnUpTrend,{0}",EvaluateStopOnUpTrend.ToString()));
    }
  }
}

