Overall Statistics |
Total Trades 9 Average Win 12.92% Average Loss -13.10% Compounding Annual Return 148.436% Drawdown 19.900% Expectancy 0.490 Net Profit 21.152% Sharpe Ratio 1.784 Probabilistic Sharpe Ratio 53.975% Loss Rate 25% Win Rate 75% Profit-Loss Ratio 0.99 Alpha -0.096 Beta 3.948 Annual Standard Deviation 0.637 Annual Variance 0.405 Information Ratio 1.499 Tracking Error 0.55 Treynor Ratio 0.288 Total Fees $16650.00 Estimated Strategy Capacity $1400000.00 Lowest Capacity Asset NQ XRX5ODZTG8OX |
using System; using System.Drawing; namespace QuantConnect.Algorithm.CSharp { public class CasualYellowGreenLemur : QCAlgorithm { private DateTime _previous; private Symbol _chainSymbol; private Symbol _contractSymbol; private const decimal StopLossPercent = 0.05m; private const decimal TakeProfitPercent = 0.05m; private const decimal tolerance = 0.00015m; private int quantity = 1000; private decimal price = 0.0m; private OrderTicket CurrentOrder; private List<OrderTicket> StopLoss = new List<OrderTicket>(); private List<OrderTicket> ProfitTarget = new List<OrderTicket>(); private Dictionary<Symbol, ExponentialMovingAverage> fast = new Dictionary<Symbol, ExponentialMovingAverage>(); private Dictionary<Symbol, ExponentialMovingAverage> slow = new Dictionary<Symbol, ExponentialMovingAverage>(); public override void Initialize() { SetStartDate(2021, 3, 1); SetEndDate(2021, 5, 16); SetCash(100000000); var future = AddFuture(Futures.Indices.NASDAQ100EMini); future.SetFilter(0, 182); _chainSymbol = future.Symbol; } public void OnData(Slice slice) { if (_previous.Date == Time.Date) return; FuturesChain chain; // Find the contracts in the FuturesChain // See docs: https://www.quantconnect.com/docs/data-library/futures if (slice.FuturesChains.TryGetValue(_chainSymbol, out chain)) { var underlying = chain.Underlying; foreach (var contract in chain) { // Create indicators for each contract and save them in dictionaries keyed by Symbol var symbol = contract.Symbol; if (!slow.ContainsKey(symbol)) { slow[symbol] = EMA(symbol, 89, Resolution.Minute); } if (!fast.ContainsKey(symbol)) { fast[symbol] = EMA(symbol, 72, Resolution.Minute); } } // For example, select the contract with the earliest expiry _contractSymbol = ( from futuresContract in chain.OrderBy(x => x.Expiry) where futuresContract.Expiry > Time.Date.AddDays(90) select futuresContract ).FirstOrDefault()?.Symbol; } if (_contractSymbol == null) { Debug("is null always"); return; } var holdings = Portfolio[_contractSymbol].Quantity; // we only want to go long if we're currently short or flat // if the fast is greater than the slow, we'll go long // the fast for the selected contract is found in the dictionary if (holdings == 0 ) { var f= fast[_contractSymbol] *1; var s = slow[_contractSymbol]* (1 + tolerance); // if the slow is greater than the fast, we'll go long if (fast[_contractSymbol] > (slow[_contractSymbol] * (1 + tolerance))) { // Entry order MarketOrder(_contractSymbol, quantity); // Stop loss order var stopLossPrice = Securities[_contractSymbol].Price - StopLossPercent * Securities[_contractSymbol].Price; StopLoss.Add(StopMarketOrder(_contractSymbol, -quantity, stopLossPrice)); // Take profit order var profitTargetPrice = Securities[_contractSymbol].Price + TakeProfitPercent * Securities[_contractSymbol].Price; ProfitTarget.Add(LimitOrder(_contractSymbol, -quantity, profitTargetPrice)); Debug("BUY >> " + Securities[_contractSymbol].Price + " Our stopLossPrice: " + stopLossPrice + " ProfitTarget: " + profitTargetPrice+ " Quantity: " + quantity); Debug("StopLoss OrderId = "+ StopLoss[StopLoss.Count()-1].OrderId + " ProfitTarget OrderId = "+ ProfitTarget[ProfitTarget.Count()-1].OrderId); } } Plot(_contractSymbol, "Price", Securities[_contractSymbol].Price); } public override void OnOrderEvent(OrderEvent orderEvent) { // Ignore OrderEvents that are not closed if (orderEvent.Status != OrderStatus.Filled) { return; } var t = ProfitTarget.Count(); var s = StopLoss; // Defensive check if (ProfitTarget.Count() == 0 || StopLoss.Count() == 0) { return; } var filledOrderId = orderEvent.OrderId; var x=0; // If the ProfitTarget order was filled, close the StopLoss order foreach(var profitTarget in ProfitTarget) { if (profitTarget.OrderId == filledOrderId) { Debug("StopLoss.Cancel OrderId = " + StopLoss[x].OrderId); StopLoss[x].Cancel(); } ++x ; } // If the StopLoss order was filled, close the ProfitTarget x=0; foreach(var stopLoss in StopLoss) { if (stopLoss.OrderId == filledOrderId) { Debug("ProfitTarget.Cancel OrderId = " + ProfitTarget[x].OrderId); ProfitTarget[x].Cancel(); } ++x ; } } } }