This function either fetches or sets up a subscription to receive the data that appear in the Account Window window of Trader Workstation. req_account_updates_multi() may be used to set up multiple simultaneous subscriptions to many accounts / model codes. IB's documentation may be found on the Account Updates page.

req_account_updates_multi(
  account = "All",
  modelCode = NULL,
  ledgerAndNLV = FALSE,
  channel = NULL,
  return_data = is.null(channel)
)

Arguments

account

Character vector of length 1 containing a valid account code.

modelCode

Character vector of length 1 containing a valid model code.

ledgerAndNLV

Boolean of length 1, defaults to FALSE. If TRUE, then the created subscriptions are treated as "lightweight requests", meaning that the data returned for the account or model codes supplied will include only currency positions (as opposed to both account values and currency positions).

channel

One of the following:

  • Not Specified (Default): Opens a new connection to IB, uses it to issue the request and retrieve the response, and closes connection behind itself upon completion.

  • The Name of a Sock: Character vector, length 1. The name of an open, connected socket in the sock_drawer; e.g., "master", "tws", or "sock_123"

  • Numeric Client ID: Numeric, length 1. The client ID for which open orders are to be retrieved; e.g., 0, 874, 123. If a client ID is passed, and no socket in the sock_drawer is connected on that ID, then a new socket will be opened on that ID, and closed upon function exit.

  • A sockconn Connection: An open connection object of class "sockconn", connected to the IB API; e.g., sock_drawer$tws

return_data

Boolean of length 1. Defaults to TRUE unless argument channel is specified. If FALSE, data retrieved by the function will be returned as the funciton's output. If TRUE, then a Boolean succeses flag will be returned as the function's output indicating the success (TRUE) or failure (FALSE) of the function's attempt to transceive data to/from IB. Data in the treasury is always updated regardless of the value passed as return_data in the function call.

Value

This function is called for its side effect of updating the treasury, which takes place every time the function executes. Additionally, the function's return value depends upon the value passed in as return_data as follows:

  • If return_data == FALSE: A Boolean success flag, returned invisibly, indicating that the function executed correctly and updated the treasury with any new data retrieved.

  • If return_data == TRUE: Any new data retrieved will be returned in a tibble in addition to being added to the treasury. If no new data is available, returns NULL.

return_data defaults to TRUE unless channel is specified.

Details

"All" Option: If account is not specified, req_account_updates_multi() will default to account = "All", which will return data for all accounts accessible by the signed-in user. This option is not available for users who manage more than 50 accounts.

Models: Model Portfolios, or "Models" for short, can be though of as named templates that will allocate funds across investment products in a specified manner. When passed to req_account_updates_multi() as model_code, they behave like stocks -- they have postions, market prices, values, etc. To use Model Portfolios you need to have a Financial Advisor account, and the Model Portfolios feature needs to be activated. Learn more on Interactive Brokers' Model Portfolios page.

No Positions: If you call req_account_updates_multi() on an account that has cash but no positions, then data will be sent to the socket once initially, but will not update thereafter.

ACCOUNTS Treasury Object

req_account_summary() updates the ACCOUNTS object in the treasury. ACCOUNTS is a tibble in which each row represents a parameter pertaining to a particular account. Has the following columns:

  • account <chr>: Account ID (e.g., "DF1234567")

  • tag <chr>: Name of account tag (e.g., "BuyingPower")

  • tag_value <chr>: Value of tag (e.g., "500000")

  • currency <chr>: 3-letter currency abbreviation if tag_value is a monetary amount, "" otherwise.

See also

Examples

