Overall Statistics
Total Trades
300
Average Win
3.05%
Average Loss
-1.95%
Compounding Annual Return
82.573%
Drawdown
28.600%
Expectancy
0.877
Net Profit
1930.779%
Sharpe Ratio
2.116
Probabilistic Sharpe Ratio
96.464%
Loss Rate
27%
Win Rate
73%
Profit-Loss Ratio
1.56
Alpha
0.451
Beta
0.91
Annual Standard Deviation
0.27
Annual Variance
0.073
Information Ratio
1.909
Tracking Error
0.23
Treynor Ratio
0.628
Total Fees
$833.46
Estimated Strategy Capacity
$42000000.00
Lowest Capacity Asset
TQQQ UK280CGTCB51
/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;

namespace QuantConnect.Algorithm.CSharp
{
    
    public class QScalper : QCAlgorithm
    {
        private string _symbol = "TQQQ";
        
        private decimal _initialBalance = 10000;
        private decimal _profitFactor;
        private decimal _cciLong;
        private decimal _maxAllocationLong;
        private decimal _crashFactor;

        private int _cciLen;
        private int _smaLen;
        
        private int _timeframeHours = 1;
        
        private decimal _previousCCI;
        
        private SimpleMovingAverage _sma;
        private CommodityChannelIndex _cci;

        
        public override void Initialize()
        {
        	_profitFactor = Convert.ToDecimal(GetParameter("profit-factor")); //1.1
        	_cciLong = Convert.ToDecimal(GetParameter("cci-long-entry")); //80
        	_cciLen = Convert.ToInt32(GetParameter("cci-length")); // 50 
        	_smaLen = Convert.ToInt32(GetParameter("sma-length")); // 50
        	_maxAllocationLong = Convert.ToDecimal(GetParameter("max-allocation-long")); // 0.8
        	_crashFactor = Convert.ToDecimal(GetParameter("crash-factor")); // 0.1
        	
        	var parameters = GetParameters();
        	foreach (var kvp in parameters)
        	{
        		Log(kvp.Key + " = " + parameters[kvp.Key]);
        	}
        	
        	
            SetStartDate(DateTime.Now.AddYears(-5));
            SetEndDate(DateTime.Now.Date); 
            SetCash(_initialBalance);
            SetBenchmark(QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA));
            
            SetBrokerageModel(BrokerageName.AlphaStreams);
            
            AddSecurity(SecurityType.Equity, _symbol, Resolution.Hour);
            
			_cci = new CommodityChannelIndex(_cciLen);
            
            _sma = SMA(_symbol, _smaLen, Resolution.Daily);
            
			var hourConsolidator = ResolveConsolidator(_symbol, TimeSpan.FromHours(_timeframeHours));
            RegisterIndicator(_symbol, _sma, hourConsolidator);
            RegisterIndicator(_symbol, _cci, hourConsolidator);            

        }
        
        public void OnData(TradeBars data)
        {
            if (!_sma.IsReady) return;
            
            if (IsCrash(data[_symbol]))
            {
            	EmitInsights(Insight.Price(
            		_symbol, 
            		TimeSpan.FromHours(_timeframeHours), 
            		InsightDirection.Down));
            		
                var allocation = 0;
            	
            	
				var targets = new List<PortfolioTarget>() {
    				new PortfolioTarget(_symbol, allocation),
				};
				SetHoldings(targets);
            }
            
            else if (IsTargetMet(data[_symbol]))
            {
            	EmitInsights(Insight.Price(
            		_symbol, 
            		TimeSpan.FromHours(_timeframeHours), 
            		InsightDirection.Down));
            		
                var allocation = 0;
            	
            	
				var targets = new List<PortfolioTarget>() {
    				new PortfolioTarget(_symbol, allocation),
				};
				SetHoldings(targets);
            }

            else if (IsEntry(data[_symbol]))
            {
            	EmitInsights(Insight.Price(
            		_symbol, 
            		TimeSpan.FromHours(_timeframeHours), 
            		InsightDirection.Up));
            	
            	//var allocation = _maxAllocationLong;
            	
            	
				var targets = new List<PortfolioTarget>() {
    				new PortfolioTarget(_symbol, _maxAllocationLong)
				};
				SetHoldings(targets);

            }
            

            Plot(_symbol, "Price", data[_symbol].Price);
            Plot(_symbol, "SMA", _sma);
            
            
            
            _previousCCI = _cci.Current.Value;
        }
        
        public override void OnOrderEvent(OrderEvent fill)
        {
        	/*
        	if (fill.Status.IsFill())
        	{
        		_psma.Update(Time, Portfolio.TotalPortfolioValue);
        	}
        	*/
        }
        
	    protected bool IsEntry(TradeBar bar) 
	    {
	    	var cci = _cci.Current.Value;
	    	return (bar.Close > _sma && _previousCCI < _cciLong && _cci >= _cciLong);
	    }
	    
	    protected bool IsTargetMet(TradeBar bar)
	    {
            if (Portfolio[_symbol].Quantity <= 0) 
            	return false;
			     
            return (bar.Close > (Portfolio[_symbol].AveragePrice * _profitFactor));
	    }
	    
	    protected bool IsCrash(TradeBar bar)
	    {
            if (Portfolio[_symbol].Quantity <= 0) 
            	return false;
			     
            return ((_sma.Current.Value - bar.Close) > (_crashFactor * _sma.Current.Value));
	    }

    }
}