Overall Statistics
using QuantConnect.Securities;
using QuantConnect.Orders.Fees;
using QuantConnect.Notifications;
using QuantConnect.Orders;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace QuantConnect 
{   

    public class BasicTemplateAlgorithm : QCAlgorithm
    {
        //Initialize the data and resolution you require for your strategy:
        string symbol = "IMI";
        int _quantity;
        decimal _pct;
        decimal _thirds;
        //decimal _takeProfit;
        bool trigger = false;
        bool first = true;
        static string globalString;
        //OrderTicket _stopLoss;
        
        //const decimal _tailingPercent = 0.05m;
    	//const decimal _stopLossFactor = 1 - _tailingPercent;
    	static readonly decimal EqualWeightPercentage = 1m/3;
    	//private ISecurityProvider _securityProvider;
        public override void Initialize() 
        {

            //Start and End Date range for the backtest:
            SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Cash);
           
            SetStartDate(2016, 03, 7);         
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            
            //Cash allocation
            SetCash(2750);
            var thirds = Portfolio.Cash/3 * .05m;
            var threePct = Portfolio.Cash/3 * .03m;
            //_takeProfit = threePct;
            _pct = Portfolio.Cash/3 + threePct;
            _thirds = Portfolio.Cash/3 - thirds;

            //Add as many securities as you like. All the data will be passed into the event handler:
            AddSecurity(SecurityType.Equity, symbol, Resolution.Second);
        }
        
        //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, ISecurityProvider _securityProvider) 
        {   
            // "TradeBars" object holds many "TradeBar" objects: it is a dictionary indexed by the symbol:
            // 
            //  e.g.  data["MSFT"] data["GOOG"]
            
            var symPrice = data[symbol].Price;
            var skimProfits = _quantity * symPrice;
            var readableProfits = skimProfits - Portfolio.Cash;
            var time = DateTime.Now;
            string messageString = String.Format("Symbol: {0}\tTime: {1}\tPrice: {2}\tProfit: {3}", symbol, time.ToString(), symPrice.ToString(), readableProfits.ToString());
            globalString = messageString;
            
            if (!Portfolio.HoldStock) 
            {
                int quantity = (int)Math.Floor(Portfolio.Cash / data[symbol].Close / 3);
                _quantity = quantity;

                //Order function places trades: enter the string symbol and the quantity you want:
                if ( first)//Time.Hour==9 && Time.Minute == 30 && Time.Second== 01)
                {
                	first = false;
					Order(symbol,  quantity);
               
                Notify.Sms("+15126454560", "Buy " + messageString);
                }
                
                //Debug sends messages to the user console: "Time" is the algorithm time keeper object 
                //Debug("Purchased SPY on " + Time.ToShortDateString());
                
                //You can also use log to send longer messages to a file. You are capped to 10kb
                //Log("This is a longer message send to log.");
                
            }

            	
            
            	//Log("skim " + skimProfits);
            	//Log("three " + _pct);
            
            // set trigger equal to true if profits are greater than 3 percent of invested portfolio cash
            if (Portfolio.HoldStock && skimProfits > _pct)
            {
            trigger = true;
            //Order(symbol, -_quantity);
            Notify.Sms("+15126454560", "The trigger price has been reached!");
        	}
        	
        	//start stop loss calculations
            //if (trigger = true)
        	//{
            //var profits = Portfolio.TotalUnleveredAbsoluteHoldingsCost;
        	//_stopLoss = StopMarketOrder(symbol, -_quantity, Securities[symbol].Price*_stopLossFactor);

			//take profit if stock is falling
            //if(skimProfits < _pct)
            //{
            //Order(symbol, -_quantity);
            //}
        	//}
        		var highPrice = _quantity * data[symbol].High;
        		var newStopLoss = highPrice * .03m;
        		var newStopLosss = newStopLoss * .10m;
        		var highPriceStop = newStopLoss - newStopLosss;
        		
        		var currentPriceStop = skimProfits *.03m;
        		
        		//Log("" + currentPriceStop);
        		//Log("" + highPriceStop);
        		//Log("skim" + skimProfits);
        		//Log("third" + _thirds);
        		//var getSecurity = _securityProvider.GetSecurity(symbol);
        		var holdingQuantity = _securityProvider.GetHoldingsQuantity(symbol);
        		Log("q" + holdingQuantity);
        		//Log("p" + symPrice);
        	
        	if (trigger == true && currentPriceStop < highPriceStop)
        	{
        		Notify.Sms("+15126454560", "Gain Sell " + globalString);
        		Order(symbol, -_quantity);
        	}
        	
        	// sell if profits go below 5% invested portfolio cash
            if (Portfolio.HoldStock && skimProfits < _thirds)
            {
            	Notify.Sms("+15126454560", "Loss Sell " + globalString);
            	Order(symbol, -_quantity);
            }
            
            // sell on close
            if ( Portfolio.HoldStock && Time.Hour==15 && Time.Minute==59 && Time.Second==58 )
            {
            	Notify.Sms("+15126454560", "End Of Day Sell " + globalString);
            	Order(symbol, -_quantity);
            }
            
            
        	
            
            /*if (_stopLoss != null && !_stopLoss.Status.IsFill())
        	{
        		var currentStopLoss = _stopLoss.Get(OrderField.StopPrice);
        		var newStopLoss = Securities[symbol].Price*_stopLossFactor;
        		if (newStopLoss > currentStopLoss)
        		{
        			_stopLoss.Update(new UpdateOrderFields {
        				StopPrice = newStopLoss	
        			});
        		}
				Plot(symbol, "Stop", _stopLoss.Get(OrderField.StopPrice));
        	}*/
        }
    }
}