Overall Statistics
using QuantConnect.Util;
using System.Reflection;

namespace QuantConnect 
{
    /*
    *   QuantConnect University: Full Basic Template:
    *
    *   The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect.
    *   We have explained some of these here, but the full algorithm can be found at:
    *   https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs
    */
    public class T3EquitySettlementAlgorithm : QCAlgorithm
    {
        public static QCAlgorithm Instance;
        
        DateTime lastTradeTime;
        // if you change the number of symbols here to only be 2, then we'll get insufficient buying power
        // errors since we'll be trying to purchase shares with unsettled funds
        static List<string> Symbols = new List<string>{"MSFT", "AAPL", "GOOG"};
        static readonly decimal EqualWeightPercentage = 1m/Symbols.Count;
        // circular queue is a never ending queue that will re-circle on itself, so
        // it will emit SPY, AAPL, GOOG, SPY, APPL, GOOG, ... and so on
        CircularQueue<string> SymbolQueue = new CircularQueue<string>(Symbols);
        
        //Initialize the data and resolution you require for your strategy:
        public override void Initialize() 
        {


            // set our brokerage model to use a cash account type
            SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Cash);
            
            SetStartDate(2015, 1, 3);
            SetEndDate(2015, 2, 10);
            SetCash(6000);
            
            SetBenchmark("XOM");
            
            foreach (var symbol in Symbols)
            {
                AddSecurity(SecurityType.Equity, symbol, Resolution.Minute, 
                    fillDataForward: true, 
                    extendedMarketHours: false, 
                    leverage: 1
                    );
            }
        }
        //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
        public void OnData(TradeBars data) 
        {
        	
            if (Time - lastTradeTime.Date < TimeSpan.FromDays(1))
            {
                // only trade once a day at market open
                return;
            }
            lastTradeTime = Time;
            
            // get the symbol to trade today

            var symbolToday = SymbolQueue.Dequeue();
            
            // calculate share count for equal portfolio weighting (TotalPortfolioValue includes unsettled funds as well!)
            var equalWeightedPorfolioSize = Portfolio.TotalPortfolioValue/Symbols.Count;
            var shareCount = CalculateOrderQuantity(symbolToday, EqualWeightPercentage);
            MarketOrder(symbolToday, shareCount, tag: "Order Target Value: $" + Math.Round(equalWeightedPorfolioSize, 2));
            Log("" + equalWeightedPorfolioSize);
            
            // submit market on close to liquidate at EOD
            MarketOnCloseOrder(symbolToday, -shareCount);

            // you can access the settled only funds using the CashBook
            var settledCash = Portfolio.CashBook["USD"].Amount;
            // you can access the unsettled fund using the UnsettledCashBook
            var unsettledCash = Portfolio.UnsettledCashBook["USD"].Amount;
        }
        
        public override void OnEndOfDay()
        {
            // at the end of each day log the state of our settled and unsettled cashbooks
            Log(string.Empty);
            Log("-------------------"+Time.Date.ToShortDateString()+"-------------------");
            Log("SETTLED::");
            var settled = Portfolio.CashBook.ToString();
            foreach (var line in settled.Split('\n'))
            {
                Log("    " + line);
            }
            Log(string.Empty);
            Log(string.Empty);
            Log("UNSETTLED::");
            var unsettled = Portfolio.UnsettledCashBook.ToString();
            foreach (var line in unsettled.Split('\n'))
            {
                Log("    " + line);
            }
        }
    }
}