New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

robinhood-typescript

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

robinhood-typescript - npm Package Compare versions

Comparing version 1.8.0 to 1.9.0

3

lib/index.d.ts

@@ -7,5 +7,5 @@ import { AccountsLoaded } from './models/account';

import { WatchListLoaded } from './models/watchlist';
import { OrdersLoaded } from './models/orders';
import { MarketsLoaded } from './models/markets';
import { QuotesLoaded } from './models/quotes';
import { OrdersLoaded, PlaceOrder } from './models/orders';
declare class RobinhoodAPI {

@@ -26,3 +26,4 @@ private _authToken;

quotes(symbol: string): Promise<QuotesLoaded>;
placeOrders(orderType: 'share' | 'dollar', side: 'buy' | 'sell', symbol: string, amount: number): Promise<PlaceOrder>;
}
export default RobinhoodAPI;

@@ -6,2 +6,3 @@ "use strict";

const axios_1 = require("axios");
const uuid_1 = require("uuid");
class RobinhoodAPI {

@@ -164,3 +165,54 @@ constructor(_authToken) {

}
async placeOrders(orderType, side, symbol, amount) {
const config = {
headers: { Authorization: `Bearer ${this._authToken}` },
};
// gets all needed account infromation (the account url )
const accountInfo = await this.account();
// gets all quote information (instrment url, stock price)
const quotesInfo = await this.quotes(symbol);
// Data is only used when orderType = share
const shareData = {
account: accountInfo.results[0].url,
extended_hours: false,
instrument: quotesInfo.instrument,
price: quotesInfo.bid_price,
quantity: amount.toString(),
// generates random uuid need for payload
ref_id: uuid_1.v4(),
side,
symbol,
time_in_force: 'gfd',
trigger: 'immediate',
type: 'market',
};
// Divides amount by current stock price to get the quantity of stock to purchase
const quantity = amount / Number(quotesInfo.bid_price);
// Data is only used when orderType = dollar
const dollarData = {
account: accountInfo.results[0].url,
dollar_based_amount: { amount: amount.toString(), currency_code: 'USD' },
amount: amount.toString(),
// TODO: make currency_code a param
currency_code: 'USD',
extended_hours: false,
quantity: parseFloat(quantity.toString()).toFixed(6).toString(),
instrument: quotesInfo.instrument,
price: quotesInfo.bid_price,
ref_id: uuid_1.v4(),
side,
symbol,
time_in_force: 'gfd',
trigger: 'immediate',
type: 'market',
};
try {
const response = await axios_1.default.post(`${defaults_1.apiUrl}${defaults_1.endpoints.orders}`, orderType === 'share' ? shareData : dollarData, config);
return response.data;
}
catch (error) {
return error;
}
}
}
exports.default = RobinhoodAPI;

