A Robinhood API client for Elixir. Currently under development.
Installation
The package can be installed by adding ex_robinhood to your list of dependencies in mix.exs:
def deps do
[
{:ex_robinhood, "~> 0.0.0"} # NOT AVAILABLE ON HEX YET !!!
]
endex_robinhood uses:
{:elixir_uuid, "~> 1.2"} # for generating device tokens
{:jason, "~> 1.2"} # decode responses
{:httpoison, "~> 1.7"} # http clientUsage
alias ExRobinhood, as: RH
# Unsuccessful response
{:error, reason} = RH.login("badEmail@example.com", "notMyPassword")
# Successful response
{:ok, "Challenge Required"} = RH.login("email@example.com", "myPassword")
# Submit 2FA sms code
{:ok, "Success"} = RH.challenge("123456")
# Query by symbol
{:ok, stock} = RH.query_instruments("nvda")
Return Values
Requests return a 2-tuple with the standard :ok or :error status.
Auth Functions
Login
Used to sign into your Robinhood account
def login(username, password)Challenge
Used to submit 2FA verification code as a string
def challenge(sms_code)Logout
Used to end your Robinhood session
def logoutAccount Functions
Account
Gets account data
def accountreturns:
{
:ok,
%{
"next" => nil,
"previous" => nil,
"results" => [
%{
"option_trading_on_expiration_enabled" => true,
"crypto_buying_power" => "0.0000",
"cash_held_for_options_collateral" => "0.0000",
"rhs_stock_loan_consent_status" => "...",
"cash_management_enabled" => false,
"account_number" => "XXXXXXXX",
"unsettled_debit" => "0.0000",
"locked" => false,
"eligible_for_drip" => false,
"eligible_for_cash_management" => true,
"only_position_closing_trades" => false,
"deactivated" => false,
"drip_enabled" => false,
"user_id" => "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"instant_eligibility" => %{
"additional_deposit_needed" => "0.0000",
"compliance_user_major_oak_email" => nil,
"created_at" => "1920-01-10T00:00:00.000000-04:00",
"created_by" => nil,
"reason" => "",
"reinstatement_date" => nil,
"reversal" => nil,
"state" => "ok",
"updated_at" => nil
},
"user" => "api.robinhood.com/user/",
"unsettled_funds" => "0.0000",
"type" => "margin",
"portfolio_cash" => "0.0000",
"cash_balances" => nil,
"cash_available_for_withdrawal" => "0.0000",
"margin_balances" => %{
"day_trades_protection" => true,
"crypto_buying_power" => "0.0000",
"cash_held_for_options_collateral" => "0.0000",
"instant_used" => "0.0000",
"start_of_day_overnight_buying_power" => "0.0000",
"marked_pattern_day_trader_date" => "1920-01-10T00:00:00.000000-04:00",
"cash_held_for_dividends" => "0.0000",
"margin_withdrawal_limit" => nil,
"unsettled_debit" => "0.0000",
"cash_held_for_restrictions" => "0.0000",
"funding_hold_balance" => "0.0000",
"margin_limit" => "0.0000",
"overnight_buying_power" => "0.0000",
"day_trade_buying_power" => "0.0000",
"gold_equity_requirement" => "0.0000",
"unsettled_funds" => "0.0000",
"cash_held_for_nummus_restrictions" => "0.0000",
"portfolio_cash" => "0.0000",
"eligible_deposit_as_instant" => "0.0000",
"cash_available_for_withdrawal" => "0.0000",
"uncleared_nummus_deposits" => "0.0000",
...
},
"received_ach_debit_locked" => false,
"uncleared_deposits" => "0.0000",
"sweep_enabled" => false,
"withdrawal_halted" => false,
"active_subscription_id" => nil,
"cash_held_for_orders" => "0.0000",
"state" => "active",
"created_at" => "1920-01-10T00:00:00.000000-04:00",
"buying_power" => "0.0000",
"cash" => "0.0000",
"sma" => "0.0000",
"eligible_for_fractionals" => true,
"rhs_account_number" => 123456789,
"is_pinnacle_account" => true,
"url" => "https://api.robinhood.com/accounts/XXXXXXXX/",
"deposit_halted" => false,
"can_downgrade_to_cash" => "https://api.robinhood.com/accounts/XXXXXXXX/can_downgrade_to_cash/",
"permanently_deactivated" => false,
"max_ach_early_access_amount" => "1000.00",
"sma_held_for_orders" => "0.0000",
"fractional_position_closing_only" => false,
...
}
]
}}
User
Gets user info
def userreturns:
{
:ok,
%{
"created_at" => "1920-01-10T00:00:00.000000-04:00",
"email" => "email@example.com",
"email_verified" => true,
"first_name" => "First",
"id" => "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"id_info" => "https://api.robinhood.com/user/id/",
"last_name" => "Last",
"origin" => %{"locality" => "US"},
"profile_name" => "FirstL12345",
"url" => "https://api.robinhood.com/user/",
"username" => "first.last"
}
}Investment Profile
Gets users investment-profile
def investment_profilereturns:
{
:ok,
%{
"annual_income" => "...",
"interested_in_options" => "...",
"investment_experience" => "...",
"investment_experience_collected" => true,
"investment_objective" => "...",
"liquid_net_worth" => "...",
"liquidity_needs" => "...",
"option_trading_experience" => "...",
"professional_trader" => "...",
"risk_tolerance" => "...",
"source_of_funds" => "...",
"suitability_verified" => true,
"tax_bracket" => "...",
"time_horizon" => "...",
"total_net_worth" => "...",
"understand_option_spreads" => "...",
"updated_at" => "1920-01-10T00:00:00.000000-04:00",
"user" => "api.robinhood.com/user/"
}
}Portfolios
Gets portfolios data
def portfoliosreturns:
{
:ok,
%{
"results" => [
%{
"account" => "https://api.robinhood.com/accounts/XXXXXXXX/",
"adjusted_equity_previous_close" => "0.0000",
"adjusted_portfolio_equity_previous_close" => "0.0000",
"equity" => "0.0000",
"equity_previous_close" => "0.0000",
"excess_maintenance" => "0.0000",
"excess_maintenance_with_uncleared_deposits" => "0.0000",
"excess_margin" => "0.0000",
"excess_margin_with_uncleared_deposits" => "0.0000",
"extended_hours_equity" => "0.0000",
"extended_hours_market_value" => "0.0000",
"extended_hours_portfolio_equity" => "0.0000",
"last_core_equity" => "0.0000",
"last_core_market_value" => "0.0000",
"last_core_portfolio_equity" => "0.0000",
"market_value" => "0.0000",
"portfolio_equity_previous_close" => "0.0000",
"start_date" => "1920-01-10T00:00:00.000000-04:00",
"unwithdrawable_deposits" => "0.0000",
"unwithdrawable_grants" => "0.0000",
"url" => "https://api.robinhood.com/portfolios/XXXXXXXX/",
"withdrawable_amount" => "0.0000"
}
]
}
}Dividends
Gets your dividends
def dividendsPositions
Gets your positions
def positionsSecurities Owned
Gets your currently owned securities
def securities_ownedProduct Functions
Query Instruments
Gets instrument by symbol, (can be used to get stocks id)
def query_instruments(stock)returns:
{
:ok,
%{
"next" => nil,
"previous" => nil,
"results" => [
%{
"bloomberg_unique" => "EQ0010169500001000",
"country" => "US",
"day_trade_ratio" => "0.2500",
"default_collar_fraction" => "0.05",
"fractional_tradability" => "tradable",
"fundamentals" => "https://api.robinhood.com/fundamentals/AAPL/",
"id" => "450dfc6d-5510-4d40-abfb-f633b7d9be3e",
"list_date" => "1990-01-02",
"maintenance_ratio" => "0.2500",
"margin_initial_ratio" => "0.5000",
"market" => "https://api.robinhood.com/markets/XNAS/",
"min_tick_size" => nil,
"name" => "Apple Inc. Common Stock",
"quote" => "https://api.robinhood.com/quotes/AAPL/",
"rhs_tradability" => "tradable",
"simple_name" => "Apple",
"splits" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/splits/",
"state" => "active",
"symbol" => "AAPL",
"tradability" => "tradable",
"tradable_chain_id" => "7dd906e5-7d4b-4161-a3fe-2c3b62038482",
"tradeable" => true,
"type" => "stock",
"url" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/"
}
]
}
}Instruments
Gets instrument by symbol
def instrument(symbol)returns:
{
:ok,
%{
"next" => nil,
"previous" => nil,
"results" => [
%{
"bloomberg_unique" => "EQ0010169500001000",
"country" => "US",
"day_trade_ratio" => "0.2500",
"default_collar_fraction" => "0.05",
"fractional_tradability" => "tradable",
"fundamentals" => "https://api.robinhood.com/fundamentals/AAPL/",
"id" => "450dfc6d-5510-4d40-abfb-f633b7d9be3e",
"list_date" => "1990-01-02",
"maintenance_ratio" => "0.2500",
"margin_initial_ratio" => "0.5000",
"market" => "https://api.robinhood.com/markets/XNAS/",
"min_tick_size" => nil,
"name" => "Apple Inc. Common Stock",
"quote" => "https://api.robinhood.com/quotes/AAPL/",
"rhs_tradability" => "tradable",
"simple_name" => "Apple",
"splits" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/splits/",
"state" => "active",
"symbol" => "AAPL",
"tradability" => "tradable",
"tradable_chain_id" => "7dd906e5-7d4b-4161-a3fe-2c3b62038482",
"tradeable" => true,
"type" => "stock",
"url" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/"
}
]
}
}Quote
Gets quote for product by id or symbol
def quote(id)returns:
{
:ok,
%{
"adjusted_previous_close" => "121.100000",
"ask_price" => "120.870000",
"ask_size" => 236,
"bid_price" => "120.830000",
"bid_size" => 100,
"has_traded" => true,
"instrument" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/",
"last_extended_hours_trade_price" => "120.850000",
"last_trade_price" => "121.190000",
"last_trade_price_source" => "consolidated",
"previous_close" => "121.100000",
"previous_close_date" => "2020-10-13",
"symbol" => "AAPL",
"trading_halted" => false,
"updated_at" => "2020-10-14T22:46:28Z"
}
}Quote List
Gets quote list for list or comma separated string of products by id or symbol (min: 2 items)
def quote_list(ids)returns:
{
:ok,
%{
"results" => [
%{
"adjusted_previous_close" => "121.100000",
"ask_price" => "121.100000",
"ask_size" => 50,
"bid_price" => "120.920000",
"bid_size" => 10,
"has_traded" => true,
"instrument" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/",
"last_extended_hours_trade_price" => "121.060000",
"last_trade_price" => "121.190000",
"last_trade_price_source" => "consolidated",
"previous_close" => "121.100000",
"previous_close_date" => "2020-10-13",
"symbol" => "AAPL",
"trading_halted" => false,
"updated_at" => "2020-10-14T23:13:18Z"
},
%{
"adjusted_previous_close" => "222.860000",
"ask_price" => "220.800000",
"ask_size" => 6,
"bid_price" => "220.350000",
"bid_size" => 1,
"has_traded" => true,
"instrument" => "https://api.robinhood.com/instruments/50810c35-d215-4866-9758-0ada4ac79ffa/",
"last_extended_hours_trade_price" => "220.600000",
"last_trade_price" => "220.860000",
"last_trade_price_source" => "consolidated",
"previous_close" => "222.860000",
"previous_close_date" => "2020-10-13",
"symbol" => "MSFT",
"trading_halted" => false,
"updated_at" => "2020-10-14T23:12:07Z"
},
nil
]
}
}Stock Marketdata
Gets marketdata for stocks
def stock_marketdata(symbols) # !Historical Quotes
Gets historical quotes for
Args:
- stock (str): stock ticker/s
-
interval (str): resolution of data ~~> Values are
5minute,10minute,hour,day,week. -
span (str): length of data ~~>
day,week,month,3month,year, or5year. -
bounds (atom ~~>
:extended|:regular): extended or regular trading hours ~~> default is:regular
returns:def historical_quotes(symbol, interval, span, bounds \\ :regular){ :ok, %{ "results" => [ %{ "InstrumentID" => "450dfc6d-5510-4d40-abfb-f633b7d9be3e", "bounds" => "regular", "historicals" => [ %{ "begins_at" => "2020-10-14T14:00:00Z", "close_price" => "122.120000", "high_price" => "122.820000", "interpolated" => false, "low_price" => "121.180000", "open_price" => "122.690700", "session" => "reg", "volume" => 13558258 }, %{ "begins_at" => "2020-10-14T15:00:00Z", "close_price" => "120.815000", "high_price" => "122.270000", "interpolated" => false, "low_price" => "120.720000", "open_price" => "122.130000", "session" => "reg", "volume" => 7667417 }, ... ], "instrument" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/", "interval" => "hour", "open_price" => "121.000000", "open_time" => "2020-10-14T13:30:00Z", "previous_close_price" => "121.100000", "previous_close_time" => "2020-10-13T20:00:00Z", "quote" => "https://api.robinhood.com/quotes/450dfc6d-5510-4d40-abfb-f633b7d9be3e/", "span" => "day", "symbol" => "AAPL" } ] } }
Popularity
Gets a stocks popularity on robinhood by id
def popularity(id) # !Tickers by Tag
Gets lists of tickers for selected category
Args: tag - Tags may include but are not limited to:
top-moversetf100-most-popularmutual-fundfinancecap-weightedinvestment-trust-or-fund
def tickers_by_tag(tag)returns:
{
:ok,
%{
"canonical_examples" => "",
"description" => "",
"instruments" => [
"https://api.robinhood.com/instruments/9f1399e5-5023-425a-9eb5-cd3f91560189/",
"https://api.robinhood.com/instruments/681574a9-a045-490d-a5f2-889f188c4605/",
"https://api.robinhood.com/instruments/01f5cac5-56e1-46d9-a782-b1a07a3ec3da/",
"https://api.robinhood.com/instruments/9f91a18c-b34d-4e67-a68b-2c29d20aa99c/",
"https://api.robinhood.com/instruments/894f3199-42be-4fcd-b725-d29ba4a8e821/",
"https://api.robinhood.com/instruments/0c7c5024-5431-4068-9034-0b0e2bfb4277/",
"https://api.robinhood.com/instruments/ece8cb62-ea02-4b9e-92fc-b404af27753f/",
"https://api.robinhood.com/instruments/8802a289-bdb5-4003-ae33-4dcd54abb1b7/",
"https://api.robinhood.com/instruments/c241e363-7635-49c4-9f98-a4a144f158eb/",
"https://api.robinhood.com/instruments/05411449-2743-475e-ab15-2f86e43e06a4/",
"https://api.robinhood.com/instruments/991a1c9b-6161-4c7a-b6ae-9a710c4fbff3/",
"https://api.robinhood.com/instruments/ea6bf532-d3ff-4094-9e6b-4fb473b2c702/",
"https://api.robinhood.com/instruments/52f36ef8-ae45-410d-8af7-0b7aaa2d276c/",
"https://api.robinhood.com/instruments/33c3c43d-d6b9-4df5-963a-7611acc416e9/",
"https://api.robinhood.com/instruments/c43ecf94-68e0-4fd8-a2a3-3ab5492ecf30/",
"https://api.robinhood.com/instruments/082877c8-2cbb-414a-9f46-e57c23b500df/",
"https://api.robinhood.com/instruments/ead8ebd4-3804-40f1-95ac-7c1b98818f9d/",
"https://api.robinhood.com/instruments/f551545a-16c0-4561-a44f-d5bcc6d316fc/",
"https://api.robinhood.com/instruments/8b486a6b-0632-4526-acf7-2167b22d8d94/",
"https://api.robinhood.com/instruments/3582a151-efd3-4e80-9496-667dfe3c86de/"
],
"membership_count" => 20,
"name" => "Top Movers",
"slug" => "top-movers"
}
}Fundamentals
Gets a stocks fundamentals info
def fundamentals(symbol)returns:
{
:ok,
%{
"average_volume" => "155470041.000000",
"average_volume_2_weeks" => "155470041.000000",
"ceo" => "Timothy Donald Cook",
"description" => "Apple, Inc. engages in the design, manufacture, and sale of smartphones, personal computers, tablets, wearables and accessories, and other variety of related services. It operates through the following geographical segments: Americas, Europe, Greater China, Japan, and Rest of Asia Pacific. The Americas segment includes North and South America. The Europe segment consists of European countries, as well as India, the Middle East, and Africa. The Greater China segment comprises of China, Hong Kong, and Taiwan. The Rest of Asia Pacific segment includes Australia and Asian countries. Its products and services include iPhone, Mac, iPad, AirPods, Apple TV, Apple Watch, Beats products, Apple Care, iCloud, digital content stores, streaming, and licensing services. The company was founded by Steven Paul Jobs, Ronald Gerald Wayne, and Stephen G. Wozniak on April 1, 1976 and is headquartered in Cupertino, CA.",
"dividend_yield" => "0.639068",
"float" => "17320118735.700001",
"headquarters_city" => "Cupertino",
"headquarters_state" => "California",
"high" => "123.030000",
"high_52_weeks" => "137.980000",
"industry" => "Telecommunications Equipment",
"instrument" => "https://api.robinhood.com/instruments/450dfc6d-5510-4d40-abfb-f633b7d9be3e/",
"low" => "119.620000",
"low_52_weeks" => "53.152500",
"market_cap" => "2101107387000.000000",
"num_employees" => 137000,
"open" => "121.000000",
"pb_ratio" => "29.491300",
"pe_ratio" => "37.819600",
"sector" => "Electronic Technology",
"shares_outstanding" => "17337300000.000000",
"volume" => "150969107.000000",
"year_founded" => 1976
}
}Order Functions
Args:
- instrument_url: the RH URL for the instrument (str)
- symbol: the ticker symbol for the instrument (str)
- order_type: 'market' or 'limit'
- time_in_force: 'gfd' or 'gtc' (day or until cancelled) (str)
- trigger: 'immediate' or 'stop' (str)
- price: The share price you'll accept (float)
- stop_price: The price at which the order becomes a market or limit order (float)
- quantity: The number of shares to buy/sell (int)
- side: 'buy' or 'sell' (str)
Order
Gets order by id
def order(order_id)Order History
Gets your order history
def order_historyPlace Market Buy Order
used to place market buy order
def place_market_buy_order(instrument_url, symbol, quantity, time_in_force \\ "gtc")Place Limit Buy Order
used to place limit buy order
def place_limit_buy_order(instrument_url, symbol, price, quantity, time_in_force \\ "gtc")Place Stop Loss Buy Order
used to stop loss buy order
def place_stop_loss_buy_order(instrument_url, symbol, stop_price, quantity, time_in_force \\ "gtc")Place Stop Limit Buy Order
used to place limit buy order
def place_stop_limit_buy_order(instrument_url, symbol, price, stop_price, quantity, time_in_force \\ "gtc")Place Market Sell Order
used to place market sell order
def place_market_sell_order(instrument_url, symbol, quantity, time_in_force \\ "gtc")Place Limit Sell Order
used to place limit sell order
def place_limit_sell_order(instrument_url, symbol, price, quantity, time_in_force \\ "gtc")Place Stop Loss Sell Order
used to place stop loss sell order
def place_stop_loss_sell_order(instrument_url, symbol, stop_price, quantity, time_in_force \\ "gtc")Place Stop Limit Sell Order
used to place stop limit sell order
def place_stop_limit_sell_order(instrument_url, symbol, price, stop_price, quantity, time_in_force \\ "gtc")Cancel Order
used to cancel an open order
def cancel_order(order_id)MSC...
(these shouldn't be needed)
Set Account Data
You can run this if it fails to run automatically during login, its needed for placing orders.
def set_account_urlPlace Order
it's easier to use: place_market_buy_order(), place_limit_sell_order(), etc...
Used to submit orders
Args:
- instrument_URL: the RH URL for the instrument (str)
- symbol: the ticker symbol for the instrument (str)
- order_type: 'market' or 'limit'
- time_in_force: 'gfd' or 'gtc' (day or until cancelled) (str)
- trigger: 'immediate' or 'stop' (str)
- price: The share price you'll accept (float)
- stop_price: The price at which the order becomes a market or limit order (float)
- quantity: The number of shares to buy/sell (int)
-
side: 'buy' or 'sell' (str)
def place_order(instrument_url, symbol, order_type, time_in_force, trigger, price, stop_price, quantity, side)
getting device token manually (instructions)
- Go to robinhood.com. Log out if you're already logged in
- Right click > Inspect element
- Click on Network tab
-
Enter
tokenin the input line at the top where it says "Filter" - With the network monitor-er open, login to Robinhood
- You'll see two new urls pop up that say "api.robinhood.com" and "/oauth2/token"
- Click the one that's not 0 bytes in size
- Click on Headers, then scroll down to the Request Payload section
- Here, you'll see new JSON parameters for your login. What you'll need here is the device token.
- Make sure you keep this saved
- If using the device_token from this method then 2FA will probably be bypassed.