using MarketData.Generator.Momentum;
using System;
using System.Collections.Generic;

namespace MarketData.ModelHelper
{
  public static class MGMomentumHelper
  {
    /// <summary>
    /// RUNMOMENTUM /STARTDATE: /MAXPOSITIONS:
    /// </summary>
    /// <param name="commandArgs"></param>
    public static void RunMomentum(CommandArgs commandArgs)
    {
      if (!commandArgs.Has("STARTDATE,MAXPOSITIONS")) return;
      DateTime analysisDate = commandArgs.Coalesce<DateTime>("STARTDATE");
      int maxPositions = commandArgs.Coalesce<int>("MAXPOSITIONS");
      MGConfiguration config = new MGConfiguration();
      MomentumCandidates momentumCandidates = MomentumGenerator.GenerateMomentum(analysisDate, config);
      MDTrace.WriteLine(LogLevel.DEBUG, String.Format("{0}", MomentumCandidate.Header()));
      for (int index = 0; index < momentumCandidates.Count; index++)
      {
        MomentumCandidate momentumCandidate = momentumCandidates[index];
        MDTrace.WriteLine(LogLevel.DEBUG, String.Format("{0}", momentumCandidate.ToString()));
      }
    }

    /// <summary>
    ///  MGLIQUIDATE /SESSIONFILE: /TRADEDATE:
    /// </summary>
    /// <param name="commandArgs"></param>
    public static void RunMGLiquidate(CommandArgs commandArgs)
    {
      DateTime? tradeDate = null;
      if (!commandArgs.Has("SESSIONFILE")) return;
      if (commandArgs.Has("TRADEDATE")) tradeDate = commandArgs.Coalesce<DateTime>("TRADEDATE");
      MomentumBacktest momentumBacktest = new MomentumBacktest();
      momentumBacktest.MGLiquididate(commandArgs.Coalesce<String>("SESSIONFILE"), tradeDate);
    }

    /// <summary>
    /// MGGAINLOSS /SESSIONFILE:{PATHSESSIONFILE}   (i.e.) MGGAINLOSS /SESSIONFILE:C:\boneyard\marketdata\bin\Debug\saferun\MG20180131.txt");
    /// </summary>
    /// <param name="commandArgs"></param>
    public static void RunMGGainLoss(CommandArgs commandArgs)
    {
      if(!commandArgs.Has("SESSIONFILE")) { MDTrace.WriteLine(LogLevel.DEBUG,"Missing SESSIONFILE"); return; }
      MomentumBacktest momentumBacktest = new MomentumBacktest();
      MomentumBacktest.DisplayGainLoss(commandArgs.Coalesce<String>("SESSIONFILE"));
    }
    /// <summary>
    /// MGSESSION /SESSIONFILE:
    /// </summary>
    /// <param name="commandArgs"></param>
    public static void RunMGSession(CommandArgs commandArgs)
    {
      if(!commandArgs.Has("SESSIONFILE")) { MDTrace.WriteLine(LogLevel.DEBUG,"Missing SESSIONFILE"); return; }
      MomentumBacktest momentumBacktest = new MomentumBacktest();
      momentumBacktest.DisplaySession(commandArgs.Coalesce<String>("SESSIONFILE"));
    }

    /// <summary>
    /// RUNBACKTEST /STARTDATE: /MAXPOSITIONS: /INITIALCASH: /HOLDINGPERIOD: /{ENDDATE}: /{SESSIONFILE}:
    /// </summary>
    /// <param name="commandArgs"></param>
    public static void RunBacktest(CommandArgs commandArgs)
    {
      MGConfiguration mgParams=new MGConfiguration();
      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;
      }
      mgParams.MaxPositions=commandArgs.Coalesce<int>("MAXPOSITIONS");
      mgParams.InitialCash=commandArgs.Coalesce<int>("INITIALCASH");
      mgParams.HoldingPeriod=commandArgs.Coalesce<int>("HOLDINGPERIOD");

      if(commandArgs.Has("INCLUDETRADEMASTERFORSYMBOLSHELD"))
      {
        mgParams.IncludeTradeMasterForSymbolsHeld=commandArgs.Get<bool>("INCLUDETRADEMASTERFORSYMBOLSHELD");
      }

      if(commandArgs.Has("USESTOCHASTICS")) 
      {
        mgParams.UseStochastics=commandArgs.Coalesce<bool>("USESTOCHASTICS",true);
      }

      if(commandArgs.Has("USECALCBETA")) 
      {
        mgParams.UseCalcBeta=commandArgs.Coalesce<bool>("USECALCBETA",true);
      }

// ** M A C D 
      if(commandArgs.Has("USEMACD"))
      {
        mgParams.UseMACD=commandArgs.Coalesce<bool>("USEMACD",true);
      }
      if(commandArgs.Has("MACDREJECTSTRONGSELLSIGNALS"))
      {
        mgParams.MACDRejectStrongSellSignals=commandArgs.Coalesce<bool>("MACDREJECTSTRONGSELLSIGNALS",true);
      }
      if(commandArgs.Has("MACDREJECTWEAKSELLSIGNALS"))
      {
        mgParams.MACDRejectWeakSellSignals=commandArgs.Coalesce<bool>("MACDREJECTWEAKSELLSIGNALS",true);
      }
      if(commandArgs.Has("MACDSIGNALDAYS"))
      {
        mgParams.MACDSignalDays=commandArgs.Coalesce<int>("MACDSIGNALDAYS",mgParams.MACDSignalDays);
      }
      if(commandArgs.Has("MACDSETUP"))
      {
        mgParams.MACDSetup=commandArgs.Coalesce<String>("MACDSETUP",mgParams.MACDSetup);
      }
// **
      QualityIndicator qualityIndicator=new QualityIndicator(QualityIndicator.QualityType.IDIndicator);
      if(commandArgs.Has("QUALITYINDICATORTYPE")) qualityIndicator.Quality=QualityIndicator.ToQuality(commandArgs.Coalesce<String>("QUALITYINDICATORTYPE","IDINDICATOR"));
      mgParams.QualityIndicatorType=qualityIndicator.ToString();

      mgParams.UseLowSlopeBetaCheck=true;
      if(commandArgs.Has("USELOWSLOPEBETACHECK")) mgParams.UseLowSlopeBetaCheck=commandArgs.Coalesce<bool>("USELOWSLOPEBETACHECK",true);

      DateTime startDate = commandArgs.Coalesce<DateTime>("STARTDATE");
      DateTime endDate=commandArgs.Coalesce<DateTime>("ENDDATE",new DateTime());

      String pathSessionFileName = commandArgs.Coalesce<String>("SESSIONFILE", null);
      if(null!=pathSessionFileName)pathSessionFileName=pathSessionFileName.Trim();

      mgParams.DisplayHeader();
      List<BacktestResult> results=new List<BacktestResult>();
      MomentumBacktest backtestMomentum=new MomentumBacktest();
      results.Add(backtestMomentum.PerformBacktest(startDate,endDate,pathSessionFileName,mgParams));
    }
  }
}
