Overall Statistics
Total Trades
5628
Average Win
0.18%
Average Loss
-0.16%
Compounding Annual Return
-9.074%
Drawdown
26.000%
Expectancy
-0.054
Net Profit
-21.788%
Sharpe Ratio
-0.964
Loss Rate
55%
Win Rate
45%
Profit-Loss Ratio
1.12
Alpha
-0.075
Beta
-0.005
Annual Standard Deviation
0.078
Annual Variance
0.006
Information Ratio
-1.348
Tracking Error
0.139
Treynor Ratio
16.613
Total Fees
$5628.01
namespace QuantConnect
{
    public partial class BootCampTask : QCAlgorithm
    {
    	private struct _tradeInfo
        {
            public decimal stopLimit;
            public bool isShort;
            public TradeBar tradeBar;
        }
        
        private Dictionary<Symbol, TradeBar> MyStocks = new Dictionary<Symbol, TradeBar>();
        private string[] tickers = new string[] { "TSLA", "AMD", "BAC", "SYMC", "HP" };
    	
        public override void Initialize()
        {
            SetStartDate(2017, 1, 1);
            SetEndDate(2019, 8, 1);
            SetCash(10000);
            AddEquity("SPY", Resolution.Minute);
            
            foreach (var ticker in tickers)
            {
            	var equity = AddEquity(ticker, Resolution.Minute);
            	MyStocks.Add(equity.Symbol, null);
            	Consolidate(equity.Symbol, TimeSpan.FromMinutes(30), OnDataConsolidation);
            }
            
            Schedule.On(DateRules.EveryDay("SPY"), TimeRules.At(13,30), CloseAllPositions);
        }
        
        private void OnDataConsolidation(TradeBar bar)
        {
            if (bar.Time.Hour == 9 && bar.Time.Minute == 30)
            {
            	// Log($"{bar.Symbol.Value} Bar Updated");
            	MyStocks[bar.Symbol] = bar;
            }
        }
        
        private void CloseAllPositions()
        {
        	// kvp = key-value-pair
        	foreach (var kvp in Securities)
        	{
        		ClosePosition(kvp.Key);
        	}
        }
        
        private void ClosePosition(string symbol)
        {
        	if (MyStocks.ContainsKey(symbol))
        		MyStocks[symbol] = null;
        	Liquidate(symbol);
        }
        
        public override void OnData(Slice data)
        {
        	// kvp = key-value-pair
        	foreach (var kvp in MyStocks)
        	{
        		var bar = kvp.Value;
        		if (bar == null) continue;
        		
        		var symbol = bar.Symbol;
        		if (Portfolio[symbol].Invested) continue;
        		
        		if (data[symbol].Close > bar.High)
        			SetHoldings(symbol, 1m/MyStocks.Count);
        			
        		if (data[symbol].Close < bar.Low)
        			SetHoldings(symbol, -1m/MyStocks.Count);
        	}
        }
    }
}
/*
 * 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.Collections.Generic;
using QuantConnect.Algorithm.Framework.Portfolio;

namespace QuantConnect.Algorithm.Framework.Risk
{
    /// <summary>
    /// Provides an implementation of <see cref="IRiskManagementModel"/> that limits the drawdown
    /// per holding to the specified percentage
    /// </summary>
    public class MaximumDrawdownPercentPerSecurity : RiskManagementModel
    {
        private readonly decimal _maximumDrawdownPercent;

        /// <summary>
        /// Initializes a new instance of the <see cref="MaximumDrawdownPercentPerSecurity"/> class
        /// </summary>
        /// <param name="maximumDrawdownPercent">The maximum percentage drawdown allowed for any single security holding,
        /// defaults to 5% drawdown per security</param>
        public MaximumDrawdownPercentPerSecurity(
            decimal maximumDrawdownPercent = 0.04m
            )
        {
            _maximumDrawdownPercent = -Math.Abs(maximumDrawdownPercent);
        }

        /// <summary>
        /// Manages the algorithm's risk at each time step
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="targets">The current portfolio targets to be assessed for risk</param>
        public override IEnumerable<IPortfolioTarget> ManageRisk(QCAlgorithm algorithm, IPortfolioTarget[] targets)
        {
            foreach (var kvp in algorithm.Securities)
            {
                var security = kvp.Value;

                if (!security.Invested)
                {
                    continue;
                }

                var pnl = security.Holdings.UnrealizedProfitPercent;
                if (pnl < _maximumDrawdownPercent)
                {
                    // liquidate
                    yield return new PortfolioTarget(security.Symbol, 0);
                }
            }
        }
    }
}