public TTInstrument CreateInstrument(string marketName, string productTypeName, string productName, string contractName) { string tag = TTHelper.GetUniqueTag(); EventInstruments.Instance.CreateInstrument(marketName, productTypeName, productName, contractName, tag); /*InstrumentDescriptor descriptor = new InstrumentDescriptor(marketName, productTypeName, productName, contractName); * string tag = TTHelper.GetUniqueTag(); * SubscribeToInstrument(descriptor, tag);*/ TTInstrument tti = null; // Loop here to wait for the order to be returned via the API callbacks const int TIMEOUT_COUNT = 100; for (int i = 0; i < TIMEOUT_COUNT; i++) { if (sentInstrumentRequests.ContainsKey(tag)) { tti = sentInstrumentRequests[tag]; sentInstrumentRequests.Remove(tag); for (int j = 0; j < TIMEOUT_COUNT; j++) { if (tti.Last.IsValid == true) { break; } Thread.Sleep(50); } break; } Thread.Sleep(100); } return(tti); }
void api_OnInstrumentFound(TTInstrument ttInstrument, bool success) { //cross thread - so you don't get the cross theading exception if (this.InvokeRequired) { this.BeginInvoke((MethodInvoker) delegate { api_OnInstrumentFound(ttInstrument, success); }); return; } if (success) { //TTInstrument ttInstrument = new TTInstrument(instrument.Key); if (!ttInstruments.ContainsKey(ttInstrument.Key)) { ttInstruments[ttInstrument.Key] = ttInstrument; } Message("Subscribed to " + ttInstrument.Name); btnPrices.Enabled = true; } else { string errorMsg = ""; /*if (e.Error != null) * errorMsg = e.Error.Message;*/ // Instrument not found and TTAPI has given up looking for it MessageBox.Show(this, "Could not find instrument:\n\n" + ttInstrument.Name + "\n\n" + errorMsg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
private void btnPrices_Click(object sender, EventArgs e) { foreach (InstrumentKey key in ttInstruments.Keys) { TTInstrument tti = ttInstruments[key]; Message(string.Format("{0}:{1} {2}:{3}", tti.BidQty, tti.Bid, tti.Ask, tti.AskQty)); } }
void its_ProfitLossChanged(object sender, ProfitLossChangedEventArgs e) { if (e.TradeSubscription.Tag != null) { TTInstrument tti = e.TradeSubscription.Tag as TTInstrument; tti.Profit = e.TradeSubscription.ProfitLoss.AsPrimaryCurrency; } //Message("PROFIT: " + string.Format("{0}", e.TradeSubscription.ProfitLoss)); }
public TTOrder SendOrder(TTInstrument instrument, BuySell buySell, OrderType orderType, Quantity quantity, Price price) { TTOrder tto = null; OrderRoute orderRoute = instrument.OrderRoute; // If the order route has not been set for this instrument, see if there is // an OrderRouteInfo for this market (user sets using SetOrderRouteInfo method) if (instrument.OrderRoute == null && orderRouteInfo.ContainsKey(instrument.Market.Name)) { OrderRouteInfo info = orderRouteInfo[instrument.Market.Name]; string orderFeedName = info.OrderFeedName; AccountType accountType = (AccountType)Enum.Parse(typeof(AccountType), info.AccountTypeName); string accountName = info.AccountName; OrderFeed feedToUse = null; foreach (OrderFeed feed in instrument.EnabledOrderFeeds) { if (feed.Name.Equals(orderFeedName)) { feedToUse = feed; break; } } orderRoute = new OrderRoute(feedToUse, accountType, accountName); } OrderProfile prof = new OrderProfile(orderRoute.OrderFeed, instrument.TTAPI_Instrument); prof.BuySell = buySell; prof.OrderType = orderType; prof.OrderQuantity = quantity; prof.LimitPrice = price; prof.AccountType = orderRoute.AccountType; prof.AccountName = orderRoute.AccountName; string tag = TTHelper.GetUniqueTag(); prof.OrderTag = tag; instrument.TTAPI_Instrument.Session.SendOrder(prof); // Loop here to wait for the order to be returned via the API callbacks const int TIMEOUT_COUNT = 300; for (int i = 0; i < TIMEOUT_COUNT; i++) { if (sentOrders.ContainsKey(tag)) { tto = sentOrders[tag]; sentOrders.Remove(tag); break; } Thread.Sleep(10); } return(tto); }
/// <summary> /// Retrieve an instrument (TTInstrument) given an InstrumentKey /// </summary> /// <param name="key">Instrument key to look up</param> /// <returns>TTInstrument object associated with the specified InstrumentKey</returns> public TTInstrument GetInstrument(InstrumentKey key) { TTInstrument result = null; if (ttInstruments.ContainsKey(key)) { result = ttInstruments[key]; } return(result); }
void instrumentLookupRequest_Update(object sender, InstrumentLookupSubscriptionEventArgs e) { TTInstrument tti; Console.WriteLine("ILR_Update on Thread"); if (e.Instrument != null && e.Error == null) { Console.WriteLine("SUBSCRIBED on thread: " + e.Instrument.Name); // successfully subscribed to an instrument so request prices if (e.Instrument.Key.IsAutospreader) { tti = processSpreadFound(e.Instrument); } else { tti = processInstrumentFound(e.Instrument); // If this instrument request was tagged, then put this instrument request // in sentInstrumentRequests with the tag as the key InstrumentLookupSubscription instrumentRequest = sender as InstrumentLookupSubscription; string tag = instrumentRequest.Tag as string; if (tag != null && !tag.Equals("")) { _sentInstrumentRequests[tag] = tti; } } if (OnInstrumentFound != null) { OnInstrumentFound(tti, true); } } else if (e.IsFinal) { Console.WriteLine("{0} {1}", e.RequestInfo.IsByName, e.RequestInfo.InstrumentName); // Instrument was not found and TTAPI has given up looking for it if (e.Instrument == null) { tti = null; } else { tti = new TTInstrument(e.Instrument); } if (OnInstrumentFound != null) { OnInstrumentFound(tti, false); } } }
/// <summary> /// Retrieve a TTInstrument whose name contains the string value passed. /// </summary> /// <param name="search">text to look for in the instrument name (i.e. 'CL' or 'CL Nov12')</param> /// <returns>a TTInstrument whose name contains your text (if one exists)</returns> public TTInstrument GetInstrument(string search) { TTInstrument result = null; foreach (TTInstrument tti in ttInstruments.Values) { if (tti.Name != null && tti.Name.ToUpper().Contains(search.ToUpper())) { result = tti; break; } } return(result); }
void api_OnInsideMarketUpdate(TTInstrument instrument) { //cross thread - so you don't get the cross theading exception if (this.InvokeRequired) { this.BeginInvoke((MethodInvoker) delegate { api_OnInsideMarketUpdate(instrument); }); return; } //InstrumentKey key = instrument.Key; //TTInstrument tti = ttInstruments[key]; }
private TTInstrument NewTTInstrument(Instrument instrument) { TTInstrument tti; if (_ttInstruments.ContainsKey(instrument.Key)) { tti = _ttInstruments[instrument.Key]; } else { tti = new TTInstrument(instrument); _ttInstruments.Add(instrument.Key, tti); } // Initialize any TTInstrument fields here: tti.TTAPI_Instrument = instrument; tti.Name = instrument.Name; return(tti); }
TTInstrument processInstrumentFound(Instrument instrument) { Dispatcher dispatcher = Dispatcher.Current; //Dispatcher dispatcher = _dispatcher; PriceSubscription priceSub = new PriceSubscription(instrument, dispatcher); if (SubscribeMarketDepth == true) { priceSub.Settings = new PriceSubscriptionSettings(PriceSubscriptionType.MarketDepth); } else { priceSub.Settings = new PriceSubscriptionSettings(PriceSubscriptionType.InsideMarket); } priceSub.FieldsUpdated += new FieldsUpdatedEventHandler(priceSub_FieldsUpdated); priceSub.Start(); InstrumentTradeSubscription its = new InstrumentTradeSubscription(_apiSession, dispatcher, instrument); its.EnablePNL = true; its.ProfitLossChanged += new EventHandler <ProfitLossChangedEventArgs>(its_ProfitLossChanged); its.Start(); if (SubscribeTimeAndSales == true) { TimeAndSalesSubscription tsSub = new TimeAndSalesSubscription(instrument, dispatcher); tsSub.Update += new EventHandler <TimeAndSalesEventArgs>(tsSub_Update); tsSub.Start(); } TTInstrument tti = NewTTInstrument(instrument); tti.TradeSubscription = its; its.Tag = tti; tti.OrderRoute = OrderRoute.GetOrderRoute(tti, instrument.Product.Market.Name); return(tti); }
public TTInstrument CreateInstrument(string instrumentName) { TTInstrument tti = null; string[] items = instrumentName.Split(' '); if (items.Length != 3 && items.Length != 4) { return(tti); } if (items.Length == 4) { tti = CreateInstrument(items[0], items[1], items[2], items[3]); } else // length == 3 { // Assume this is a future if no product type provided tti = CreateInstrument(items[0], "FUTURE", items[1], items[2]); } return(tti); }
void tsSub_Update(object sender, TimeAndSalesEventArgs e) { if (e.Error == null) { TTInstrument tti = _ttInstruments[e.Instrument.Key]; Price ltp; Quantity ltq; DateTime timestamp; TradeDirection direction; bool isOTC; foreach (TimeAndSalesData tsData in e.Data) { timestamp = tsData.TimeStamp; ltp = tsData.TradePrice; ltq = tsData.TradeQuantity; direction = tsData.Direction; isOTC = tsData.IsOverTheCounter; if (OnTimeAndSales != null) { OnTimeAndSales(tti, timestamp, ltp, ltq, direction, isOTC); } } } }
void processFill(FillOriginator originator, FillAction action, Fill fill, params Fill[] fills) { TTFill newFill = null; /* * fill.BuySell; * fill.FFT2; * fill.FFT3; * fill.FillKey; * fill.FillType; * fill.InstrumentKey; * fill.IsHedge; // autospreader hedge order * fill.IsQuoting; // autospreader quoting order * fill.MatchPrice; * fill.Quantity; * fill.SpreadId; * fill.TransactionDateTime; */ // If this is the first fill for this instrument, then add it to our list and // subscribe to the instrument updates if AutoSubscribeInstruments is true. if (!_ttInstruments.ContainsKey(fill.InstrumentKey)) { if (AutoSubscribeInstruments) { //TODO: Make the subscribe to instrument work //SubscribeToInstrument(fill.InstrumentKey); /*InstrumentLookupSubscription ils = new InstrumentLookupSubscription(apiSession, Dispatcher.Current, fill.InstrumentKey); * ils.Update += new EventHandler<InstrumentLookupSubscriptionEventArgs>(ils_Update); * ils.Start();*/ } TTInstrument tti = new TTInstrument(fill.InstrumentKey); _ttInstruments.Add(fill.InstrumentKey, tti); } TTFill ttf = NewTTFill(fill); #region LOOK FOR '#' IN THE FFT FIELDS // See if this fill contains our '#' hashtag in either FFT field. string hashField = null; if (fill.FFT2.StartsWith("#")) { hashField = fill.FFT2; } if (fill.FFT3.StartsWith("#")) { hashField = fill.FFT3; } // If we found a valid '#' hashtag value, then put it in our dropdown combo box. if (hashField != null) { // Add this fill to our list of fills with this same hashsymbol if (!_hashSymbols.ContainsKey(hashField)) { _hashSymbols.Add(hashField, new List <Fill>()); } List <Fill> hashFills = _hashSymbols[hashField]; hashFills.Add(fill); } #endregion // There are definitely times when the fill key already exists in the dictionary. In those // cases I am just overwriting the previous fill with the new one (asuming it is an updated // fill or whatever). _currentTTFills[fill.FillKey] = ttf; if (OnFill != null) { OnFill(originator, action, _ttInstruments[fill.InstrumentKey], ttf, newFill); } }
void processOrder(TTOrderStatus status, Order order, params Order[] orders) { TTOrder oldOrder = null; // If this order's instrument is not yet in our dictionary, then add the instrument // to our list and subscribe to the instrument updates if AutoSubscribeInstruments // is true. if (!_ttInstruments.ContainsKey(order.InstrumentKey)) { if (AutoSubscribeInstruments) { //TODO: figure out how to subscribe to instruments here //SubscribeToInstrument(order.InstrumentKey); /*InstrumentLookupSubscription ils = new InstrumentLookupSubscription(apiSession, Dispatcher.Current, order.InstrumentKey); * ils.Update += new EventHandler<InstrumentLookupSubscriptionEventArgs>(ils_Update); * ils.Start();*/ } TTInstrument tti = new TTInstrument(order.InstrumentKey); _ttInstruments.Add(order.InstrumentKey, tti); } TTOrder tto; if (_workingTTOrders.ContainsKey(order.SiteOrderKey)) { tto = _workingTTOrders[order.SiteOrderKey]; } else { tto = NewTTOrder(order); } tto.Status = status; string orderKey = tto.Key; // Maintain our working orders switch (status) { case TTOrderStatus.Added: _workingTTOrders[orderKey] = tto; break; case TTOrderStatus.Deleted: case TTOrderStatus.Filled: case TTOrderStatus.Rejected: _workingTTOrders.Remove(orderKey); break; case TTOrderStatus.Updated: oldOrder = tto.Clone(); tto.TTAPI_Order = orders[0]; //newOrder = NewTTOrder(orders[0]); string newOrderKey = orders[0].SiteOrderKey; _workingTTOrders.Remove(orderKey); _workingTTOrders.Add(newOrderKey, tto); System.Diagnostics.Debug.Assert(orderKey.Equals(newOrderKey)); break; } // When we send an order using the SendOrder method, the method creates a // unique OrderTag and then blocks waiting for that order to be "created". // It waits for it to appear in the sentOrders dictionary with the OrderTag // that was generated as the key. This is the only way I could deduce to // be able to return a TTOrder object to the caller of SendOrder since all // the order sending methods appear to be asynchronous. if (!order.OrderTag.Equals("")) { _sentOrders[order.OrderTag] = tto; } //Console.WriteLine("Working orders size: {0}", workingTTOrders.Count); if (OnOrder != null) { OnOrder(status, _ttInstruments[order.InstrumentKey], tto, oldOrder); } }
public TTOrder SellMarket(TTInstrument tti, int quantity) { Instrument instr = tti.TTAPI_Instrument; return(SendOrder(tti, BuySell.Sell, OrderType.Market, Quantity.FromInt(instr, quantity), Price.Invalid)); }
public TTOrder SellLimit(TTInstrument tti, int quantity, double price) { Instrument instr = tti.TTAPI_Instrument; return(SendOrder(tti, BuySell.Sell, OrderType.Limit, Quantity.FromInt(instr, quantity), Price.FromDouble(instr, price))); }
void priceSub_FieldsUpdated(object sender, FieldsUpdatedEventArgs e) { if (e.Error == null) { // A full snapshot update occurs when the TTAPI loses and restores its connection // with a TT Gateway or associated Exchange. // If you modify the ProductSubscription.Settings property, the TTAPI automatically // stops and restarts the subscription with the new settings. The TTAPI does not deliver // updates during the restart process. /* * if (e.UpdateType == UpdateType.Snapshot) * ; * else * e.UpdateType == UpdateType.Update; */ InstrumentKey key = e.Fields.Instrument.Key; TTInstrument tti = _ttInstruments[key]; tti.Bid = e.Fields.GetDirectBidPriceField().Value; tti.BidQty = e.Fields.GetDirectBidQuantityField().Value; tti.Ask = e.Fields.GetDirectAskPriceField().Value; tti.AskQty = e.Fields.GetDirectAskQuantityField().Value; tti.Last = e.Fields.GetLastTradedPriceField().Value; tti.LastQty = e.Fields.GetLastTradedQuantityField().Value; tti.Open = e.Fields.GetOpenPriceField().Value; tti.High = e.Fields.GetHighPriceField().Value; tti.Low = e.Fields.GetLowPriceField().Value; tti.Close = e.Fields.GetClosePriceField().Value; tti.NetChange = e.Fields.GetNetChangeField().Value; tti.NetChangePercent = e.Fields.GetNetChangePercentField().Value; tti.Volume = e.Fields.GetTotalTradedQuantityField().Value; if (OnInsideMarketUpdate != null) { OnInsideMarketUpdate(tti); } if (SubscribeMarketDepth == true) { if (tti.MarketDepth == null) { int maxDepthCount = e.Fields.GetLargestCurrentDepthLevel(); tti.MarketDepth = new TTMarketDepth(maxDepthCount); } for (int i = 0; i < tti.MarketDepth.DepthCount; i++) { tti.MarketDepth[i].Bid = e.Fields.GetDirectBidPriceField(i).Value; tti.MarketDepth[i].BidQty = e.Fields.GetDirectBidQuantityField(i).Value; tti.MarketDepth[i].Ask = e.Fields.GetDirectAskPriceField(i).Value; tti.MarketDepth[i].AskQty = e.Fields.GetDirectAskQuantityField(i).Value; } if (OnMarketDepthUpdate != null) { OnMarketDepthUpdate(_ttInstruments[key], tti.MarketDepth); } } } else { if (e.Error.IsRecoverableError == false) { if (OnSystemMessage != null) { OnSystemMessage(SystemMessage.UNRECOVERABLE_PRICE_ERROR); } } } }