Overall Statistics
Total Trades
32
Average Win
0%
Average Loss
-0.04%
Compounding Annual Return
-9.349%
Drawdown
0.600%
Expectancy
-1
Net Profit
-0.640%
Sharpe Ratio
-29.98
Loss Rate
100%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.09
Beta
0
Annual Standard Deviation
0.003
Annual Variance
0
Information Ratio
-0.057
Tracking Error
0.187
Treynor Ratio
-210.546
Total Fees
$32.00
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Orders;

	public class OrderEvents 
	{
		public static decimal FillPrice;
	}
	
namespace QuantConnect.Algorithm.CSharp
{
    public class CoarseFundamentalTop5Algorithm : QCAlgorithm
    {
        // initialize our security changes to nothing
        DateTime lastTradeTime;
        SecurityChanges _changes = SecurityChanges.None;
        static readonly decimal EqualWeightPercentage = 1m/3;


        public override void Initialize()
        {
        	
        	SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Cash);
        	// this sets the resolution for securities added via universe selection
            UniverseSettings.Resolution = Resolution.Second;

            SetStartDate(2016, 2, 1);
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            SetCash(5000);
            
            foreach (var symbol in _changes.AddedSecurities)
            {
            	var myString = symbol.ToString();
                AddSecurity(SecurityType.Equity, myString, Resolution.Minute, 
                    fillDataForward: true, 
                    extendedMarketHours: false, 
                    leverage: 1
                    );
            }

            // this add universe method accepts a single parameter that is a function that
            // accepts an IEnumerable<CoarseFundamental> and returns IEnumerable<Symbol>
            AddUniverse(CoarseSelectionFunction);
        }

        // sort the data by daily dollar volume and take the top 5 symbols
        public static IEnumerable<Symbol> CoarseSelectionFunction(IEnumerable<CoarseFundamental> coarse)
        {
         return (from stock in coarse
            		orderby stock.Price
            		//function that sorts by percent change
            		//where stock.Price > stock.Price - stock.Value / stock.Price ??
            		
            		where stock.Price < 5 && stock.Price > 2
            		select stock.Symbol).Take(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)
        {
        	
        	var closedTrades = TradeBuilder.ClosedTrades;
        	
        	if (Time - lastTradeTime.Date < TimeSpan.FromDays(1))
            {
                // only trade once a day at market open
                return;
            }
            lastTradeTime = Time;
        	
            // if we have no changes, do nothing
            if (_changes == SecurityChanges.None) return;

            // liquidate removed securities
            foreach (var security in _changes.RemovedSecurities)
            {
            Log("Removed " + security);
                /*if (security.Invested)
                {
                    Liquidate(security.Symbol);
                }*/
            }
            
            foreach (var security in _changes.AddedSecurities)
            {
            	
            	//var symbolToday = Convert.ToString(_changes.AddedSecurities);
        		//Log("" + symbolToday);
        		var equalWeightedPorfolioSize = Portfolio.TotalPortfolioValue/3;
            	var shareCount = CalculateOrderQuantity(security.Symbol, EqualWeightPercentage);
                //SetHoldings(security.Symbol, 0.25m);
				if (Portfolio.Cash > 0)
				{
                MarketOrder(security.Symbol, shareCount, tag: "Order Target Value: $" + Math.Round(equalWeightedPorfolioSize, 2));
				}
				
                
			    var test = Portfolio.TotalProfit;
			    var threePercent = test * .3m;
			    
                if (test < 30 && Portfolio.HoldStock)
                {
                 Liquidate(security.Symbol);
                 Log("Total Profit " + test);
                }
				if (Portfolio.HoldStock)
				{
                MarketOnCloseOrder(security.Symbol, -shareCount);
                
				}
            }
            var myfill = OrderEvents.FillPrice;
                Log("Fill Price " + myfill);
                        	
            // 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;

            _changes = SecurityChanges.None;
        }

        // this event fires whenever we have changes to our universe
        public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            _changes = changes;
        }
        
        /*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);
            }
        }*/
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Orders;
using QuantConnect.Util;

namespace QuantConnect.Statistics
{
    /// <summary>
    /// The <see cref="TradeBuilder"/> class generates trades from executions and market price updates
    /// </summary>
    public class TradeBuilder
    {
        /// <summary>
        /// Helper class to manage pending trades and market price updates for a symbol
        /// </summary>
        private class Position 
        {
            internal List<Trade> PendingTrades { get; set; }
            internal List<OrderEvent> PendingFills { get; set; }
            internal decimal TotalFees { get; set; }
            internal decimal MaxPrice { get; set; }
            internal decimal MinPrice { get; set; }