@@ -106,2 +106,3 @@ export interface AccountsLoaded {

}
export declare const mockAccountData: AccountsLoaded;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mockAccountData = void 0;
exports.mockAccountData = {
next: null,
previous: null,
results: [
{
url: 'https://api.robinhood.com/accounts/123/',
portfolio_cash: '46.3200',
can_downgrade_to_cash: 'https://api.robinhood.com/accounts/598754190/can_downgrade_to_cash/',
user: 'api.robinhood.com/user/',
account_number: '51231',
type: 'margin',
created_at: '2019-01-04T01:40:28.560782Z',
updated_at: '2020-06-26T20:42:27.966301Z',
deactivated: false,
deposit_halted: false,
withdrawal_halted: false,
only_position_closing_trades: false,
buying_power: '46.0800',
cash_available_for_withdrawal: '0.0000',
cash: '46.3200',
cash_held_for_orders: '0.2400',
uncleared_deposits: '513.5400',
sma: '0',
sma_held_for_orders: '0',
unsettled_funds: '0.0000',
unsettled_debit: '407.2500',
crypto_buying_power: '46.0800',
max_ach_early_access_amount: '1000.00',
cash_balances: null,
margin_balances: {
uncleared_deposits: '513.5400',
cash: '46.3200',
cash_held_for_dividends: '0',
cash_held_for_restrictions: '0',
cash_held_for_nummus_restrictions: '0.0000',
cash_held_for_orders: '0.2400',
cash_available_for_withdrawal: '0.0000',
unsettled_funds: '0.0000',
unsettled_debit: '407.2500',
outstanding_interest: '0.0000',
unallocated_margin_cash: '46.0800',
margin_limit: '0.0000',
crypto_buying_power: '46.0800',
day_trade_buying_power: '46.0800',
sma: '0',
day_trades_protection: '',
start_of_day_overnight_buying_power: '46.0800',
overnight_buying_power: '46.0800',
overnight_buying_power_held_for_orders: '0.2400',
day_trade_buying_power_held_for_orders: '0.2400',
overnight_ratio: '1.00',
day_trade_ratio: '0.25',
marked_pattern_day_trader_date: null,
created_at: '2019-01-04T01:40:28.563354Z',
updated_at: '2020-07-01T02:38:31.938934Z',
start_of_day_dtbp: '46.2990',
portfolio_cash: '46.3200',
cash_held_for_options_collateral: '0.0000',
gold_equity_requirement: '0.0000',
uncleared_nummus_deposits: '0.0000',
cash_pending_from_options_events: '0.0000',
settled_amount_borrowed: '0.0000',
pending_deposit: '513.5400',
funding_hold_balance: '0.0000',
pending_debit_card_debits: '0.0000',
net_moving_cash: '0.0000',
margin_withdrawal_limit: null,
instant_used: '513.5400',
instant_allocated: '467.4600',
},
sweep_enabled: false,
instant_eligibility: {
reason: '',
reinstatement_date: null,
reversal: null,
state: 'ok',
updated_at: null,
additional_deposit_needed: '0.0000',
compliance_user_major_oak_email: null,
created_at: '2019-01-04T01:40:28.560782Z',
created_by: null,
},
option_level: 'option_level_2',
is_pinnacle_account: true,
rhs_account_number: 41651654,
state: false,
active_subscription_id: null,
locked: false,
permanently_deactivated: false,
received_ach_debit_locked: false,
drip_enabled: true,
eligible_for_fractionals: true,
eligible_for_drip: true,
eligible_for_cash_management: null,
eligible_for_trading_on_expiration: false,
cash_management_enabled: true,
option_trading_on_expiration_enabled: false,
cash_held_for_options_collateral: '0.0000',
fractional_position_closing_only: false,
user_id: 'kjlkfajs90klahjfasdj;l',
rhs_stock_loan_consent_status: 'needs_response',
},
],
};

@@ -53,2 +53,44 @@ export interface OrdersLoaded {

}
export interface PlaceOrder {
id: string;
ref_id: string;
url: string;
account: string;
position: string;
cancel: string;
instrument: string;
cumulative_quantity: string;
average_price: null | string;
fees: string;
state: string;
type: string;
side: 'buy' | 'sell';
time_in_force: string;
trigger: string;
price: string;
stop_price: null | string;
quantity: string;
reject_reason: null | string;
created_at: string;
updated_at: string;
last_transaction_at: string;
executions: any[];
extended_hours: boolean;
override_dtbp_checks: boolean;
override_day_trade_checks: boolean;
response_category: null | string;
stop_triggered_at: null | string;
last_trail_price: null | string;
last_trail_price_updated_at: null | string;
dollar_based_amount: null | DollarBasedAmount;
drip_dividend_id: null | string;
total_notional: TotalNotional;
executed_notional: null | string;
investment_schedule_id: null | string;
}
interface TotalNotional {
amount: string;
currency_code: string;
currency_id: string;
}
export {};

