### Example: place order, wait for status, cancel on timeout Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/order-monitor.md Complete example showing how to create an InterReactClient with order placement enabled, get a market data snapshot, place a limit order, monitor for terminal status, and cancel on timeout. Requires AllowOrderPlacement = true. Uses OrderMonitor.Messages to observe alerts and order status reports. ```csharp IInterReactClient client = await InterReactClient.CreateAsync(options => { options.AllowOrderPlacement = true; }); Contract contract = new() { SecurityType = ContractSecurityType.Cash, Symbol = "EUR", Currency = "USD", Exchange = "IDEALPRO" }; // Snapshot ask price, then place a limit order at that price. PriceTick ask = (PriceTick)(await client.Service.GetMarketDataSnapshotAsync(contract)) .OfType().First(t => t.TickType == TickType.AskPrice); Order order = new() { Action = OrderAction.Buy, OrderType = OrderTypes.Limit, LimitPrice = ask.Price, TotalQuantity = 50000, }; OrderMonitor monitor = await client.Service.PlaceOrderAsync(order, contract); Console.WriteLine($"Placed order {monitor.OrderId}."); // Any alerts from TWS arrive on Messages: monitor.Messages.OfType() .Subscribe(a => Console.WriteLine($"Alert {a.Code}: {a.Message}")); try { // Wait for a terminal status. OrderStatusReport osr = await monitor.Messages .OfType() .Where(s => s.Status == OrderStatus.Filled || s.Status == OrderStatus.Cancelled || s.Status == OrderStatus.ApiCancelled) .Timeout(TimeSpan.FromSeconds(5)) .FirstAsync(); if (osr.Status == OrderStatus.Filled) Console.WriteLine($"Filled at {osr.AverageFillPrice} ({osr.Filled} / {osr.Remaining})."); else Console.WriteLine($"Order {osr.Status}. Why held: {osr.WhyHeld}"); } catch (TimeoutException) { await monitor.CancelOrderAsync(); // no fill within 5 s Console.WriteLine("Timed out — order cancelled."); } await client.DisposeAsync(); ``` -------------------------------- ### Basic usage example Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-contract-details.md Basic usage example that retrieves contract details and prints them, catching AlertException. ```csharp try { ContractDetails[] all = await client.Service.GetContractDetailsAsync(selector); for (ContractDetails cd : all) Console.WriteLine($"{cd.Contract.Symbol} on {cd.ValidExchanges} tick={cd.MinimumTick}"); } catch (AlertException ex) { Console.WriteLine($"Alert {ex.AlertMessage.Code}: {ex.AlertMessage.Message}"); } ``` -------------------------------- ### Typical production configuration Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/interreact-options.md Configures the InterReact client with typical production settings, including IP address, port, client ID, order placement, delayed ticks, optional capabilities, and logging. Use this as a starting point for a standard setup. ```csharp IInterReactClient client = await InterReactClient.CreateAsync(options => { options.TwsIpAddress = IPAddress.Parse("192.168.1.50"); options.TwsPortAddresses = [TwsDefaultPorts.RegularAccount]; // 7496 only options.TwsClientId = 42; options.AllowOrderPlacement = true; options.UseDelayedTicks = true; // keep Delayed* tick types options.OptionalCapabilities = ""; options.LogFactory = LoggerFactory.Create(builder => builder.AddSimpleConsole()); }); ``` -------------------------------- ### Example - read the latest ask price Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-market-data.md Uses CreateMarketDataSnapshotObservable to get the latest ask price. Filters for PriceTick and AskPrice, then prints the price. ```csharp PriceTick ask = await client.Service .CreateMarketDataSnapshotObservable(contract) .OfTickClass(s => s.PriceTick) .Where(t => t.TickType == TickType.AskPrice) .FirstAsync(); Console.WriteLine($"Ask = {ask.Price}"); ``` -------------------------------- ### Careful expiry usage example Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-contract-details.md Usage example with a future contract selector, a 15-second timeout, and cancellation token. ```csharp Contract futureSelector = new() { SecurityType = ContractSecurityType.Future, Symbol = "ES", Currency = "USD", Exchange = "GLOBEX", LastTradeDateOrContractMonth = "202412" // restrict to one contract month }; // Retrieve with a 15 s cap and cancellation. CancellationTokenSource cts = new(); cts.CancelAfter(TimeSpan.FromSeconds(15)); ContractDetails[] results = await client.Service.GetContractDetailsAsync( futureSelector, includeExpired: false, timeout: TimeSpan.FromSeconds(15), ct: cts.Token); ``` -------------------------------- ### Example: Requesting and Cancelling a Scanner Subscription Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/market-messages.md Demonstrates how to create a ScannerSubscription, request a scanner subscription, handle the ScannerData response, and cancel the subscription. ```APIDOC ## Example: Requesting and Cancelling a Scanner Subscription ### Description Demonstrates how to create a ScannerSubscription, request a scanner subscription, handle the ScannerData response, and cancel the subscription. ### Code ```csharp ScannerSubscription sub = new() { NumberOfRows = 10, Instrument = "STK", LocationCode = "us", ScanCode = "TOP_PERC_GAIN", MarketCapAbove = 100000000, }; int id = client.Request.GetNextId(); await client.Request.RequestScannerSubscriptionAsync(id, sub); client.Response.WithRequestId(id).OfTypeOnly().Subscribe(data => { for (ScannerDataItem item : data.Items) Console.WriteLine($"#{item.Rank} {item.ContractDetails.Contract.Symbol} {item.ContractDetails.MarketName}"); }); // ... later: await client.Request.CancelScannerSubscriptionAsync(id); ``` ``` -------------------------------- ### Example: GetAccountSummaryAsync with AlertException handling Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-account-and-misc.md Example usage of GetAccountSummaryAsync. It filters out end-marker rows and prints each row's Tag, Value, and Currency. Catches AlertException to report the alert message and code. ```csharp AccountSummary[] summary; try { summary = await client.Service.GetAccountSummaryAsync(); foreach (AccountSummary row in summary.Where(r => !r.IsEndMessage)) Console.WriteLine($"{row.Tag} {row.Value} {row.Currency}"); } catch (AlertException ex) { Console.WriteLine($"Request failed: {ex.AlertMessage.Message} ({ex.AlertMessage.Code})"); } ``` -------------------------------- ### Example - with timeout and cancellation Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-market-data.md Uses GetMarketDataSnapshotAsync with a 5-second timeout and a 10-second cancellation token. Catches TimeoutException if the snapshot does not complete in time. ```csharp using System.Reactive.Concurrency; CancellationTokenSource cts = new(); cts.CancelAfter(TimeSpan.FromSeconds(10)); IHasRequestId[] ticks; try { ticks = await client.Service.GetMarketDataSnapshotAsync( contract, genericTickTypes: [GenericTickType.RealtimeVolume], timeout: TimeSpan.FromSeconds(5), ct: cts.Token); } catch (TimeoutException) { Console.WriteLine("Snapshot did not complete in time."); } ``` -------------------------------- ### GetCache usage example Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Example of using GetCache to track the latest full map of account positions by account. It subscribes to the cached observable and prints the total position. ```csharp // Track the latest full map of account positions by account. IObservable caches = client.Service.AccountPositionsObservable.GetCache( a => $"{a.Account}:{a.Contract.ContractId}", a => a.IsEndMessage); caches.Subscribe(arr => Console.WriteLine($"{arr.Length} positions; total " + arr.Where(p => !p.IsEndMessage).Sum(p => p.Position))); ``` -------------------------------- ### Example: alerts surface on error paths Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-market-data.md Subscribes to market data with handlers for ticks/alerts, errors, and completion. Alerts surface on error paths. ```csharp client.Service.CreateMarketDataObservable(contract) .Subscribe( onNext: m => { /* IHasRequestId (ticks) or Alert */ }, onError: ex => Console.WriteLine("Error: " + ex.Message), onCompleted: () => Console.WriteLine("Completed")); ``` -------------------------------- ### InterReact client usage example Source: https://github.com/dshe/interreact/blob/master/README.md Shows how to connect to TWS/Gateway, create a stock contract, subscribe to last price ticks, and clean up. Requires TWS or Gateway running with API access enabled and 'Enable ActiveX and Socket Clients' selected. ```csharp using System; using System.Threading.Tasks; using System.Reactive.Linq; using InterReact; ``` ```csharp // Create the InterReact client by connecting to TWS/Gateway on the local host. IInterReactClient client = await InterReactClient.ConnectAsync(); // Create a contract object. Contract contract = new() { SecurityType = ContractSecurityType.Stock, Symbol = "AMZN", Currency = "USD", Exchange = "SMART" }; // Create and then subscribe to the observable which can observe ticks for the contract. IDisposable subscription = client .Service .CreateMarketDataObservable(contract) .OfTickClass(selector => selector.PriceTick) .Where(tick => tick.TickType == TickType.LastPrice) .Subscribe(onNext: priceTick => Console.WriteLine($"Last Price = {priceTick.Price}")); Console.WriteLine(Environment.NewLine + "press a key to exit..."); Console.ReadKey(); Console.Clear(); // Dispose the subscription to stop receiving ticks. subscription.Dispose(); // Disconnect from TWS/Gateway. await client.DisposeAsync(); ``` -------------------------------- ### GetManagedAccountsAsync usage example Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-account-and-misc.md Example usage of GetManagedAccountsAsync with a 10-second timeout. It retrieves the managed account codes and prints them joined by commas. ```csharp IReadOnlyList accounts = await client.Service.GetManagedAccountsAsync( timeout: TimeSpan.FromSeconds(10)); Console.WriteLine(accounts.JoinStrings(", ")); ``` -------------------------------- ### Example: Create contract selector and subscribe to details Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-contract-details.md Shows how to create a Contract selector for AMZN stock and subscribe to the observable, printing contract details. The subscription filters for ContractDetails messages and outputs contract ID, long name, and minimum tick. ```csharp Contract selector = new() { SecurityType = ContractSecurityType.Stock, Symbol = "AMZN", Currency = "USD", Exchange = "SMART" }; IObservable details = client.Service .CreateContractDetailsObservable(selector, includeExpired: false); details.OfTypeOnly().Subscribe(cd => Console.WriteLine($"{cd.Contract.ContractId} {cd.LongName} minTick={cd.MinimumTick}")); ``` -------------------------------- ### Example usage of JoinStrings and Stringify Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Shows how to use the JoinStrings and Stringify extension methods. JoinStrings joins an array of strings with a comma and space, and Stringify serializes an alert object to JSON. ```csharp Console.WriteLine(["a", "b", "c"].JoinStrings(", ")); // "a, b, c" Console.WriteLine(alert.Stringify()); // 'Alert {...}' JSON ``` -------------------------------- ### Request and cancel market depth example Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/market-messages.md Shows how to request market depth for a contract, subscribe to MarketDepth responses, and cancel the request later. Uses RequestMarketDepthAsync with numRows and isSmartDepth parameters, and filters responses by request ID. ```csharp int id = client.Request.GetNextId(); await client.Request.RequestMarketDepthAsync(id, contract, numRows: 5, isSmartDepth: false); client.Response.WithRequestId(id).OfTypeOnly() .Subscribe(md => { string op = md.Operation.ToString(); Console.WriteLine($"[{md.Position}] {op} {md.Side} {md.Price} x {md.Size} {md.MarketMaker}"); }); // ... later: await client.Request.CancelMarketDepthAsync(id); ``` -------------------------------- ### Example: Subscribe to market data and filter PriceTick Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-market-data.md Subscribes to market data for an AMZN stock contract, filters for PriceTick and LastPrice, and prints the last price. Disposes the subscription and client after a console read. ```csharp IInterReactClient client = await InterReactClient.CreateAsync(); Contract contract = new() { SecurityType = ContractSecurityType.Stock, Symbol = "AMZN", Currency = "USD", Exchange = "SMART" }; IDisposable subscription = client.Service .CreateMarketDataObservable(contract) .OfTickClass(selector => selector.PriceTick) .Where(tick => tick.TickType == TickType.LastPrice) .Subscribe(onNext: priceTick => Console.WriteLine($"Last Price = {priceTick.Price}")); await Console.In.ReadLineAsync(); subscription.Dispose(); await client.DisposeAsync(); ``` -------------------------------- ### OfTypeOnly usage example with ContractDetails Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Shows how to use OfTypeOnly to retrieve contract details, catching AlertException to handle alerts as exceptions. ```csharp try { ContractDetails[] cds = await client.Service .CreateContractDetailsObservable(contract) .OfTypeOnly() .ToArray(); } catch (AlertException ex) { Console.WriteLine($"{ex.AlertMessage.Code} {ex.AlertMessage.Message}"); } ``` -------------------------------- ### Example — current trading state Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/contract-details-time.md Creates a ContractDetailsTime from contract details, prints the time zone and each event, then retrieves and prints the current period's previous status and time. ```csharp ContractDetailsTime time = new(contractDetails); Console.WriteLine($"TimeZone: {time.TimeZone}"); foreach (ContractDetailsTimeEvent e in time.Events) Console.WriteLine($"{e.Time} -> {e.Status}"); ContractDetailsTimePeriod? now = time.Get(); if (now?.Previous != null) Console.WriteLine($"Now: {now.Previous.Value.Status} (since {now.Previous.Value.Time})"); ``` -------------------------------- ### Example — custom one-shot request Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Shows how to use ToObservable0 for a one-shot request that completes after the first CurrentTime value, with cancellation on dispose. ```csharp // Get current time as CurrentTime, cancelling on dispose. IObservable times = client.Response.ToObservable0( () => client.Request.RequestCurrentTimeAsync(), () => { }); CurrentTime ct = await times.FirstAsync(); // completes after first CurrentTime ``` -------------------------------- ### News flow example: enumerate providers, fetch article, and historical news Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/market-messages.md Shows how to enumerate news providers, fetch a news article by ID, and request historical news. Uses RequestNewsProvidersAsync, RequestNewsArticleAsync, and RequestHistoricalNewsAsync. HistoricalNews and HistoricalNewsEnd (codes 86/87) are documented in misc-messages.md. ```csharp // Enumerate providers, then fetch an article and historical headlines. client.Request.RequestNewsProvidersAsync(); client.Response.OfTypeOnly().Take(1).Subscribe(np => np.Providers.ForEach(p => Console.WriteLine($"{p.Code}: {p.Name}"))); int id = client.Request.GetNextId(); await client.Request.RequestNewsArticleAsync(id, providerCode: "FLY", articleId: "123456"); client.Response.WithRequestId(id).OfTypeOnly().Take(1) .Subscribe(a => Console.WriteLine($"Article type {a.ArticleType}:\n{a.ArticleText}")); int hid = client.Request.GetNextId(); await client.Request.RequestHistoricalNewsAsync(hid, contractId: contract.ContractId, providerCodes: "FLY", startTime: "", endTime: "", totalResults: 25); client.Response.WithRequestId(hid).OfTypeOnly() .TakeUntil(m => m is HistoricalNewsEnd) .Subscribe(n => Console.WriteLine($"{n.Time} [{n.ProviderCode}] {n.Headline} ({n.ArticleId})")); ``` -------------------------------- ### CacheSource usage example with AccountPositionsObservable Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Subscribes to AccountPositionsObservable and demonstrates that a late subscriber immediately receives the latest cached positions. ```csharp client.AccountPositionsObservable .Subscribe(p => Console.WriteLine($"{p.Account} {p.Contract.ContractId}: {p.Position}")); // Late subscriber immediately gets the latest cached positions. ``` -------------------------------- ### GetContractDetailsAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-contract-details.md Documentation for the GetContractDetailsAsync method, including parameters, return type, exceptions, and usage examples. ```APIDOC ## GetContractDetailsAsync ### Description Retrieves all contract details for a given contract selector, optionally including expired contracts. This is the asynchronous task-based variant that collects all emitted ContractDetails until the end marker, cancellation, or timeout. ### Method GetContractDetailsAsync ### Endpoint client.Service.GetContractDetailsAsync(contract, includeExpired, timeout, ct) ### Parameters - **contract** (Contract) - Required - Selector contract (same validation as the observable variant). - **includeExpired** (bool) - Optional - Include expired contracts. Default: false. - **timeout** (TimeSpan?) - Optional - If null → TimeSpan.MaxValue. Default: null. - **ct** (CancellationToken) - Optional - Cancels the wait. Default: default. ### Return Task — every ContractDetails emitted before ContractDetailsEnd (or until ct cancels / timeout fires). ### Throws - ArgumentException — same validation as CreateContractDetailsObservable. - TimeoutException — when timeout elapses (Timeout(Timespan) operator). - AlertException — on an Alert for the request id (OfTypeOnly). - InvalidOperationException — on an unexpected non-ContractDetails response type (OfTypeOnly's else branch, "Unexpected type: …"). ### Example — basic ```csharp try { ContractDetails[] all = await client.Service.GetContractDetailsAsync(selector); for (ContractDetails cd : all) Console.WriteLine($"{cd.Contract.Symbol} on {cd.ValidExchanges} tick={cd.MinimumTick}"); } catch (AlertException ex) { Console.WriteLine($"Alert {ex.AlertMessage.Code}: {ex.AlertMessage.Message}"); } ``` ### Example — careful expiry ```csharp Contract futureSelector = new() { SecurityType = ContractSecurityType.Future, Symbol = "ES", Currency = "USD", Exchange = "GLOBEX", LastTradeDateOrContractMonth = "202412" // restrict to one contract month }; // Retrieve with a 15 s cap and cancellation. CancellationTokenSource cts = new(); cts.CancelAfter(TimeSpan.FromSeconds(15)); ContractDetails[] results = await client.Service.GetContractDetailsAsync( futureSelector, includeExpired: false, timeout: TimeSpan.FromSeconds(15), ct: cts.Token); ``` > Note: passing an empty LastTradeDateOrContractMonth/Strike requests *all* expiries/strikes — the API warns this can be a huge result set. ``` -------------------------------- ### Request and cancel a scanner subscription Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/market-messages.md Shows how to request a scanner subscription: build a ScannerSubscription, get a request id, call RequestScannerSubscriptionAsync, subscribe to ScannerData responses, and later cancel with CancelScannerSubscriptionAsync. ```csharp ScannerSubscription sub = new() { NumberOfRows = 10, Instrument = "STK", LocationCode = "us", ScanCode = "TOP_PERC_GAIN", MarketCapAbove = 100000000, }; int id = client.Request.GetNextId(); await client.Request.RequestScannerSubscriptionAsync(id, sub); client.Response.WithRequestId(id).OfTypeOnly().Subscribe(data => { for (ScannerDataItem item : data.Items) Console.WriteLine($"#{item.Rank} {item.ContractDetails.Contract.Symbol} {item.ContractDetails.MarketName}"); }); // ... later: await client.Request.CancelScannerSubscriptionAsync(id); ``` -------------------------------- ### RequestAccountSummaryAsync / CancelAccountSummaryAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/request.md Starts or stops a stream of account summary data. Optionally specify a group and tags to filter the summary. ```APIDOC ## RequestAccountSummaryAsync / CancelAccountSummaryAsync ### Description Starts or stops a stream of account summary data. When tags is null/empty, all AccountSummaryTag values are used. The tag list always includes "$LEDGER:ALL". ### Method Async method ### Endpoint RequestAccountSummaryAsync / CancelAccountSummaryAsync ### Parameters - **requestId** (int) - Required - Identifier for the request. - **group** (string) - Optional - Group name, defaults to "All". - **tags** (IList?) - Optional - List of tags to include. When null/empty, all tags are used. ### Request Example ```csharp await client.RequestAccountSummaryAsync(1, "All", new List { AccountSummaryTag.NetLiquidation }); ``` ### Response Returns AccountSummary messages followed by an AccountSummaryEnd message (IsEndMessage=true on the last AccountSummary). ### Cancel CancelAccountSummaryAsync(requestId) stops the stream. ``` -------------------------------- ### RequestAccountUpdatesAsync method Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/request.md Starts receiving account updates. If more than one managed account, specify the account code; empty accountCode returns updates for all accounts. Returns AccountValue, PortfolioUpdate, and TimeUpdate messages, updated every three minutes. ```csharp /// Call this function to start receiving account updates. /// In case there if more than one managed account, the account must be specified. /// Returns AccountValue, PortfolioUpdate and TimeUpdate messages. /// Updates for all accounts are returned when accountCode is empty. /// This information is updated every three minutes. public async ValueTask RequestAccountUpdatesAsync(bool subscribe, string accountCode = "") => await createMessage().Write(RequestCode.RequestAccountData, "2", subscribe, accountCode).SendAsync().ConfigureAwait(false); ``` -------------------------------- ### Subscribe to AccountPositionsObservable and filter end messages Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-account-and-misc.md Subscribes to the AccountPositionsObservable, filters out the end-of-batch message, and prints account, symbol, and position for each update. The example then disposes the client asynchronously. ```csharp client.Service.AccountPositionsObservable .Where(p => !p.IsEndMessage) .Subscribe(p => Console.WriteLine($"{p.Account} {p.Contract.Symbol} {p.Position}")); await client.DisposeAsync(); ``` -------------------------------- ### Example: resync ID counter after another client places orders (C#) Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/service-account-and-misc.md Shows how to call UpdateNextIdAsync with a 5-second timeout before retrieving the next order ID with GetNextId(). Use this after another client has placed orders to avoid ID collisions. ```csharp // Another client placed orders — resync the id counter before placing more. await client.Service.UpdateNextIdAsync(timeout: TimeSpan.FromSeconds(5)); int nextOrderId = client.Request.GetNextId(); ``` -------------------------------- ### RequestAccountUpdatesAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/request.md Starts or stops receiving account update messages. Optionally specify an account code when multiple managed accounts exist. ```APIDOC ## RequestAccountUpdatesAsync ### Description Starts or stops receiving account updates. When accountCode is empty, updates for all accounts are returned. Updates are delivered every three minutes. ### Method Async method ### Endpoint RequestAccountUpdatesAsync ### Parameters - **subscribe** (bool) - Required - true to subscribe, false to cancel. - **accountCode** (string) - Optional - Account code for a specific managed account. Empty for all accounts. ### Request Example ```csharp await client.RequestAccountUpdatesAsync(true, "DU12345"); ``` ### Response Returns AccountValue, PortfolioUpdate, and TimeUpdate messages. ``` -------------------------------- ### Raw request usage with ToObservableById Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/request.md Shows raw request usage: create client, get a request id, then fire a one-shot request and await the typed stream via the raw Response observable using ToObservableById and OfTypeOnly. ```csharp IInterReactClient client = await InterReactClient.CreateAsync(); int id = client.Request.GetNextId(); // Fire a one-shot request and await the typed stream via the raw Response observable. HistoricalData data = await client.Response .ToObservableById(id, reqId => client.Request.RequestHistoricalDataAsync(reqId, contract, duration: HistoricalDataDuration.OneMonth)) // see extensions .OfTypeOnly() .FirstAsync(); ``` -------------------------------- ### Create Contract and Combo (bag) contract Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/contract-messages.md Shows how to construct a Contract using the record-literal syntax. The first creates a simple stock contract for AMZN; the second creates a combo (bag) contract with a single leg. Public constructors are internal, so this new() { Field = ... } syntax is the standard usage. ```csharp Contract contract = new() { SecurityType = ContractSecurityType.Stock, Symbol = "AMZN", Currency = "USD", Exchange = "SMART" }; // Combo (bag) contract: Contract bag = new() { SecurityType = ContractSecurityType.Bag, Symbol = "CLD", Currency = "USD", ContractId = 999999, ComboLegs = [ new ContractComboLeg() { ContractId = 1001, Ratio = 1, Action = OrderAction.Buy, Exchange = "A" } ] }; ``` -------------------------------- ### IObservable.ToObservable(Func startRequest, Func? stopRequest = null) Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Async variant where the start request is dispatched on a background task. Disposal also runs on a background task, guarded by an Interlocked started flag to ensure the stop sender runs at most once per start. ```APIDOC ## IObservable.ToObservable(Func startRequest, Func? stopRequest = null) ### Description Creates an observable sequence where the start request is dispatched on a background task, with disposal also on a background task. ### Method Extension method ### Endpoint IObservable.ToObservable(Func startRequest, Func? stopRequest = null) ### Parameters #### Parameters - `startRequest` (Func) - Required - Async request sender. - `stopRequest` (Func?) - Optional - Async cancel sender, called on dispose. ### Returns IObservable that completes after the first emitted value. ``` -------------------------------- ### OfTickClass usage example Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Example of using OfTickClass to filter price ticks from a market data observable and from a snapshot. It shows both the observable and enumerable forms. ```csharp client.Service.CreateMarketDataObservable(contract) .OfTickClass(s => s.PriceTick) // IObservable .Where(t => t.TickType == TickType.BidPrice) .Subscribe(t => Console.WriteLine($"Bid: {t.Price}")); // IEnumerable form: PriceTick latest = (await client.Service.GetMarketDataSnapshotAsync(contract)) .OfTickClass(list => list.PriceTick) // IEnumerable .Last(); ``` -------------------------------- ### OrderMonitor.PlaceOrderAsync static method Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/order-monitor.md Static factory method to create an OrderMonitor instance and place the order. It creates the monitor, calls request.PlaceOrderAsync, and returns the monitor. ```csharp internal static async ValueTask PlaceOrderAsync(Order order, Contract contract, Request request, IObservable response) { OrderMonitor orderMonitor = new(order, contract, request, response); await request.PlaceOrderAsync(orderMonitor.OrderId, order, contract).ConfigureAwait(false); return orderMonitor; } ``` -------------------------------- ### Options, error handling, and null instance with CreateAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/interreact-client.md Configures connection options (IP, ports, client id, order placement, logging), handles login timeouts, unreachable TWS, and cancellation. Uses a null instance as a safe fallback for optional members. ```csharp using System.Net; using Microsoft.Extensions.Logging; using InterReact; ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder .AddSimpleConsole(c => c.SingleLine = true) .SetMinimumLevel(LogLevel.Information)); try { IInterReactClient client = await InterReactClient.CreateAsync(options => { options.TwsIpAddress = IPAddress.Parse("192.168.100.15"); options.TwsPortAddresses = [TwsDefaultPorts.RegularAccount]; options.TwsClientId = 123456; // unique id (1..8 clients per TWS) options.AllowOrderPlacement = true; // required before PlaceOrderAsync options.LogFactory = loggerFactory; }); Console.WriteLine($"Connected: {client.RemoteIpEndPoint}"); await client.DisposeAsync(); } catch (TimeoutException ex) { Console.WriteLine($"Login timed out: {ex.Message}"); // "Try restarting." } catch (InvalidOperationException ex) { Console.WriteLine($"Not reachable: {ex.Message}"); // API not enabled in TWS } catch (OperationCanceledException) { Console.WriteLine("Connect was cancelled."); } // Null instance is a safe default for optional members: IInterReactClient fallback = InterReactClient.NullInstance; // DisposeAsync() is a no-op ``` -------------------------------- ### Get() and Get(Instant) method implementations Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/contract-details-time.md Returns the current period using the scheduler's clock, or the period at a given instant. Returns null when Events is empty. ```csharp public ContractDetailsTimePeriod? Get() => Get(Instant.FromDateTimeOffset(_theScheduler.Now)); public ContractDetailsTimePeriod? Get(Instant dt) { if (!Events.Any()) return null; return new ContractDetailsTimePeriod( Events.LastOrDefault(x => x.Time.ToInstant() <= dt), Events.FirstOrDefault(x => x.Time.ToInstant() > dt)); } ``` -------------------------------- ### Basic connection using InterReactClient.CreateAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/interreact-client.md Connects to the local TWS/Gateway fallback ports with a random client id. After connecting, prints the remote endpoint, then disposes the client. Always dispose the client to release resources. ```csharp using InterReact; // Connects to the local TWS/Gateway fallback ports, random client id. IInterReactClient client = await InterReactClient.CreateAsync(); Console.WriteLine(client.RemoteIpEndPoint); // e.g. [::1]:7496 // Use the service layer... // client.Service.CreateMarketDataObservable(contract)... // Always dispose. await client.DisposeAsync(); ``` -------------------------------- ### Catch AlertException in consumer code Source: https://github.com/dshe/interreact/blob/master/_autodocs/errors.md Example of catching AlertException when calling GetContractDetailsAsync, accessing the alert code and message, and optionally printing the AdvancedOrderRejectJson. ```APIDOC ## Catch AlertException ### Description Catches the library-specific AlertException thrown when TWS reports a problem for a request. ### Method N/A (code example) ### Endpoint N/A ### Parameters None ### Request Example ```csharp try { ContractDetails[] details = await client.Service.GetContractDetailsAsync(contract); } catch (AlertException ex) { // TWS reported a problem for this request. Console.WriteLine($"Code {ex.AlertMessage.Code}: {ex.AlertMessage.Message}"); if (!ex.AlertMessage.AdvancedOrderRejectJson.IsEmpty()) Console.WriteLine(ex.AlertMessage.AdvancedOrderRejectJson); } ``` ### Response #### Success Response (200) No response body; exception handling example. #### Response Example ``` Code : ``` ``` -------------------------------- ### ExerciseOptionsAsync method signature Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/request.md Exercises an option with the given parameters. Writes the contract without primary exchange, then exercise action, quantity, account, and override flag. Server-version gated optional fields are commented out at Request.cs:432. ```csharp public async ValueTask ExerciseOptionsAsync( int requestId, Contract contract, OptionExerciseAction exerciseAction, int exerciseQuantity, string account, bool overrideOrder) ``` -------------------------------- ### Monitor an order's lifecycle with OrderMonitor Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/order-messages.md Place an order and subscribe to OrderStatusReport, Execution, and CommissionReport messages to monitor its lifecycle. Use this to track order status, fills, and commissions in real time. ```csharp OrderMonitor monitor = await client.Service.PlaceOrderAsync(order, contract); monitor.Messages.OfType() .Subscribe(osr => Console.WriteLine($"{osr.Status}: filled={osr.Filled} remaining={osr.Remaining}")); monitor.Messages.OfType() .Subscribe(ex => Console.WriteLine($"Execution {ex.ExecutionId}: {ex.Shares} @ {ex.Price} on {ex.Exchange}")); monitor.Messages.OfType() .Subscribe(cr => Console.WriteLine($"Commission {cr.Commission} {cr.Currency}")); ``` -------------------------------- ### ExerciseOptionsAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/request.md Exercises an options contract with the specified action, quantity, account, and override flag. ```APIDOC ## ExerciseOptionsAsync ### Description Exercises an options contract with the specified action, quantity, account, and override flag. ### Method ExerciseOptionsAsync ### Signature public async ValueTask ExerciseOptionsAsync( int requestId, Contract contract, OptionExerciseAction exerciseAction, int exerciseQuantity, string account, bool overrideOrder) ### Parameters - **requestId** (int) - Required - The request identifier. - **contract** (Contract) - Required - The options contract (written without primary exchange). - **exerciseAction** (OptionExerciseAction) - Required - The exercise action (e.g., exercise or lapse). - **exerciseQuantity** (int) - Required - The number of contracts to exercise. - **account** (string) - Required - The account to exercise in. - **overrideOrder** (bool) - Required - Whether to override existing orders. ### Notes Server-version gated optional fields (manualOrderTime, customerAccount, professionalCustomer) are commented out at Request.cs:432. ``` -------------------------------- ### Tag usage in RequestFundamentalDataAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/misc-messages.md Example usage of Tag in a request: passes a Tag with name "SortBy" and value "MarketCap" as an option to RequestFundamentalDataAsync. ```csharp await client.Request.RequestFundamentalDataAsync(id, contract, reportType: FundamentalDataReportType.CompanyOverview, options: [ new Tag("SortBy", "MarketCap") ]); ``` -------------------------------- ### PlaceOrderAsync method Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/order-monitor.md Places an order and returns an OrderMonitor object. The method is async and returns a ValueTask. It calls OrderMonitor.PlaceOrderAsync with the order, contract, request, and response. ```csharp /// Places an order and returns an OrderMonitor object (below) which can be used to monitor the order. public async ValueTask PlaceOrderAsync(Order order, Contract contract) => await OrderMonitor.PlaceOrderAsync(order, contract, _request, _response).ConfigureAwait(false); ``` -------------------------------- ### CreateAsync — connect to TWS/Gateway Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/interreact-client.md Creates a new InterReact client by connecting to TWS/Gateway, performing the login handshake, and assembling the dependency injection container. Returns a fully connected, logged-in client. ```APIDOC ## [POST] /connect ### Description Creates a new InterReact client by connecting to TWS/Gateway, performing the login handshake, and assembling the dependency injection container. Returns a fully connected, logged-in client. ### Method POST ### Endpoint /connect ### Parameters #### Query Parameters - **action** (Action?) - Optional - Callback that mutates the freshly created `InterReactOptions`. - **ct** (CancellationToken) - Optional - Cancellation token propagated to `Connection.CreateAsync`. ### Request Example ```json { "action": "options => { options.TwsIpAddress = IPAddress.Parse(\"192.168.100.15\"); }", "ct": "default" } ``` ### Response #### Success Response (200) - **client** (IInterReactClient) - A fully connected, logged-in client. #### Response Example ```json { "client": "IInterReactClient instance" } ``` ### Error Handling - **InvalidOperationException** - If no port could be connected. - **InvalidDataException** - Unparseable or out-of-range server version. - **TimeoutException** - No response within 3 seconds of the initial login message. - **OperationCanceledException** - If `ct` is cancelled during connection or login. ``` -------------------------------- ### Configure InterReactOptions logging with LogFactory or Logger Source: https://github.com/dshe/interreact/blob/master/_autodocs/configuration.md Configure logging for InterReactOptions. Option (a) creates a LoggerFactory with simple console output and Information minimum level. Option (b) assigns a bare logger that is auto-converted to a factory. Option (c) uses the default NullLogger/NullLoggerFactory, producing no output. ```csharp options.LogFactory = LoggerFactory.Create(builder => builder .AddSimpleConsole(c => c.SingleLine = true) .SetMinimumLevel(LogLevel.Information)); ``` ```csharp options.Logger = myLogger; ``` ```csharp // (c) none — NullLogger/NullLoggerFactory (default), no output. ``` -------------------------------- ### Build a conditional order programmatically Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/conditions.md Constructs a PriceCondition to sell if the bid/ask price of conid 12345 on SMART is <= 9.50, attaches it to a limit order, and places it via PlaceOrderAsync. Note that Type is assigned by Create() but set here for manual construction. ```csharp // "Sell if the bid/ask price of conid 12345 on SMART is <= 9.50" PriceCondition price = new(); price.Type = OrderConditionType.Price; // assigned by Create(); set here for manual construction price.IsConjunctionConnection = false; price.IsMore = false; price.Price = 9.50; price.TriggerMethod = TriggerMethod.BidAsk; price.ConId = 12345; price.Exchange = "SMART"; Order order = new() { Action = OrderAction.Sell, OrderType = OrderTypes.Limit, TotalQuantity = 100, LimitPrice = 9.50, }; order.Conditions.Add(price); order.ConditionsIgnoreRegularTradingHours = false; order.ConditionsCancelOrder = false; OrderMonitor monitor = await client.Service.PlaceOrderAsync(order, contract); ``` -------------------------------- ### IObservable.ToObservable0(...) — async, cancellable Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/tick-selector-extensions.md Async extension method with optional stopRequest for cancellation. Tracks cancelable state to prevent cancelling a request that never started or already completed/errored. ```csharp public IObservable ToObservable0(Func startRequest, Func? stopRequest = null) ``` -------------------------------- ### Parse and serialize order conditions Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/conditions.md Parses a wire string into an OrderCondition and prints its type. Then uses the factory to create a PriceCondition, sets properties, and serializes it to a RequestMessage, writing fields like "o" or "a", IsMore, price, conid, exchange, and trigger method. ```csharp OrderCondition? parsed = OrderCondition.Parse( "bid/ask 1 of 12345(SMART) is <= 9.5"); Console.WriteLine(parsed); // " 1 of 12345(SMART) is <= 9.5" Console.WriteLine(parsed.GetType().Name); // "PriceCondition" // Use the factory + wire serialization: PriceCondition c = (PriceCondition)OrderCondition.Create(OrderConditionType.Price); c.IsMore = true; c.Price = 100; c.ConId = 999; c.Exchange = "SMART"; c.TriggerMethod = TriggerMethod.Last; RequestMessage msg = ...; // obtained via the DI-transient factory (client-internal) c.Serialize(msg); // writes: "o" (or "a"), 1 (IsMore), "100", 999, "SMART", 2 (TriggerMethod) ``` -------------------------------- ### ContractDetailsTime class definition Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/contract-details-time.md Defines the ContractDetailsTime class with properties for TimeZone, Events, and ContractTimeObservable, along with constructor and Get methods. The class converts trading hours strings into typed events and provides an observable for trading-state periods. ```csharp public sealed class ContractDetailsTime { public DateTimeZone TimeZone { get; } // null if not available // empty if no hours or timeZone public IReadOnlyList Events { get; } // completes immediately if no timeZone or hours public IObservable ContractTimeObservable { get; } public ContractDetailsTime(ContractDetails contractDetails, IScheduler? scheduler = null) public ContractDetailsTimePeriod? Get() public ContractDetailsTimePeriod? Get(Instant dt) } ``` -------------------------------- ### InterReactClient.CreateAsync Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/interreact-client.md Static factory method to create an InterReactClient instance asynchronously. ```APIDOC ## CreateAsync ### Description Creates a new InterReactClient instance asynchronously. This is the only way to instantiate the client, as the constructor is package-internal. ### Method CreateAsync ### Signature ```csharp public static async Task CreateAsync(Action? action = null, CancellationToken ct = default) ``` ### Parameters #### Parameters - **action** (`Action?`) - Optional - Configuration action for InterReactOptions. - **ct** (`CancellationToken`) - Optional - Cancellation token for the operation. ### Returns - **Task** - A task representing the asynchronous operation, resulting in an IInterReactClient instance. ### Exceptions - **OperationCanceledException** - If the operation is cancelled via the provided token. ``` -------------------------------- ### Handle InvalidOperationException when AllowOrderPlacement is false Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/order-monitor.md Use when placing an order while AllowOrderPlacement is false. The PlaceOrderAsync call throws InvalidOperationException with the message 'To place orders, first set Options.AllowOrderPlacement to true.' The example catches and prints the exception message. ```csharp IInterReactClient client = await InterReactClient.CreateAsync(); // AllowOrderPlacement = false try { OrderMonitor monitor = await client.Service.PlaceOrderAsync(order, contract); } catch (InvalidOperationException ex) { // "To place orders, first set Options.AllowOrderPlacement to true." Console.WriteLine(ex.Message); } ``` -------------------------------- ### Watch transitions with error handling (C#) Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/contract-details-time.md Creates a ContractDetailsTime from contract details and subscribes to ContractTimeObservable to print previous period time and status on each transition. Handles errors with a timer failure message and prints a completion message. A commented-out line shows how to pass a custom scheduler for testing. ```csharp ContractDetailsTime time = new(contractDetails); time.ContractTimeObservable.Subscribe( onNext: period => { if (period.Previous is { } p) Console.WriteLine($"{p.Time}: {p.Status}"); }, onError: ex => Console.WriteLine("timer failure: " + ex.Message), onCompleted: () => Console.WriteLine("no further events")); // Custom scheduler (e.g. test virtual time): // IObservable obs = new ContractDetailsTime(contractDetails, myScheduler).ContractTimeObservable; ``` -------------------------------- ### ContractDetailsTime constructor implementation Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/contract-details-time.md Initializes a ContractDetailsTime instance from ContractDetails, using an optional Rx scheduler. Throws ArgumentNullException if contractDetails is null, ArgumentException if the time zone cannot be resolved, and InvalidDataException for invalid trading-hour periods. ```csharp public ContractDetailsTime(ContractDetails contractDetails, IScheduler? scheduler = null) { ArgumentNullException.ThrowIfNull(contractDetails); _contractDetails = contractDetails; _theScheduler = scheduler ?? Scheduler.Default; ContractTimeObservable = CreateContractTimeObservable(); string tzi = contractDetails.TimeZoneId; // for expired Future Options there is no TimeZoneId(?) if (string.IsNullOrEmpty(tzi)) tzi = "Etc/GMT"; TimeZone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(tzi) ?? throw new ArgumentException($"TimeZoneId '{tzi}' not found."); Events = GetList(); } ``` -------------------------------- ### Rejecting order placement Source: https://github.com/dshe/interreact/blob/master/_autodocs/api-reference/interreact-options.md Shows how to configure the client to reject order placement by setting AllowOrderPlacement to false. Includes a try-catch block that catches InvalidOperationException when attempting to place an order, with a comment about the error message. Note that options must be captured before awaiting CreateAsync because the object is mutated in-place. ```csharp // ServerVersionCurrent is only known after login; options captured before connecting. InterReactOptions captured = new InterReactOptions(); IInterReactClient client = await InterReactClient.CreateAsync(options => { options.AllowOrderPlacement = false; options.CopyTo(captured); // (pseudocode — C# records/structs: options object is mutated in-place) }); try { OrderMonitor m = await client.Service.PlaceOrderAsync(order, contract); } catch (InvalidOperationException ex) { // "To place orders, first set Options.AllowOrderPlacement to true." Console.WriteLine(ex.Message); } ```