//public void PublishStats() //{ // if (Publisher != null) // { // Publisher.SendAsync("algo-stats", this.Name, this.Stats); // Debug.WriteLine("Sending state update for " + Name); // } //} public void PublishStats(OrderStats stats) { if (Publisher != null) { Publisher.SendAsync("algo-stats", Name, stats); Debug.WriteLine("Sending state update for " + Name); } }
private void Adapter_StatsChanged(string name, OrderStats stats) { if (name == "*" || Name == name) { Stats = stats; PublishToConsole(Name + " Stats: " + stats); PublishStats(stats); } }
public void StatsRecalcNeeded(string name) { if (Stats.ContainsKey(name)) { OrderStats stats = Stats[name]; if (stats != null) { stats._statsRecalcNeeded = true; } } }
public RapidAlgo(AlgoMetadata metadata, ITradingSystemAdapter adapter) { Name = metadata.Name; Adapter = adapter; Metadata = metadata; Stats = new OrderStats(); Adapter.StatsChanged += Adapter_StatsChanged; _timer.Interval = 1000; _timer.Elapsed += Timer_Elapsed; _timer.Enabled = true; }
private void ProcessOrder(OrderRecord order, bool bRequest) { if (order != null) { if (order.Type == "UserSubmitStagedOrder") { string sDetails = order.GetDetails(); if (!bRequest) // don't want to spam the console at startup... { Console.WriteLine("Received Order Update: " + sDetails); } OrderRecord oldOrder = null; if (_book.ContainsKey(order.OrderID)) { oldOrder = _book[order.OrderID]; } OrderStats stats = GetOrCreateStats(order.Portfolio); stats.ReplaceOrder(order, oldOrder); // it's ok if oldOrder is null _book[order.OrderID] = order; // I don't like this... if (stats._statsRecalcNeeded) { RecalculateStats(order.Portfolio); } // Fire event to publish the result if (!bRequest) // only do this here for realtime updates. Otherwise, do it outside of loop. { StatsChanged?.Invoke(order.Portfolio, stats); } if (!bRequest) { if (_rand.Next(10) == 0) { var IDs = new List <string>(); IDs.Add(order.OrderID); AppendMagicDataToOrders(IDs); } } } else if (order.Type == "UserSubmitOrder") { _child_book[order.OrderID] = order; } } }
private OrderStats GetOrCreateStats(string name) { if (name == null || name == "") { name = "<none>"; } OrderStats stats = null; if (Stats.ContainsKey(name)) { stats = Stats[name]; } if (stats == null) { stats = new OrderStats(); Stats[name] = stats; } return(stats); }
// Call this to walk the book and recalculate all stats. May not be necessary anymore, now that we support // delta updates for stats. public void RecalculateStats(string algoName) { if (algoName != null && algoName != "") { if (Stats.ContainsKey(algoName)) { Stats[algoName] = null; } } else // clear them all { Stats.Clear(); } foreach (KeyValuePair <string, OrderRecord> entry in _book) { if (algoName == null || algoName.Length == 0 || entry.Value.Portfolio == algoName) { OrderStats stats = GetOrCreateStats(entry.Value.Portfolio); stats.AddOrder(entry.Value); } } }
private void Timer_Elapsed(object sender, ElapsedEventArgs e) { if (this.Enabled && _rand.Next(Metadata.FrequencySec) == 0) { // Prevent crazy huge number of trades. if (Stats.Total > 10000) { Enabled = false; } var numTrades = _rand.Next(Metadata.MinBatchSize, Metadata.MaxBatchSize); var tradesToCreate = new List <Trade>(); for (int i = 0; i < numTrades; i++) { var trade = new Trade() { Symbol = Metadata.Symbols[_rand.Next(0, Metadata.Symbols.Count)], Side = (_rand.Next(100) < Metadata.BuyShortRatio) ? "Buy" : "Short", Amount = _rand.Next(1, 60) * 100, Trader = "JEFF", Manager = "FO", Algo = Name }; tradesToCreate.Add(trade); PublishToConsole(Name + " created trade: " + trade.ToString()); } Adapter.CreateTrades(tradesToCreate); OrderStats EmsStats = Adapter.GetStats(Name); StampHistory(); } else { // do nothing, just record history; StampHistory(); } }
private void ProcessDataBlock(IDataBlock block, bool bRequest) { foreach (Row row in block) { OrderRecord order = new OrderRecord(); foreach (Field f in row) { if (f.FieldInfo.Name == "TYPE") { order.Type = f.StringValue; } else if (f.FieldInfo.Name == "ORDER_ID") { order.OrderID = f.StringValue; } else if (f.FieldInfo.Name == "CURRENT_STATUS") { order.Status = f.StringValue; } else if (f.FieldInfo.Name == "DISP_NAME") { order.Symbol = f.StringValue; } else if (f.FieldInfo.Name == "VOLUME") { order.lQty = f.IntValue; } else if (f.FieldInfo.Name == "VOLUME_TRADED") { order.lQtyTraded = f.IntValue; } else if (f.FieldInfo.Name == "BUYORSELL") { order.Side = f.StringValue; } else if (f.FieldInfo.Name == "AVG_PRICE") { order.dPrice = f.DoubleValue; } else if (f.FieldInfo.Name == "WORKING_QTY") { order.lWorking = f.LongValue; } else if (f.FieldInfo.Name == "ORDER_TAG") { order.OrderTag = f.StringValue; } else if (f.FieldInfo.Name == "PORTFOLIO_NAME") { order.Portfolio = f.StringValue; } else if (f.FieldInfo.Name == "TRDPRC_1") { order.ArrivalPrice = f.PriceValue; } else if (f.FieldInfo.Name == "TS3_CONVERSION_RULE_FLAGS") { order.ConversionRuleFlags = (ulong)f.LongValue; } else if (f.FieldInfo.Name == "TICKET_ID") { order.TicketID = f.StringValue; } } ProcessOrder(order, bRequest); } if (bRequest) // when we get a data refesh, re-publish all stats { foreach (KeyValuePair <string, OrderStats> s in Stats) { OrderStats stats = s.Value; // Fire event to publish the result StatsChanged?.Invoke(s.Key, stats); } } }