/// <summary> /// Set live mode state of the algorithm run: Public setter for the algorithm property LiveMode. /// </summary> public void SetLiveMode(bool live) { if (!_locked) { _liveMode = live; Notify = new NotificationManager(live); TradeBuilder.SetLiveMode(live); } }
public override void OnData(Slice data) { //if (!isSent) // return; if (!data.Bars.ContainsKey(Symbol(BIST_SECURITY_NAME))) { return; } if (!security.Exchange.ExchangeOpen) { Debug("----------- security exchange is not open"); return; } decimal holdingQty = Portfolio.GetHoldingsQuantity(Symbol(BIST_SECURITY_NAME)); Debug("............Purchase Start.............. "); Debug("----------- Portfolio is invested? : " + Portfolio.Invested); Debug("----------- Portfolio.Count : " + Portfolio.Count); Debug("----------- Holding Quantity : " + holdingQty); Debug("----------- HasOpenPosition? : " + TradeBuilder.HasOpenPosition(Symbol(BIST_SECURITY_NAME))); //int quantity = (int)Math.Floor(Portfolio.Cash / data["AAPL"].Close); TradeBar bar = data.Bars[BIST_SECURITY_NAME]; if (bar.DataType != MarketDataType.TradeBar) { return; } DisplayBarInfo(bar); OrderTicket marketTicket = PlaceMarketOrder(bar); DisplayTicketInfo(marketTicket); OrderTicket limitTicket = PlaceLimitOrder(bar); DisplayTicketInfo(limitTicket); DisplayPortfolioInfo(); //UpdateOrder(ticket); //CancelOrder(ticket); DisplayOpenOrders(); Debug("............Purchase End.............. "); }
public override void OnOrderEvent(OrderEvent orderEvent) { if (orderEvent.Status == OrderStatus.Filled) { Log($"OnOrderEvent(): New filled order event: {orderEvent}"); // leave 1 unit as error in expected value if (Math.Abs(orderEvent.FillQuantity - _expectedOrderQuantity) > 1) { throw new Exception($"Unexpected order event fill quantity: {orderEvent.FillQuantity}. " + $"Expected {_expectedOrderQuantity}"); } var orderFeeInAccountCurrency = Portfolio.CashBook.ConvertToAccountCurrency(orderEvent.OrderFee.Value).Amount; var expectedOrderFee = _spy.Holdings.TotalFees - _previousHoldingsFees; if (orderEvent.OrderFee.Value.Currency == AccountCurrency // leave 0.00001m as error in expected fee value || Math.Abs(expectedOrderFee - orderFeeInAccountCurrency) > 0.00001m) { throw new Exception($"Unexpected order fee: {orderFeeInAccountCurrency}. " + $"Expected {expectedOrderFee}"); } if (!TradeBuilder.HasOpenPosition(_spy.Symbol)) { var lastTrade = TradeBuilder.ClosedTrades.Last(); var expectedProfitLoss = (lastTrade.ExitPrice - lastTrade.EntryPrice) * lastTrade.Quantity * _spy.QuoteCurrency.ConversionRate * (lastTrade.Direction == TradeDirection.Long ? 1 : -1); if (Math.Abs(expectedProfitLoss - lastTrade.ProfitLoss) > 1) { throw new Exception($"Unexpected last trade ProfitLoss: {lastTrade.ProfitLoss}. " + $"Expected {expectedProfitLoss}"); } // There is a difference in what does Holdings and TradeBuilder consider LastTrade if (TradeBuilder.ClosedTrades.Count - _previousClosedTradesCount > 1) { var trade = TradeBuilder.ClosedTrades[_previousClosedTradesCount]; expectedProfitLoss += trade.ProfitLoss; } if (Math.Abs(_spy.Holdings.LastTradeProfit - expectedProfitLoss) > 1) { throw new Exception($"Unexpected Holdings.NetProfit: {_spy.Holdings.LastTradeProfit}. " + $"Expected {expectedProfitLoss}"); } } _previousHoldingsFees = _spy.Holdings.TotalFees; _previousClosedTradesCount = TradeBuilder.ClosedTrades.Count; } }
public void ShouldGenerateTradeJson() { var trade = new TradeBuilder() .Set(x => x.Order, new OrderBuilder().Build) .Set(x => x.Product, new ProductBuilder().Build) .Build(); var payload = JsonConvert.SerializeObject(trade, Formatting.Indented); var dir = TestContext.CurrentContext.WorkDirectory; var saveFile = Path.Combine(dir, "trade.json"); //File.WriteAllText(saveFile, payload); var copyDir = Path.Combine(dir, "..\\..\\Artifacts\\trade.json"); File.WriteAllText(copyDir, payload); }
/// <summary> /// QCAlgorithm Base Class Constructor - Initialize the underlying QCAlgorithm components. /// QCAlgorithm manages the transactions, portfolio, charting and security subscriptions for the users algorithms. /// </summary> public QCAlgorithm() { // AlgorithmManager will flip this when we're caught up with realtime IsWarmingUp = true; //Initialise the Algorithm Helper Classes: //- Note - ideally these wouldn't be here, but because of the DLL we need to make the classes shared across // the Worker & Algorithm, limiting ability to do anything else. //Initialise Start and End Dates: _startDate = new DateTime(1998, 01, 01); _endDate = DateTime.Now.AddDays(-1); // intialize our time keeper with only new york _timeKeeper = new TimeKeeper(_startDate, new[] { TimeZones.NewYork }); // set our local time zone _localTimeKeeper = _timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork); //Initialise Data Manager SubscriptionManager = new SubscriptionManager(_timeKeeper); Securities = new SecurityManager(_timeKeeper); Transactions = new SecurityTransactionManager(Securities); Portfolio = new SecurityPortfolioManager(Securities, Transactions); BrokerageModel = new DefaultBrokerageModel(); Notify = new NotificationManager(false); // Notification manager defaults to disabled. //Initialise Algorithm RunMode to Series - Parallel Mode deprecated: _runMode = RunMode.Series; //Initialise to unlocked: _locked = false; // get exchange hours loaded from the market-hours-database.csv in /Data/market-hours _exchangeHoursProvider = SecurityExchangeHoursProvider.FromDataFolder(); UniverseSettings = new SubscriptionSettings(Resolution.Minute, 2m, true, false); // initialize our scheduler, this acts as a liason to the real time handler Schedule = new ScheduleManager(Securities, TimeZone); // initialize the trade builder TradeBuilder = new TradeBuilder(FillGroupingMethod.FillToFill, FillMatchingMethod.FIFO); }
public override void OnData(Slice data) { //if (!isSent) // return; if (!data.Bars.ContainsKey(Symbol(BIST_SYMBOL))) { return; } if (!security.Exchange.ExchangeOpen) { Debug("----------- security exchange is not open"); return; } TradeBar bar = data.Bars[BIST_SYMBOL]; if (bar.DataType != MarketDataType.TradeBar) { Debug("............ bar is not TradeBar.............. "); return; } // only once per day if (previous.Date == Time.Date) //only once per second if (previous.ToString("yyyyMMdd-HH:mm:ss") == Time.ToString("yyyyMMdd-HH:mm:ss")) { return; } if (!macd.IsReady) { return; } var holding = Portfolio[BIST_SYMBOL]; decimal signalDeltaPercent = (macd - macd.Signal) / macd.Fast; var tolerance = 0.0025m; bool isSent = false; // if our macd is greater than our signal, then let's go long if (holding.Quantity <= 0 && signalDeltaPercent > tolerance) // 0.01% { // longterm says buy as well SetHoldings(BIST_SYMBOL, 1.0); isSent = true; } // of our macd is less than our signal, then let's go short else if (holding.Quantity >= 0 && signalDeltaPercent < -tolerance) { Liquidate(BIST_SYMBOL); isSent = true; } // plot both lines Plot("MACD", macd, macd.Signal); Plot(BIST_SYMBOL, "Open", data[BIST_SYMBOL].Open); Plot(BIST_SYMBOL, macd.Fast, macd.Slow); previous = Time; if (isSent) { decimal holdingQty = Portfolio.GetHoldingsQuantity(Symbol(BIST_SYMBOL)); Debug("----------- Portfolio is invested? : " + Portfolio.Invested); Debug("----------- Portfolio.Count : " + Portfolio.Count); Debug("----------- Holding Quantity : " + holdingQty); Debug("----------- HasOpenPosition? : " + TradeBuilder.HasOpenPosition(Symbol(BIST_SYMBOL))); //int quantity = (int)Math.Floor(Portfolio.Cash / data["AAPL"].Close); DisplayBarInfo(bar); //OrderTicket marketTicket = PlaceMarketOrder(bar); //DisplayTicketInfo(marketTicket); //OrderTicket limitTicket = PlaceLimitOrder(bar); //DisplayTicketInfo(limitTicket); DisplayPortfolioInfo(); //UpdateOrder(ticket); //CancelOrder(ticket); DisplayOpenOrders(); } }