Overall Statistics
using System.Collections.Concurrent;


public class ConsolidatorDemoAlgorithm : QCAlgorithm
{
    private const string Symbol = "AMD";
    private SimpleMovingAverage sma50;
    
    // we need a concurrent data structure since we're using it in both OnData and OnOrderEvent which run on separate t
    public readonly ConcurrentBag<OneCancelsAll> orderGroups = new ConcurrentBag<OneCancelsAll>();


	public override void Initialize()
	{
	    SetStartDate(2018, 1, 1);         
        SetEndDate(2019, 1, 18);

		SetCash(10000);

		//AddEquity(Symbol, Resolution.Minute);
		AddEquity(Symbol, Resolution.Minute, Market.USA, true, 1, true);
		AddEquity("SPY", Resolution.Minute);
		
       // Securities[Symbol].SetDataNormalizationMode(DataNormalizationMode.SplitAdjusted);
        
		var minConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5));
		minConsolidator.DataConsolidated += OnDataConsolidated;
		SubscriptionManager.AddConsolidator(Symbol, minConsolidator);

		sma50 = new SimpleMovingAverage(Symbol, 50);
        RegisterIndicator(Symbol, sma50, minConsolidator);
	}

	public void OnDataConsolidated(object sender, TradeBar bar) {
	}

     //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 (data[Symbol].Close > sma50 && !Portfolio[Symbol].Invested)
        {
            // open an initial position
          
            MarketOrder(Symbol, 100);

            var oca = new OneCancelsAll();
            // set profit taking order
            var limitPrice = data[Symbol].Close * 1.05m;
            var profitTakingTicket = LimitOrder(Symbol, -100, limitPrice, tag: "TakeProfit: " + limitPrice);
            // set stop loss order
            var stopPrice = data[Symbol].Close * .99m;
            var stopLossTicket = StopMarketOrder(Symbol, -100, stopPrice, tag: "StopLoss: " + stopPrice);

            // add tickets to our oca group
            oca.Tickets.Add(profitTakingTicket);
            oca.Tickets.Add(stopLossTicket);
            orderGroups.Add(oca);
        }
        
    }

    public override void OnOrderEvent(OrderEvent fill)
    {
        Console.WriteLine(Time + ": " + Transactions.GetOrderById(fill.OrderId).Type + ": " + fill);
        if (fill.Status.IsClosed())
        {
            // find the oca grouping from this fill
            foreach (var oca in orderGroups)
            {
                // check if this oca matches the fill we received
                if (oca.Tickets.Any(x => x.OrderId == fill.OrderId))
                {
                    // cancel all orders that aren't this order id
                    foreach (var ticket in oca.Tickets)
                    {
                        // cancel each other ticket in our OCA group
                        if (ticket.OrderId != fill.OrderId && ticket.Status.IsOpen())
                        {
                            ticket.Cancel();
                            Log("Cancelled OCA: " + ticket.OrderId + " tag: " + ticket.Tag);
                        }
                    }
                }
            }
        }
    }
	
	  // class to hold ticks in an OCA group
    public class OneCancelsAll
    {
        public List<OrderTicket> Tickets = new List<OrderTicket>();
    }
	
}