            public Position()
            {
                PendingTrades = new List<Trade>();
                PendingFills = new List<OrderEvent>();
            }
        }

        private const int LiveModeMaxTradeCount = 10000;
        private const int LiveModeMaxTradeAgeMonths = 12;
        private const int MaxOrderIdCacheSize = 1000;

        private readonly List<Trade> _closedTrades = new List<Trade>();
        private readonly Dictionary<Symbol, Position> _positions = new Dictionary<Symbol, Position>();
        private readonly FixedSizeHashQueue<int> _ordersWithFeesAssigned = new FixedSizeHashQueue<int>(MaxOrderIdCacheSize);
        private readonly FillGroupingMethod _groupingMethod;
        private readonly FillMatchingMethod _matchingMethod;
        private bool _liveMode;

        /// <summary>
        /// Initializes a new instance of the <see cref="TradeBuilder"/> class
        /// </summary>
        public TradeBuilder(FillGroupingMethod groupingMethod, FillMatchingMethod matchingMethod)
        {
            _groupingMethod = groupingMethod;
            _matchingMethod = matchingMethod;
        }

        /// <summary>
        /// Sets the live mode flag
        /// </summary>
        /// <param name="live">The live mode flag</param>
        public void SetLiveMode(bool live)
        {
            _liveMode = live;
        }

        /// <summary>
        /// The list of closed trades
        /// </summary>
        public List<Trade> ClosedTrades
        {
            get { return _closedTrades; }
        }

        /// <summary>
        /// Returns true if there is an open position for the symbol
        /// </summary>
        /// <param name="symbol">The symbol</param>
        /// <returns>true if there is an open position for the symbol</returns>
        public bool HasOpenPosition(Symbol symbol)
        {
            Position position;
            if (!_positions.TryGetValue(symbol, out position)) return false;

            if (_groupingMethod == FillGroupingMethod.FillToFill)
                return position.PendingTrades.Count > 0;

            return position.PendingFills.Count > 0;
        }

        /// <summary>
        /// Sets the current market price for the symbol
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="price"></param>
        public void SetMarketPrice(Symbol symbol, decimal price)
        {
            Position position;
            if (!_positions.TryGetValue(symbol, out position)) return;

            if (price > position.MaxPrice)
                position.MaxPrice = price;
            else if (price < position.MinPrice)
                position.MinPrice = price;
        }

        /// <summary>
        /// Processes a new fill, eventually creating new trades
        /// </summary>
        /// <param name="fill">The new fill order event</param>
        /// <param name="conversionRate">The current market conversion rate into the account currency</param>
        public void ProcessFill(OrderEvent fill, decimal conversionRate)
        {
            // If we have multiple fills per order, we assign the order fee only to its first fill
            // to avoid counting the same order fee multiple times.
            var orderFee = 0m;
            if (!_ordersWithFeesAssigned.Contains(fill.OrderId))
            {
                orderFee = fill.OrderFee;
                _ordersWithFeesAssigned.Add(fill.OrderId);
            }

            switch (_groupingMethod)
            {
                case FillGroupingMethod.FillToFill:
                    ProcessFillUsingFillToFill(fill.Clone(), orderFee, conversionRate);
                    break;

                case FillGroupingMethod.FlatToFlat:
                    ProcessFillUsingFlatToFlat(fill.Clone(), orderFee, conversionRate);
                    break;

                case FillGroupingMethod.FlatToReduced:
                    ProcessFillUsingFlatToReduced(fill.Clone(), orderFee, conversionRate);
                    break;
            }
        }