################################################################################ #### Effect of ledgerAndNLV #################################################### ################################################################################ # Let's look at the difference between calling req_account_updates_multi with # ledgerAndNLV = TRUE vs. setting it to FALSE. #1) Fetch an update using req_account_updates_multi()'s default values for # for account and ledgerAndNLV ("ALL" and TRUE, respectively). req_account_updates_multi()
#> # A tibble: 166 x 4 #> account tag tag_value currency #> * <chr> <chr> <chr> <chr> #> 1 DF1267859A AccountCode DF1267859A "" #> 2 DF1267859A AccountReady TRUE "" #> 3 DF1267859A AccountType UNIVERSAL "" #> 4 DF1267859A AccruedCash 1350.39 "USD" #> 5 DF1267859A AccruedCash-C 0.00 "USD" #> 6 DF1267859A AccruedCash-S 1350.39 "USD" #> 7 DF1267859A AccruedDividend 0.00 "USD" #> 8 DF1267859A AccruedDividend-C 0.00 "USD" #> 9 DF1267859A AccruedDividend-S 0.00 "USD" #> 10 DF1267859A AvailableFunds 5007628.56 "USD" #> # … with 156 more rows
# The update printed to screen but it's not lost -- it's in the treasury. # 2) Save the treasury object in a variable to use for comparing later: aum_true <- treasury$ACCOUNTS # 3) Clear out the treasury. Without this step, InteractiveTradeR would update # the new ACCOUNTS object when we call req_account_updates_multi() again with # ledgerAndNLV = FALSE, making it hard to tell exactly what effect our changing # of the value of ledgerAndNLV had. clean_slate() # Call req_account_updates_multi() again, but with ledgerAndNLV = FALSE: req_account_updates_multi(ledgerAndNLV = FALSE)
#> # A tibble: 166 x 4 #> account tag tag_value currency #> * <chr> <chr> <chr> <chr> #> 1 DF1267859A AccountCode DF1267859A "" #> 2 DF1267859A AccountReady TRUE "" #> 3 DF1267859A AccountType UNIVERSAL "" #> 4 DF1267859A AccruedCash 1350.39 "USD" #> 5 DF1267859A AccruedCash-C 0.00 "USD" #> 6 DF1267859A AccruedCash-S 1350.39 "USD" #> 7 DF1267859A AccruedDividend 0.00 "USD" #> 8 DF1267859A AccruedDividend-C 0.00 "USD" #> 9 DF1267859A AccruedDividend-S 0.00 "USD" #> 10 DF1267859A AvailableFunds 5007628.56 "USD" #> # … with 156 more rows
aum_false <- treasury$ACCOUNTS # Compare the two: # 3.1) Same account: unique(aum_true$account)
#> [1] "DF1267859A"
unique(aum_false$account)
#> [1] "DF1267859A"
# 3.2) See that ledger_and_NLV = FALSE includes more parameters: setdiff(unique(aum_false$tag), unique(aum_true$tag))
#> character(0)
################################################################################ #### Subscriptions ############################################################# ################################################################################ # Clean slate clean_slate() # Open a socket create_new_connections() # Fetch the account IDs of your six paper trading accounts and use walk() from # the purrr package to subscribe to each one req_managed_accts() %>% purrr::walk( req_account_updates_multi, channel = "async" ) # Verify that you're now subscribed to the six paper trading accounts: subscriptions$account_updates_multi
#> # A tibble: 6 x 6 #> req_name account ledgerAndNLV req_id conn_row client_id #> <chr> <chr> <lgl> <dbl> <dbl> <int> #> 1 DF1267859 DF1267859 FALSE 2 4 1 #> 2 DU1267860 DU1267860 FALSE 3 4 1 #> 3 DU1267861 DU1267861 FALSE 4 4 1 #> 4 DU1267862 DU1267862 FALSE 5 4 1 #> 5 DU1267863 DU1267863 FALSE 6 4 1 #> 6 DU1267864 DU1267864 FALSE 7 4 1
# Access the retrieved updates: treasury$ACCOUNTS
#> # A tibble: 925 x 4 #> account tag tag_value currency #> * <chr> <chr> <chr> <chr> #> 1 DU1267864 AccountType INDIVIDUAL "" #> 2 DU1267864 AccountCode DU1267864 "" #> 3 DU1267864 AccountReady TRUE "" #> 4 DU1267864 Cushion 0.992283 "" #> 5 DU1267864 DayTradesRemaining -1 "" #> 6 DU1267864 DayTradesRemainingT+1 -1 "" #> 7 DU1267864 DayTradesRemainingT+2 -1 "" #> 8 DU1267864 DayTradesRemainingT+3 -1 "" #> 9 DU1267864 DayTradesRemainingT+4 -1 "" #> 10 DU1267864 Leverage-S 0.03 "" #> # … with 915 more rows
# You should have all six paper account codes represented in the "account" # column of the ACCOUNTS treasury object. # This information will update every 3 minutes -- and probably more frequently # than that in practice -- for those accounts that have positions in financial # instruments. You can wait for at least one cycle and call read_sock_drawer() # again to see this for yourself. # Save the treasury object to use for comparing later before_cancel <- treasury$ACCOUNTS # When you're ready, cancel a subscription or two: how about the 1st and 3rd? cancel_accounts <- subscriptions$account_updates_multi$req_name[c(1,3)] cancel_account_updates_multi(cancel_accounts)
#> [1] "DF1267859" "DU1267861"
# Check that the two accounts are indeed removed from subscriptions: subscriptions$account_updates_multi
#> # A tibble: 4 x 6 #> req_name account ledgerAndNLV req_id conn_row client_id #> <chr> <chr> <lgl> <dbl> <dbl> <int> #> 1 DU1267860 DU1267860 FALSE 3 4 1 #> 2 DU1267862 DU1267862 FALSE 5 4 1 #> 3 DU1267863 DU1267863 FALSE 6 4 1 #> 4 DU1267864 DU1267864 FALSE 7 4 1
any(cancel_accounts %in% subscriptions$account_updates_multi$req_name)
#> [1] FALSE
# From this point on, the sock drawer will no longer get updated data for the # two accounts that were unsubscribed. # To convince yourself, first read off any data that might have gotten sent # in the time between the last read and the call to cancel: read_sock_drawer() # From this point on, the canceled accounts' treasury data -- which can be # selected using the following code: treasury$ACCOUNTS %>% dplyr::filter(account %in% cancel_accounts)
#> # A tibble: 313 x 4 #> account tag tag_value currency #> <chr> <chr> <chr> <chr> #> 1 DU1267861 AccountType INDIVIDUAL "" #> 2 DU1267861 AccountCode DU1267861 "" #> 3 DU1267861 AccountReady TRUE "" #> 4 DU1267861 Cushion 0.956605 "" #> 5 DU1267861 DayTradesRemaining -1 "" #> 6 DU1267861 DayTradesRemainingT+1 -1 "" #> 7 DU1267861 DayTradesRemainingT+2 -1 "" #> 8 DU1267861 DayTradesRemainingT+3 -1 "" #> 9 DU1267861 DayTradesRemainingT+4 -1 "" #> 10 DU1267861 Leverage-S 0.17 "" #> # … with 303 more rows
# -- will not update, no matter how many times you call read_sock_drawer(), # unless you subscribe to them again. ################################################################################ #### CANCELLING Subscriptions ################################################## ################################################################################ # Clear out the treasury & subscriptions for this example clean_slate(c("treasury", "subscriptions")) # Open a socket create_new_connections() # Fetch the account IDs of your six paper trading accounts and use walk() from # the purrr package to subscribe to each one req_managed_accts() %>% purrr::walk( req_account_updates_multi, channel = "async" ) # Verify that you're now subscribed to the six paper trading accounts: subscriptions$account_updates_multi
#> # A tibble: 6 x 6 #> req_name account ledgerAndNLV req_id conn_row client_id #> <chr> <chr> <lgl> <dbl> <dbl> <int> #> 1 DF1267859 DF1267859 FALSE 8 4 1 #> 2 DU1267860 DU1267860 FALSE 9 4 1 #> 3 DU1267861 DU1267861 FALSE 10 4 1 #> 4 DU1267862 DU1267862 FALSE 11 5 2 #> 5 DU1267863 DU1267863 FALSE 12 5 2 #> 6 DU1267864 DU1267864 FALSE 13 4 1
# Access the retrieved updates: treasury$ACCOUNTS
#> # A tibble: 489 x 4 #> account tag tag_value currency #> * <chr> <chr> <chr> <chr> #> 1 DU1267861 AccountType INDIVIDUAL "" #> 2 DU1267861 AccountCode DU1267861 "" #> 3 DU1267861 AccountReady TRUE "" #> 4 DU1267861 Cushion 0.956605 "" #> 5 DU1267861 DayTradesRemaining -1 "" #> 6 DU1267861 DayTradesRemainingT+1 -1 "" #> 7 DU1267861 DayTradesRemainingT+2 -1 "" #> 8 DU1267861 DayTradesRemainingT+3 -1 "" #> 9 DU1267861 DayTradesRemainingT+4 -1 "" #> 10 DU1267861 Leverage-S 0.17 "" #> # … with 479 more rows
# You should have all six paper account codes represented in the "account" # column of the ACCOUNTS treasury object. # This information will become available every 3 minutes -- and probably more # frequently than that in practice -- for those accounts that have positions in # financial instruments. # You can wait for at least one cycle and see this for yourself; just call # read_sock_drawer() as many times as you'd like to refresh the data. # Save the treasury object to use for comparing later before_cancel <- treasury$ACCOUNTS # When you're ready, cancel a subscription or two: how about the 1st and 3rd? cancel_accounts <- subscriptions$account_updates_multi$req_name[c(1,3)] cancel_account_updates_multi(cancel_accounts)
#> [1] "DF1267859" "DU1267861"
# Check that the two accounts are indeed removed from subscriptions: subscriptions$account_updates_multi
#> # A tibble: 4 x 6 #> req_name account ledgerAndNLV req_id conn_row client_id #> <chr> <chr> <lgl> <dbl> <dbl> <int> #> 1 DU1267860 DU1267860 FALSE 9 4 1 #> 2 DU1267862 DU1267862 FALSE 11 5 2 #> 3 DU1267863 DU1267863 FALSE 12 5 2 #> 4 DU1267864 DU1267864 FALSE 13 4 1
any(cancel_accounts %in% subscriptions$account_updates_multi$req_name)
#> [1] FALSE
# From this point on, the sock drawer will no longer get updated data for the # two accounts that were unsubscribed. # To convince yourself, first read off any data that might have gotten sent # in the time between the last read and the call to cancel: read_sock_drawer() # From this point on, the canceled accounts' treasury data -- which can be # selected using the following code: treasury$ACCOUNTS %>% dplyr::filter(account %in% cancel_accounts)
#> # A tibble: 171 x 4 #> account tag tag_value currency #> <chr> <chr> <chr> <chr> #> 1 DU1267861 AccountType INDIVIDUAL "" #> 2 DU1267861 AccountCode DU1267861 "" #> 3 DU1267861 AccountReady TRUE "" #> 4 DU1267861 Cushion 0.956605 "" #> 5 DU1267861 DayTradesRemaining -1 "" #> 6 DU1267861 DayTradesRemainingT+1 -1 "" #> 7 DU1267861 DayTradesRemainingT+2 -1 "" #> 8 DU1267861 DayTradesRemainingT+3 -1 "" #> 9 DU1267861 DayTradesRemainingT+4 -1 "" #> 10 DU1267861 Leverage-S 0.17 "" #> # … with 161 more rows
# -- will not update, no matter how many times you call read_sock_drawer(), # unless you subscribe to them again.