/// <summary> /// Write Data to file /// </summary> /// <param name="dataObject"> Tick Or Bar Object</param> public void Write(MarketDataEvent dataObject) { try { //TODO: Safty Cast if (dataObject is DetailBar) { //TODO : NULL Reference Check For CreateDirectoryPath var newBar = (DetailBar)dataObject; using (var fileStream = new FileStream(CreateDirectoryPathForBarObject(newBar.Security.Symbol, newBar, newBar.MarketDataProvider) + ".obj", FileMode.Append)) { var bFormatter = new BinaryFormatter(); bFormatter.Serialize(fileStream, newBar); fileStream.Close(); } } else if (dataObject is Tick) { var newTick = (Tick)dataObject; using (var fileStream = new FileStream(CreateDirectoryPath(newTick.Security.Symbol, MarketDataType.Tick, newTick.MarketDataProvider) + ".obj", FileMode.Append)) { var bFormatter = new BinaryFormatter(); bFormatter.Serialize(fileStream, newTick); fileStream.Close(); } } } catch (Exception exception) { Logger.Error(exception, _oType.FullName, "Write"); } }
/// <summary> /// Check all orders in the pending queue, and execute if price condition is met. /// This is called by the OrderEvents websocket /// </summary> /// <param name="currency"></param> /// <param name="data"></param> public static void CheckPendingOrders(string currency, MarketDataEvent data) { Parallel.ForEach(Pending, order => { var price = decimal.Parse(order.Price); if (order.Symbol == currency) { if (order.Side == "buy") { /* If currenct price is above the stop-buy price, execute */ if (price <= data.Price) { order.Price = (data.Price + 0.01M).ToString(); order.ClientOrderID += "STOP"; order.Options = new string[] { "immediate-or-cancel" }; GeminiClient.PlaceOrder(order); Pending.Remove(order); } } else { /* if curenct price is below the stop-loss price, execute */ if (price >= data.Price) { /* Decrease by 10, since this is still viewed as a limit order * by the server, and this increases our chances of getting filled */ order.Price = (data.Price - 0.01M).ToString(); order.ClientOrderID += "STOP"; GeminiClient.PlaceOrder(order); Pending.Remove(order); } } } }); }
private string price_str(string currency, MarketDataEvent e) { if (LastTrades[currency] != null) { var diff = " (" + (e.Price - LastTrades[currency].Price).ToString("+0.00;-0.00") + ")"; return(e.Price.ToString() + diff); } return(e.Price.ToString()); }
/// <summary> /// Update the connection status label with current prices /// </summary> private void UpdateTicker(string currency, MarketDataEvent e) { var ticker = Symbols .Aggregate(new StringBuilder(), (sb, s) => sb.Append(String.Format("{0}: {1} ", s.ToUpper(), s == currency ? e.Price : LastTrades[s]?.Price)), sb => sb.ToString()); connectionStatusLabel.Text = String.Format("Connected: {0} {1}", GeminiClient.Wallet.Key(), ticker); if (currency == null) { tbBtcUsdPrice.Text = LastTrades["btcusd"]?.Price.ToString(); tbEthUsdPrice.Text = LastTrades["ethusd"]?.Price.ToString(); tbEthBtcPrice.Text = LastTrades["ethbtc"]?.Price.ToString(); } else if (currency == "btcusd") { tbBtcUsdPrice.Text = price_str(currency, e); if (e.Price - LastTrades[currency].Price > 0) { tbBtcUsdPrice.ForeColor = System.Drawing.Color.Green; } else { tbBtcUsdPrice.ForeColor = System.Drawing.Color.Red; } } else if (currency == "ethbtc") { tbEthBtcPrice.Text = price_str(currency, e); if (e.Price - LastTrades[currency].Price > 0) { tbEthBtcPrice.ForeColor = System.Drawing.Color.Green; } else { tbEthBtcPrice.ForeColor = System.Drawing.Color.Red; } } else if (currency == "ethusd") { tbEthUsdPrice.Text = price_str(currency, e); if (e.Price - LastTrades[currency].Price > 0) { tbEthUsdPrice.ForeColor = System.Drawing.Color.Green; } else { tbEthUsdPrice.ForeColor = System.Drawing.Color.Red; } } tbBtcUsdVwap.Text = V["btcusd"] != 0 ? Math.Round(PV["btcusd"] / V["btcusd"], 2).ToString() : "Calculating"; tbEthUsdVwap.Text = V["ethusd"] != 0 ? Math.Round(PV["ethusd"] / V["ethusd"], 2).ToString() : "Calculating"; tbEthBtcVwap.Text = V["ethbtc"] != 0 ? Math.Round(PV["ethbtc"] / V["ethbtc"], 4).ToString() : "Calculating"; }
/// <summary> /// Seed the last trade dictionary /// </summary> public void InitialPrices() { Parallel.ForEach(Symbols, s => { var t = GeminiClient.GetTicker(s); LastTrades[s] = new MarketDataEvent() { Price = t.Last, }; PV[s] = t.Volume.Currency2; V[s] = t.Volume.Currency1; }); UpdateTicker(null, null); }
/// <summary> /// Handles market data request reject /// </summary> /// <param name="reject"></param> /// <param name="sessionId"></param> private void OnMessage(QuickFix.FIX43.MarketDataRequestReject reject, SessionID sessionId) { try { //MarketDataReject marketDataReject = new MarketDataReject(reject.MDReqID.getValue(), reject.MDReqRejReason.getValue(), reject.Text.getValue()); MarketDataEvent marketDataReject = new MarketDataEvent(new Security(), _provider); if (MarketDataRejectionArrived != null) { MarketDataRejectionArrived(marketDataReject); } } catch (Exception exception) { Logger.Error(exception.ToString(), _type.FullName, "OnMessage"); } }
/// <summary> /// Writes Data to csv file. /// Main Purpose of this Methord is to /// check that if data is Bar or Tick /// and handle is Respectively /// </summary> /// <param name="dataObject">Bar Or Tick</param> public void Write(MarketDataEvent dataObject) { try { if (dataObject is HistoricBarData) { WriteHistoricBarsToFile(dataObject as HistoricBarData); } else if (dataObject is Bar) { WriteBarDataToCsvFile(dataObject as DetailBar); } else if (dataObject is Tick) { var newTick = dataObject as Tick; WriteTickToCsvFile(newTick); } } catch (Exception exception) { Logger.Error(exception, _oType.FullName, "WriteToFile"); } }
private static void ApplicationControlOnDataArrived(MarketDataEvent newdata) { Console.WriteLine(newdata); }