@@ -18,1 +18,2 @@ export interface QuotesLoaded {

}
export declare const mockQuotesData: QuotesLoaded;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mockQuotesData = void 0;
exports.mockQuotesData = {
ask_price: '0.280000',
ask_size: 12000,
bid_price: '0.202800',
bid_size: 100,
last_trade_price: '0.220400',
last_extended_hours_trade_price: '0.219000',
previous_close: '0.222000',
adjusted_previous_close: '0.222000',
previous_close_date: '2020-06-29',
symbol: 'OCGN',
trading_halted: false,
has_traded: true,
last_trade_price_source: 'consolidated',
updated_at: '2020-07-01T00:00:00Z',
instrument: 'https://api.robinhood.com/instruments/2a75b4f6-1c01-426e-a836-e93860d3e105/',
};
{
"name": "robinhood-typescript",
"version": "1.8.0",
"version": "1.9.0",
"description": "NodeJS Framework to make trades with the private Robinhood API. Using this API is not encouraged, since it's not officially available and it has been reverse engineered. See @Sanko's Unofficial Documentation for more information.",

@@ -42,3 +42,5 @@ "main": "lib/index.js",

"dependencies": {
"axios": "^0.19.2"
"@types/uuid": "^8.0.0",
"axios": "^0.19.2",
"uuid": "^8.2.0"
},

@@ -45,0 +47,0 @@ "publishConfig": {

import RobinhoodAPI from '../index';
import axios from 'axios';
import { AccountsLoaded, mockAccountData } from '../models/account';
import { QuotesLoaded, mockQuotesData } from '../models/quotes';

@@ -474,1 +476,100 @@ jest.mock('axios');

});
describe('Place Order', () => {
test('successfully placed Order of shares', async () => {
const api = new RobinhoodAPI('token');
const spyAccount = jest.spyOn(api, 'account');
const spyQuotes = jest.spyOn(api, 'quotes');
mockedAxios.get.mockResolvedValue(mockAccountData);
spyAccount.mockResolvedValue(Promise.resolve(mockAccountData));
mockedAxios.get.mockResolvedValue(mockQuotesData);
spyQuotes.mockResolvedValue(Promise.resolve(mockQuotesData));
const data = {
id: 'b7fb9387-8f65-4fe4-b841-5d85adc26aa0',
ref_id: 'de420631-7d8c-4af8-8e5a-ae7ddebec36',
url: 'https://api.robinhood.com/orders/b7fb9387-8f65-4fe4-b841-5d85adc26aa0/',
account: 'https://api.robinhood.com/accounts/598754190/',
position: 'https://api.robinhood.com/positions/598754190/2a75b4f6-1c01-426e-a836-e93860d3e105/',
cancel: 'https://api.robinhood.com/orders/b7fb9387-8f65-4fe4-b841-5d85adc26aa0/cancel/',
instrument: 'https://api.robinhood.com/instruments/2a75b4f6-1c01-426e-a836-e93860d3e105/',
cumulative_quantity: '0.00000000',
average_price: null,
fees: '0.00',
state: 'confirmed',
};
mockedAxios.post.mockResolvedValue({ data });
const placeOrderInfo = await api.placeOrders('share', 'buy', 'NIO', 1);
expect(placeOrderInfo).toEqual(data);
});
test('successfully placed Order of dollars', async () => {
const api = new RobinhoodAPI('token');
const spyAccount = jest.spyOn(api, 'account');
const spyQuotes = jest.spyOn(api, 'quotes');
mockedAxios.get.mockResolvedValue(mockAccountData);
spyAccount.mockResolvedValue(Promise.resolve(mockAccountData));
mockedAxios.get.mockResolvedValue(mockQuotesData);
spyQuotes.mockResolvedValue(Promise.resolve(mockQuotesData));
const data = {
id: 'b7fb9387-8f65-4fe4-b841-5d85adc26aa0',
ref_id: 'de420631-7d8c-4af8-8e5a-ae7ddebec36',
url: 'https://api.robinhood.com/orders/b7fb9387-8f65-4fe4-b841-5d85adc26aa0/',
account: 'https://api.robinhood.com/accounts/598754190/',
position: 'https://api.robinhood.com/positions/598754190/2a75b4f6-1c01-426e-a836-e93860d3e105/',
cancel: 'https://api.robinhood.com/orders/b7fb9387-8f65-4fe4-b841-5d85adc26aa0/cancel/',
instrument: 'https://api.robinhood.com/instruments/2a75b4f6-1c01-426e-a836-e93860d3e105/',
cumulative_quantity: '0.00000000',
average_price: null,
fees: '0.00',
state: 'confirmed',
};
mockedAxios.post.mockResolvedValue({ data });
const placeOrderInfo = await api.placeOrders('dollar', 'buy', 'NIO', 1);
expect(placeOrderInfo).toEqual(data);
});
test('failure placeOrder', async () => {
const api = new RobinhoodAPI('token');
const errorMessage = 'not enough funds';
const spyAccount = jest.spyOn(api, 'account');
const spyQuotes = jest.spyOn(api, 'quotes');
mockedAxios.get.mockResolvedValue(mockAccountData);
spyAccount.mockResolvedValue(Promise.resolve(mockAccountData));
mockedAxios.get.mockResolvedValue(mockQuotesData);
spyQuotes.mockResolvedValue(Promise.resolve(mockQuotesData));
const data = {
id: 'b7fb9387-8f65-4fe4-b841-5d85adc26aa0',
ref_id: 'de420631-7d8c-4af8-8e5a-ae7ddebec36',
url: 'https://api.robinhood.com/orders/b7fb9387-8f65-4fe4-b841-5d85adc26aa0/',
account: 'https://api.robinhood.com/accounts/598754190/',
position: 'https://api.robinhood.com/positions/598754190/2a75b4f6-1c01-426e-a836-e93860d3e105/',
cancel: 'https://api.robinhood.com/orders/b7fb9387-8f65-4fe4-b841-5d85adc26aa0/cancel/',
instrument: 'https://api.robinhood.com/instruments/2a75b4f6-1c01-426e-a836-e93860d3e105/',
cumulative_quantity: '0.00000000',
average_price: null,
fees: '0.00',
state: 'confirmed',
};
mockedAxios.post.mockRejectedValue(errorMessage);
const placeOrderInfo = await api.placeOrders('share', 'buy', 'NIO', 1);
expect(placeOrderInfo).toEqual(errorMessage);
});
});

