JestonBlu / RobinHood

An R interface for the RobinHood.com no commision investing site
https://jestonblu.github.io/RobinHood/
GNU Lesser General Public License v3.0
45 stars 12 forks source link

Error when I run get_positions() #171

Open ostokes1 opened 5 months ago

ostokes1 commented 5 months ago

I had an error come up when using the get positions() function starting this morning (3/26). I am using R 4.3.3 and RStudio 2023.12.1.

When I run get_positions(RH), I get the following error:

Error in fix.by(by.x, x) : 'by' must specify a uniquely valid column

I have updated all packages and am still getting this error.

Thanks!

ericvaughn11 commented 5 months ago

Also got this. The issue occurs because Robinhood's API appears to be including another 'symbol' column in both positions and instruments which are then bound by cbind. The result is a dataframe with two columns labeled 'symbol', so when the function calls merge it doesn't know which 'symbol' column to merge by. Here's a very rough replacement until this is fixed in the package. You should be able to swap in custom_get_positions for get_positions in your script. It removes the duplicated columns so you can run merge correctly

custom_get_positions = function (RH, limit_output = TRUE){
    RobinHood::check_rh(RH)
    positions <- RobinHood::api_positions(RH)
    if (nrow(positions) == 0) {
      return(cat("You have no current positions"))
    }
    instrument_id <- positions$instrument
    instruments <- c()
    for (i in 1:length(instrument_id)) {
      instrument <- RobinHood::api_instruments(RH, instrument_url = instrument_id[i])
      x <- data.frame(simple_name = ifelse(is.null(instrument$simple_name), 
                                           instrument$name, instrument$simple_name), symbol = instrument$symbol)
      instruments <- rbind(instruments, x)
    }
    positions <- cbind(instruments, positions)
    symbols <- paste(as.character(positions$symbol), collapse = ",")
    symbols_url <- paste(RobinHood::api_endpoints(endpoint = "quotes"), 
                         symbols, sep = "")
    quotes <- RobinHood::api_quote(RH, symbols_url)
    quotes <- quotes[, c("last_trade_price", "symbol")]
    positions <- merge(positions[,!duplicated(colnames(positions))], quotes, by.x = 'symbol', by.y = 'symbol')
    positions <- positions[, !names(positions) %in% c("account", 
                                                      "url", "instrument")]
    positions$updated_at <- lubridate::ymd_hms(positions$updated_at)
    positions$created_at <- lubridate::ymd_hms(positions$created_at)
    positions$quantity <- as.numeric(positions$quantity)
    positions$average_buy_price <- as.numeric(positions$average_buy_price)
    positions$last_trade_price <- as.numeric(positions$last_trade_price)
    positions$shares_held_for_stock_grants <- as.numeric(positions$shares_held_for_stock_grants)
    positions$shares_held_for_options_events <- as.numeric(positions$shares_held_for_options_events)
    positions$shares_held_for_options_collateral <- as.numeric(positions$shares_held_for_options_collateral)
    positions$shares_held_for_buys <- as.numeric(positions$shares_held_for_buys)
    positions$shares_held_for_sells <- as.numeric(positions$shares_held_for_sells)
    positions$shares_pending_from_options_events <- as.numeric(positions$shares_pending_from_options_events)
    positions$pending_average_buy_price <- as.numeric(positions$pending_average_buy_price)
    positions$intraday_average_buy_price <- as.numeric(positions$intraday_average_buy_price)
    positions$intraday_quantity <- as.numeric(positions$intraday_quantity)
    positions$cost <- positions$average_buy_price * positions$quantity
    positions$current_value <- positions$last_trade_price * 
      positions$quantity
    if (limit_output == TRUE) {
      positions <- positions[, c("simple_name", "symbol", 
                                 "quantity", "average_buy_price", "last_trade_price", 
                                 "cost", "current_value", "updated_at")]
    }
    if (limit_output == FALSE) {
      positions <- positions[, c("symbol", "simple_name", 
                                 "quantity", "average_buy_price", "last_trade_price", 
                                 "cost", "current_value", "shares_held_for_stock_grants", 
                                 "shares_held_for_options_events", "shares_held_for_options_collateral", 
                                 "shares_held_for_buys", "shares_held_for_sells", 
                                 "shares_pending_from_options_events", "pending_average_buy_price", 
                                 "intraday_average_buy_price", "intraday_quantity", 
                                 "created_at", "updated_at")]
    }
    return(positions)
}

environment(custom_get_positions) <- asNamespace('RobinHood')
assignInNamespace("get_positions", custom_get_positions, ns = "RobinHood")