// TWS message response to real-time data: Last update private static void Ibclient_tickByTickAllLast(messages.TickByTickAllLastMessage last) { // This request id will be active as long as the data subscription is valid GooContract c = GetDataRequestContract(last.ReqId, false); c.Last = last.Price; }
/// <summary> /// Download all available historical data for a given contract from TWS server /// </summary> /// <param name="c"></param> public static void GetHistoricalData(GooContract c) { // Historical data is retrieved using a state machine var e = new FSM_EventArgs.GooContract_With_Payload(c); c.FSM.DownloadHistoricalData.Start(e); }
/// <summary> /// Request full contract details based on some initial specifications. /// Enough info should be provided so that only a single instrument type (FUT,Stock) will be returned. /// </summary> public static GooContract GetContractDetails(string symbol, string sectype, string primaryExchange) { // This is a throw-away contract used for requesting information. TWS will return ones that are fully populated IBApi.Contract requestContract = new Contract(); requestContract.Symbol = symbol; requestContract.SecType = sectype; requestContract.Exchange = primaryExchange; var reqId = GetOrderId(); // New blank GooContract. TWS ContractDetails event will populate it. GooContract c = new GooContract(); string contractKey = GetContractKey(requestContract); // Internal list if (contracts.ContainsKey(contractKey) == false) { contracts.Add(contractKey, c); } // Transmit request for details of all contracts as described above. Info will be returned via TWS events. AddContractRequest(reqId, contractKey); ibclient.ClientSocket.reqContractDetails(reqId, requestContract); // We can look it up with the contract key as well. return(c); }
// Real-time data #region Live Data // TWS message response to real-time data: Bid/Ask update private static void Ibclient_tickByTickBidAsk(messages.TickByTickBidAskMessage bidask) { // This request id will be active for as long as the data subscription is valid GooContract c = GetDataRequestContract(bidask.ReqId, false); c.Bid = bidask.BidPrice; c.Ask = bidask.AskPrice; }
/// <summary> /// Get a new request id and associate a contract with it. /// </summary> /// <param name="c"></param> /// <returns>new request id</returns> private static int AddContractRequest(GooContract c) { int reqId = GetOrderId(); AddContractRequest(reqId, c); // Return in case it is needed for use in a TWS call. return(reqId); }
// Received final packet of data for the duration requested in the current historical data request. private static void Ibclient_HistoricalDataEnd(messages.HistoricalDataEndMessage hDataEnd) { // Data request is now completed = delete GooContract c = GetDataRequestContract(hDataEnd.RequestId, true); var e = new FSM_EventArgs.GooContract_With_Payload(c); c.FSM.DownloadHistoricalData.FireEvent(FSM_DownloadHistoricalData.Events.HistoricalDataEnd, e); }
/// <summary> /// Wrapper to request historical data starting point for a given contract /// </summary> /// <param name="c"></param> public static void RequestHeadTimeStamp(GooContract c) { int id_historical = GetOrderId(); AddContractRequest(id_historical, c); var ib_contract = c.TWSActiveContractDetails.Contract; ibclient.ClientSocket.reqHeadTimestamp(id_historical, ib_contract, TWSInfo.WhatTicksToShow.Trades, TWSInfo.UseRealTimeHoursOnly.No, TWSInfo.TimeStampType.Standard); }
// TWS message response to request for how much data is available. Returns timestamp of furthest out data. private static void Ibclient_HeadTimestamp(messages.HeadTimestampMessage headTimeStamp) { // Get contract. This request is finished, so don't need any more. GooContract c = GetDataRequestContract(headTimeStamp.ReqId, true); // Send event to the download FSM to tell it the head time stamp has been received from TWS. var e = new FSM_EventArgs.GooContract_With_Payload(c, headTimeStamp.HeadTimestamp); c.FSM.DownloadHistoricalData.FireEvent(FSM_DownloadHistoricalData.Events.HeadTimeStamp, e); }
// Received packet of historical data from TWS private static void Ibclient_HistoricalData(messages.HistoricalDataMessage hData) { // Data request is valid until HistoricalDataEnd is received. GooContract c = GetDataRequestContract(hData.RequestId, false); // Package the quote and send the data received event to the state machine. OHLCQuote quote = new OHLCQuote(hData.Date, hData.Open, hData.High, hData.Low, hData.Close); var e = new FSM_EventArgs.GooContract_With_Payload(c, quote); c.FSM.DownloadHistoricalData.FireEvent(FSM_DownloadHistoricalData.Events.HistoricalData, e); }
/// <summary> /// Get contract associated with the data request /// </summary> /// <param name="reqId">request Id to associate (int)</param> /// <param name="deleteAfterUse">true=>remove after lookup</param> /// <returns></returns> private static GooContract GetDataRequestContract(int reqId, bool deleteAfterUse) { string contractKey = datarequests[reqId]; GooContract c = contracts[contractKey]; // No need to keep track of this request any more if it was single-use only. if (deleteAfterUse == true) { datarequests.Remove(reqId); } return(c); }
/// <summary> /// Wrapper to request historical data. Can be used from FSM /// </summary> /// <param name="c"></param> /// <param name="downloadDate">start date (DateTime)</param> /// <param name="twsinfo_stepsize">Duration (TWSInfo.TWS_StepSizes</param> /// <param name="twsinfo_barsize">Data bar size (TWSInfo.TWS_BarSizeSetting)</param> public static void RequestHistoricalData(GooContract c, DateTime downloadDate, string twsinfo_stepsize, string twsinfo_barsize) { // Get a new order id for historical data request int histDataReqId = AddContractRequest(c); // TWS requires date to be in a specific format, so must convert from DateTime var startStr = downloadDate.ToString(TWSInfo.TimeStampStringFormat); // Submit request to tws based on the desired download criteria for the active contract ibclient.ClientSocket.reqHistoricalData(histDataReqId, c.TWSActiveContractDetails.Contract, startStr, twsinfo_stepsize, twsinfo_barsize, TWSInfo.WhatTicksToShow.Trades, 0, 1, false, null); }
/// <summary> /// Wrapper to request tick market data (Level I bid/ask/last) /// </summary> /// <param name="cd"></param> public static void RequestTickData(GooContract c) { int id_last = GetOrderId(); int id_bidask = GetOrderId(); var ib_contract = c.TWSActiveContractDetails.Contract; string contractKey = GetContractKey(ib_contract); AddContractRequest(id_last, c); AddContractRequest(id_bidask, c); ibclient.ClientSocket.reqTickByTickData(id_last, ib_contract, TWSInfo.TickType.Last, 0, false); ibclient.ClientSocket.reqTickByTickData(id_bidask, ib_contract, TWSInfo.TickType.BidAsk, 0, false); }
// TWS response for a single instance of contractDetails for a given request private static void Ibclient_ContractDetails(messages.ContractDetailsMessage msg_cd) { ContractDetails cd = msg_cd.ContractDetails; string contractKey = GetContractKey(cd.Contract); // Keep the request active until end is signaled by ContractDetailsEnd event. GooContract c = GetDataRequestContract(msg_cd.RequestId, false); // TWS returns contracts in calendar order (front month first) so we preserve the order. c.TWSContractDetailsList.Add(cd); MessageLogger.LogMessage(String.Format("ContractDetails request {0}: {1}", msg_cd.RequestId.ToString(), contractKey)); }
// TWS has replied with all available contract details for a given request Id private static void Ibclient_ContractDetailsEnd(int reqId) { // Details end means this request is done, so delete after it is accessed. GooContract c = GetDataRequestContract(reqId, true); // TODO: Active month is front month. Near expiration this may not be the best. c.TWSActiveContractDetails = c.TWSContractDetailsList[0]; // Some details we want to break out for the UI c.Expiration = c.TWSActiveContractDetails.ContractMonth; c.Name = c.TWSActiveContractDetails.LongName; c.Symbol = c.TWSActiveContractDetails.MarketName; string contractKey = GetContractKey(c.TWSActiveContractDetails.Contract); // Notify outside world that a new contract has been created and pass along the contractkey and GooContract. OnNewContract?.Invoke(contractKey, c); MessageLogger.LogMessage(String.Format("ContractDetails request {0} completed", reqId.ToString())); }
private void btnReqContracts_Click(object sender, RoutedEventArgs e) { sp500 = TWS.GetContractDetails("ES", "FUT", TWSInfo.Exchanges.Globex); nq100 = TWS.GetContractDetails("NQ", "FUT", TWSInfo.Exchanges.Globex); }
/// <summary> /// Associate contract with a specifc request id /// </summary> /// <param name="reqId"></param> /// <param name="c"></param> private static void AddContractRequest(int reqId, GooContract c) { string contractKey = GetContractKey(c.TWSActiveContractDetails.Contract); AddContractRequest(reqId, contractKey); }
// Constructor public FSM_DownloadHistoricalData(GooContract c) : base(typeof(States), typeof(Events), Transitions, typeof(Action <FSM_EventArgs.GooContract_With_Payload>), c) { }
public TWSFiniteStateMachines(GooContract c) { // state machines need the contract so it can be accessed during execution of the FSM. DownloadHistoricalData = new FSM_DownloadHistoricalData(c); }
// Can remove default null if we want events to be explicit that there is no payload public GooContract_With_Payload(GooContract c, object p = null) { Contract = c; Payload = p; }