using System; using System.Collections.Generic; using IBApi; namespace Backend.MarketDataRequest { public enum LiveMarketDataType { RealTime = 1, Frozen = 2, Delayed = 3, DelayedFrozen = 4 } public sealed class LiveEquityRequest { public int RequestId { get; set; } public string Symbol { get; set; } = string.Empty; public string Exchange { get; set; } = "SMART"; public string PrimaryExchange { get; set; } = "NASDAQ"; public string Currency { get; set; } = "USD"; /// /// Generic ticks string, e.g. "233,236" /// Leave empty for standard top-of-book. /// public string GenericTickList { get; set; } = string.Empty; public bool Snapshot { get; set; } = false; public bool RegulatorySnapshot { get; set; } = false; public LiveMarketDataType MarketDataType { get; set; } = LiveMarketDataType.RealTime; public void Send(IBGatewayControl gateway) { if (gateway == null) { throw new ArgumentNullException(nameof(gateway)); } if (!gateway.IsConnected) { throw new InvalidOperationException("IB Gateway is not connected."); } if (string.IsNullOrWhiteSpace(Symbol)) { throw new ArgumentException("Symbol cannot be empty."); } gateway.Client.reqMarketDataType((int)MarketDataType); var contract = BuildContract(); gateway.Client.reqMktData( RequestId, contract, GenericTickList, Snapshot, RegulatorySnapshot, new List() ); } public void Cancel(IBGatewayControl gateway) { if (gateway == null) { throw new ArgumentNullException(nameof(gateway)); } if (!gateway.IsConnected) { throw new InvalidOperationException("IB Gateway is not connected."); } gateway.Client.cancelMktData(RequestId); } private Contract BuildContract() { return new Contract { Symbol = Symbol, SecType = "STK", Exchange = Exchange, PrimaryExch = PrimaryExchange, Currency = Currency }; } } }