| 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 ;
}
}
}
}