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

namespace MarketData
{
  public static class  CMMomentumHelper
  {
    /// <summary>
    ///  CMCANDIDATELASTRESORT /TRADEDATE:
    /// </summary>
    /// <param name="args"></param>
    public static void RunCMCandidateLastResort(CommandArgs commandArgs)
    {
      CMParams cmParams = new CMParams();
      List<String> candidates = Utility.ToList(cmParams.FallbackCandidateBestOf);
      if (!commandArgs.Has("TRADEDATE")) { MDTrace.WriteLine(LogLevel.DEBUG, "TRADEDATE required"); return; }
      CMCandidate cmCandidate = CMCandidateGenerator.GetFallbackCandidateOfLastResort(candidates, commandArgs.Coalesce<DateTime>("TRADEDATE"), commandArgs.Coalesce<DateTime>("TRADEDATE"), cmParams);
      if (null == cmCandidate) { MDTrace.WriteLine(LogLevel.DEBUG, "Unable to determine candidate of last resort."); return; }
      foreach (String candidate in candidates)
      {
        MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Candidate examined..{0}", candidate));
      }
      MDTrace.WriteLine(LogLevel.DEBUG, String.Format("Best candidate is {0}", cmCandidate.Symbol));
    }

    /// <summary>
    /// CMGAINLOSS /SESSIONFILE:{PATHSESSIONFILE}  (i.e.) CMGAINLOSS /SESSIONFILE:C:\boneyard\marketdata\bin\Debug\saferun\CM20191031.txt"); 
    /// </summary>
    /// <param name="args"></param>
    public static void RunCMGainLoss(CommandArgs commandArgs)
    {
      if(!commandArgs.Has("SESSIONFILE")) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Missing SESSIONFILE")); return; }
      CMMomentumBacktest cmBacktest=new CMMomentumBacktest();
      cmBacktest.DisplayGainLoss(commandArgs.Coalesce<String>("SESSIONFILE"));
    }

    /// <summary>
    /// CMSESSION /SESSIONFILE:
    /// </summary>
    /// <param name="args"></param>
    public static void RunCMSession(CommandArgs commandArgs)
    {
      if (!commandArgs.Has("SESSIONFILE"))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Missing SESSIONFILE"));
        return;
      }
      CMMomentumBacktest cmBacktest = new CMMomentumBacktest();
      cmBacktest.DisplaySession(commandArgs.Coalesce<String>("SESSIONFILE"));
    }