        private void ProcessFillUsingFillToFill(OrderEvent fill, decimal orderFee, decimal conversionRate)
        {
            Position position;
            if (!_positions.TryGetValue(fill.Symbol, out position) || position.PendingTrades.Count == 0)
            {
                // no pending trades for symbol
                _positions[fill.Symbol] = new Position
                {
                    PendingTrades = new List<Trade>
                    {
                        new Trade
                        {
                            Symbol = fill.Symbol,
                            EntryTime = fill.UtcTime,
                            EntryPrice = fill.FillPrice,
                            Direction = fill.FillQuantity > 0 ? TradeDirection.Long : TradeDirection.Short,
                            Quantity = fill.AbsoluteFillQuantity,
                            TotalFees = orderFee
                        }
                    },
                    MinPrice = fill.FillPrice,
                    MaxPrice = fill.FillPrice
                };
                return;
            }

            SetMarketPrice(fill.Symbol, fill.FillPrice);

            var index = _matchingMethod == FillMatchingMethod.FIFO ? 0 : position.PendingTrades.Count - 1;

            if (Math.Sign(fill.FillQuantity) == (position.PendingTrades[index].Direction == TradeDirection.Long ? +1 : -1))
            {
                // execution has same direction of trade
                position.PendingTrades.Add(new Trade
                {
                    Symbol = fill.Symbol,
                    EntryTime = fill.UtcTime,
                    EntryPrice = fill.FillPrice,
                    Direction = fill.FillQuantity > 0 ? TradeDirection.Long : TradeDirection.Short,
                    Quantity = fill.AbsoluteFillQuantity,
                    TotalFees = orderFee
                });
            }
            else
            {
                // execution has opposite direction of trade
                var totalExecutedQuantity = 0;
                var orderFeeAssigned = false;
                while (position.PendingTrades.Count > 0 && Math.Abs(totalExecutedQuantity) < fill.AbsoluteFillQuantity)
                {
                    var trade = position.PendingTrades[index];

                    if (fill.AbsoluteFillQuantity >= trade.Quantity)
                    {
                        totalExecutedQuantity -= trade.Quantity * (trade.Direction == TradeDirection.Long ? +1 : -1);
                        position.PendingTrades.RemoveAt(index);

                        if (index > 0 && _matchingMethod == FillMatchingMethod.LIFO) index--;

                        trade.ExitTime = fill.UtcTime;
                        trade.ExitPrice = fill.FillPrice;
                        trade.ProfitLoss = Math.Round((trade.ExitPrice - trade.EntryPrice) * trade.Quantity * (trade.Direction == TradeDirection.Long ? +1 : -1) * conversionRate, 2);
                        // if closing multiple trades with the same order, assign order fee only once
                        trade.TotalFees += orderFeeAssigned ? 0 : orderFee;
                        trade.MAE = Math.Round((trade.Direction == TradeDirection.Long ? position.MinPrice - trade.EntryPrice : trade.EntryPrice - position.MaxPrice) * trade.Quantity * conversionRate, 2);
                        trade.MFE = Math.Round((trade.Direction == TradeDirection.Long ? position.MaxPrice - trade.EntryPrice : trade.EntryPrice - position.MinPrice) * trade.Quantity * conversionRate, 2);
                        
                        AddNewTrade(trade);
                    }
                    else
                    {
                        totalExecutedQuantity += fill.FillQuantity;
                        trade.Quantity -= fill.AbsoluteFillQuantity;

                        AddNewTrade(new Trade
                        {
                            Symbol = trade.Symbol,
                            EntryTime = trade.EntryTime,
                            EntryPrice = trade.EntryPrice,
                            Direction = trade.Direction,
                            Quantity = fill.AbsoluteFillQuantity,
                            ExitTime = fill.UtcTime,
                            ExitPrice = fill.FillPrice,
                            ProfitLoss = Math.Round((fill.FillPrice - trade.EntryPrice) * fill.AbsoluteFillQuantity * (trade.Direction == TradeDirection.Long ? +1 : -1) * conversionRate, 2),
                            TotalFees = trade.TotalFees + (orderFeeAssigned ? 0 : orderFee),
                            MAE = Math.Round((trade.Direction == TradeDirection.Long ? position.MinPrice - trade.EntryPrice : trade.EntryPrice - position.MaxPrice) * fill.AbsoluteFillQuantity * conversionRate, 2),
                            MFE = Math.Round((trade.Direction == TradeDirection.Long ? position.MaxPrice - trade.EntryPrice : trade.EntryPrice - position.MinPrice) * fill.AbsoluteFillQuantity * conversionRate, 2)
                        });

                        trade.TotalFees = 0;
                    }

                    orderFeeAssigned = true;
                }

                if (Math.Abs(totalExecutedQuantity) == fill.AbsoluteFillQuantity && position.PendingTrades.Count == 0)
                {
                    _positions.Remove(fill.Symbol);
                }
                else if (Math.Abs(totalExecutedQuantity) < fill.AbsoluteFillQuantity)
                {
                    // direction reversal
                    fill.FillQuantity -= totalExecutedQuantity;
                    position.PendingTrades = new List<Trade>
                    {
                        new Trade
                        {
                            Symbol = fill.Symbol,
                            EntryTime = fill.UtcTime,
                            EntryPrice = fill.FillPrice,
                            Direction = fill.FillQuantity > 0 ? TradeDirection.Long : TradeDirection.Short,
                            Quantity = fill.AbsoluteFillQuantity,
                            TotalFees = 0
                        }
                    };
                    position.MinPrice = fill.FillPrice;
                    position.MaxPrice = fill.FillPrice;
                }
            }
        }