@@ -8,8 +8,9 @@ import { apiUrl, endpoints } from './models/defaults';

import { WatchListLoaded } from './models/watchlist';
import { OrdersLoaded } from './models/orders';
import { MarketsLoaded } from './models/markets';
import { QuotesLoaded } from './models/quotes';
import { OrdersLoaded, PlaceOrder } from './models/orders';
// Dependencies
import axios, { AxiosResponse } from 'axios';
import { v4 as uuidv4 } from 'uuid';

@@ -202,4 +203,69 @@ class RobinhoodAPI {

}
async placeOrders(
orderType: 'share' | 'dollar',
side: 'buy' | 'sell',
symbol: string,
amount: number,
): Promise<PlaceOrder> {
const config = {
headers: { Authorization: `Bearer ${this._authToken}` },
};
// gets all needed account infromation (the account url )
const accountInfo = await this.account();
// gets all quote information (instrment url, stock price)
const quotesInfo = await this.quotes(symbol);
// Data is only used when orderType = share
const shareData = {
account: accountInfo.results[0].url,
extended_hours: false,
instrument: quotesInfo.instrument,
price: quotesInfo.bid_price,
quantity: amount.toString(),
// generates random uuid need for payload
ref_id: uuidv4(),
side,
symbol,
time_in_force: 'gfd',
trigger: 'immediate',
type: 'market',
};
// Divides amount by current stock price to get the quantity of stock to purchase
const quantity = amount / Number(quotesInfo.bid_price);
// Data is only used when orderType = dollar
const dollarData = {
account: accountInfo.results[0].url,
dollar_based_amount: { amount: amount.toString(), currency_code: 'USD' },
amount: amount.toString(),
// TODO: make currency_code a param
currency_code: 'USD',
extended_hours: false,
quantity: parseFloat(quantity.toString()).toFixed(6).toString(),
instrument: quotesInfo.instrument,
price: quotesInfo.bid_price,
ref_id: uuidv4(),
side,
symbol,
time_in_force: 'gfd',
trigger: 'immediate',
type: 'market',
};
try {
const response: AxiosResponse<PlaceOrder> = await axios.post(
`${apiUrl}${endpoints.orders}`,
orderType === 'share' ? shareData : dollarData,
config,
);
return response.data;
} catch (error) {
return error;
}
}
}
export default RobinhoodAPI;

