- ago
Can the IB broker information provided in the Accounts screen be accessed programmatically? Or how can a C# program query account positions, value, cash?
0
2,957
Solved
52 Replies

Reply

Bookmark

Sort
Cone8
 ( 24.57% )
- ago
#1
"Can it?" Anything is possible, but right now you'd have to create your own API client to do it.

I thought there was a feature request out there to build a bridge to access that info, but I couldn't find one in the list (yet).
0
- ago
#2
And I'm also curious as to "why" because WL7 encapsulates this in using the actual broker account's Equity value (optionally).
0
- ago
#3
QUOTE:
And I'm also curious as to "why" because WL7 encapsulates this in using the actual broker account's Equity value (optionally).

(Did you mean WL8?) Regarding account value, in a strategy that open positions with an algorithmically calculated % of equity for each symbol, wouldn't I require this data to calculate position size using Transaction.Quantity?
0
- ago
#4
QUOTE:
"Can it?" Anything is possible, but right now you'd have to create your own API client to do it.


Haha. Well, almost anything ;). By "can" I mean is it available in the product today.

I know these capabilities are exposed in IBKR API, based on their API documentation and I want to make sure I am not missing some capabilities that already exist in WL8 I'm not finding.

I'm not sure what's involved in creating my own API client. I'm betting it's way beyond my technical capabilities. Is the WL8 IB connector open source?

I will create a feature request post based on my experience with IB connector so far.
0
Cone8
 ( 24.57% )
- ago
#5
WL7 or WL8 -
If you just need a % of Equity-based Position Sizer, just select the Trading Preferences for Portfolio Sync - especially the one to use the Broker-reported Account value for new signals. Hit F1 to see the documentation on that.

However, if there's a reason you must calculate it in the script, then we'll need a feature request.
0
- ago
#6
QUOTE:
can you comment Cone's Post #5 here?
Cone is correct about TD, but I am talking about Interactive Brokers (IB or IBKR), where this functionality appears to be available through their TWS API.

Here's what I was inquiring about:
If you just need a % of Equity-based Position Sizer, just select the Trading Preferences for Portfolio Sync - especially the one to use the Broker-reported Account value for new signals. Hit F1 to see the documentation on that.

QUOTE:
In order to potentially automate the process I go through manually today.

Have you tested the Broker-reported Account value for new signals?
0
- ago
#7
QUOTE:
Here's what I was inquiring about:
If you just need a % of Equity-based Position Sizer, just select the Trading Preferences for Portfolio Sync - especially the one to use the Broker-reported Account value for new signals. Hit F1 to see the documentation on that.

I believe I already answered your question in https://www.wealth-lab.com/Discussion/Access-Accounts-data-from-broker-programmatically-7914 Post #3. Cone suggested I create a feature request for this, which is the origin of this feature request.
0
- ago
#8
QUOTE:
Have you tested the Broker-reported Account value for new signals?

Sorry, I'm unclear what you are asking. Are you asking if I looked at the Accounts page? If so, I am looking to access this information from new methods in C# code.
0
- ago
#9
QUOTE:
Sorry, I'm unclear what you are asking. Are you asking if I looked at the Accounts page? If so, I am looking to access this information from new methods in C# code.

It's been clear. Before we consider new features I asked why you think it may be even necessary now that WL8 encapsulates this.
QUOTE:
I believe I already answered your question in https://www.wealth-lab.com/Discussion/Access-Accounts-data-from-broker-programmatically-7914 Post #3. Cone suggested I create a feature request for this, which is the origin of this feature request.

Can you elaborate with an example proving that Transaction.Quantity is superior to the built-in convenience?
0
- ago
#10
QUOTE:
Can you elaborate with an example proving that Transaction.Quantity is superior to the built-in convenience?

@Eugene, the Accounts page will show a live human being looking at their computer what is going on so in their account so they can make certain trading decisions. I don't see what that has to do with the request for automation hooks in code, although it is essentially the same account data. So I know the current API WL8 IB already knows how to access and *report* it. I am looking for it to be available to the strategy code via broker account queries as well.

Does that help?
0
- ago
#11
QUOTE:
Does that help?

No.

I've been talking about this option in Preferences, per Cone's Post #5 here, which is designed to remove complexity:

Wealth-Lab gets the account value via broker APIs and uses it as the total Equity value for Pct of Equity sizing for new signals.
0
- ago
#12
QUOTE:
I've been talking about this option in Preferences, per Cone's Post #5 here, which is designed to remove complexity:

@Eugene It definitely removes complexity but also lacks some flexibility when it comes to coding strategies. There are two shortcomings in regard to the use case envisioned in this feature request:
1. The account information is presented in the Accounts window but is not available to strategy code where it might be used for additional trading decisions.
2. Reporting data in a window requires a live human to look at it. I don't know how to drive automation from that (scraping?).
3. Please tell me how that would work with the use case to specify different % equity positions for different trades. I couldn't figure out how to do it with the current hooks in WL8.

I feel like we are retracing old ground as I have previously described this more than once. I'm apparently not communicating clearly. I'm not sure how else to explain it.

@Cone's response to me was that we would need a Feature Request to implement it, which I created here.
1
Cone8
 ( 24.57% )
- ago
#13
I'll mention this similar request which has an example of how a strategy might make use of account info -
https://www.wealth-lab.com/Discussion/Add-methods-for-portfolio-sync-in-strategy-code-like-FindPortfolioOpenPosition-7851
0
- ago
#14
If WL could see the actual "real" portfolio positions, then one wouldn't need Strategy Monitor anymore for "real-time" trading. Instead, we could use a "Strategy Trader" solution that would evaluate indicators in Initialize{} then Execute{} would only evaluate the last bar (skipping the backtesting part altogether) and generate Signals (Alerts) accordingly.

I'm not saying Strategy Monitor (and backtesting) should be scraped. We still need the backtesting simulation to develop and optimize the strategy and its parameters. But for actually generating the daily trading Signals, Strategy Trader only needs to Execute the last bar with the real portfolio positions. There's simply no need to perform a backtest simulation for the real-time trading case. And you wouldn't have to worry about trying to keep the simulation in sync with the real portfolio anymore.

And since Strategy Trader isn't doing backtesting in the first place (except with the last bar), it will be much more responsive than Strategy Monitor.

---
There's an issue about how PreExecute{} should work with this Strategy Trader solution, but perhaps that's a different topic.
0
Glitch8
 ( 10.41% )
- ago
#15
Interesting idea!
0
- ago
#16
QUOTE:
Interesting idea!

There are some issues (probably better discussed in another topic). And some of these issues have already been discussed when we talked about my ResyncPort(...) class a year ago, which I use both on WL6 and WL7/8. That class simply forces the off-the-Chart bar to use the real portfolio positions instead of the simulated positions. Recall, we do not want ResyncPort(...) to affect any of the backtesting stats, so the on-the-Chart bars are off limits to it. ResyncPort() only affects trading Signals and nothing else.

But what we can do today is provide the strategy a WL "supported" API to look at the real portfolio. What we do from there is another story (not related to this topic). After we get this feature request passed, we can talk more about what's next (like a Strategy Trader mode that uses the real portfolio to generate Signals for the off-the-Chart bar).
0
Cone8
 ( 24.57% )
- ago
#17
I don't know how that would reduce the need for the S. Monitor (you need a "conglomerator" to monitor many symbols), but there's certainly merit to the idea for the fast tick and n-second traders.
0
Glitch8
 ( 10.41% )
- ago
#18
You actually can already get the LIVE BROKER POSITION data in WL8 from within your Strategy code, so I'm closing this as complete. Here's the pattern to use:

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript1 { public class MyStrategy : UserStrategyBase { //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) {          r4 = RSI.Series(bars.Close, 5);          PlotIndicator(r4); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) { //code your buy conditions here     if (r4[idx] < 40)                PlaceTrade(bars, TransactionType.Buy, OrderType.Market); } else {             //code your sell conditions here             if (r4[idx] > 70)             {                Transaction t = PlaceTrade(bars, TransactionType.Sell, OrderType.Market);                //are we on the last bar of data? this would be the signal bar.                if (idx == bars.Count - 1)                {                   //see if we have a live position in the broker account                   BrokerPosition bp = GetBrokerPosition("Account 1", bars.Symbol, PositionType.Long);                   if (bp != null)                   {                      //adjust the transaction quantity based on the ACTUAL BROKER LIVE POSITION shares                      //here we show selling half of the live position                      t.Quantity = bp.Quantity / 2;                      WriteToDebugLog("Quantity for " + bars.Symbol + " adjusted to " + t.Quantity);                   }                }             } } }       //declare private variables below       private RSI r4;       //this method looks through all of the installed brokers, for the specified account       //and returns the live broker position for the specified symbol.       private BrokerPosition GetBrokerPosition(string acct, string symbol, PositionType pt)       {          foreach (BrokerBase broker in SignalManager.Brokers)          {             BrokerAccount ba = broker.FindAccount(acct);             if (ba != null)                return ba.FindPosition(symbol, pt);          }          return null;       } } }
4
Best Answer
MIH8
- ago
#19
Thanks
0
- ago
#20
QUOTE:
You actually can already get the LIVE BROKER POSITION data in WL8 from within your Strategy code, so I'm closing this as complete. Here's the pattern to use:


@Glitch Yikes!! This request was simply to make data already available on the Accounts page, "Account Value"available to a coded strategy, without having to know what symbols are being held or rotating though held positions to calculate it.

I do not see how the approach you offered satisfies the original feature request,
0
Cone8
 ( 24.57% )
- ago
#21
innertrader - all the clues are there! Here it is explicitly -

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript123 {    public class MyStrategy : UserStrategyBase    {       //create indicators and other objects here, this is executed prior to the main trading loop       public override void Initialize(BarHistory bars)       {          BrokerAccount brokerAccount = GetBrokerAccount("U5555555"); /* IMPORTANT!!! pass your Account ID here */          if (brokerAccount != null)          {             WriteToDebugLog("Account Value = " + brokerAccount.AccountValue);             WriteToDebugLog("Buying Power = " + brokerAccount.BuyingPower);             WriteToDebugLog("Cash = " + brokerAccount.Cash);             //Instead of Cash IB sets each currency balance             foreach (KeyValuePair<string, double> kvp in brokerAccount.CurrencyBalances)             {                WriteToDebugLog(kvp.Key + " = " + kvp.Value);             }             // for IB, Turn on Streaming Last Price Updates             foreach (BrokerPosition p in brokerAccount.Positions)             {                WriteToDebugLog(p.Symbol + "\t" + p.Quantity + "\t" + p.BasisPrice.ToString("N2") + "\t" + p.CurrentPrice.ToString("N2")+ "\t" + p.Value.ToString("N2") );             }          }          else          {             WriteToDebugLog("Make sure WealthLab is connected to the account");          }       }       //execute the strategy rules here, this is executed once for each bar in the backtest history       public override void Execute(BarHistory bars, int idx)       {       }       private BrokerAccount GetBrokerAccount(string acct)       {          foreach (BrokerBase broker in SignalManager.Brokers)          {             BrokerAccount ba = broker.FindAccount(acct);             if (ba != null)                return ba;          }          return null;       }    } }
0
Glitch8
 ( 10.41% )
- ago
#22
Yes, you just needed to look at the code a little bit more. You see the BrokerAccount object? It contains all of the information in the Accounts Window, exposed as properties.
0
- ago
#23
Were these new classes / methods released in a recent build? Or has this functionality been around for a while?

I'm not seeing how I could have figured out what @Cone (thank you) just provided. There is no documentation (yet) on how this works. Intellisense?

Anyhow, I'm glad this functionality is accessible, and I'll be digging into it.
0
Glitch8
 ( 10.41% )
- ago
#24
No, you would not have been able to figure it out on your own, that’s why I posted the info here.
0
Cone8
 ( 24.57% )
- ago
#25
BrokerAccount appears in the Broker Adapter API (https://www.wealth-lab.com/Support/ExtensionApi/BrokerAdapter) which was its intended purpose. Nonetheless, it's also in the QuickRef (BrokerAccount class), albeit without Examples.
2
- ago
#26
Thanks @Glitch, @Cone for posting example code.
0
- ago
#27
Often
CODE:
GetBrokerPosition.Price GetBrokerPosition.Value

returns Price: 0, Value: 0

Quantities are always correct.

1. Do these properties only work when market is open, and are they dependent on getting a streaming price?
2. If yes, does the "Turn on Streaming Last Price Updates" checkbox need to be checked in the Accounts window for these to work?
3. Should a current price and value always be available for active positions?
0
Cone8
 ( 24.57% )
- ago
#28
IB (context matters) doesn't return these values in the callback used by the Broker adapter. Notice that these values are missing in the Accounts tool too.

It could get them, but:
1. it could cause sluggishness in updating positions, and,
2. you have several other ways to get this price info.

For example, when your script runs, you already have the last price. Just multiply the shares and you have the value too.
0
- ago
#29
I see that now. So, if I am using these functions on IB and TDA brokerages, I might code them differently?

I have always used last bar price in daily strategies (yesterday's Close, e.g.). Is there a way to get current (real-time, last tick) price without using the Broker API? I see this method in Help

CODE:
public double Price The price of the tick.


...but I don't see an example of how it works and don't know if this would replicate the Broker function we are discussing.

Basically, I want to get current price in order to allocate quantity of Buy shares based a calculated dollar value for a specific symbol. I'm assuming from your reply that this question is specific to strategies run on the IB Broker, as I could simply use the GetBrokerPosition.Price and GetBrokerPosition.Value methods as-is on TDA.
0
Glitch8
 ( 10.41% )
- ago
#30
Yes, you can accomplish it using these methods:

CODE:
using WealthLab.Data; // declare up top public override void Initialize(BarHistory bars) {          DataProviderBase provider = DataProviderFactory.Instance.Find("TD Ameritrade");          provider.InitializeIfRequired();          double quote = provider.GetQuote("TQQQ");          DrawHeaderText("TQQQ is now: " + quote.ToString("N2"), WLColor.Aqua, 20); }


Change the TD Ameritrade to the provider name you wish to use.
2
Cone8
 ( 24.57% )
- ago
#31
That's a good one to know, but you don't have to go there.

Instead, for IB just make sure to Turn on Streaming Last Price Updates in the Accounts tool, and then the BrokerPosition will be updated with the Last Price and Value too. Added this to the sample code above -

CODE:
            // for IB, Turn on Streaming Last Price Updates             foreach (BrokerPosition p in brokerAccount.Positions)             {                WriteToDebugLog(p.Symbol + "\t" + p.Quantity + "\t" + p.BasisPrice.ToString("N2") + "\t" + p.CurrentPrice.ToString("N2")+ "\t" + p.Value.ToString("N2") );             }
0
- ago
#32
Thank you @Glitch for the alternative approach and the sample code.

Thank you @Cone for the Turn on Streaming tip for IB. I have found that this setting is not persistent, even if I save the Workspace as Default after selecting. Each time the strategy is restarted, this setting defaults to unchecked. Is there a programmatically correct way to set this, as the strategy will run automatically?

0
Cone8
 ( 24.57% )
- ago
#33
It's true - that Accounts tool option isn't saved with the Workspace. Glitch?
0
Glitch8
 ( 10.41% )
- ago
#34
Let's make this a #FeatureRequest to add the option to Workspace.
0
- ago
#35
Hi @Glitch, the code in Post #30 above appears not to work with a fully formed option symbol (the one IB returns for an underlying) on IB. Is that a known issue and is there a workaround or is this one the things (option current / last price) that has to be developed along with the Greeks feature request?
0
- ago
#36
Hi again @Glitch. I tried with TD Ameritrade broker and got NaN for price returned from the method. That was better than BI, which caused an "Object reference not set...." error. Here's the code I used:
CODE:
         DataProviderBase provider = DataProviderFactory.Instance.Find("Interactive Brokers");

Did I use the correct name for IB? I presume it has to be exact. Is there a list of these somewhere?
0
Cone8
 ( 24.57% )
- ago
#37
"Object reference not set...." is a coding error. "All of us" should be checking for that possibility and handle it in the code.

Anyway, the example works for me (as long as IB is connected).

CODE:
      public override void Initialize(BarHistory bars)       {          DataProviderBase provider = DataProviderFactory.Instance.Find("Interactive Brokers");          if (provider != null)          {             provider.InitializeIfRequired();             double quote = provider.GetQuote("TQQQ");             DrawHeaderText("TQQQ is now: " + quote.ToString("N2"), WLColor.Aqua, 20);          }          else          {             DrawHeaderText("Provider is null", WLColor.Aqua, 20);          }          }
However, there's still a place that's failing in the IB Provider code when the quote can't be returned. We'll correct it for the next build.

But the real problem with options here is that the GetQuote request always uses a Daily scale, which IB doesn't handle. If you need options data, you need to use an intraday chart and call GetHistory().
0
- ago
#38
@Cone: Got it. Since I am building the strategy using example code you supplied in Post #21 above, I realized I don't have to do either of these. I already have the bar history, so last option price is:

CODE:
double optionPrice = _obars.Close[idx];


Duh!
0
- ago
#39
Is there a way to determine which account is being processed when running in the strategy monitor? I'm running the same strategy using two accounts.
0
Cone8
 ( 24.57% )
- ago
#40
Determine in what way? The broker account will be the one you select for the Strategy Monitor item.

If it's confusing, just create a clone of the Strategy and change the name of the clone.
1
- ago
#41
Is there a way to get the account id on the fly? I'm putting some diagnostics and want to separate them out. If not, I'll clone it as you suggest.

Thank you.
0
Cone8
 ( 24.57% )
- ago
#42
If "get the account id on the fly" means "tell the Strategy which account id will receive its Signals", I think the answer is no.
0
- ago
#43
Ok
0
- ago
#44
RE: Post #30
QUOTE:
Yes, you can accomplish it using these methods:


I am using a version of this snapshot symbol pricing code set up for TDA in a strategy (using daily data). It works during market hours. It returns NaN when the market is closed. Do these methods have to be used by a strategy only during regular trading hours? If so, why? Does it not default to last price?
0
Glitch8
 ( 10.41% )
- ago
#45
The methods need to be used after the broker is connected, whether manually or automatically. Best bet is to connect to the broker in the Order Manager to ensure it's connected.
0
- ago
#46
Got it. Possibly I didn't check the connection for TDA before running the strategy. I'm usually focused on IB connection. Thanks.
0
Cone8
 ( 24.57% )
- ago
#47
While all the methods discussed are still valid, Build 67 will have a shortcut to access the live broker Account when running in the Strategy Monitor or Streaming Strategy with the "Use Live Positions" Trading Preference enabled.

CODE:
BrokerAccount ba = Backtester.LiveAccount;

That's it. No need for extra code and running loops to find the selected BrokerAccount.
0
- ago
#48
Just to confirm: this would replace the syntax

CODE:
            BrokerAccount ba = GetBrokerAccount(_activeAcctNum);


and other than that, there is no new functionality that comes with this change (thus defining it as a "shortcut")?
0
Cone8
 ( 24.57% )
- ago
#49
Well, it would also remove the need for the method code GetBrokerAccount() too.

Just keep in mind, the shortcut is only useful when "Use Live Positions" is in use.
0
- ago
#50
Since this doesn't work in Strategy Window, I would still require the original coding for testing or otherwise running standalone. In other words, the version for the Strategy Monitor would have to have a different code set.

Is there a property that can be tested to tell where the strategy is running? Even if there is, I would need both implementations present in the code if I didn't want to keep specialized versions. Not sure what the benefit of that would be.
0
Glitch8
 ( 10.41% )
- ago
#51
Yes, the property you’re looking for is ExecutionMode.
0
- ago
#52
Thanks!
0

Reply

Bookmark

Sort