        private void ProcessFillUsingFlatToFlat(OrderEvent fill, decimal orderFee, decimal conversionRate)
        {
            Position position;
            if (!_positions.TryGetValue(fill.Symbol, out position) || position.PendingFills.Count == 0)
            {
                // no pending executions for symbol
                _positions[fill.Symbol] = new Position
                {
                    PendingFills = new List<OrderEvent> { fill },
                    TotalFees = orderFee,
                    MinPrice = fill.FillPrice,
                    MaxPrice = fill.FillPrice
                };
                return;
            }

            SetMarketPrice(fill.Symbol, fill.FillPrice);

            if (Math.Sign(position.PendingFills[0].FillQuantity) == Math.Sign(fill.FillQuantity))
            {
                // execution has same direction of trade
                position.PendingFills.Add(fill);
                position.TotalFees += orderFee;
            }
            else
            {
                // execution has opposite direction of trade
                if (position.PendingFills.Sum(x => x.FillQuantity) + fill.FillQuantity == 0 || fill.AbsoluteFillQuantity > Math.Abs(position.PendingFills.Sum(x => x.FillQuantity)))
                {
                    // trade closed
                    position.PendingFills.Add(fill);
                    position.TotalFees += orderFee;

                    var reverseQuantity = position.PendingFills.Sum(x => x.FillQuantity);

                    var index = _matchingMethod == FillMatchingMethod.FIFO ? 0 : position.PendingFills.Count - 1;

                    var entryTime = position.PendingFills[0].UtcTime;
                    var totalEntryQuantity = 0;
                    var totalExitQuantity = 0;
                    var entryAveragePrice = 0m;
                    var exitAveragePrice = 0m;

                    while (position.PendingFills.Count > 0)
                    {
                        if (Math.Sign(position.PendingFills[index].FillQuantity) != Math.Sign(fill.FillQuantity))
                        {
                            // entry
                            totalEntryQuantity += position.PendingFills[index].FillQuantity;
                            entryAveragePrice += (position.PendingFills[index].FillPrice - entryAveragePrice) * position.PendingFills[index].FillQuantity / totalEntryQuantity;
                        }
                        else
                        {
                            // exit
                            totalExitQuantity += position.PendingFills[index].FillQuantity;
                            exitAveragePrice += (position.PendingFills[index].FillPrice - exitAveragePrice) * position.PendingFills[index].FillQuantity / totalExitQuantity;
                        }
                        position.PendingFills.RemoveAt(index);

                        if (_matchingMethod == FillMatchingMethod.LIFO && index > 0) index--;
                    }

                    var direction = Math.Sign(fill.FillQuantity) < 0 ? TradeDirection.Long : TradeDirection.Short;

                    AddNewTrade(new Trade
                    {
                        Symbol = fill.Symbol,
                        EntryTime = entryTime,
                        EntryPrice = entryAveragePrice,
                        Direction = direction,
                        Quantity = Math.Abs(totalEntryQuantity),
                        ExitTime = fill.UtcTime,
                        ExitPrice = exitAveragePrice,
                        ProfitLoss = Math.Round((exitAveragePrice - entryAveragePrice) * Math.Abs(totalEntryQuantity) * Math.Sign(totalEntryQuantity) * conversionRate, 2),
                        TotalFees = position.TotalFees,
                        MAE = Math.Round((direction == TradeDirection.Long ? position.MinPrice - entryAveragePrice : entryAveragePrice - position.MaxPrice) * Math.Abs(totalEntryQuantity) * conversionRate, 2),
                        MFE = Math.Round((direction == TradeDirection.Long ? position.MaxPrice - entryAveragePrice : entryAveragePrice - position.MinPrice) * Math.Abs(totalEntryQuantity) * conversionRate, 2)
                    });

                    _positions.Remove(fill.Symbol);

                    if (reverseQuantity != 0)
                    {
                        // direction reversal
                        fill.FillQuantity = reverseQuantity;
                        _positions[fill.Symbol] = new Position
                        {
                            PendingFills = new List<OrderEvent> { fill },
                            TotalFees = 0,
                            MinPrice = fill.FillPrice,
                            MaxPrice = fill.FillPrice
                        };
                    }
                }
                else
                {
                    // trade open
                    position.PendingFills.Add(fill);
                    position.TotalFees += orderFee;
                }
            }
        }

