robinhood-yolo
Version:
NodeJS API wrapper for Robinhood Options trading and CLI to trade from your terminal
1,158 lines (1,114 loc) • 32.6 kB
JavaScript
var Api, assert, axios, b64Dec, dataStore, detPrint, endpoints, newApiObj, p, roundNum, sleep, sortOptions, uuid;
p = require('print-tools-js');
assert = require('assert');
uuid = require('uuidv4').uuid;
endpoints = require('./endpoints');
axios = require('axios');
b64Dec = require('./miscFunctions').b64Dec;
detPrint = require('./miscFunctions').detPrint;
roundNum = require('./miscFunctions').roundNum;
sortOptions = require('./miscFunctions').sortOptions;
dataStore = require('./dataStore')();
//: API Object
Api = class Api {
//: Constructor
constructor(args = {
newLogin: false,
configIndex: 0,
configData: null,
print: false
}) {
args = {
newLogin: false,
configIndex: 0,
configData: null,
print: false,
...args
};
this.headers = {
Accept: '*/*',
Connection: 'keep-alive',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en;q=1, fr;q=0.9, de;q=0.8, ja;q=0.7, nl;q=0.6, it;q=0.5',
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'X-Robinhood-API-Version': '1.0.0',
'User-Agent': 'Robinhood/823 (iPhone; iOS 7.1.2; Scale/2.00)'
};
this.clientId = 'c82SH0WZOsabOXGP2sxqcj34FxkvfnWRZBKlBjFS';
this.session = axios.create({
timeout: 10000,
headers: this.headers
});
this.configIndex = args.configIndex;
this.newLogin = args.newLogin;
this.print = args.print;
if (args.configData != null) {
this.configData = args.configData;
this.externalConfig = true;
} else {
dataStore.getDataFiles();
this.configData = dataStore.configData[this.configIndex];
this.externalConfig = false;
}
}
//: Login Flow
async login(args = {
newLogin: false,
configIndex: 0
}) {
var error;
args = {
newLogin: false,
configIndex: 0,
...args
};
try {
if (args.newLogin != null) {
this.newLogin = args.newLogin;
}
await this.auth({
newLogin: args.newLogin,
configIndex: args.configIndex
});
if (this.print) {
p.success(`${this.username} logged in.`);
}
return true;
} catch (error1) {
error = error1;
if (this.print) {
p.error(`${this.username} could not login.`);
detPrint(error);
}
throw error;
}
}
//: Authentification
async auth(args = {
newLogin: false,
configIndex: 0
}) {
var accUrl, error, res;
try {
args = {
newLogin: false,
configIndex: 0,
...args
};
this.configIndex = args.configIndex;
if (this.configData == null) {
this.configData = dataStore.configData[this.configIndex];
this.externalConfig = false;
}
this.username = b64Dec(this.configData.u_n);
if ((Date.now() > this.configData.t_s + 86400000) || args.newLogin) {
res = (await this.postUrl(endpoints.login(), {
grant_type: 'password',
client_id: this.clientId,
device_token: b64Dec(this.configData.d_t),
username: this.username,
password: b64Dec(this.configData.p_w)
}));
this.accessToken = res.access_token;
this.refreshToken = res.refresh_token;
this.authToken = `Bearer ${this.accessToken}`;
this.session.defaults.headers.common['Authorization'] = this.authToken;
if ((this.configData.a_u != null) || this.configData.a_u === '' || args.newLogin) {
accUrl = (await this.getAccount());
this.accountUrl = accUrl.url;
this.accountId = accUrl.account_number;
} else {
this.accountUrl = this.configData.a_u;
this.accountId = this.configData.a_i;
}
Object.assign(this.configData, {
a_t: this.accessToken,
r_t: this.refreshToken,
a_b: this.authToken,
a_u: this.accountUrl,
a_i: this.accountId,
t_s: Date.now()
});
dataStore.configData[this.configIndex] = this.configData;
if (!this.externalConfig) {
dataStore.updateJson('yolo_config', dataStore.configData);
}
} else {
this.accessToken = this.configData.a_t;
this.refreshToken = this.configData.r_t;
this.authToken = this.configData.a_b;
this.accountUrl = this.configData.a_u;
this.accountId = this.configData.a_i;
this.session.defaults.headers.common['Authorization'] = this.authToken;
}
if (!this.externalConfig) {
return true;
} else {
return this.configData;
}
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Account Info
async getAccount(args = {
consume: true
}) {
var data, error;
try {
args = {
consume: true,
...args
};
data = (await this.getUrl(endpoints.accounts(), args.consume));
return data[0];
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Portfolio Info
async getPortfolioInfo() {
var accountInfo, error;
try {
if (this.accountId == null) {
accountInfo = (await this.getAccount());
this.accountId = accountInfo.account_number;
}
return (await this.getUrl(endpoints.portfolios(this.accountId)));
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Account Equity
async getAccountEquity() {
var curTime, dateNum, equity, error, portfolioInfo;
try {
portfolioInfo = (await this.getPortfolioInfo());
curTime = new Date();
dateNum = (curTime.getHours() * 10000) + (curTime.getMinutes() * 100) + curTime.getSeconds();
equity = (dateNum >= 93000 && dateNum <= 160000) ? portfolioInfo.equity : portfolioInfo.extended_hours_equity;
return Number(equity);
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Cash Balance
async getCashBalance() {
var accountInfo, cash, cashBalance, unclearedDeposits;
accountInfo = (await this.getAccount());
cash = Number(accountInfo.margin_balances.cash) || 0;
unclearedDeposits = Number(accountInfo.margin_balances.uncleared_deposits) || 0;
cashBalance = cash - unclearedDeposits;
return cashBalance;
}
//: Get Transfers
async getTransfers(args = {
consume: true
}) {
var error;
try {
args = {
consume: true,
...args
};
return (await this.getUrl(endpoints.transfers(), args.consume));
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Market Hours
async getMarketHours(date) {
var error;
try {
return (await this.getUrl(endpoints.marketHours(date)));
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Watch List
async getWatchList(args = {
watchList: 'Default',
instrumentData: false,
quoteData: false,
consume: true
}) {
var data, error, i, instData, j, k, len, quotes, ref, ticker, tickers;
try {
args = {
watchList: 'Default',
instrumentData: false,
quoteData: false,
consume: true,
...args
};
tickers = [];
data = (await this.getUrl(endpoints.watchList(args.watchList), args.consume));
for (j = 0, len = data.length; j < len; j++) {
ticker = data[j];
ticker.id = ticker.instrument.match('(?<=instruments\/).[^\/]+')[0];
if (args.instrumentData) {
instData = (await this.getUrl(ticker.instrument));
ticker.instrument_data = instData;
}
if (args.quoteData) {
tickers.push(ticker.instrument_data.symbol);
}
}
if (args.quoteData) {
quotes = (await this.quotes(tickers));
for (i = k = 0, ref = data.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
data[i].quote_data = quotes[i];
}
}
return data;
} catch (error1) {
error = error1;
throw error;
}
}
//: Get History
async getHistory(args = {
options: true,
stocks: true,
banking: true,
consume: true
}) {
var allHistory, allOptions, allStocks, allTransfers, chainIndex, chainRes, defaultLeg, defaultRecord, endIndex, error, execution, histRes, instIndex, instRes, instruments, j, k, l, leg, legChains, legIndex, legPrice, legQuantity, len, len1, len2, len3, len4, m, n, newOrder, optionIndex, order, ref, ref1, requests, stock, stockStartIndex, transfer, typeIndex, typeIndexes;
try {
args = {
options: true,
stocks: true,
banking: true,
consume: true,
...args
};
defaultRecord = {
broker: 'Robinhood',
account: this.username,
type: '',
direction: '',
date: '',
ticker: '',
strategy: '',
amount: 0,
quantity: 0
};
defaultLeg = {
price: 0,
quantity: 0,
strike: 0,
type: '',
expiration: '',
side: ''
};
requests = [];
typeIndex = 0;
typeIndexes = {
options: -1,
stocks: -1,
transfers: -1
};
if (args.options) {
requests.push(this.optionsOrders({
consume: args.consume
}));
typeIndexes.options = typeIndex;
typeIndex += 1;
}
if (args.stocks) {
requests.push(this.stockOrders({
consume: args.consume
}));
typeIndexes.stocks = typeIndex;
typeIndex += 1;
}
if (args.banking) {
requests.push(this.getTransfers({
consume: args.consume
}));
typeIndexes.transfers = typeIndex;
typeIndex += 1;
}
histRes = (await Promise.all(requests));
allOptions = typeIndexes.options === -1 ? [] : histRes[typeIndexes.options];
allStocks = typeIndexes.stocks === -1 ? [] : histRes[typeIndexes.stocks];
allTransfers = typeIndexes.transfers === -1 ? [] : histRes[typeIndexes.transfers];
allHistory = [];
legChains = [];
instruments = [];
// Options Transactions
for (j = 0, len = allOptions.length; j < len; j++) {
order = allOptions[j];
if (Number(order.processed_premium) > 0) {
newOrder = {
...defaultRecord,
type: 'option',
direction: order.direction,
date: order.updated_at,
ticker: order.chain_symbol,
strategy: order.opening_strategy || order.closing_strategy || '',
amount: Number(order.processed_premium),
quantity: Number(order.processed_quantity),
legIndex: legChains.length,
legs: []
};
ref = order.legs;
for (k = 0, len1 = ref.length; k < len1; k++) {
leg = ref[k];
legPrice = 0;
legQuantity = 0;
ref1 = leg.executions;
for (l = 0, len2 = ref1.length; l < len2; l++) {
execution = ref1[l];
legPrice += Number(execution.price);
legQuantity += Number(execution.quantity);
}
legChains.push(this.getUrl(leg.option));
newOrder.legs.push({
...defaultLeg,
price: legPrice,
quantity: legQuantity,
side: leg.side
});
}
allHistory.push(newOrder);
}
}
optionIndex = 0;
legIndex = 0;
endIndex = allHistory[optionIndex + 1] != null ? allHistory[optionIndex + 1].legIndex : allHistory.length;
chainRes = (await Promise.all(legChains));
for (chainIndex in chainRes) {
if (chainIndex >= endIndex) {
optionIndex += 1;
legIndex = allHistory[optionIndex].legIndex;
endIndex = allHistory[optionIndex + 1] != null ? allHistory[optionIndex + 1].legIndex : allHistory.length;
}
if (allHistory[optionIndex].legIndex != null) {
delete allHistory[optionIndex].legIndex;
}
allHistory[optionIndex].legs[chainIndex - legIndex] = {
...allHistory[optionIndex].legs[chainIndex - legIndex],
strike: Number(chainRes[chainIndex].strike_price),
type: chainRes[chainIndex].type,
expiration: chainRes[chainIndex].expiration_date
};
}
// Stock Transactions
stockStartIndex = allHistory.length;
for (m = 0, len3 = allStocks.length; m < len3; m++) {
stock = allStocks[m];
if ((stock.executed_notional != null) && Number(stock.executed_notional.amount) > 0) {
allHistory.push({
...defaultRecord,
type: 'stock',
direction: stock.side === 'sell' ? 'credit' : 'debit',
date: stock.updated_at,
amount: Number(stock.executed_notional.amount) - Number(stock.fees),
quantity: Number(stock.cumulative_quantity),
legs: []
});
instruments.push(this.getUrl(stock.instrument));
}
}
instRes = (await Promise.all(instruments));
for (instIndex in instRes) {
allHistory[stockStartIndex + Number(instIndex)].ticker = instRes[instIndex].symbol;
}
// Account Transactions
for (n = 0, len4 = allTransfers.length; n < len4; n++) {
transfer = allTransfers[n];
if (transfer.state === 'completed') {
allHistory.push({
...defaultRecord,
type: 'transfer',
direction: transfer.direction === 'withdraw' ? 'debit' : 'credit',
date: transfer.updated_at,
amount: Number(transfer.amount),
legs: []
});
}
}
allHistory.sort((a, b) => {
if (a.date > b.date) {
return -1;
} else {
return 1;
}
});
return allHistory;
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Quotes
async quotes(symbols, args = {
chainData: false,
consume: true
}) {
var data, error, j, len, obj;
try {
args = {
chainData: false,
consume: true,
...args
};
if (!Array.isArray(symbols)) {
data = (await this.getUrl(endpoints.quotes(symbols)));
} else {
data = (await this.getUrl(endpoints.quotes(symbols), args.consume));
}
if (!Array.isArray(data)) {
data = [data];
}
if (args.chainData) {
for (j = 0, len = data.length; j < len; j++) {
obj = data[j];
obj.instrument_data = (await this.getUrl(obj.instrument));
obj.chain_data = (await this.chain(obj.instrument_data.id));
}
}
if (!Array.isArray(symbols)) {
return data[0];
}
return data;
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Historicals
async historicals(symbols, args = {
span: 'month',
bounds: 'regular'
}) {
var arr, data, error, j, len, symbolData;
try {
args = {
span: 'month',
bounds: 'regular',
...args
};
data = (await this.getUrl(endpoints.historicals(symbols, args.span, args.bounds)));
if (!Array.isArray(symbols)) {
return data[0].historicals;
} else {
symbolData = [];
for (j = 0, len = data.length; j < len; j++) {
arr = data[j];
symbolData.push(arr.historicals);
}
return symbolData;
}
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Instrument Data
async chain(instrumentId, args = {
consume: true
}) {
var error;
try {
args = {
consume: true,
...args
};
return (await this.getUrl(endpoints.chain(instrumentId), args.consume));
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Market Data
async marketData(optionId) {
var error;
try {
return (await this.getUrl(endpoints.marketData(optionId)));
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Options
async getOptions(symbol, expirationDate, args = {
optionType: 'call',
marketData: false,
expired: false,
consume: true
}) {
var chainData, chainId, data, error, j, k, len, len1, obj, ticker;
try {
args = {
optionType: 'call',
marketData: false,
expired: false,
consume: true,
...args
};
chainId;
chainData = (await this.quotes(symbol, {
chainData: true
}));
chainData = chainData.chain_data;
for (j = 0, len = chainData.length; j < len; j++) {
ticker = chainData[j];
if (ticker.symbol === symbol) {
chainId = ticker.id;
}
}
if (!args.expired) {
data = (await this.getUrl(endpoints.options(chainId, expirationDate, args.optionType), args.consume));
} else {
data = (await this.getUrl(endpoints.expiredOptions(chainId, expirationDate, args.optionType), args.consume));
}
if (args.marketData) {
for (k = 0, len1 = data.length; k < len1; k++) {
obj = data[k];
obj.market_data = (await this.marketData(obj.id));
}
}
return data;
} catch (error1) {
error = error1;
throw error;
}
}
//: Find Options
async findOptions(symbol, expirationDate, args = {
optionType: 'call',
strikeType: 'itm',
strikeDepth: 0,
marketData: false,
range: null,
strike: null,
expired: false
}) {
var curTime, dateNum, error, i, itmIndex, j, k, len, obj, options, quote, ref, strikePrice;
try {
args = {
optionType: 'call',
strikeType: 'itm',
strikeDepth: 0,
marketData: false,
range: null,
strike: null,
expired: false,
...args
};
curTime = new Date();
dateNum = (curTime.getHours() * 10000) + (curTime.getMinutes() * 100) + curTime.getSeconds();
options = (await this.getOptions(symbol, expirationDate, {
optionType: args.optionType,
expired: args.expired
}));
options.sort(sortOptions);
if (args.strike != null) {
args.strike = roundNum(args.strike);
}
quote = (await this.quotes(symbol));
if (dateNum > 93000) {
quote = roundNum(quote.last_trade_price);
} else {
quote = roundNum(quote.last_extended_hours_trade_price);
}
itmIndex;
for (i = j = 0, ref = options.length; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) {
strikePrice = roundNum(options[i].strike_price);
if (strikePrice === quote || strikePrice === args.strike) {
itmIndex = i;
break;
} else if (args.optionType === 'call' && strikePrice < quote) {
itmIndex = i;
break;
} else if (args.optionType === 'put' && strikePrice < quote) {
itmIndex = i - 1;
break;
}
}
if ((args.range == null) && (args.strike == null)) {
if (args.optionType === 'call' && args.strikeType === 'itm') {
options = [options[itmIndex + args.strikeDepth]];
} else if (args.optionType === 'call' && args.strikeType === 'otm') {
options = [options[itmIndex - 1 - args.strikeDepth]];
} else if (args.optionType === 'put' && args.strikeType === 'itm') {
options = [options[itmIndex - args.strikeDepth]];
} else if (args.optionType === 'put' && args.strikeType === 'otm') {
options = [options[itmIndex + 1 + args.strikeDepth]];
}
} else if (args.range != null) {
options = options.slice(itmIndex - args.range, itmIndex + args.range);
} else if (args.strike != null) {
options = [options[itmIndex]];
}
if (args.marketData) {
for (k = 0, len = options.length; k < len; k++) {
obj = options[k];
obj.market_data = (await this.marketData(obj.id));
}
}
if (args.range == null) {
return options[0];
} else {
return options;
}
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Options Historicals
async findOptionHistoricals(symbol, expirationDate, args = {
optionType: 'call',
strikeType: 'itm',
strikeDepth: 0,
strike: null,
expired: true,
span: 'month',
consume: true
}) {
var data, error, option;
try {
args = {
optionType: 'call',
strikeType: 'itm',
strikeDepth: 0,
strike: null,
expired: true,
interval: 'hour',
span: 'month',
consume: true,
...args
};
option = (await this.findOptions(symbol, expirationDate, args));
data = (await this.getUrl(endpoints.optionsHistoricals(option.url, args.span), args.consume));
return data[0].data_points;
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Options Postions
async optionsPositions(args = {
marketData: false,
orderData: false,
openOnly: true,
notFilled: false,
consume: true
}) {
var arg, breakLoop, data, error, j, k, key, l, leg, len, len1, len2, len3, len4, len5, len6, m, n, notFilled, o, obj, openData, options, orderData, orders, pos, q, ref, value;
try {
args = {
markedData: false,
orderData: false,
openOnly: true,
notFilled: false,
consume: true,
...args
};
data = (await this.getUrl(endpoints.optionsPositions(), args.consume));
if (args.openOnly) {
openData = [];
for (j = 0, len = data.length; j < len; j++) {
pos = data[j];
if (Number(pos.quantity) > 0) {
openData.push(pos);
}
}
data = openData;
}
if (args.orderData) {
orders = [];
for (k = 0, len1 = data.length; k < len1; k++) {
obj = data[k];
orders.push(obj.option);
}
if (!args.notFilled) {
orderData = (await this.optionsOrders({
urls: orders,
buyOnly: true
}));
for (l = 0, len2 = data.length; l < len2; l++) {
obj = data[l];
for (key in orderData) {
value = orderData[key];
if (obj.option === key) {
obj.order_data = value;
delete orderData[key];
break;
}
}
}
} else if (args.notFilled) {
notFilled = [];
orderData = (await this.optionsOrders({
notFilled: true
}));
breakLoop = false;
for (m = 0, len3 = orderData.length; m < len3; m++) {
obj = orderData[m];
for (n = 0, len4 = data.length; n < len4; n++) {
arg = data[n];
ref = obj.legs;
for (o = 0, len5 = ref.length; o < len5; o++) {
leg = ref[o];
breakLoop = false;
if (leg.option === arg.option) {
breakLoop = true;
arg.order_data = obj;
notFilled.push(arg);
break;
}
}
if (breakLoop) {
break;
}
}
}
data = notFilled;
}
}
if (args.marketData) {
options = [];
for (q = 0, len6 = data.length; q < len6; q++) {
obj = data[q];
obj.option_data = (await this.getUrl(obj.option));
obj.market_data = (await this.marketData(obj.option_data.id));
}
}
return data;
} catch (error1) {
error = error1;
throw error;
}
}
//: Get Options Orders
async optionsOrders(args = {
urls: null,
id: null,
notFilled: false,
buyOnly: false,
consume: true
}) {
var data, error, fetchOrders, j, len, notFilled, order;
try {
data = null;
args = {
urls: null,
id: null,
notFilled: false,
buyOnly: false,
consume: true,
...args
};
if (args.id != null) {
return (await this.getUrl(endpoints.optionsOrders(args.id)));
}
if (args.urls != null) {
fetchOrders = function(data, options) {
var arg, breakLoop, j, k, l, leg, len, len1, len2, obj, ref, ref1, results;
results = {};
breakLoop = false;
if (!Array.isArray(options.args)) {
options.args = [options.args];
}
ref = options.args;
for (j = 0, len = ref.length; j < len; j++) {
arg = ref[j];
for (k = 0, len1 = data.length; k < len1; k++) {
obj = data[k];
ref1 = obj.legs;
for (l = 0, len2 = ref1.length; l < len2; l++) {
leg = ref1[l];
breakLoop = false;
if (leg.option === arg) {
if (options.mod && obj.direction === 'debit' && leg.side === 'buy') {
breakLoop = true;
results[arg] = obj;
break;
} else if (!options.mod) {
breakLoop = true;
results[arg] = obj;
break;
}
}
}
if (breakLoop) {
break;
}
}
}
return results;
};
data = (await this.getDataFromUrl(endpoints.optionsOrders(), fetchOrders, {
args: args.urls,
mod: args.buyOnly
}));
} else {
data = (await this.getUrl(endpoints.optionsOrders(), args.consume));
}
if (args.notFilled) {
notFilled = [];
if (!Array.isArray(data)) {
data = [data];
}
for (j = 0, len = data.length; j < len; j++) {
order = data[j];
if (order.cancel_url != null) {
notFilled.push(order);
}
}
data = notFilled;
}
return data;
} catch (error1) {
error = error1;
throw error;
}
}
//: Stock Orders
async stockOrders(args = {
consume: true
}) {
var data, error;
try {
args = {
consume: true,
...args
};
data = (await this.getUrl(endpoints.stockOrders(), args.consume));
return data;
} catch (error1) {
error = error1;
throw error;
}
}
//: Place Option Order
async placeOptionOrder(option, quantity, price, args = {
direction: 'debit',
side: 'buy',
positionEffect: 'open',
legs: null
}) {
var error, legs;
try {
legs = null;
args = {
direction: 'debit',
side: 'buy',
positionEffect: 'open',
legs: null,
...args
};
assert(typeof option === 'string');
assert(!isNaN(quantity));
assert(!isNaN(price));
assert(['debit', 'credit'].includes(args.direction));
assert(['buy', 'sell'].includes(args.side));
assert(['open', 'close'].includes(args.positionEffect));
if (args.legs == null) {
legs = [
{
option: option,
side: args.side,
position_effect: args.positionEffect,
ratio_quantity: 1
}
];
} else {
legs = args.legs;
}
if (option === 'null' && args.direction === 'credit' && legs[0].side === 'sell') {
if (this.print) {
p.warning('Will sleep before placing sell order...');
}
await sleep(1000);
}
return (await this.placeOrderFlow(quantity, price, args, legs));
} catch (error1) {
error = error1;
throw error;
}
}
//: Cancel Option Order
async cancelOptionOrder(cancelUrl) {
var data, error;
try {
assert(typeof cancelUrl === 'string');
data = (await this.postUrl(cancelUrl, {}));
if (data = {}) {
return true;
} else {
return false;
}
} catch (error1) {
error = error1;
throw error;
}
}
//: Replace Option Order
async replaceOptionOrder(quantity, price, args = {
order: null,
orderId: null
}) {
var data, error;
try {
data = null;
args = {
order: null,
orderId: null,
...args
};
assert((args.order != null) || (args.orderId != null));
if ((args.order == null) && (args.orderId != null)) {
data = (await this.optionsOrders({
id: args.orderId
}));
} else {
data = args.order;
}
if ((await this.cancelOptionOrder(data.cancel_url))) {
return (await this.placeOptionOrder('null', quantity, price, {
direction: data.direction,
legs: data.legs
}));
} else {
return false;
}
} catch (error1) {
error = error1;
throw error;
}
}
//: Place Order Flow
async placeOrderFlow(quantity, price, args, legs) {
return (await this.postUrl(endpoints.optionsOrders(), {
account: this.accountUrl,
direction: args.direction,
legs: legs,
price: price,
quantity: quantity,
time_in_force: 'gfd',
trigger: 'immediate',
type: 'limit',
override_day_trade_checks: false,
override_dtbp_checks: false,
ref_id: uuid()
}));
}
//: Get URL
async getUrl(url, consume = false) {
var data, error, pages;
try {
if (!consume) {
data = ((await this.session.get(url))).data;
if (data.results != null) {
return data.results;
} else {
return data;
}
} else {
data = ((await this.session.get(url))).data;
pages = data.results;
while (data.next != null) {
data = ((await this.session.get(data.next))).data;
pages.push(...data.results);
}
return pages;
}
} catch (error1) {
error = error1;
if ((error.response != null) && (error.response.data != null)) {
return error.response.data;
} else {
throw error;
}
}
}
//: Post URL
async postUrl(url, data) {
var error;
try {
return ((await this.session.post(url, data, {
headers: {
'Content-Type': 'application/json'
}
}))).data;
} catch (error1) {
error = error1;
if ((error.response != null) && (error.response.data != null)) {
return error.response.data;
} else {
throw error;
}
}
}
//: Get Data from URL based on Condition
async getDataFromUrl(url, conditionFunc, args) {
var data, error, hasArrayArgs, res, resKeys, results;
try {
results = {};
resKeys;
hasArrayArgs = Array.isArray(args.args);
data = ((await this.session.get(url))).data;
results = conditionFunc(data.results, args);
while (data.next != null) {
data = ((await this.session.get(data.next))).data;
res = conditionFunc(data.results, args);
results = {...results, ...res};
resKeys = Object.keys(results);
if (hasArrayArgs && args.args.length === resKeys.length) {
return results;
} else if (!hasArrayArgs && resKeys.length === 1) {
return results[resKeys[0]];
}
}
return results;
} catch (error1) {
error = error1;
if ((error.response != null) && (error.response.data != null)) {
return error.response.data;
} else {
throw error;
}
}
}
};
//: Sleep
sleep = function(time) {
return new Promise(function(resolve) {
return setTimeout(resolve, time);
});
};
//: New API Object
newApiObj = function(args = {
newLogin: false,
configIndex: 0,
configData: null,
print: false
}) {
args = {
newLogin: false,
configIndex: 0,
configData: null,
print: false,
...args
};
return new Api({
newLogin: args.newLogin,
configIndex: args.configIndex,
configData: args.configData,
print: args.print
});
};
//: Exports
module.exports = newApiObj;
//::: End Program :::