    /// <summary>
    /// RUNCMBACKTEST /STARTDATE: /MAXPOSITIONS: /INITIALCASH: /HOLDINGPERIOD: /{USEBINBASEDPOSITIONSIZING}: /{USEBINBASEDPOSITIONSIZINGNUMBINS}: /{TARGETBETA}: /{ENDDATE}: /SESSIONFILE: /{USECNN}: /{USECNNHOST}: /{USECNNDAYCOUNT}: 
    /// </summary>
    /// <param name="args"></param>
		public static void RunCMMomentum(CommandArgs commandArgs)
    {				  
				if(!commandArgs.Has("STARTDATE,MAXPOSITIONS,INITIALCASH,HOLDINGPERIOD"))
				{
					if(!commandArgs.Has("STARTDATE")) MDTrace.WriteLine(LogLevel.DEBUG,"Missing STARTDATE");
					if(!commandArgs.Has("MAXPOSITIONS")) MDTrace.WriteLine(LogLevel.DEBUG,"Missing MAXPOSITIONS");
					if(!commandArgs.Has("INITIALCASH")) MDTrace.WriteLine(LogLevel.DEBUG,"Missing INITIALCASH");
					if(!commandArgs.Has("HOLDINGPERIOD")) MDTrace.WriteLine(LogLevel.DEBUG,"Missing HOLDINGPERIOD");
					return;
				}

				CMParams cmParams=new CMParams();
				cmParams.AnalysisDate=commandArgs.Get<DateTime>("STARTDATE");
				cmParams.MaxPositions=commandArgs.Get<int>("MAXPOSITIONS");
				cmParams.InitialCash=commandArgs.Get<double>("INITIALCASH");
				cmParams.HoldingPeriod=commandArgs.Get<int>("HOLDINGPERIOD");

				if(commandArgs.Has("USECNN"))
				{
				  if(!commandArgs.Has("USECNNCLIENT,USECNNDAYCOUNT"))
					{
						MDTrace.WriteLine(LogLevel.DEBUG,"Missing USECNNCLIENT, USECNNDAYCOUNT");
						return;
					}
					cmParams.UseCNN=true;
					cmParams.UseCNNHost=commandArgs.Get<String>("USECNNHOST");
					cmParams.UseCNNDayCount=commandArgs.Get<int>("USECNNDAYCOUNT");
          if(commandArgs.Has("USECNNREWARDPERCENTDECIMAL"))cmParams.UseCNNRewardPercentDecimal=commandArgs.Get<double>("USECNNREWARDPERCENTDECIMAL");
				}

				if(commandArgs.Has("USEOVEREXTENDEDINDICATOR"))
				{
					if(!commandArgs.Has("USEOVEREXTENDEDINDICATORDAYS,USEOVEREXTENDEDINDICATORVIOLATIONTHRESHHOLD,USEOVEREXTENDEDINDICATORMARGINPERCENT"))
					{
						MDTrace.WriteLine(LogLevel.DEBUG,"Missing USEOVEREXTENDEDINDICATORDAYS, USEOVEREXTENDEDINDICATORVIOLATIONTHRESHHOLD, USEOVEREXTENDEDINDICATORMARGINPERCENT");
						return;
					}
					cmParams.UseOverExtendedIndicator=commandArgs.Get<bool>("USEOVEREXTENDEDINDICATOR");
					cmParams.UseOverExtendedIndicatorDays=commandArgs.Get<int>("USEOVEREXTENDEDINDICATORDAYS");
					cmParams.UseOverExtendedIndicatorViolationThreshhold=commandArgs.Get<int>("USEOVEREXTENDEDINDICATORVIOLATIONTHRESHHOLD");
					cmParams.UseOverExtendedIndicatorMarginPercent=commandArgs.Get<double>("USEOVEREXTENDEDINDICATORMARGINPERCENT");
				}


				if(commandArgs.Has("USEMAXPOSITIONBUCKETWEIGHT"))   // UseMaxPositionBucketWeight
				{
					if(!commandArgs.Has("USEMAXPOSITIONBUCKETWEIGHTMAXWEIGHT"))     // UseMaxPositionBucketWeightMaxWeight
					{
						MDTrace.WriteLine(LogLevel.DEBUG,"Missing USEMAXPOSITIONBUCKETWEIGHTMAXWEIGHT");
						return;
					}
					cmParams.UseMaxPositionBucketWeight=commandArgs.Get<bool>("USEMAXPOSITIONBUCKETWEIGHT");
					cmParams.UseMaxPositionBucketWeightMaxWeight=commandArgs.Get<double>("USEMAXPOSITIONBUCKETWEIGHTMAXWEIGHT");
				}
				else
				{
					cmParams.UseMaxPositionBucketWeight=false;
					cmParams.UseMaxPositionBucketWeightMaxWeight=0;
				}

				if(commandArgs.Has("TARGETBETA"))cmParams.TargetBeta=commandArgs.Get<double>("TARGETBETA");
				else cmParams.TargetBeta=1.00;

				DateTime endDate=DateTime.Now;
				String pathSessionFileName=commandArgs.Coalesce<String>("SESSIONFILE",null);
				if(null!=pathSessionFileName) pathSessionFileName=pathSessionFileName.Trim();
				cmParams.DisplayHeader();

				CMMomentumBacktest backtestMomentum=new CMMomentumBacktest();
				List<CMBacktestResult> results=new List<CMBacktestResult>();
				results.Add(backtestMomentum.PerformBacktest(cmParams.AnalysisDate,endDate,pathSessionFileName,cmParams));
		}
  }
}