        private void ProcessFillUsingFlatToReduced(OrderEvent fill, decimal orderFee, decimal conversionRate)
        {
            Position position;
            if (!_positions.TryGetValue(fill.Symbol, out position) || position.PendingFills.Count == 0)
            {
                // no pending executions for symbol
                _positions[fill.Symbol] = new Position
                {
                    PendingFills = new List<OrderEvent> { fill },
                    TotalFees = orderFee,
                    MinPrice = fill.FillPrice,
                    MaxPrice = fill.FillPrice
                };
                return;
            }

            SetMarketPrice(fill.Symbol, fill.FillPrice);

            var index = _matchingMethod == FillMatchingMethod.FIFO ? 0 : position.PendingFills.Count - 1;

            if (Math.Sign(fill.FillQuantity) == Math.Sign(position.PendingFills[index].FillQuantity))
            {
                // execution has same direction of trade
                position.PendingFills.Add(fill);
                position.TotalFees += orderFee;
            }
            else
            {
                // execution has opposite direction of trade
                var entryTime = position.PendingFills[index].UtcTime;
                var totalExecutedQuantity = 0;
                var entryPrice = 0m;
                position.TotalFees += orderFee;

                while (position.PendingFills.Count > 0 && Math.Abs(totalExecutedQuantity) < fill.AbsoluteFillQuantity)
                {
                    if (fill.AbsoluteFillQuantity >= Math.Abs(position.PendingFills[index].FillQuantity))
                    {
                        if (_matchingMethod == FillMatchingMethod.LIFO)
                            entryTime = position.PendingFills[index].UtcTime;

                        totalExecutedQuantity -= position.PendingFills[index].FillQuantity;
                        entryPrice -= (position.PendingFills[index].FillPrice - entryPrice) * position.PendingFills[index].FillQuantity / totalExecutedQuantity;
                        position.PendingFills.RemoveAt(index);

                        if (_matchingMethod == FillMatchingMethod.LIFO && index > 0) index--;
                    }
                    else
                    {
                        totalExecutedQuantity += fill.FillQuantity;
                        entryPrice += (position.PendingFills[index].FillPrice - entryPrice) * fill.FillQuantity / totalExecutedQuantity;
                        position.PendingFills[index].FillQuantity += fill.FillQuantity;
                    }
                }

                var direction = totalExecutedQuantity < 0 ? TradeDirection.Long : TradeDirection.Short;

                AddNewTrade(new Trade
                {
                    Symbol = fill.Symbol,
                    EntryTime = entryTime,
                    EntryPrice = entryPrice,
                    Direction = direction,
                    Quantity = Math.Abs(totalExecutedQuantity),
                    ExitTime = fill.UtcTime,
                    ExitPrice = fill.FillPrice,
                    ProfitLoss = Math.Round((fill.FillPrice - entryPrice) * Math.Abs(totalExecutedQuantity) * Math.Sign(-totalExecutedQuantity) * conversionRate, 2),
                    TotalFees = position.TotalFees,
                    MAE = Math.Round((direction == TradeDirection.Long ? position.MinPrice - entryPrice : entryPrice - position.MaxPrice) * Math.Abs(totalExecutedQuantity) * conversionRate, 2),
                    MFE = Math.Round((direction == TradeDirection.Long ? position.MaxPrice - entryPrice : entryPrice - position.MinPrice) * Math.Abs(totalExecutedQuantity) * conversionRate, 2)
                });

                if (Math.Abs(totalExecutedQuantity) < fill.AbsoluteFillQuantity)
                {
                    // direction reversal
                    fill.FillQuantity -= totalExecutedQuantity;
                    position.PendingFills = new List<OrderEvent> { fill };
                    position.TotalFees = 0;
                    position.MinPrice = fill.FillPrice;
                    position.MaxPrice = fill.FillPrice;
                }
                else if (Math.Abs(totalExecutedQuantity) == fill.AbsoluteFillQuantity)
                {
                    if (position.PendingFills.Count == 0)
                        _positions.Remove(fill.Symbol);
                    else
                        position.TotalFees = 0;
                }
            }
        }

        /// <summary>
        /// Adds a trade to the list of closed trades, capping the total number only in live mode
        /// </summary>
        private void AddNewTrade(Trade trade)
        {
            _closedTrades.Add(trade);

            // Due to memory constraints in live mode, we cap the number of trades
            if (!_liveMode) 
                return;

            // maximum number of trades
            if (_closedTrades.Count > LiveModeMaxTradeCount)
            {
                _closedTrades.RemoveRange(0, _closedTrades.Count - LiveModeMaxTradeCount);
            }

            // maximum age of trades
            while (_closedTrades.Count > 0 && _closedTrades[0].ExitTime.Date.AddMonths(LiveModeMaxTradeAgeMonths) < DateTime.Today)
            {
                _closedTrades.RemoveAt(0);
            }
        }

    }
}