Overall Statistics |
Total Trades 6687 Average Win 0.05% Average Loss -0.09% Compounding Annual Return -3.272% Drawdown 35.300% Expectancy -0.107 Net Profit -27.675% Sharpe Ratio -0.277 Loss Rate 42% Win Rate 58% Profit-Loss Ratio 0.54 Alpha -0.021 Beta 0.006 Annual Standard Deviation 0.074 Annual Variance 0.005 Information Ratio -0.777 Tracking Error 0.143 Treynor Ratio -3.406 Total Fees $12927.80 |
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 Test { public class TestAlgo : QCAlgorithm { public RollingWindow<decimal> BidPrice = new RollingWindow<decimal>(5); public RollingWindow<decimal> AskPrice = new RollingWindow<decimal>(5); public RollingWindow<decimal> Volume = new RollingWindow<decimal>(5); private OrderTicket EntryOrder { get; set; } private Func<QCAlgorithm, string, decimal, OneCancelsOtherTicketSet> OnOrderFilledEvent { get; set; } private OneCancelsOtherTicketSet ProfitLossOrders { get; set; } private const string Testalgo = Futures.Indices.Nikkei225Dollar; public Symbol test = QuantConnect.Symbol.Create(Testalgo, SecurityType.Future, Market.USA); public override void Initialize() { SetStartDate(2010, 01, 01); SetEndDate(DateTime.Now); SetCash(1000000); var test = AddFuture(Testalgo, Resolution.Minute); test.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(365)); } public override void OnData(Slice slice) { if (Time.DayOfWeek == DayOfWeek.Friday) { if (Time.Hour >= 16) { return; }} if (Time.DayOfWeek == DayOfWeek.Saturday && Time.DayOfWeek == DayOfWeek.Sunday) { return; } DateTime dt = Time; if (dt.DayOfWeek == DayOfWeek.Friday) { if (Time.Hour == 15 && Time.Minute == 59) { foreach (var holding in Portfolio.Values) { if (holding.HoldStock) { MarketOnCloseOrder(holding.Symbol, -holding.Quantity, tag: "Liquidate Market Close"); } }}} foreach(var chain in slice.FutureChains) { if (chain.Value.Symbol.StartsWith("NKD")) { var contract = (from futuresContract in chain.Value.OrderBy(x => x.Expiry) where futuresContract.Expiry > Time.Date.AddDays(9) select futuresContract).FirstOrDefault(); AskPrice.Add(contract.AskPrice); BidPrice.Add(contract.BidPrice); Volume.Add(contract.Volume); if (!AskPrice.IsReady || !BidPrice.IsReady || !Volume.IsReady) continue; if (contract != null) { if (contract.LastPrice != 0) { var test_Leverage = 6.6m; var test_minSize = ((contract.LastPrice*1.001m)-contract.LastPrice) ; var test_TPLong = 1.001m ; var test_SLLong = 0.95m ; var test_TPShort = 1.001m ; var test_SLShort = 0.95m ; if (BidPrice[0]>AskPrice[1]) { if (BidPrice[2]>AskPrice[1]) { if ((BidPrice[0]-AskPrice[1]) > test_minSize) { this.OnOrderFilledEvent = (Testalgo, Symbol, FillPrice) => { return new OneCancelsOtherTicketSet( Testalgo.LimitOrder(contract.Symbol, -1, FillPrice * test_TPLong, "Profit Long test_Target"), Testalgo.StopMarketOrder(contract.Symbol, -1, FillPrice * test_SLLong, "Stop Long test_Loss")); }; this.EntryOrder = MarketOrder(contract.Symbol, 1, false, "Entry"); }}} if (AskPrice[0]<BidPrice[1]) { if (AskPrice[2]<BidPrice[1]) { if ((BidPrice[1]-AskPrice[0]) > test_minSize) { this.OnOrderFilledEvent = (Testalgo, Symbol, FillPrice) => { return new OneCancelsOtherTicketSet( Testalgo.LimitOrder(contract.Symbol, -1, FillPrice * test_TPLong, "Profit Short test_Target"), Testalgo.StopMarketOrder(contract.Symbol, -1, FillPrice * test_SLLong, "Stop Short test_Loss")); }; this.EntryOrder = MarketOrder(contract.Symbol, 1, false, "Entry"); }}} } } } } } 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 override void OnMarginCall(List<SubmitOrderRequest> requests) { // this code gets called BEFORE the orders are placed, so we can try to liquidate some of our positions // before we get the margin call orders executed. We could also modify these orders by changing their // quantities foreach (var order in requests.ToList()) { // liquidate an extra 10% each time we get a margin call to give us more padding var newQuantity = (int)(Math.Sign(order.Quantity) * order.Quantity * 1.1m); requests.Remove(order); requests.Add(new SubmitOrderRequest(order.OrderType, order.SecurityType, order.Symbol, newQuantity, order.StopPrice, order.LimitPrice, Time, "OnMarginCall")); } } /// <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 QuantConnect { 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(); } } } } }