/// <summary> /// Called when data is received. /// </summary> /// <param name="updates">The datapoints.</param> public void OnData(DataUpdates updates) { //Process for each quant fund attached and running QuantFunds.ForEach(quantfund => quantfund.OnData(updates)); //Send updates if (!IsBacktesting) { SendEventMessages(); } }
/// <summary> /// Called when data is received. /// </summary> /// <param name="data">The data.</param> public void OnData(DataUpdates data) { //get the data that belongs to this quant fund var filtereddata = data[Universe]; var cloneddata = filtereddata.Clone(); //Send data to modules if (IsRunning) { Modules.ForEach(x => x.OnData(cloneddata)); } }
/// <summary> /// Updates the currency conversion based on tick received /// </summary> /// <param name="updates">The current data updates.</param> public void Update(DataUpdates updates) { foreach (var tick in updates.Ticks.Values.SelectMany(x => x)) { //Check symbol if (!CurrencySymbols.ContainsKey(tick.Ticker.Name)) { return; } //get base rate var baserate = CurrencySymbols[tick.Ticker.Name][0].ToString(); var torate = CurrencySymbols[tick.Ticker.Name][1].ToString(); var date = tick.OccuredUtc.Date; //Set pricing decimal price = tick.IsFullQuote ? Math.Abs(tick.AskPrice + tick.BidPrice) / 2 : tick.Price; if (!History.TryGetValue(baserate, out Dictionary <DateTime, CurrencyRatesConfig> his)) { if (!his.TryGetValue(date, out CurrencyRatesConfig config)) { config.Rates[torate] = price; } else { his.Add(date, new CurrencyRatesConfig { Base = baserate, Date = date, Rates = new Dictionary <string, decimal> { { torate, price } } }); } } else { History.Add(baserate, new Dictionary <DateTime, CurrencyRatesConfig> { { date, new CurrencyRatesConfig { Base = baserate, Date = date, Rates = new Dictionary <string, decimal> { { torate, price } } } } }); } } }
public Response() { this.dataUpdatesField = new DataUpdates(); }
/// <summary> /// Called when data is received. /// </summary> /// <param name="data">The data.</param> public virtual void OnData(DataUpdates data) { }
/// <summary> /// Processes the market data. /// </summary> /// <param name="dataupdates">The data updates.</param> public void ProcessMarketData(DataUpdates dataupdates) { //Only accept market data if (_activeOrders.Count == 0) { return; } //Check if we have any data if (!dataupdates.HasUpdates) { return; } lock (_locker) { foreach (var pkv in _activeOrders.OrderBy(x => x.Key)) { //get the order var pendingorder = pkv.Value; var order = pendingorder.Order; //Get datapoint if (!dataupdates[order.Security].HasUpdates) { continue; } var datapoint = dataupdates[order.Security].Ticks.Count > 0 ? dataupdates[order.Security].Ticks.First().Value.First() as DataPoint : dataupdates[order.Security].QuoteBars.Count > 0 ? dataupdates[order.Security].QuoteBars.First().Value as DataPoint : dataupdates[order.Security].TradeBars.Count > 0 ? dataupdates[order.Security].TradeBars.First().Value as DataPoint : null; if (datapoint == null) { continue; } //Check if order is already done if (order.State.IsDone()) { _activeOrders.TryRemove(pkv.Key, out pendingorder); continue; } //Check if we have enough buying power if (!_portfolio.OrderTicketHandler.GetSufficientCapitalForOrder(pendingorder)) { //Remove order from active orders, as it is cancelled by the broker instance _activeOrders.TryRemove(pkv.Key, out pendingorder); _portfolio.Log(LogLevel.Error, $"Insufficient funds to process order by sim broker"); OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(pendingorder.OrderId, "Insufficient funds to process order by sim broker")); } //Check if we need to fill this order var fillmodel = BrokerModel.GetFillModel(order); Fill filledresult = Fill.NoFill(); try { filledresult = fillmodel.FillOrder(BrokerModel, datapoint, pendingorder, _usehighlyliquidfills); } catch (Exception exc) { _log.Error(exc); _portfolio.Log(LogLevel.Error, string.Format("Order Error: id: {0}, Transaction model failed to fill for order type: {1} with error: {2}", order.InternalId, order.Type, exc.Message)); OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(pendingorder.OrderId, "Exception during processing fill for this order, please check logs")); } //Check for any full or partial fills if (filledresult.FillQuantity > 0) { if (filledresult.Status == OrderState.Filled) { OrderStateChange?.Invoke(this, OrderTicketEvent.Filled(order.InternalId, filledresult)); } else if (filledresult.Status == OrderState.PartialFilled) { OrderStateChange?.Invoke(this, OrderTicketEvent.PartiallyFilled(order.InternalId, filledresult)); } } //Check if order is done if (filledresult.Status.IsDone()) { _activeOrders.TryRemove(pkv.Key, out pendingorder); } } } }
/// <summary> /// Initializes a new instance of the <see cref="DataUpdateHolder"/> class. /// </summary> /// <param name="updates">The updates.</param> /// <param name="datapoints">The datapoints.</param> /// <param name="aggregatorupdates">The aggregatorupdates.</param> public DataUpdateHolder(DataUpdates updates, List <DataPoint> datapoints, List <UpdateData <DataSubscription> > aggregatorupdates) { Updates = updates; DataPoints = datapoints; AggregatorUpdates = aggregatorupdates; }
public Updater(IVersionSource version_source, string data_folder) { this.Data = new DataUpdates(data_folder); this.Program = new ProgramUpdates(); this.VersionSource = version_source; }
/// <summary> /// On data point received (for simulated order types) /// </summary> /// <param name="updates">The data updates.</param> public void OnData(DataUpdates updates) => ProcessSimulatedOrders(updates.Data);