Overall Statistics
Total Trades
347
Average Win
10.05%
Average Loss
0%
Compounding Annual Return
986.049%
Drawdown
7.400%
Expectancy
0
Net Profit
45.805%
Sharpe Ratio
10.019
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
0.316
Beta
0.616
Annual Standard Deviation
0.229
Annual Variance
0.053
Information Ratio
-5.06
Tracking Error
0.181
Treynor Ratio
3.729
Total Fees
$359.40
using System.Threading;
using System.Threading.Tasks;

namespace QuantConnect 
{ 
    public partial class QCUMartingalePositionSizing : QCAlgorithm 
    {
    	[Parameter]
    	public int iPeriod = 15;

		[Parameter]
		public decimal iIncomePercents = 0.1m;
		
		[Parameter]
		public decimal iStopPips = 5m;
		
		[Parameter]
		public decimal iVolume = 10m;
		
		[Parameter]
		public decimal iBalance = 10000m;
		
		[Parameter]
		public string iSymbol = "SQ";

		decimal iRsiStep = 0;
		
        RelativeStrengthIndex iRsi = null;

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

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

        public override void Initialize()
        {
        	SetCash(iBalance);
        	SetBenchmark(iSymbol);
            SetStartDate(2017, 10, 1);
            SetEndDate(DateTime.Now.Date); 
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
            AddSecurity(SecurityType.Equity, iSymbol, Resolution.Minute, true, 4m, false);

            iRsi = RSI(iSymbol, iPeriod, MovingAverageType.Simple, Resolution.Minute);

            var chart = new Chart("Custom Chart");
			var seriesStock = new Series("Stock", SeriesType.Line, 0);
			var seriesBuy = new Series("Buy", SeriesType.Scatter, 0);
			var seriesSell = new Series("Sell", SeriesType.Scatter, 0);
			var seriesBalance = new Series("Balance", SeriesType.Line, 1);
			var seriesIndicator = new Series("RSI", SeriesType.Line, 2);

			chart.AddSeries(seriesStock);
			chart.AddSeries(seriesBuy);
			chart.AddSeries(seriesSell);
			chart.AddSeries(seriesBalance);
			chart.AddSeries(seriesIndicator);            
            AddChart(chart);
        }
        
        public void OnData(TradeBars data) 
        {
        	if (iRsi.IsReady == false || IsMarketOpen(iSymbol) == false)
        	{
        		return;
        	}
        	
        	Plot("Custom Chart", "Stock", data[iSymbol].Price);
        	Plot("Custom Chart", "Balance", iBalance);
        	Plot("Custom Chart", "RSI", iRsi);
        	
            if (CanOpen() == 1) 
            {
            	Action(iSymbol, iVolume, 1);
            	Plot("Custom Chart", "Buy", data[iSymbol].Price);
                return;
            }
            
            if (CanClose() == 1) 
            {
                Liquidate();
                Plot("Custom Chart", "Sell", data[iSymbol].Price);
                return;
            }
        }
        
		protected OrderTicket Action(string symbol, decimal volume, int direction)
		{
			var ticket = MarketOrder(symbol, volume * direction, false);

			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 + iIncomePips * 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 (iRsi.IsReady) 
            {
            	var previous = iRsiStep;
            	
            	iRsiStep = iRsi;
            	
                if (iRsi < 70 && previous > 70) 
                {
                	return -1;
                }
                
                if (iRsi > 30 && previous < 30)
                {
                	return 1;
                }
            }
            
            return 0;
        }
        
        protected int CanClose() 
        {
        	var profit = Portfolio[iSymbol].UnrealizedProfit;

			if (profit > iBalance * iIncomePercents) 
			{
				iBalance += profit;
				return 1;
			}

            return 0;
        }
    }
}