¿ªÔÆÌåÓý

ctrl + shift + ? for shortcuts
© 2025 Groups.io

C++ Client Class visibility w/ the Sample App


 

Hi,

In the sample application of TestCppClient the visibility for EWrapper's hooks is being stored as private.? EReaderOSSignal m_osSignal, EClientSocket * const m_pClient, etc. are all private and initialized in the initializer list of the TestCppClient. As we all know.

Now, I already have a strategy adhering to this visibility, but I find my classes to be not so cohesive. I have a class where I am doing a lot of the heavy lifting around preprocessing the data I need to make predictions, and then subsequently deciding how to trade signals from the model I have. My main loop is in my Client Class so I am constantly going back and forth b/w the Client Class and the Model's Class, which is eh, but I have functions in the Client Class specific to the Model's class and they should just be in the model's class, but when I put them in there I do not have the hook into m_pClient which is obviously crucial for order placing etc.

So, I am thinking, if I alter the visibility, I can create another derived class, i.e. MyModel() -> does heavy lifting for preprocessing and decision modeling, instead that inherits Client Class, make the visibility of EReaderOSSignal, EClientSocket objects, etc. protected in said Client Class and run my main loop from the derived MyModel() Class. I would put functions that were previously MyModelStrategyGetLong(), MyModelStrategyGetShort() in the Client Class, which were only in the Client Class b/c of visibility problems, into the appropriate, cohesive, MyModel() class. I would have to change the visibility for all the abstract virtual functions too that the TestCppClient has as private to protected or public as well.

1. Is this even allowed w/ the API's design?
2. If so, does anyone think this would be a good idea?

I am spit balling here... It just seems my program would be so much cleaner and cohesive, because really the Client Class is only used for getting things from IB. My strategy is really the focal point of making things happen. I really only need data, order submissions/fills, and account details from IB. The extensive preprocessing and analysis that comes after getting the data is not really cohesive to this Client Class and is really the main class IMO. It just seems silly to be doing all my analysis from this Client Class. We all want High Cohesion & Less Coupling no? I just don't seem to be getting that with this current design.

Thanks


 

The reason I am asking, is because I want to modularize this Client Class to use for other strategies.


 

Try making the client as a shared_ptr<> in your Controller class which you can pass to your Model class.

Personally I make all my IB client calls from a single Controler class. If you design your application correctly it should not be an issue.


 

David is correct. You should hide all low-level TWS API details in a Controller class.

The Java TWS API implementation ships with a sample ApiController class that could be a starting point for your own design. For each API request, it groups all corresponding callbacks into a small handler interface and transparently manages requestIds and most orderIds. Requests are called with handler objects instead of requestIds and the controller routes all corresponding callbacks to that handler.

Our implementation has a few improvements over that controller class. The most important ones are:
  • A handler super-interface that all handler interfaces extend. The super interface provides an error callback method.
  • An error router that routes any request related error callbacks to the handler for that request
  • More comprehensive transparent orderID management. The sample Java ApiController already has basic transparent orderId management for single orders (your client/framework does not assign orderIds) but it lacks support for attached orders and orderId management when multiple API clients are connected to the same account.

Based upon such an ApiController you can then implement domain or task specific higher level controllers such as OrderController,PositionController, DataStreamController, ... that hide TWS API entirely from your trading and business logic or enable safe multi-threaded operation.

´³¨¹°ù²µ±ð²Ô



On Sat, Sep 9, 2023 at 11:06 AM, David Armour wrote:
Try making the client as a shared_ptr<> in your Controller class which you can pass to your Model class.
?
Personally I make all my IB client calls from a single Controler class. If you design your application correctly it should not be an issue.


 

My grain of salt after theses excellent answers
I would be surprised that you can do what you want directly through inheritance.
1-??? IB did make some privates for good reasons, and if you break this model, you may postpone some pretty hard to track bug. Remember this is Asynchronous coding.?
So, I strongly recommend that you keep all private and protected the way they are in particular what is around m_osSignal.

2-??? It¡¯s a data model issue before being a class issue. (classical)
EWrapper is a IO model. (data model of it is focused on IO need)
Once your data model set then you derived your automates for handling the data and then you look at the EWrapper for what you need.
Here also I would be surprised that you can directly hook your needs using EWrapper as the underlying structure, even for what seems a simple action like Buy/Sale your need more than a couple of call. Also handling position even once open, require quit some calls that give rewards thanks to the asynchronous capabilities of the API.

3-??? The API is very fast but not that fast.
Some structures(class) Contract/Orders/etc are pretty verbose once decoded.
Otherwise said exchange of data in a thread safe manner between your model and theirs will not induce a lag that you should ever feel.

So, to share experiences I start by a data model suited for the needs, then slightly superclass the IB Wrapper to feed it (In/Out) to do all the handling but in a completely separated class system. (Allowing relax coding in multiple thread)
Additional reason to not consider the EWrapper as a model class is that you may have to federate data from other feeds and will be happy to not depend upon the data model of IB.

Once all that said, nothing is as good as self-inflicted experience and it look to me like you need to experiment first to see what suit your programming style, keeping what is written above just as MHO amongst others, just to make your feeling more comfortable with tradeoff you will most likely need to do but you may feel afraid to do so because you wonder if it will hold very long. Answer is no it won't if you use EWrapper model.

In short, your first implementation will be pretty far away from final one, so better do it ASAP without investing too much in putting your implementation atop existing API model.


 

I completely revamped my design over the weekend and just went with a class architecture similar to the Java Implementation rather than using inheritance. I took David's advice and am passing a smart pointer around that is my IBClient() which contains all callbacks and logic involving the TWS API. I then took Jurgen's advice and built IBHistData(), IBOrders(), IBMktDepth(), etc. to handle specific tasks. These include logic to store information from callbacks, etc. These are then located in the IBClient() and wrapped nicely so I can now grab what I need when I need it in my main Model() Class through the IBClient() smart pointer.??