@@ -109,1 +109,106 @@ export interface AccountsLoaded {

}
export const mockAccountData: AccountsLoaded = {
next: null,
previous: null,
results: [
{
url: 'https://api.robinhood.com/accounts/123/',
portfolio_cash: '46.3200',
can_downgrade_to_cash: 'https://api.robinhood.com/accounts/598754190/can_downgrade_to_cash/',
user: 'api.robinhood.com/user/',
account_number: '51231',
type: 'margin',
created_at: '2019-01-04T01:40:28.560782Z',
updated_at: '2020-06-26T20:42:27.966301Z',
deactivated: false,
deposit_halted: false,
withdrawal_halted: false,
only_position_closing_trades: false,
buying_power: '46.0800',
cash_available_for_withdrawal: '0.0000',
cash: '46.3200',
cash_held_for_orders: '0.2400',
uncleared_deposits: '513.5400',
sma: '0',
sma_held_for_orders: '0',
unsettled_funds: '0.0000',
unsettled_debit: '407.2500',
crypto_buying_power: '46.0800',
max_ach_early_access_amount: '1000.00',
cash_balances: null,
margin_balances: {
uncleared_deposits: '513.5400',
cash: '46.3200',
cash_held_for_dividends: '0',
cash_held_for_restrictions: '0',
cash_held_for_nummus_restrictions: '0.0000',
cash_held_for_orders: '0.2400',
cash_available_for_withdrawal: '0.0000',
unsettled_funds: '0.0000',
unsettled_debit: '407.2500',
outstanding_interest: '0.0000',
unallocated_margin_cash: '46.0800',
margin_limit: '0.0000',
crypto_buying_power: '46.0800',
day_trade_buying_power: '46.0800',
sma: '0',
day_trades_protection: '',
start_of_day_overnight_buying_power: '46.0800',
overnight_buying_power: '46.0800',
overnight_buying_power_held_for_orders: '0.2400',
day_trade_buying_power_held_for_orders: '0.2400',
overnight_ratio: '1.00',
day_trade_ratio: '0.25',
marked_pattern_day_trader_date: null,
created_at: '2019-01-04T01:40:28.563354Z',
updated_at: '2020-07-01T02:38:31.938934Z',
start_of_day_dtbp: '46.2990',
portfolio_cash: '46.3200',
cash_held_for_options_collateral: '0.0000',
gold_equity_requirement: '0.0000',
uncleared_nummus_deposits: '0.0000',
cash_pending_from_options_events: '0.0000',
settled_amount_borrowed: '0.0000',
pending_deposit: '513.5400',
funding_hold_balance: '0.0000',
pending_debit_card_debits: '0.0000',
net_moving_cash: '0.0000',
margin_withdrawal_limit: null,
instant_used: '513.5400',
instant_allocated: '467.4600',
},
sweep_enabled: false,
instant_eligibility: {
reason: '',
reinstatement_date: null,
reversal: null,
state: 'ok',
updated_at: null,
additional_deposit_needed: '0.0000',
compliance_user_major_oak_email: null,
created_at: '2019-01-04T01:40:28.560782Z',
created_by: null,
},
option_level: 'option_level_2',
is_pinnacle_account: true,
rhs_account_number: 41651654,
state: false,
active_subscription_id: null,
locked: false,
permanently_deactivated: false,
received_ach_debit_locked: false,
drip_enabled: true,
eligible_for_fractionals: true,
eligible_for_drip: true,
eligible_for_cash_management: null,
eligible_for_trading_on_expiration: false,
cash_management_enabled: true,
option_trading_on_expiration_enabled: false,
cash_held_for_options_collateral: '0.0000',
fractional_position_closing_only: false,
user_id: 'kjlkfajs90klahjfasdj;l',
rhs_stock_loan_consent_status: 'needs_response',
},
],
};

@@ -56,1 +56,45 @@ export interface OrdersLoaded {

}
export interface PlaceOrder {
id: string;
ref_id: string;
url: string;
account: string;
position: string;
cancel: string;
instrument: string;
cumulative_quantity: string;
average_price: null | string;
fees: string;
state: string;
type: string;
side: 'buy' | 'sell';
time_in_force: string;
trigger: string;
price: string;
stop_price: null | string;
quantity: string;
reject_reason: null | string;
created_at: string;
updated_at: string;
last_transaction_at: string;
executions: any[];
extended_hours: boolean;
override_dtbp_checks: boolean;
override_day_trade_checks: boolean;
response_category: null | string;
stop_triggered_at: null | string;
last_trail_price: null | string;
last_trail_price_updated_at: null | string;
dollar_based_amount: null | DollarBasedAmount;
drip_dividend_id: null | string;
total_notional: TotalNotional;
executed_notional: null | string;
investment_schedule_id: null | string;
}
interface TotalNotional {
amount: string;
currency_code: string;
currency_id: string;
}

@@ -1,3 +0,1 @@

import { SupportOptionValue } from 'prettier';
export interface QuotesLoaded {

@@ -20,1 +18,19 @@ ask_price: string;

}
export const mockQuotesData: QuotesLoaded = {
ask_price: '0.280000',
ask_size: 12000,
bid_price: '0.202800',
bid_size: 100,
last_trade_price: '0.220400',
last_extended_hours_trade_price: '0.219000',
previous_close: '0.222000',
adjusted_previous_close: '0.222000',
previous_close_date: '2020-06-29',
symbol: 'OCGN',
trading_halted: false,
has_traded: true,
last_trade_price_source: 'consolidated',
updated_at: '2020-07-01T00:00:00Z',
instrument: 'https://api.robinhood.com/instruments/2a75b4f6-1c01-426e-a836-e93860d3e105/',
};

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc