using MarketData.Generator.MGSHMomentum;
using MarketData.Utils;
using System;
using System.Collections.Generic;
using System.IO;

namespace MarketData
{
  public static class MGSHMomentumHelper
  {
    public static void HandleMGSHSession(CommandArgs commandArgs)
    {
      if(!commandArgs.Has("SESSIONFILE")) 
      { 
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,"Missing SESSIONFILE");
        return;
      }
      MGSHMomentumBacktest momentumBacktest = new MGSHMomentumBacktest();
      momentumBacktest.DisplaySession(commandArgs.Coalesce<String>("SESSIONFILE"));
    }

    public static void HandleMGSHRunDaily(CommandArgs commandArgs)
    {
      DateGenerator dateGenerator = new DateGenerator();
      if(!commandArgs.Has("SESSIONFILE,TRADEDATE"))
      { 
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,"SESSIONFILE and TRADEDATE are required parameters.");
        return;
      }
      DateTime tradeDate = commandArgs.Get<DateTime>("TRADEDATE");

      if(!dateGenerator.IsMarketOpen(tradeDate))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,$"TRADEDATE {tradeDate.ToShortDateString()} is not a trading date.");
        return;
      }

      DateTime endDate = dateGenerator.FindNextBusinessDay(tradeDate);   // UpdateDaily will not process the endDate (i.e.) while(tradeDate<endDate){;}

      String pathSessionFile = commandArgs.Get<String>("SESSIONFILE");
      pathSessionFile = pathSessionFile.Trim();
      if(!File.Exists(pathSessionFile))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,$"The specified file '{pathSessionFile}' does not exist.");
        return;
      }

      MGSHMomentumBacktest momentumBacktest = new MGSHMomentumBacktest();

      if(!dateGenerator.IsMarketOpen(tradeDate))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,String.Format("The market is closed today, please confirm Y/N:{0}?",tradeDate.ToShortDateString()));
        String result=Console.ReadLine();
        if(null==result||!(result.ToUpper().Equals("Y")||result.ToUpper().Equals("YES")))return;
      }

      MGSHBacktestResult backtestResult = momentumBacktest.UpdateDaily(tradeDate, endDate, DateTime.Now, pathSessionFile);
    }

    public static void HandleMGSHRunBacktest(CommandArgs commandArgs)
    {
      MGSHConfiguration mgParams=new MGSHConfiguration();
      if (!commandArgs.Has("STARTDATE,MAXPOSITIONS,INITIALCASH,HOLDINGPERIOD"))
      {
        if (!commandArgs.Has("STARTDATE")) MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red, "Missing STARTDATE");
        if (!commandArgs.Has("MAXPOSITIONS")) MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red, "Missing MAXPOSITIONS");
        if (!commandArgs.Has("INITIALCASH")) MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red, "Missing INITIALCASH");
        if (!commandArgs.Has("HOLDINGPERIOD")) MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red, "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("USESTOPLIMITS"))
      {
        mgParams.UseStopLimits=commandArgs.Coalesce<bool>("USESTOPLIMITS",false);
      }

      if(commandArgs.Has("STOPLIMITRISKPERCENTDECIMAL"))
      {
        mgParams.StopLimitRiskPercentDecimal=commandArgs.Coalesce<double>("STOPLIMITRISKPERCENTDECIMAL",.12);
      }

      if(commandArgs.Has("USEHEDGING"))
      {
        mgParams.UseHedging=commandArgs.Coalesce<bool>("USEHEDGING",false);
        if(commandArgs.Has("INITIALHEDGECASH"))
        {
          mgParams.HedgeInitialCash=commandArgs.Get<double>("INITIALHEDGECASH");
        }
      }

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

// ** 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);
      }
// **
      MGSHQualityIndicator qualityIndicator=new MGSHQualityIndicator(MGSHQualityIndicator.QualityType.IDIndicator);
      if(commandArgs.Has("QUALITYINDICATORTYPE")) qualityIndicator.Quality=MGSHQualityIndicator.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());

      DateGenerator dateGenerator = new DateGenerator();
      if(!dateGenerator.IsMarketOpen(startDate))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,$"STARTDATE {startDate.ToShortDateString()} is not a trading date.");
        return;
      }
      if(!dateGenerator.IsMarketOpen(endDate))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,$"ENDDATE {endDate.ToShortDateString()} is not a trading date.");
        return;
      }

      if(!commandArgs.Has("SESSIONFILE"))
      {
        MDTrace.WriteLine(LogLevel.DEBUG,ConsoleColor.Red,$"SESSIONFILE is a required parameter.");
        return;
      }

      String pathSessionFile = commandArgs.Get<String>("SESSIONFILE");
      pathSessionFile = pathSessionFile.Trim();

      List<MGSHBacktestResult> results=new List<MGSHBacktestResult>();
      MGSHMomentumBacktest backtestMomentum=new MGSHMomentumBacktest();
      results.Add(backtestMomentum.PerformBacktest(startDate, endDate, pathSessionFile, mgParams));
    }
  }
}
