public void ClonesBaseDataDerivedTypes() { BaseData data = new IndicatorDataPoint(Symbols.SPY, DateTime.Now, 1m); BaseData clone = ObjectActivator.Clone(data) as BaseData; Assert.IsNotNull(clone); Assert.IsInstanceOf(data.GetType(), clone); Assert.AreEqual(data.Symbol, clone.Symbol); Assert.AreEqual(data.Time, clone.Time); Assert.AreEqual(data.Value, clone.Value); data = new TradeBar(DateTime.Now, Symbols.SPY, 1m, 2m, 3m, 4m, 5); var bar = ObjectActivator.Clone(data) as TradeBar; Assert.IsNotNull(clone); Assert.IsInstanceOf(data.GetType(), bar); Assert.AreEqual(data.Symbol, bar.Symbol); Assert.AreEqual(data.Time, bar.Time); Assert.AreEqual(data.Value, bar.Value); Assert.AreEqual(((TradeBar)data).Open, bar.Open); Assert.AreEqual(((TradeBar)data).High, bar.High); Assert.AreEqual(((TradeBar)data).Low, bar.Low); Assert.AreEqual(((TradeBar)data).Close, bar.Close); Assert.AreEqual(data.Price, bar.Price); }
public void IsFasterThanRawReflection() { int count = 100000; var data = new TradeBar(DateTime.Now, Symbols.SPY, 1m, 2m, 3m, 4m, 5); var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { var clone = Clone(data); } stopwatch.Stop(); var elapsed1 = stopwatch.Elapsed; Console.WriteLine(elapsed1.TotalMilliseconds); stopwatch.Reset(); stopwatch.Start(); for (int i = 0; i < count; i++) { var clone = ObjectActivator.Clone(data); } stopwatch.Stop(); var elapsed2 = stopwatch.Elapsed; Console.WriteLine(elapsed2.TotalMilliseconds); Assert.Less(elapsed2, elapsed1); }
/// <summary> /// Gets all holdings for the account /// </summary> /// <returns>The current holdings from the account</returns> public override List <Holding> GetAccountHoldings() { var holdings = _accountHoldings.Select(x => (Holding)ObjectActivator.Clone(x.Value)).ToList(); // fire up tasks to resolve the conversion rates so we can do them in parallel var tasks = holdings.Select(local => { // we need to resolve the conversion rate for non-USD currencies if (local.Type != SecurityType.Forex) { // this assumes all non-forex are us denominated, we should add the currency to 'holding' local.ConversionRate = 1m; return(null); } // if quote currency is in USD don't bother making the request string currency = local.Symbol.Substring(3); if (currency == "USD") { local.ConversionRate = 1m; return(null); } // this will allow us to do this in parallel return(Task.Factory.StartNew(() => local.ConversionRate = GetUsdConversion(currency))); }).Where(x => x != null).ToArray(); Task.WaitAll(tasks, 5000); return(holdings); }
public override BaseData Clone() { var clone = ObjectActivator.Clone(this); foreach (var kvp in _storage) { clone._storage.Add(kvp); } return(clone); }
/// <summary> /// Return a new instance clone of this object, used in fill forward /// </summary> /// <remarks> /// This base implementation uses reflection to copy all public fields and properties /// </remarks> /// <returns>A clone of the current object</returns> public override BaseData Clone() { var clone = ObjectActivator.Clone(this); foreach (var kvp in _storage) { // don't forget to add the dynamic members! clone._storage.Add(kvp); } return clone; }
/// <summary> /// Return a new instance clone of this object, used in fill forward /// </summary> /// <remarks> /// This base implementation uses reflection to copy all public fields and properties /// </remarks> /// <returns>A clone of the current object</returns> public virtual BaseData Clone() { return((BaseData)ObjectActivator.Clone((object)this)); }
public override BaseData Clone() { return(ObjectActivator.Clone(this) as FakeTradeBarCustom); }
/// <summary> /// Return a new instance clone of this object, used in fill forward /// </summary> /// <remarks> /// This base implementation uses reflection to copy all public fields and properties /// </remarks> /// <returns>A clone of the current object</returns> public virtual BaseData Clone() { return(ObjectActivator.Clone(this) as BaseData); }
} // End Run(); /// <summary> /// Every so often send an update to the browser with the current state of the algorithm. /// </summary> public void Update() { //Initialize: Dictionary <int, Order> deltaOrders; //Error checks if the algorithm & threads have not loaded yet, or are closing down. if (_algorithm == null || _algorithm.Transactions == null || _algorithm.Transactions.Orders == null || !_algorithm.GetLocked()) { Log.Error("LiveTradingResultHandler.Update(): Algorithm not yet initialized."); return; } try { if (DateTime.Now > _nextUpdate) { //Extract the orders created since last update OrderEvent orderEvent; deltaOrders = new Dictionary <int, Order>(); var stopwatch = Stopwatch.StartNew(); while (_orderEvents.TryDequeue(out orderEvent) && stopwatch.ElapsedMilliseconds < 15) { var order = _algorithm.Transactions.GetOrderById(orderEvent.OrderId); deltaOrders[orderEvent.OrderId] = ObjectActivator.Clone(order) as Order; } //For charting convert to UTC foreach (var order in deltaOrders) { order.Value.Time = order.Value.Time.ToUniversalTime(); } //Reset loop variables: _lastOrderId = (from order in deltaOrders.Values select order.Id).DefaultIfEmpty(_lastOrderId).Max(); //Limit length of orders we pass back dynamically to avoid flooding. //if (deltaOrders.Count > 50) deltaOrders.Clear(); //Create and send back the changes in chart since the algorithm started. var deltaCharts = new Dictionary <string, Chart>(); lock (_chartLock) { //Get the updates since the last chart foreach (var chart in _charts) { deltaCharts.Add(chart.Value.Name, chart.Value.GetUpdates()); } } //Profit loss changes, get the banner statistics, summary information on the performance for the headers. var holdings = new Dictionary <string, Holding>(); var deltaStatistics = new Dictionary <string, string>(); var runtimeStatistics = new Dictionary <string, string>(); var serverStatistics = OS.GetServerStatistics(); // only send holdings updates when we have changes in orders, except for first time, then we want to send all foreach (var asset in _algorithm.Securities.Values.OrderBy(x => x.Symbol)) { holdings.Add(asset.Symbol, new Holding(asset.Holdings)); } //Add the algorithm statistics first. lock (_runtimeStatistics) { foreach (var pair in _runtimeStatistics) { runtimeStatistics.Add(pair.Key, pair.Value); } } //Add other fixed parameters. runtimeStatistics.Add("Unrealized:", "$" + _algorithm.Portfolio.TotalUnrealizedProfit.ToString("N2")); runtimeStatistics.Add("Fees:", "-$" + _algorithm.Portfolio.TotalFees.ToString("N2")); runtimeStatistics.Add("Net Profit:", "$" + _algorithm.Portfolio.TotalProfit.ToString("N2")); runtimeStatistics.Add("Return:", ((_algorithm.Portfolio.TotalPortfolioValue - Engine.SetupHandler.StartingPortfolioValue) / Engine.SetupHandler.StartingPortfolioValue).ToString("P")); runtimeStatistics.Add("Equity:", "$" + _algorithm.Portfolio.TotalPortfolioValue.ToString("N2")); runtimeStatistics.Add("Holdings:", "$" + _algorithm.Portfolio.TotalHoldingsValue.ToString("N2")); runtimeStatistics.Add("Volume:", "$" + _algorithm.Portfolio.TotalSaleVolume.ToString("N2")); // since we're sending multiple packets, let's do it async and forget about it // chart data can get big so let's break them up into groups var splitPackets = SplitPackets(deltaCharts, deltaOrders, holdings, deltaStatistics, runtimeStatistics, serverStatistics); foreach (var liveResultPacket in splitPackets) { Engine.Notify.Send(liveResultPacket); } //Send full packet to storage. if (DateTime.Now > _nextChartsUpdate) { _nextChartsUpdate = DateTime.Now.AddMinutes(1); lock (_chartLock) { var chartComplete = new Dictionary <string, Chart>(Charts); var orders = new Dictionary <int, Order>(_algorithm.Transactions.Orders); var complete = new LiveResultPacket(_job, new LiveResult(chartComplete, orders, _algorithm.Transactions.TransactionRecord, holdings, deltaStatistics, runtimeStatistics, serverStatistics)); StoreResult(complete); } } // Upload the logs every 1-2 minutes; this can be a heavy operation depending on amount of live logging and should probably be done asynchronously. if (DateTime.Now > _nextLogStoreUpdate) { Log.Trace("LiveTradingResultHandler.Update(): Storing log..."); lock (_logStoreLock) { var utc = DateTime.UtcNow; var logs = (from log in _logStore where log.Time >= utc.RoundDown(TimeSpan.FromHours(1)) select log).ToList(); //Override the log master to delete the old entries and prevent memory creep. _logStore = logs; StoreLog(logs); } _nextLogStoreUpdate = DateTime.Now.AddMinutes(2); } // Every 5 send usage statistics: if (DateTime.Now > _nextStatisticsUpdate) { try { Engine.Api.SendStatistics( _job.AlgorithmId, _algorithm.Portfolio.TotalUnrealizedProfit, _algorithm.Portfolio.TotalFees, _algorithm.Portfolio.TotalProfit, _algorithm.Portfolio.TotalHoldingsValue, _algorithm.Portfolio.TotalPortfolioValue, ((_algorithm.Portfolio.TotalPortfolioValue - Engine.SetupHandler.StartingPortfolioValue) / Engine.SetupHandler.StartingPortfolioValue), _algorithm.Portfolio.TotalSaleVolume, _lastOrderId, 0); } catch (Exception err) { Log.Error("LiveTradingResultHandler.Update(): Error sending statistics: " + err.Message); } _nextStatisticsUpdate = DateTime.Now.AddMinutes(1); } lock (_chartLock) { foreach (var chart in Charts) { foreach (var series in chart.Value.Series) { // trim data that's older than 2 days series.Value.Values = (from v in series.Value.Values where v.x > Time.DateTimeToUnixTimeStamp(DateTime.UtcNow.AddDays(-2)) select v).ToList(); } } } //Set the new update time after we've finished processing. // The processing can takes time depending on how large the packets are. _nextUpdate = DateTime.Now.AddSeconds(2); } // End Update Charts: } catch (Exception err) { Log.Error("LiveTradingResultHandler().Update(): " + err.Message, true); } }