AutoFinance.Broker
AutoFinance.Broker copied to clipboard
can't request streaming market data
As I see TwsControllerBase::RequestMarketDataAsync
method written in a way
to get something, then omit all callbacks and stop listening any data.
What to do if I want to receive a stream of quotes?
Hi @Neznakomec ,
There is a test here https://github.com/amittleider/AutoFinance.Broker/blob/09d40057bdf70859aaa8fab8abca4890700b5cdb/AutoFinance.Broker.IntegrationTests/InteractiveBrokers/Controllers/TwsControllerBaseTests.cs#L669 which you can use as a template for your production code.
In short, for a streaming API, you will need to register to the MarketData events or TickEvents (or others) that are located on the TwsBaseController, like this:
twsCallbackHandler.MarketDataTypeEvent +=
(sender, args) => { myfunc(args.x); };
twsCallbackHandler.TickPriceEvent +=
(sender, args) => { myfunc(args.x) };
It's not impossible that there's a bug here. This API was not originally intended for streaming data (it works better for things that have a real "end", like placing orders, requesting historical data, searching contracts, etc.; and less good for streaming, which has no real end). It may be the case that simply using the client socket will be easier in the case of streaming.
Your contributions are welcome. If you use the integration tests project, please be sure to sign into Trader Workstation with your test credentials. The integration tests place real orders, so you wouldn't want to be running them against a prod account.
I'm also don't know a good solution for streaming market data, may be just return an identifier
if (snapshot == false) {
taskSource.SetResult(new TickSnapshotEndEventArgs(tickerId));
}
and leave the user to choose what to do with event handling
Indeed, the user will have to register their own event handling. It may not make sense to follow the pattern of TaskSource when it comes to this type of API.
If you want to make a prototype, I'd be happy to review it.
On Wed, Aug 17, 2022 at 4:50 PM Neznakomec @.***> wrote:
I'm also don't know a good solution for streaming market data, may be just return an identifier
if (snapshot == false) { taskSource.SetResult(new TickSnapshotEndEventArgs(tickerId)); }
and leave the user to choose what to do with event handling
— Reply to this email directly, view it on GitHub https://github.com/amittleider/AutoFinance.Broker/issues/36#issuecomment-1218115113, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMM6X5X6SUC23I63QXYJ4DVZT3ZVANCNFSM56UXQDGQ . You are receiving this because you commented.Message ID: @.***>
@amittleider Hi, thanks for API. I have also used an example from [TwsControllerBaseTests.cs] to get ticks for MSFT, and it works, but the problem is that this work only about 1 minute... After 1 minute, no new ticks :) And how to get order book subscription?
Found in code limitation for 1 minute. Why did you do this? :)
For the case of using snapshot=true
this cancelling not required, cause
TWS API do it for you: it opens subscription for 11 seconds maximum, tries to collect all appropriate tick types, then closes subscription with tickSnapshotEnd
event. Of course you can cancel subscription by tickerId
(request identifier) earlier, if you want to free a market data line (which is about 100 data lines by default) earlier.
"What to do if I want to receive a stream of quotes?" - Have you find the realization? Or if you have done for yourself. Can you share pls?
@hftcryptobot I think you can use TwsControllerBase::RequestMarketDataAsync
, but you should omit the moment with cancelling market data after 1 min.
Then, you can use callbacks and catch the events as described in 2nd message of this thread.
Although, it can be possible that TWS API won't send you anything (it's probably a bug, or a strange behaviour - you're subscribing on instrument market data, no any errors and exceptions, security described correctly...But there are no ticks coming out of TWS API for this security). Then TwsControllerBase::RequestMarketDataAsync
without that 1-minute stop and cancel will be an endless method, that's bad...
So, probably the solution is
CancellationTokenSource tokenSource = new CancellationTokenSource(60 * 1000);
tokenSource.Token.Register(() =>
{
// this.CancelMarketData(tickerId);
this.twsCallbackHandler.TickPriceEvent -= tickPriceEventHandler;
this.twsCallbackHandler.TickSizeEvent -= tickSizeEventHandler;
this.twsCallbackHandler.TickStringEvent -= tickStringEventHandler;
this.twsCallbackHandler.TickGenericEvent -= tickGenericEventHandler;
this.twsCallbackHandler.TickOptionComputationEvent -= tickOptionComputationEventHandler;
this.twsCallbackHandler.TickSnapshotEndEvent -= tickSnapshotEndEventHandler;
this.twsCallbackHandler.TickEFPEvent -= tickEFPEventHandler;
this.twsCallbackHandler.ErrorEvent -= errorEventHandler;
// taskSource.TrySetCanceled();
taskSource.TrySetResult(new TickSnapshotEndEventArgs(args.TickerId));
});
I don't sure about taskSource.TrySetCanceled();
, probably we shouldn't raise a TaskCancelledException
. It will interfere our pipeline.
``
@hftcryptobot I think you can use
TwsControllerBase::RequestMarketDataAsync
, but you should omit the moment with cancelling market data after 1 min.Then, you can use callbacks and catch the events as described in 2nd message of this thread.
Although, it can be possible that TWS API won't send you anything (it's probably a bug, or a strange behaviour - you're subscribing on instrument market data, no any errors and exceptions, security described correctly...But there are no ticks coming out of TWS API for this security). Then
TwsControllerBase::RequestMarketDataAsync
without that 1-minute stop and cancel will be an endless method, that's bad...
RequestMarketDataAsync can return orderbook? The cancellation for 1 minute I have fixed..
@hftcryptobot no, this method not designed to work with level 2 and orderbook.
You can use TwsControllerBase::RequestMarketDataAsync
only for level 1 market data ticks.
I'm sorry to say that, but the support of market depth (reqMktDepth + updateMktDepth, updateMktDepthL2) not covered in this wrapper library yet: https://interactivebrokers.github.io/tws-api/market_depth.html
Probably, you can directly call method:
twsObjectFactory.ClientSocket.EClientSocket.reqMarketDepth