Overall Statistics
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;

namespace QuantConnect 
{
    public partial class QCUMartingalePositionSizing : QCAlgorithm 
    {
    	[Parameter]
		public decimal iStopPips = 5m;
    	
    	[Parameter]
		public decimal iVolume = 1m;
    	
    	[Parameter]
		public decimal iCommission = 1m;
    	
		[Parameter]
		public string iSymbol = "PEP";

		decimal iVolumeStep = 0;
		decimal iBalanceStep = 0;
		decimal iBalance = 10000m;
		string iChartName = "Deals";
		int iDirection = 0;

		public class iDeal
		{
			public int SL;
			public int TP;	
			public int Market;	
		};

        Dictionary<int, iDeal> iDeals = new Dictionary<int, iDeal>();

        public override void Initialize()
        {
        	var resolution = Resolution.Minute;

        	SetCash(iBalance);
            //SetStartDate(2008, 1, 1);
            //SetEndDate(2009, 12, 1);
            SetStartDate(2017, 1, 1);
            SetEndDate(DateTime.Now.Date); 
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
            AddSecurity(SecurityType.Equity, iSymbol, resolution, true, 4m, false);

            var chart = new Chart(iChartName);
			var seriesStock = new Series("Stock", SeriesType.Line, 0) { Color = Color.Gray };
			var seriesBuy = new Series("Buy", SeriesType.Scatter, 0) { Color = Color.Blue, ScatterMarkerSymbol = ScatterMarkerSymbol.Triangle };
			var seriesSell = new Series("Sell", SeriesType.Scatter, 0) { Color = Color.Red, ScatterMarkerSymbol = ScatterMarkerSymbol.TriangleDown };
			var seriesBalance = new Series("Balance", SeriesType.Line, 1) { Color = Color.Yellow };

			chart.AddSeries(seriesStock);
			chart.AddSeries(seriesBuy);
			chart.AddSeries(seriesSell);
			chart.AddSeries(seriesBalance);

			iDirection = 1;
			iVolumeStep = iVolume;
			iBalanceStep = GetBalance();

            AddChart(chart);
        }
        
        public void OnData(TradeBars data) 
        {
        	if (IsMarketOpen(iSymbol) == false)
        	{
        		return;
        	}

        	Plot(iChartName, "Stock", data[iSymbol].Price);
        	Plot(iChartName, "Balance", iBalance);

			var direction = CanOpen();

			if (direction > 0) 
            {
            	Plot(iChartName, "Buy", Securities[iSymbol].Price);
            	Action(iSymbol, iVolumeStep, 1);
                return;
            }

            if (direction < 0) 
            {
            	Plot(iChartName, "Sell", Securities[iSymbol].Price);
            	Action(iSymbol, iVolumeStep, -1);
                return;
            }
            
            CanClose();
        }
        
		protected OrderTicket Action(string symbol, decimal volume, int direction)
		{
			var ticket = MarketOrder(symbol, volume * direction, false, "MK");

			iDeals[ticket.OrderId] = new iDeal { Market = ticket.OrderId };

			var process = new Thread(() => {

				Transactions.WaitForOrder(ticket.OrderId);

				if (Transactions.GetOrderById(ticket.OrderId).Status != OrderStatus.Filled) 
				{
					return;
				}

				var price = Securities[symbol].Price;
	        	var orderSL = StopMarketOrder(symbol, -volume * direction, price - iStopPips * direction, "SL #" + ticket.OrderId.ToString());
	        	//var orderTP = LimitOrder(symbol, -volume * direction, price + iStopPips * 3 * direction, "TP #" + ticket.OrderId.ToString());	

				iDeals[ticket.OrderId].SL = orderSL.OrderId;
				//iDeals[ticket.OrderId].TP = orderTP.OrderId;
			});

			process.Start();

			return ticket;
		}

        protected int CanOpen()
        {
            if (Portfolio.Invested == false)
            {
            	var balance = GetBalance();
            	
            	if (balance < iBalanceStep)
            	{
            		iVolumeStep = iVolumeStep * 2;
            		iDirection = iDirection * -1;
            	}
            	else
            	{
            		Plot(iChartName, "Balance", balance);
            		iBalanceStep = balance;
            		iVolumeStep = iVolume;
            	}

                return iDirection;
            }

            return 0;
        }
        
        protected int CanClose()
        {
        	var balance = GetBalance() - iCommission * 2;
        	
            if (Portfolio.Invested && balance > iBalanceStep)
            {
            	Liquidate();
                return 1;
            }

            return 0;
        }
        
        protected decimal GetBalance()
        {
        	return iBalance + 
        		Portfolio.TotalUnrealizedProfit + 
        		Portfolio.TotalProfit - 
        		Portfolio.TotalFees;
        }
    }
}