Overall Statistics |
Total Trades 80 Average Win 0.36% Average Loss -0.90% Compounding Annual Return 0.666% Drawdown 8.200% Expectancy 0.366 Net Profit 14.096% Sharpe Ratio 0.235 Probabilistic Sharpe Ratio 0.002% Loss Rate 2% Win Rate 98% Profit-Loss Ratio 0.40 Alpha 0.006 Beta -0.002 Annual Standard Deviation 0.024 Annual Variance 0.001 Information Ratio -0.316 Tracking Error 0.17 Treynor Ratio -3.637 Total Fees $7914.30 |
using System; using System.Collections.Generic; using QuantConnect.Data; using QuantConnect.Data.Market; using System.Linq; using QuantConnect.Interfaces; using QuantConnect.Indicators; using QuantConnect.Securities; using QuantConnect.Orders; using QuantConnect.Data.Consolidators; namespace Quant { public class TestAlgo : QCAlgorithm { public RollingWindow<decimal> BidPrice = new RollingWindow<decimal>(4); public RollingWindow<decimal> AskPrice = new RollingWindow<decimal>(4); public RollingWindow<decimal> Volume = new RollingWindow<decimal>(4); public OrderTicket EntryOrder { get; set; } public Func<QCAlgorithm, string, decimal, OneCancelsOtherTicketSet> OnOrderFilledEvent { get; set; } public OneCancelsOtherTicketSet ProfitLossOrders { get; set; } public override void Initialize() { SetStartDate(2000, 01, 01); SetEndDate(DateTime.Now); SetCash(1000000); var contract = AddFuture(Futures.Indices.SP500EMini, Resolution.Minute); contract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(182)); SetSecurityInitializer(x => x.SetSlippageModel(new CustomSlippageModel(this))); SetBrokerageModel(BrokerageName.AlphaStreams); SetExecution(new VolumeWeightedAveragePriceExecutionModel()); AddRiskManagement(new MaximumUnrealizedProfitPercentPerSecurity(0.09m)); AddRiskManagement(new MaximumDrawdownPercentPerSecurity(0.09m)); } public override void OnData(Slice slice) { var accountCurrencyCash = Portfolio.TotalPortfolioValue; foreach(var chain in slice.FutureChains) { // remplacer les lettre entre guillemet par l'abreviation correspondant au contract analysé. if (chain.Value.Symbol.StartsWith("ES")) { var ES = (from futuresContract in chain.Value.OrderBy(x => x.Expiry) where futuresContract.Expiry > Time.Date.AddDays(1) select futuresContract).FirstOrDefault(); if ( ES != null) { BidPrice.Add(ES.BidPrice); AskPrice.Add(ES.AskPrice); Volume.Add(ES.Volume); if (!BidPrice.IsReady || !AskPrice.IsReady || !Volume.IsReady) continue; if (ES.BidPrice != 0 && ES.AskPrice != 0) { var _minSize = Var.Coefminsize ; var _quantity = ((Var.CentageLoss * accountCurrencyCash)/(Var.valpoint*(((AskPrice[0]+BidPrice[0])/2)-Var.SLShort*((AskPrice[0]+BidPrice[0])/2))/Var.minprizefluct)) ; var _quantityy = (decimal)(Volume[0]+Volume[1]) * 0.01m; if (AskPrice[0]-BidPrice[0] <= Var.minprizefluct || (AskPrice[0]-BidPrice[0]) > 0) { if (Volume[1] > Var.minVolume) { if (Volume[0]>(Var.coefVolume*Volume[1])) { if (BidPrice[0]>AskPrice[1]) { if (AskPrice[1]<BidPrice[2]) { if ((BidPrice[0]-AskPrice[1]) >= _minSize) { if ((BidPrice[0]-AskPrice[1])*Var.coefBidAskSize < (BidPrice[2]-AskPrice[1])) { if (((decimal)(Volume[0]+Volume[1]) * 0.01m)<_quantity) { this.OnOrderFilledEvent = (O_, Symbol, FillPrice) => { return new OneCancelsOtherTicketSet( O_.LimitOrder(ES.Symbol, -_quantityy, FillPrice * Var.TPLong, "Profit Long _Target"), O_.StopMarketOrder(ES.Symbol, -_quantityy, FillPrice * Var.SLLong, "Stop Long _Loss")); }; this.EntryOrder = MarketOrder(ES.Symbol, _quantityy, false, "Entry"); break; } if (((decimal)(Volume[0]+Volume[1]) * 0.01m)>_quantity) { this.OnOrderFilledEvent = (O_, Symbol, FillPrice) => { return new OneCancelsOtherTicketSet( O_.LimitOrder(ES.Symbol, -_quantity, FillPrice * Var.TPLong, "Profit Long _Target"), O_.StopMarketOrder(ES.Symbol, -_quantity, FillPrice * Var.SLLong, "Stop Long _Loss")); }; this.EntryOrder = MarketOrder(ES.Symbol, _quantity, false, "Entry"); break; } }}}} if (AskPrice[0]<BidPrice[1]) { if (BidPrice[1]>AskPrice[2]) { if ((BidPrice[1]-AskPrice[0]) >= _minSize) { if ((BidPrice[1]-AskPrice[0])*Var.coefBidAskSize < (BidPrice[1]-AskPrice[2])) { if (((decimal)(Volume[0]+Volume[1]) * 0.01m)<_quantity) { this.OnOrderFilledEvent = (O_, Symbol, FillPrice) => { return new OneCancelsOtherTicketSet( O_.LimitOrder(ES.Symbol, -_quantityy, FillPrice * Var.TPShort, "Profit Short _Target"), O_.StopMarketOrder(ES.Symbol, -_quantityy, FillPrice * Var.SLShort, "Stop Short _Loss")); }; this.EntryOrder = MarketOrder(ES.Symbol, _quantityy, false, "Entry"); break; } if (((decimal)(Volume[0]+Volume[1]) * 0.01m)>_quantity) { this.OnOrderFilledEvent = (O_, Symbol, FillPrice) => { return new OneCancelsOtherTicketSet( O_.LimitOrder(ES.Symbol, -_quantity, FillPrice * Var.TPShort, "Profit Short _Target"), O_.StopMarketOrder(ES.Symbol, -_quantity, FillPrice * Var.SLShort, "Stop Short _Loss")); }; this.EntryOrder = MarketOrder(ES.Symbol, _quantity, false, "Entry"); break; } }}}} }}}}}} } } public override void OnOrderEvent(OrderEvent orderEvent) { if (EntryOrder != null) { this.EntryOrder = null; } if (orderEvent.Status == OrderStatus.Filled || orderEvent.Status == OrderStatus.PartiallyFilled) { if (this.OnOrderFilledEvent != null) { this.ProfitLossOrders = OnOrderFilledEvent(this, orderEvent.Symbol, orderEvent.FillPrice); OnOrderFilledEvent = null; } else if (this.ProfitLossOrders != null) { this.ProfitLossOrders.Filled(); this.ProfitLossOrders = null; } } } public class CustomSlippageModel : ISlippageModel { private readonly QCAlgorithm _algorithm; public RollingWindow<decimal> High = new RollingWindow<decimal>(2); public RollingWindow<decimal> Low = new RollingWindow<decimal>(2); public RollingWindow<decimal> Volume = new RollingWindow<decimal>(2); public CustomSlippageModel(QCAlgorithm algorithm) { _algorithm = algorithm; } public decimal GetSlippageApproximation(Security asset, Order order) { High.Add(asset.High); Low.Add(asset.Low); Volume.Add(asset.Volume); var orderVolume = order.AbsoluteQuantity; var slippage = (High[0]-Low[0]) * 0.01m / (Volume[0]/orderVolume); if (asset.Symbol.StartsWith("ES")) { if (((High[0]-Low[0]) * 0.01m / (Volume[0]/orderVolume)) < Var.minprizefluct) { return 0.25m ; } } return slippage; } } /// <summary> /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm. /// </summary> public bool CanRunLocally { get; } = true; /// <summary> /// This is used by the regression test system to indicate which languages this algorithm is written in. /// </summary> public Language[] Languages { get; } = { Language.CSharp }; } }
namespace Quant { public class OneCancelsOtherTicketSet { public OneCancelsOtherTicketSet(params OrderTicket[] orderTickets) { this.OrderTickets = orderTickets; } private OrderTicket[] OrderTickets { get; set; } public void Filled() { // Cancel all the outstanding tickets. foreach (var orderTicket in this.OrderTickets) { if (orderTicket.Status == OrderStatus.Submitted) { orderTicket.Cancel(); } } } } }
namespace Quant { public static class Var { public const decimal MaxQuantity = 50m ; public const decimal CentageLoss = 0.1m ; public const decimal valpoint = 12.5m ; public const decimal minprizefluct = 0.25m ; public const decimal Coefminsize = minprizefluct ; public const decimal coefBidAskSize = 4m ; public const decimal coefVolume = 0.98m ; public const int minVolume = 15800 ; public const decimal TPLong = 1.001m ; public const decimal SLLong = 0.972m ; public const decimal TPShort = 1.001m ; public const decimal SLShort = 0.972m ; } }