Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@master-chief/alpaca

Package Overview
Dependencies
Maintainers
1
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@master-chief/alpaca - npm Package Compare versions

Comparing version 1.4.1 to 2.0.0

.github/workflows/jest.yml

4

dist/index.js

@@ -1,2 +0,2 @@

export { Client } from './lib/client.js';
export { Stream } from './lib/stream.js';
export { AlpacaClient } from './lib/client.js';
export { AlpacaStream } from './lib/stream.js';

@@ -0,9 +1,11 @@

import qs from 'qs';
import fetch from 'node-fetch';
import qs from 'qs';
import urls from './urls.js';
import limiter from 'limiter';
import urls from './urls.js';
export class Client {
import { Parser } from './parser.js';
export class AlpacaClient {
constructor(options) {
this.options = options;
this.limiter = new limiter.RateLimiter(199, 'minute');
this.limiter = new limiter.RateLimiter(200, 'minute');
this.parser = new Parser();
}

@@ -16,39 +18,39 @@ async isAuthenticated() {

catch {
throw new Error('not authenticated');
return false;
}
}
getAccount() {
return this.request('GET', urls.rest.account, 'account');
async getAccount() {
return this.parser.parseAccount(await this.request('GET', urls.rest.account, 'account'));
}
getOrder(params) {
return this.request('GET', urls.rest.account, `orders/${params.order_id || params.client_order_id}?${qs.stringify({
async getOrder(params) {
return this.parser.parseOrder(await this.request('GET', urls.rest.account, `orders/${params.order_id || params.client_order_id}?${qs.stringify({
nested: params.nested,
})}`);
})}`));
}
getOrders(params) {
return this.request('GET', urls.rest.account, `orders?${qs.stringify(params)}`);
async getOrders(params) {
return this.parser.parseOrders(await this.request('GET', urls.rest.account, `orders?${qs.stringify(params)}`));
}
placeOrder(params) {
return this.request('POST', urls.rest.account, `orders`, params);
async placeOrder(params) {
return this.parser.parseOrder(await this.request('POST', urls.rest.account, `orders`, params));
}
replaceOrder(params) {
return this.request('PATCH', urls.rest.account, `orders/${params.order_id}`, params);
async replaceOrder(params) {
return this.parser.parseOrder(await this.request('PATCH', urls.rest.account, `orders/${params.order_id}`, params));
}
cancelOrder(params) {
return this.request('DELETE', urls.rest.account, `orders/${params.order_id}`);
async cancelOrder(params) {
return this.parser.parseOrder(await this.request('DELETE', urls.rest.account, `orders/${params.order_id}`));
}
cancelOrders() {
return this.request('DELETE', urls.rest.account, `orders`);
async cancelOrders() {
return this.parser.parseOrders(await this.request('DELETE', urls.rest.account, `orders`));
}
getPosition(params) {
return this.request('GET', urls.rest.account, `positions/${params.symbol}`);
async getPosition(params) {
return this.parser.parsePosition(await this.request('GET', urls.rest.account, `positions/${params.symbol}`));
}
getPositions() {
return this.request('GET', urls.rest.account, `positions`);
async getPositions() {
return this.parser.parsePositions(await this.request('GET', urls.rest.account, `positions`));
}
closePosition(params) {
return this.request('DELETE', urls.rest.account, `positions/${params.symbol}`);
async closePosition(params) {
return this.parser.parseOrder(await this.request('DELETE', urls.rest.account, `positions/${params.symbol}`));
}
closePositions() {
return this.request('DELETE', urls.rest.account, `positions`);
async closePositions() {
return this.parser.parseOrders(await this.request('DELETE', urls.rest.account, `positions`));
}

@@ -85,4 +87,4 @@ getAsset(params) {

}
getClock() {
return this.request('GET', urls.rest.account, `clock`);
async getClock() {
return this.parser.parseClock(await this.request('GET', urls.rest.account, `clock`));
}

@@ -95,4 +97,4 @@ getAccountConfigurations() {

}
getAccountActivities(params) {
return this.request('GET', urls.rest.account, `account/activities/${params.activity_type}?${qs.stringify(params)}`);
async getAccountActivities(params) {
return this.parser.parseActivities(await this.request('GET', urls.rest.account, `account/activities/${params.activity_type}?${qs.stringify(params)}`));
}

@@ -129,3 +131,2 @@ getPortfolioHistory(params) {

return new Promise(async (resolve, reject) => {
// do rate limiting
if (this.options.rate_limit) {

@@ -140,7 +141,6 @@ await new Promise((resolve) => this.limiter.removeTokens(1, resolve));

},
body: data ? JSON.stringify(data) : undefined,
body: JSON.stringify(data),
})
.then(
// if json parse fails we default to an empty object
async (response) => (await response.json().catch(() => false)) || {})
// if json parse fails we default to an empty object
.then(async (resp) => (await resp.json().catch(() => false)) || {})
.then((json) => 'code' in json && 'message' in json ? reject(json) : resolve(json))

@@ -147,0 +147,0 @@ .catch(reject);

import WebSocket from 'ws';
import urls from './urls.js';
import { EventEmitter } from 'events';
export class Stream extends EventEmitter {
export class AlpacaStream extends EventEmitter {
constructor(params) {

@@ -6,0 +6,0 @@ // construct EventEmitter

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

export { Client } from './lib/client.js'
export { Stream } from './lib/stream.js'
export { AlpacaClient } from './lib/client.js'
export { AlpacaStream } from './lib/stream.js'

@@ -4,0 +4,0 @@ export {

@@ -0,7 +1,10 @@

import qs from 'qs'
import fetch from 'node-fetch'
import qs from 'qs'
import urls from './urls.js'
import limiter from 'limiter'
import urls from './urls.js'
import { Parser } from './parser.js'
import {
RawAccount,
Account,

@@ -15,4 +18,2 @@ Order,

AccountConfigurations,
NonTradeActivity,
TradeActivity,
PortfolioHistory,

@@ -23,2 +24,6 @@ Bar,

Credentials,
RawOrder,
RawPosition,
RawActivity,
Activity,
} from './entities.js'

@@ -51,4 +56,5 @@

export class Client {
private limiter = new limiter.RateLimiter(199, 'minute')
export class AlpacaClient {
private limiter = new limiter.RateLimiter(200, 'minute')
private parser = new Parser()

@@ -68,71 +74,97 @@ constructor(

} catch {
throw new Error('not authenticated')
return false
}
}
getAccount(): Promise<Account> {
return this.request('GET', urls.rest.account, 'account')
async getAccount(): Promise<Account> {
return this.parser.parseAccount(
await this.request<RawAccount>('GET', urls.rest.account, 'account')
)
}
getOrder(params: GetOrder): Promise<Order> {
return this.request(
'GET',
urls.rest.account,
`orders/${params.order_id || params.client_order_id}?${qs.stringify({
nested: params.nested,
})}`
async getOrder(params: GetOrder): Promise<Order> {
return this.parser.parseOrder(
await this.request<RawOrder>(
'GET',
urls.rest.account,
`orders/${params.order_id || params.client_order_id}?${qs.stringify({
nested: params.nested,
})}`
)
)
}
getOrders(params?: GetOrders): Promise<Order[]> {
return this.request(
'GET',
urls.rest.account,
`orders?${qs.stringify(params)}`
async getOrders(params?: GetOrders): Promise<Order[]> {
return this.parser.parseOrders(
await this.request<RawOrder[]>(
'GET',
urls.rest.account,
`orders?${qs.stringify(params)}`
)
)
}
placeOrder(params: PlaceOrder): Promise<Order> {
return this.request('POST', urls.rest.account, `orders`, params)
async placeOrder(params: PlaceOrder): Promise<Order> {
return this.parser.parseOrder(
await this.request<RawOrder>('POST', urls.rest.account, `orders`, params)
)
}
replaceOrder(params: ReplaceOrder): Promise<Order> {
return this.request(
'PATCH',
urls.rest.account,
`orders/${params.order_id}`,
params
async replaceOrder(params: ReplaceOrder): Promise<Order> {
return this.parser.parseOrder(
await this.request<RawOrder>(
'PATCH',
urls.rest.account,
`orders/${params.order_id}`,
params
)
)
}
cancelOrder(params: CancelOrder): Promise<Order> {
return this.request(
'DELETE',
urls.rest.account,
`orders/${params.order_id}`
async cancelOrder(params: CancelOrder): Promise<Order> {
return this.parser.parseOrder(
await this.request<RawOrder>(
'DELETE',
urls.rest.account,
`orders/${params.order_id}`
)
)
}
cancelOrders(): Promise<Order[]> {
return this.request('DELETE', urls.rest.account, `orders`)
async cancelOrders(): Promise<Order[]> {
return this.parser.parseOrders(
await this.request<RawOrder[]>('DELETE', urls.rest.account, `orders`)
)
}
getPosition(params: GetPosition): Promise<Position> {
return this.request('GET', urls.rest.account, `positions/${params.symbol}`)
async getPosition(params: GetPosition): Promise<Position> {
return this.parser.parsePosition(
await this.request<RawPosition>(
'GET',
urls.rest.account,
`positions/${params.symbol}`
)
)
}
getPositions(): Promise<Position[]> {
return this.request('GET', urls.rest.account, `positions`)
async getPositions(): Promise<Position[]> {
return this.parser.parsePositions(
await this.request<RawPosition[]>('GET', urls.rest.account, `positions`)
)
}
closePosition(params: ClosePosition): Promise<Order> {
return this.request(
'DELETE',
urls.rest.account,
`positions/${params.symbol}`
async closePosition(params: ClosePosition): Promise<Order> {
return this.parser.parseOrder(
await this.request<RawOrder>(
'DELETE',
urls.rest.account,
`positions/${params.symbol}`
)
)
}
closePositions(): Promise<Order[]> {
return this.request('DELETE', urls.rest.account, `positions`)
async closePositions(): Promise<Order[]> {
return this.parser.parseOrders(
await this.request<RawOrder[]>('DELETE', urls.rest.account, `positions`)
)
}

@@ -210,4 +242,6 @@

getClock(): Promise<Clock> {
return this.request('GET', urls.rest.account, `clock`)
async getClock(): Promise<Clock> {
return this.parser.parseClock(
await this.request('GET', urls.rest.account, `clock`)
)
}

@@ -230,9 +264,11 @@

getAccountActivities(
async getAccountActivities(
params: GetAccountActivities
): Promise<Array<NonTradeActivity | TradeActivity>> {
return this.request(
'GET',
urls.rest.account,
`account/activities/${params.activity_type}?${qs.stringify(params)}`
): Promise<Activity[]> {
return this.parser.parseActivities(
await this.request<RawActivity[]>(
'GET',
urls.rest.account,
`account/activities/${params.activity_type}?${qs.stringify(params)}`
)
)

@@ -279,8 +315,8 @@ }

private request(
private request<T = any>(
method: string,
url: string,
endpoint: string,
data?: any
): Promise<any> {
data?: { [key: string]: any }
): Promise<T> {
// modify the base url if paper is true

@@ -300,8 +336,5 @@ if (this.options.paper && url == urls.rest.account) {

return new Promise<any>(async (resolve, reject) => {
// do rate limiting
return new Promise<T>(async (resolve, reject) => {
if (this.options.rate_limit) {
await new Promise<void>((resolve) =>
this.limiter.removeTokens(1, resolve)
)
await new Promise((resolve) => this.limiter.removeTokens(1, resolve))
}

@@ -315,8 +348,6 @@

},
body: data ? JSON.stringify(data) : undefined,
body: JSON.stringify(data),
})
.then(
// if json parse fails we default to an empty object
async (response) => (await response.json().catch(() => false)) || {}
)
// if json parse fails we default to an empty object
.then(async (resp) => (await resp.json().catch(() => false)) || {})
.then((json) =>

@@ -323,0 +354,0 @@ 'code' in json && 'message' in json ? reject(json) : resolve(json)

@@ -0,1 +1,5 @@

/**
* Your Alpaca key id and secret.
* Can be passed to the AlpacaClient and AlpacaStream.
*/
export interface Credentials {

@@ -6,3 +10,7 @@ key: string

export interface Account {
/**
* The account information with unparsed types, exactly as Alpaca provides it.
* We encourage you to use the Account interface, which has many of these fields parsed.
*/
export interface RawAccount {
account_blocked: boolean

@@ -36,7 +44,213 @@ account_number: string

/**
* The following are the possible account status values. Most likely, the account status
* is ACTIVE unless there is any problem. The account status may get in ACCOUNT_UPDATED
* when personal information is being updated from the dashboard, in which case you may
* not be allowed trading for a short period of time until the change is approved.
*/
export type AccountStatus =
/**
* The account is onboarding.
*/
| 'ONBOARDING'
/**
* The account application submission failed for some reason.
*/
| 'SUBMISSION_FAILED'
/**
* The account application has been submitted for review.
*/
| 'SUBMITTED'
/**
* The account information is being updated.
*/
| 'ACCOUNT_UPDATED'
/**
* The final account approval is pending.
*/
| 'APPROVAL_PENDING'
/**
* The account is active for trading.
*/
| 'ACTIVE'
/**
* The account application has been rejected.
*/
| 'REJECTED'
/**
* Information related to an Alpaca account, such as account status, funds, and various
* flags relevant to an account's ability to trade.
*/
export interface Account {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawAccount
/**
* If true, the account activity by user is prohibited.
*/
account_blocked: boolean
/**
* Account number.
*/
account_number: string
/**
* Current available $ buying power; If multiplier = 4, this is your daytrade buying
* power which is calculated as (last_equity - (last) maintenance_margin) * 4; If
* multiplier = 2, buying_power = max(equity – initial_margin,0) * 2; If multiplier = 1,
* buying_power = cash
*/
buying_power: number
/**
* Cash balance
*/
cash: number
/**
* Timestamp this account was created at
*/
created_at: Date
/**
* "USD"
*/
currency: string
/**
* The current number of daytrades that have been made in the last 5 trading days
* (inclusive of today)
*/
daytrade_count: number
/**
* Your buying power for day trades (continuously updated value)
*/
daytrading_buying_power: number
/**
* Cash + long_market_value + short_market_value
*/
equity: number
/**
* Account ID.
*/
id: string
/**
* Reg T initial margin requirement (continuously updated value)
*/
initial_margin: number
/**
* Equity as of previous trading day at 16:00:00 ET
*/
last_equity: number
/**
* Your maintenance margin requirement on the previous trading day
*/
last_maintenance_margin: number
/**
* Real-time MtM value of all long positions held in the account
*/
long_market_value: number
/**
* Maintenance margin requirement (continuously updated value)
*/
maintenance_margin: number
/**
* Buying power multiplier that represents account margin classification; valid values 1
* (standard limited margin account with 1x buying power), 2 (reg T margin account with
* 2x intraday and overnight buying power; this is the default for all non-PDT accounts
* with $2,000 or more equity), 4 (PDT account with 4x intraday buying power and 2x reg
* T overnight buying power)
*/
multiplier: number
/**
* Whether or not the account has been flagged as a pattern day trader
*/
pattern_day_trader: boolean
/**
* Total value of cash + holding positions (This field is deprecated. It is equivalent
* to the equity field.)
*/
portfolio_value: number
/**
* Your buying power under Regulation T (your excess equity - equity minus margin
* value - times your margin multiplier)
*/
regt_buying_power: number
/**
* Real-time MtM value of all short positions held in the account
*/
short_market_value: number
/**
* Flag to denote whether or not the account is permitted to short
*/
shorting_enabled: boolean
/**
* Value of special memorandum account (will be used at a later date to provide
* additional buying_power)
*/
sma: number
/**
* The following are the possible account status values. Most likely, the account status
* is ACTIVE unless there is any problem. The account status may get in ACCOUNT_UPDATED
* when personal information is being updated from the dashboard, in which case you may
* not be allowed trading for a short period of time until the change is approved.
*/
status: AccountStatus
/**
* User setting. If true, the account is not allowed to place orders.
*/
trade_suspended_by_user: boolean
/**
* If true, the account is not allowed to place orders.
*/
trading_blocked: boolean
/**
* If true, the account is not allowed to request money transfers.
*/
transfers_blocked: boolean
}
export interface AccountConfigurations {
dtbp_check: string
/**
* both, entry, or exit. Controls Day Trading Margin Call (DTMC) checks.
*/
dtbp_check: 'both' | 'entry' | 'exit'
/**
* If true, account becomes long-only mode.
*/
no_shorting: boolean
/**
* If true, new orders are blocked.
*/
suspend_trade: boolean
trade_confirm_email: string
/**
* all or none. If none, emails for order fills are not sent.
*/
trade_confirm_email: 'all' | 'none'
}

@@ -71,30 +285,122 @@

export type AssetExchange =
| 'AMEX'
| 'ARCA'
| 'BATS'
| 'NYSE'
| 'NASDAQ'
| 'NYSEARCA'
export type AssetStatus = 'active' | 'inactive'
/**
* The assets API serves as the master list of assets available for trade and data
* consumption from Alpaca. Assets are sorted by asset class, exchange and symbol. Some
* assets are only available for data consumption via Polygon, and are not tradable with
* Alpaca. These assets will be marked with the flag tradable=false.
*/
export interface Asset {
/**
* Asset ID
*/
id: string
/**
* "us_equity"
*/
class: string
exchange: string
/**
* AMEX, ARCA, BATS, NYSE, NASDAQ or NYSEARCA
*/
exchange: AssetExchange
/**
* Asset symbol
*/
symbol: string
status: string
/**
* active or inactive
*/
status: AssetStatus
/**
* Asset is tradable on Alpaca or not
*/
tradable: boolean
/**
* Asset is marginable or not
*/
marginable: boolean
/**
* Asset is shortable or not
*/
shortable: boolean
/**
* Asset is easy-to-borrow or not (filtering for easy_to_borrow = True is the best way
* to check whether the name is currently available to short at Alpaca).
*/
easy_to_borrow: boolean
}
/**
* Price and volume data during a particular time interval
*/
export interface Bar {
/**
* the beginning time of this bar as a Unix epoch in seconds
*/
t: number
/**
* open price
*/
o: number
/**
* high price
*/
h: number
/**
* low price
*/
l: number
/**
* close price
*/
c: number
/**
* volume
*/
v: number
}
/**
* Contains the time of open and close for a market on a particular day from 1970 to 2029
*/
export interface Calendar {
/**
* Date string in YYYY-MM-DD format
*/
date: string
/**
* The time the market opens at on this date in HH:MM format
*/
open: string
/**
* The time the market closes at on this date in HH:MM format
*/
close: string
}
export interface Clock {
export interface RawClock {
timestamp: string

@@ -106,2 +412,36 @@ is_open: boolean

/**
* The clock API serves the current market timestamp, whether or not the market is
* currently open, as well as the times of the next market open and close.
*/
export interface Clock {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawClock
/**
* Current timestamp
*/
timestamp: Date
/**
* Whether or not the market is open
*/
is_open: boolean
/**
* Next market open timestamp
*/
next_open: Date
/**
* Next market close timestamp
*/
next_close: Date
}
/**
* Last quote details for a symbol
*/
export interface LastQuote {

@@ -111,8 +451,35 @@ status: string

last: {
/**
* the current ask price
*/
askprice: number
/**
* the current ask size
*/
asksize: number
/**
* the exchange code of the ask quote
*/
askexchange: number
/**
* the current bid price
*/
bidprice: number
/**
* the current bid size
*/
bidsize: number
/**
* the exchange code of the bid quote
*/
bidexchange: number
/**
* epoch timestamp in nanoseconds
*/
timestamp: number

@@ -122,2 +489,5 @@ }

/**
* Last trade details for a symbol
*/
export interface LastTrade {

@@ -127,9 +497,40 @@ status: string

last: {
/**
* last trade price
*/
price: number
/**
* last trade volume size
*/
size: number
/**
* exchange code where the last trade was made
*/
exchange: number
/**
* condition flag 1
*/
cond1: number
/**
* condition flag 2
*/
cond2: number
/**
* condition flag 3
*/
cond3: number
/**
* condition flag 4
*/
cond4: number
/**
* epoch timestamp in nanoseconds
*/
timestamp: number

@@ -139,3 +540,7 @@ }

export interface Order {
/**
* The order entity with unparsed fields, exactly as Alpaca provides it.
* We encourage you to use the Order interface, which has many of these fields parsed.
*/
export interface RawOrder {
id: string

@@ -152,3 +557,3 @@ client_order_id: string

replaced_by: string
replaces: any
replaces: string
asset_id: string

@@ -167,15 +572,363 @@ symbol: string

extended_hours: boolean
legs: any
legs: RawOrder[]
trail_price: string
trail_percent: string
hwm: string
}
export type OrderType =
| 'market'
| 'limit'
| 'stop'
| 'stop_limit'
| 'trailing_stop'
export type OrderSide = 'buy' | 'sell'
export type OrderTimeInForce =
/**
* A day order is eligible for execution only on the day it is live. By default, the
* order is only valid during Regular Trading Hours (9:30am - 4:00pm ET). If unfilled
* after the closing auction, it is automatically canceled. If submitted after the
* close, it is queued and submitted the following trading day. However, if marked as
* eligible for extended hours, the order can also execute during supported extended
* hours.
*/
| 'day'
/**
* The order is good until canceled. Non-marketable GTC limit orders are subject to
* price adjustments to offset corporate actions affecting the issue. We do not
* currently support Do Not Reduce(DNR) orders to opt out of such price adjustments.
*/
| 'gtc'
/**
* Use this TIF with a market/limit order type to submit "market on open" (MOO) and
* "limit on open" (LOO) orders. This order is eligible to execute only in the market
* opening auction. Any unfilled orders after the open will be cancelled. OPG orders
* submitted after 9:28am but before 7:00pm ET will be rejected. OPG orders submitted
* after 7:00pm will be queued and routed to the following day's opening auction. On
* open/on close orders are routed to the primary exchange. Such orders do not
* necessarily execute exactly at 9:30am / 4:00pm ET but execute per the exchange's
* auction rules.
*/
| 'opg'
/**
* Use this TIF with a market/limit order type to submit "market on close" (MOC) and
* "limit on close" (LOC) orders. This order is eligible to execute only in the market
* closing auction. Any unfilled orders after the close will be cancelled. CLS orders
* submitted after 3:50pm but before 7:00pm ET will be rejected. CLS orders submitted
* after 7:00pm will be queued and routed to the following day's closing auction. Only
* available with API v2.
*/
| 'cls'
/**
* An Immediate Or Cancel (IOC) order requires all or part of the order to be executed
* immediately. Any unfilled portion of the order is canceled. Only available with API
* v2.
*/
| 'ioc'
/**
* A Fill or Kill (FOK) order is only executed if the entire order quantity can be
* filled, otherwise the order is canceled. Only available with API v2.
*/
| 'fok'
export type OrderStatus =
/**
* The order has been received by Alpaca, and routed to exchanges for execution. This
* is the usual initial state of an order.
*/
| 'new'
/**
* The order has been partially filled.
*/
| 'partially_filled'
/**
* The order has been filled, and no further updates will occur for the order.
*/
| 'filled'
/**
* The order is done executing for the day, and will not receive further updates until
* the next trading day.
*/
| 'done_for_day'
/**
* The order has been canceled, and no further updates will occur for the order. This
* can be either due to a cancel request by the user, or the order has been canceled by
* the exchanges due to its time-in-force.
*/
| 'canceled'
/**
* The order has expired, and no further updates will occur for the order.
*/
| 'expired'
/**
* The order was replaced by another order, or was updated due to a market event such
* as corporate action.
*/
| 'replaced'
/**
* The order is waiting to be canceled.
*/
| 'pending_cancel'
/**
* The order is waiting to be replaced by another order. The order will reject cancel
* request while in this state.
*/
| 'pending_replace'
/**
* (Uncommon) The order has been received by Alpaca, but hasn't yet been routed to the
* execution venue. This could be seen often out side of trading session hours.
*/
| 'accepted'
/**
* (Uncommon) The order has been received by Alpaca, and routed to the exchanges, but
* has not yet been accepted for execution. This state only occurs on rare occasions.
*/
| 'pending_new'
/**
* (Uncommon) The order has been received by exchanges, and is evaluated for pricing.
* This state only occurs on rare occasions.
*/
| 'accepted_for_bidding'
/**
* (Uncommon) The order has been stopped, and a trade is guaranteed for the order,
* usually at a stated price or better, but has not yet occurred. This state only
* occurs on rare occasions.
*/
| 'stopped'
/**
* (Uncommon) The order has been rejected, and no further updates will occur for the
* order. This state occurs on rare occasions and may occur based on various conditions
* decided by the exchanges.
*/
| 'rejected'
/**
* (Uncommon) The order has been suspended, and is not eligible for trading. This state
* only occurs on rare occasions.
*/
| 'suspended'
/**
* (Uncommon) The order has been completed for the day (either filled or done for day),
* but remaining settlement calculations are still pending. This state only occurs on
* rare occasions.
*/
| 'calculated'
/**
* An Order in Alpaca
*/
export interface Order {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawOrder
/**
* Order id
*/
id: string
/**
* Client unique order id
*/
client_order_id: string
/**
* When the order was created
*/
created_at: Date
/**
* When the order was last updated
*/
updated_at: Date
/**
* When the order was submitted
*/
submitted_at: Date
/**
* When the order was filled
*/
filled_at: Date
/**
* When the order expired
*/
expired_at: Date
/**
* When the order was canceled
*/
canceled_at: Date
/**
* When the order failed
*/
failed_at: Date
/**
* When the order was last replaced
*/
replaced_at: Date
/**
* The order ID that this order was replaced by
*/
replaced_by: string
/**
* The order ID that this order replaces
*/
replaces: string
/**
* Asset ID
*/
asset_id: string
/**
* Asset symbol
*/
symbol: string
/**
* Asset class
*/
asset_class: string
/**
* Ordered quantity
*/
qty: number
/**
* Filled quantity
*/
filled_qty: number
/**
* Order type (market, limit, stop, stop_limit, trailing_stop)
*/
type: OrderType
/**
* Buy or sell
*/
side: OrderSide
/**
* Order Time in Force
*/
time_in_force: OrderTimeInForce
/**
* Limit price
*/
limit_price: number
/**
* Stop price
*/
stop_price: number
/**
* Filled average price
*/
filled_avg_price: number
/**
* The status of the order
*/
status: OrderStatus
/**
* If true, eligible for execution outside regular trading hours.
*/
extended_hours: boolean
/**
* When querying non-simple order_class orders in a nested style, an array of Order
* entities associated with this order. Otherwise, null.
*/
legs: Order[]
/**
* The dollar value away from the high water mark for trailing stop orders.
*/
trail_price: number
/**
* The percent value away from the high water mark for trailing stop orders.
*/
trail_percent: number
/**
* The highest (lowest) market price seen since the trailing stop order was submitted.
*/
hwm: number
}
/**
* Timeseries data for equity and profit loss information of the account
*/
export interface PortfolioHistory {
/**
* time of each data element, left-labeled (the beginning of time window)
*/
timestamp: number[]
/**
* equity value of the account in dollar amount as of the end of each time window
*/
equity: number[]
/**
* profit/loss in dollar from the base value
*/
profit_loss: number[]
/**
* profit/loss in percentage from the base value
*/
profit_loss_pct: number[]
/**
* basis in dollar of the profit loss calculation
*/
base_value: number
/**
* time window size of each data element
*/
timeframe: string
}
export interface Position {
/**
* A position with unparsed fields, exactly as Alpaca provides it.
* We encourage you to use the Position interface, which has many of these fields parsed.
*/
export interface RawPosition {
asset_id: string

@@ -199,2 +952,94 @@ symbol: string

export type PositionSide = 'long' | 'short'
/**
* A position in Alpaca
*/
export interface Position {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawPosition
/**
* Asset ID
*/
asset_id: string
/**
* Symbol name of the asset
*/
symbol: string
/**
* Exchange name of the asset
*/
exchange: string
/**
* Asset class name
*/
asset_class: string
/**
* Average entry price of the position
*/
avg_entry_price: number
/**
* The number of shares
*/
qty: number
/**
* long or short
*/
side: PositionSide
/**
* Total dollar amount of the position
*/
market_value: number
/**
* Total cost basis in dollar
*/
cost_basis: number
/**
* Unrealized profit/loss in dollars
*/
unrealized_pl: number
/**
* Unrealized profit/loss percent (by a factor of 1)
*/
unrealized_plpc: number
/**
* Unrealized profit/loss in dollars for the day
*/
unrealized_intraday_pl: number
/**
* Unrealized profit/loss percent (by a factor of 1)
*/
unrealized_intraday_plpc: number
/**
* Current asset price per share
*/
current_price: number
/**
* Last day's asset price per share based on the closing value of the last trading day
*/
lastday_price: number
/**
* Percent change from last day price (by a factor of 1)
*/
change_today: number
}
export interface Quote {

@@ -225,4 +1070,172 @@ ev: string

export interface TradeActivity {
activity_type: string
export type ActivityType =
/**
* Order fills (both partial and full fills)
*/
| 'FILL'
/**
* Cash transactions (both CSD and CSR)
*/
| 'TRANS'
/**
* Miscellaneous or rarely used activity types (All types except those in TRANS, DIV,
* or FILL)
*/
| 'MISC'
/**
* ACATS IN/OUT (Cash)
*/
| 'ACATC'
/**
* ACATS IN/OUT (Securities)
*/
| 'ACATS'
/**
* Cash disbursement(+)
*/
| 'CSD'
/**
* Cash receipt(-)
*/
| 'CSR'
/**
* Dividends
*/
| 'DIV'
/**
* Dividend (capital gain long term)
*/
| 'DIVCGL'
/**
* Dividend (capital gain short term)
*/
| 'DIVCGS'
/**
* Dividend fee
*/
| 'DIVFEE'
/**
* Dividend adjusted (Foreign Tax Withheld)
*/
| 'DIVFT'
/**
* Dividend adjusted (NRA Withheld)
*/
| 'DIVNRA'
/**
* Dividend return of capital
*/
| 'DIVROC'
/**
* Dividend adjusted (Tefra Withheld)
*/
| 'DIVTW'
/**
* Dividend (tax exempt)
*/
| 'DIVTXEX'
/**
* Interest (credit/margin)
*/
| 'INT'
/**
* Interest adjusted (NRA Withheld)
*/
| 'INTNRA'
/**
* Interest adjusted (Tefra Withheld)
*/
| 'INTTW'
/**
* Journal entry
*/
| 'JNL'
/**
* Journal entry (cash)
*/
| 'JNLC'
/**
* Journal entry (stock)
*/
| 'JNLS'
/**
* Merger/Acquisition
*/
| 'MA'
/**
* Name change
*/
| 'NC'
/**
* Option assignment
*/
| 'OPASN'
/**
* Option expiration
*/
| 'OPEXP'
/**
* Option exercise
*/
| 'OPXRC'
/**
* Pass Thru Charge
*/
| 'PTC'
/**
* Pass Thru Rebate
*/
| 'PTR'
/**
* Reorg CA
*/
| 'REORG'
/**
* Symbol change
*/
| 'SC'
/**
* Stock spinoff
*/
| 'SSO'
/**
* Stock split
*/
| 'SSP'
export interface RawTradeActivity {
// Only FILL
activity_type: Extract<ActivityType, 'FILL'>
cum_qty: string

@@ -240,4 +1253,5 @@ id: string

export interface NonTradeActivity {
activity_type: string
export interface RawNonTradeActivity {
// Everything except FILL
activity_type: Exclude<ActivityType, 'FILL'>
id: string

@@ -251,2 +1265,119 @@ date: string

export type TradeActivityType = 'fill' | 'partial_fill'
export type TradeActivitySide = 'buy' | 'sell'
export interface TradeActivity {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawTradeActivity
/**
* FILL
*/
activity_type: Extract<ActivityType, 'FILL'>
/**
* The cumulative quantity of shares involved in the execution.
*/
cum_qty: number
/**
* An id for the activity. Always in "::" format. Can be sent as page_token in requests
* to facilitate the paging of results.
*/
id: string
/**
* For partially_filled orders, the quantity of shares that are left to be filled.
*/
leaves_qty: number
/**
* The per-share price that the trade was executed at.
*/
price: number
/**
* The number of shares involved in the trade execution.
*/
qty: number
/**
* buy or sell
*/
side: TradeActivitySide
/**
* The symbol of the security being traded.
*/
symbol: string
/**
* The time at which the execution occurred.
*/
transaction_time: string
/**
* The id for the order that filled.
*/
order_id: string
/**
* fill or partial_fill
*/
type: TradeActivityType
}
export interface NonTradeActivity {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawNonTradeActivity
/**
* Activity type
*/
activity_type: Exclude<ActivityType, 'FILL'>
/**
* An ID for the activity, always in "::" format. Can be sent as page_token in requests
* to facilitate the paging of results.
*/
id: string
/**
* The date on which the activity occurred or on which the transaction associated with
* the activity settled.
*/
date: string
/**
* The net amount of money (positive or negative) associated with the activity.
*/
net_amount: number
/**
* The symbol of the security involved with the activity. Not present for all activity
* types.
*/
symbol: string
/**
* For dividend activities, the number of shares that contributed to the payment. Not
* present for other activity types.
*/
qty: number
/**
* For dividend activities, the average amount paid per share. Not present for other
* activity types.
*/
per_share_amount: number
}
export type RawActivity = RawTradeActivity | RawNonTradeActivity
export type Activity = TradeActivity | NonTradeActivity
export interface TradeUpdate {

@@ -269,8 +1400,31 @@ event: string

export interface Watchlist {
/**
* account ID
*/
account_id: string
/**
* the content of this watchlist, in the order as registered by the client
*/
assets: Asset[]
/**
* When the watchlist was created
*/
created_at: string
/**
* watchlist id
*/
id: string
/**
* user-defined watchlist name (up to 64 characters)
*/
name: string
/**
* When the watchlist was last updated
*/
updated_at: string
}

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

import { OrderSide, OrderType, OrderTimeInForce } from './entities.js'
export interface AddToWatchList {

@@ -72,7 +74,7 @@ uuid: string

export interface GetOrders {
status?: string
status?: 'open' | 'closed' | 'all'
limit?: number
after?: Date
until?: Date
direction?: string
direction?: 'asc' | 'desc'
nested?: boolean

@@ -99,11 +101,11 @@ }

qty: number
side: 'buy' | 'sell'
type: 'market' | 'limit' | 'stop' | 'stop_limit' | 'trailing_stop'
time_in_force: 'day' | 'gtc' | 'opg' | 'cls' | 'ioc' | 'fok'
side: OrderSide
type: OrderType
time_in_force: OrderTimeInForce
limit_price?: number
stop_price?: number
extended_hours?: boolean
client_order_id?: string
trail_price?: number
trail_percent?: number
extended_hours?: boolean
client_order_id?: string
order_class?: 'simple' | 'bracket' | 'oco' | 'oto'

@@ -127,3 +129,3 @@ take_profit?: {

qty?: number
time_in_force?: string
time_in_force?: OrderTimeInForce
limit_price?: number

@@ -130,0 +132,0 @@ stop_price?: number

@@ -7,14 +7,17 @@ import WebSocket from 'ws'

export declare interface Stream {
on<U extends keyof StreamEvents>(event: U, listener: StreamEvents[U]): this
emit<U extends keyof StreamEvents>(
export declare interface AlpacaStream {
on<U extends keyof AlpacaStreamEvents>(
event: U,
...args: Parameters<StreamEvents[U]>
listener: AlpacaStreamEvents[U]
): this
emit<U extends keyof AlpacaStreamEvents>(
event: U,
...args: Parameters<AlpacaStreamEvents[U]>
): boolean
}
export declare interface StreamEvents {
open: (connection: Stream) => void
close: (connection: Stream) => void
authenticated: (connection: Stream) => void
export declare interface AlpacaStreamEvents {
open: (connection: AlpacaStream) => void
close: (connection: AlpacaStream) => void
authenticated: (connection: AlpacaStream) => void
error: (error: Error) => void

@@ -29,3 +32,3 @@ message: (data: Object) => void

export class Stream extends EventEmitter {
export class AlpacaStream extends EventEmitter {
private host: string

@@ -32,0 +35,0 @@ private connection: WebSocket

{
"name": "@master-chief/alpaca",
"version": "1.4.1",
"version": "2.0.0",
"description": "a TypeScript Node.js library for the https://alpaca.markets REST API and WebSocket streams",

@@ -21,7 +21,21 @@ "main": "dist/index.js",

"scripts": {
"build": "tsc",
"test": "npm run build && $(npm bin)/ava -v"
"build": "npm run clean && tsc",
"clean": "rimraf dist types",
"test": "npm run build && npm run test:unit",
"test:unit": "jest",
"test:watch": "jest --watchAll"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"roots": [
"<rootDir>/lib"
],
"testMatch": [
"**/tests/**/*.test.ts"
]
},
"author": "master-chief",
"contributors": [
"lbstr",
"AqilCont",

@@ -38,6 +52,11 @@ "KalebMills"

"devDependencies": {
"@types/jest": "^26.0.14",
"@types/node-fetch": "^2.5.7",
"@types/qs": "^6.9.3",
"@types/ws": "^7.2.4"
"@types/ws": "^7.2.4",
"jest": "^26.4.2",
"rimraf": "^3.0.2",
"ts-jest": "^26.4.0",
"typescript": "^4.0.3"
}
}

@@ -21,4 +21,5 @@ # alpaca

- [x] Fully asynchronous API.
- [x] Extensible `Client` and `Stream` classes.
- [x] Extensible `AlpacaClient` and `AlpacaStream` classes.
- [x] Built-in rate limiting.
- [x] Built-in number and date parsing.
- [x] A 1:1 mapping of the official Alpaca [docs](https://docs.alpaca.markets/).

@@ -42,14 +43,34 @@

```typescript
import { Client } from "@master-chief/alpaca";
import { AlpacaClient } from '@master-chief/alpaca'
const client = new Client({
const client = new AlpacaClient({
credentials: {
key: "...",
secret: "...",
key: '...',
secret: '...',
},
paper: true,
rate_limit: true,
});
})
```
#### Parsing
Alpaca provides numbers as strings. From
[their docs](https://alpaca.markets/docs/api-documentation/api-v2/#numbers):
> Decimal numbers are returned as strings to preserve full precision across
> platforms. When making a request, it is recommended that you also convert your
> numbers to strings to avoid truncation and precision errors.
This package provides numbers as `number` instead, and date strings as `Date`
objects which is what most developers want out of the box. If you want the
original data, as it came from Alpaca, you can call `raw()` on any entity.
```javascript
const account = await client.getAccount()
console.log(typeof account.buying_power) // number
console.log(typeof account.raw().buying_power) // string
```
#### Examples

@@ -93,3 +114,3 @@

```typescript
await client.isAuthenticated();
await client.isAuthenticated()
```

@@ -100,3 +121,3 @@

```typescript
await client.getAccount();
await client.getAccount()
```

@@ -108,4 +129,4 @@

await client.getOrder({
order_id: "6187635d-04e5-485b-8a94-7ce398b2b81c",
});
order_id: '6187635d-04e5-485b-8a94-7ce398b2b81c',
})
```

@@ -118,4 +139,4 @@

limit: 25,
status: "all",
});
status: 'all',
})
```

@@ -127,8 +148,8 @@

await client.placeOrder({
symbol: "SPY",
symbol: 'SPY',
qty: 1,
side: "buy",
type: "market",
time_in_force: "day",
});
side: 'buy',
type: 'market',
time_in_force: 'day',
})
```

@@ -140,5 +161,5 @@

await client.replaceOrder({
order_id: "69a3db8b-cc63-44da-a26a-e3cca9490308",
order_id: '69a3db8b-cc63-44da-a26a-e3cca9490308',
limit_price: 9.74,
});
})
```

@@ -150,4 +171,4 @@

await client.cancelOrder({
order_id: "69a3db8b-cc63-44da-a26a-e3cca9490308",
});
order_id: '69a3db8b-cc63-44da-a26a-e3cca9490308',
})
```

@@ -158,3 +179,3 @@

```typescript
await client.cancelOrders();
await client.cancelOrders()
```

@@ -165,3 +186,3 @@

```typescript
await client.getPosition({ symbol: "SPY" });
await client.getPosition({ symbol: 'SPY' })
```

@@ -172,3 +193,3 @@

```typescript
await client.getPositions();
await client.getPositions()
```

@@ -179,3 +200,3 @@

```typescript
await client.closePosition({ symbol: "SPY" });
await client.closePosition({ symbol: 'SPY' })
```

@@ -186,3 +207,3 @@

```typescript
await client.closePositions();
await client.closePositions()
```

@@ -193,3 +214,3 @@

```typescript
await client.getAsset({ asset_id_or_symbol: "SPY" });
await client.getAsset({ asset_id_or_symbol: 'SPY' })
```

@@ -200,3 +221,3 @@

```typescript
await client.getAssets({ status: "active" });
await client.getAssets({ status: 'active' })
```

@@ -207,3 +228,3 @@

```typescript
await client.getWatchlist({ uuid: "2000e463-6f87-41c0-a8ba-3e40cbf67128" });
await client.getWatchlist({ uuid: '2000e463-6f87-41c0-a8ba-3e40cbf67128' })
```

@@ -214,3 +235,3 @@

```typescript
await client.getWatchlists();
await client.getWatchlists()
```

@@ -222,5 +243,5 @@

await client.createWatchlist({
name: "my watchlist",
symbols: ["SPY", "DIA", "EEM", "XLF"],
});
name: 'my watchlist',
symbols: ['SPY', 'DIA', 'EEM', 'XLF'],
})
```

@@ -232,6 +253,6 @@

await client.updateWatchlist({
uuid: "2000e463-6f87-41c0-a8ba-3e40cbf67128",
name: "new watchlist name",
symbols: ["TSLA", "AAPL"],
});
uuid: '2000e463-6f87-41c0-a8ba-3e40cbf67128',
name: 'new watchlist name',
symbols: ['TSLA', 'AAPL'],
})
```

@@ -243,5 +264,5 @@

await client.addToWatchlist({
uuid: "2000e463-6f87-41c0-a8ba-3e40cbf67128",
symbol: "F",
});
uuid: '2000e463-6f87-41c0-a8ba-3e40cbf67128',
symbol: 'F',
})
```

@@ -253,5 +274,5 @@

await client.removeFromWatchlist({
uuid: "2000e463-6f87-41c0-a8ba-3e40cbf67128",
symbol: "F",
});
uuid: '2000e463-6f87-41c0-a8ba-3e40cbf67128',
symbol: 'F',
})
```

@@ -263,4 +284,4 @@

await client.deleteWatchlist({
uuid: "2000e463-6f87-41c0-a8ba-3e40cbf67128",
});
uuid: '2000e463-6f87-41c0-a8ba-3e40cbf67128',
})
```

@@ -271,3 +292,3 @@

```typescript
await client.getCalendar({ start: new Date(), end: new Date() });
await client.getCalendar({ start: new Date(), end: new Date() })
```

@@ -278,3 +299,3 @@

```typescript
await client.getClock();
await client.getClock()
```

@@ -285,3 +306,3 @@

```typescript
await client.getAccountConfigurations();
await client.getAccountConfigurations()
```

@@ -295,3 +316,3 @@

suspend_trade: true,
});
})
```

@@ -303,4 +324,4 @@

await client.getAccountActivities({
activity_type: "FILL",
});
activity_type: 'FILL',
})
```

@@ -312,5 +333,5 @@

await client.getPortfolioHistory({
period: "1D",
timeframe: "1Min",
});
period: '1D',
timeframe: '1Min',
})
```

@@ -322,4 +343,4 @@

await client.getBars({
symbols: ["SPY", "DIA", "XLF"],
});
symbols: ['SPY', 'DIA', 'XLF'],
})
```

@@ -331,4 +352,4 @@

await client.getLastTrade({
symbol: "SPY",
});
symbol: 'SPY',
})
```

@@ -340,4 +361,4 @@

await client.getLastQuote({
symbol: "SPY",
});
symbol: 'SPY',
})
```

@@ -353,11 +374,11 @@

```typescript
import { Stream } from "@master-chief/alpaca";
import { AlpacaStream } from '@master-chief/alpaca'
const stream = new Stream({
const stream = new AlpacaStream({
credentials: {
key: "...",
secret: "...",
key: '...',
secret: '...',
},
stream: "market_data",
});
stream: 'market_data',
})
```

@@ -386,3 +407,3 @@

```typescript
stream.subscribe(["AM.SPY"]);
stream.subscribe(['AM.SPY'])
```

@@ -389,0 +410,0 @@

@@ -1,4 +0,4 @@

export { Client } from './lib/client.js';
export { Stream } from './lib/stream.js';
export { AlpacaClient } from './lib/client.js';
export { AlpacaStream } from './lib/stream.js';
export { Account, Order, Position, Asset, Watchlist, Calendar, Clock, AccountConfigurations, NonTradeActivity, TradeActivity, PortfolioHistory, Bar, LastQuote, LastTrade, } from './lib/entities.js';
export { GetOrder, GetOrders, PlaceOrder, ReplaceOrder, CancelOrder, GetPosition, ClosePosition, GetAsset, GetAssets, GetWatchList, CreateWatchList, UpdateWatchList, AddToWatchList, RemoveFromWatchList, DeleteWatchList, GetCalendar, UpdateAccountConfigurations, GetAccountActivities, GetPortfolioHistory, GetBars, GetLastTrade, GetLastQuote, } from './lib/params.js';

@@ -1,4 +0,4 @@

import { Account, Order, Position, Asset, Watchlist, Calendar, Clock, AccountConfigurations, NonTradeActivity, TradeActivity, PortfolioHistory, Bar, LastQuote, LastTrade, Credentials } from './entities.js';
import { Account, Order, Position, Asset, Watchlist, Calendar, Clock, AccountConfigurations, PortfolioHistory, Bar, LastQuote, LastTrade, Credentials, Activity } from './entities.js';
import { GetOrder, GetOrders, PlaceOrder, ReplaceOrder, CancelOrder, GetPosition, ClosePosition, GetAsset, GetAssets, GetWatchList, CreateWatchList, UpdateWatchList, AddToWatchList, RemoveFromWatchList, DeleteWatchList, GetCalendar, UpdateAccountConfigurations, GetAccountActivities, GetPortfolioHistory, GetBars, GetLastTrade, GetLastQuote } from './params.js';
export declare class Client {
export declare class AlpacaClient {
protected options: {

@@ -10,2 +10,3 @@ credentials: Credentials;

private limiter;
private parser;
constructor(options: {

@@ -41,3 +42,3 @@ credentials: Credentials;

updateAccountConfigurations(params: UpdateAccountConfigurations): Promise<AccountConfigurations>;
getAccountActivities(params: GetAccountActivities): Promise<Array<NonTradeActivity | TradeActivity>>;
getAccountActivities(params: GetAccountActivities): Promise<Activity[]>;
getPortfolioHistory(params?: GetPortfolioHistory): Promise<PortfolioHistory>;

@@ -44,0 +45,0 @@ getBars(params: GetBars): Promise<Map<String, Bar[]>>;

@@ -0,1 +1,5 @@

/**
* Your Alpaca key id and secret.
* Can be passed to the AlpacaClient and AlpacaStream.
*/
export interface Credentials {

@@ -5,3 +9,7 @@ key: string;

}
export interface Account {
/**
* The account information with unparsed types, exactly as Alpaca provides it.
* We encourage you to use the Account interface, which has many of these fields parsed.
*/
export interface RawAccount {
account_blocked: boolean;

@@ -34,7 +42,182 @@ account_number: string;

}
/**
* The following are the possible account status values. Most likely, the account status
* is ACTIVE unless there is any problem. The account status may get in ACCOUNT_UPDATED
* when personal information is being updated from the dashboard, in which case you may
* not be allowed trading for a short period of time until the change is approved.
*/
export declare type AccountStatus =
/**
* The account is onboarding.
*/
'ONBOARDING'
/**
* The account application submission failed for some reason.
*/
| 'SUBMISSION_FAILED'
/**
* The account application has been submitted for review.
*/
| 'SUBMITTED'
/**
* The account information is being updated.
*/
| 'ACCOUNT_UPDATED'
/**
* The final account approval is pending.
*/
| 'APPROVAL_PENDING'
/**
* The account is active for trading.
*/
| 'ACTIVE'
/**
* The account application has been rejected.
*/
| 'REJECTED';
/**
* Information related to an Alpaca account, such as account status, funds, and various
* flags relevant to an account's ability to trade.
*/
export interface Account {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawAccount;
/**
* If true, the account activity by user is prohibited.
*/
account_blocked: boolean;
/**
* Account number.
*/
account_number: string;
/**
* Current available $ buying power; If multiplier = 4, this is your daytrade buying
* power which is calculated as (last_equity - (last) maintenance_margin) * 4; If
* multiplier = 2, buying_power = max(equity – initial_margin,0) * 2; If multiplier = 1,
* buying_power = cash
*/
buying_power: number;
/**
* Cash balance
*/
cash: number;
/**
* Timestamp this account was created at
*/
created_at: Date;
/**
* "USD"
*/
currency: string;
/**
* The current number of daytrades that have been made in the last 5 trading days
* (inclusive of today)
*/
daytrade_count: number;
/**
* Your buying power for day trades (continuously updated value)
*/
daytrading_buying_power: number;
/**
* Cash + long_market_value + short_market_value
*/
equity: number;
/**
* Account ID.
*/
id: string;
/**
* Reg T initial margin requirement (continuously updated value)
*/
initial_margin: number;
/**
* Equity as of previous trading day at 16:00:00 ET
*/
last_equity: number;
/**
* Your maintenance margin requirement on the previous trading day
*/
last_maintenance_margin: number;
/**
* Real-time MtM value of all long positions held in the account
*/
long_market_value: number;
/**
* Maintenance margin requirement (continuously updated value)
*/
maintenance_margin: number;
/**
* Buying power multiplier that represents account margin classification; valid values 1
* (standard limited margin account with 1x buying power), 2 (reg T margin account with
* 2x intraday and overnight buying power; this is the default for all non-PDT accounts
* with $2,000 or more equity), 4 (PDT account with 4x intraday buying power and 2x reg
* T overnight buying power)
*/
multiplier: number;
/**
* Whether or not the account has been flagged as a pattern day trader
*/
pattern_day_trader: boolean;
/**
* Total value of cash + holding positions (This field is deprecated. It is equivalent
* to the equity field.)
*/
portfolio_value: number;
/**
* Your buying power under Regulation T (your excess equity - equity minus margin
* value - times your margin multiplier)
*/
regt_buying_power: number;
/**
* Real-time MtM value of all short positions held in the account
*/
short_market_value: number;
/**
* Flag to denote whether or not the account is permitted to short
*/
shorting_enabled: boolean;
/**
* Value of special memorandum account (will be used at a later date to provide
* additional buying_power)
*/
sma: number;
/**
* The following are the possible account status values. Most likely, the account status
* is ACTIVE unless there is any problem. The account status may get in ACCOUNT_UPDATED
* when personal information is being updated from the dashboard, in which case you may
* not be allowed trading for a short period of time until the change is approved.
*/
status: AccountStatus;
/**
* User setting. If true, the account is not allowed to place orders.
*/
trade_suspended_by_user: boolean;
/**
* If true, the account is not allowed to place orders.
*/
trading_blocked: boolean;
/**
* If true, the account is not allowed to request money transfers.
*/
transfers_blocked: boolean;
}
export interface AccountConfigurations {
dtbp_check: string;
/**
* both, entry, or exit. Controls Day Trading Margin Call (DTMC) checks.
*/
dtbp_check: 'both' | 'entry' | 'exit';
/**
* If true, account becomes long-only mode.
*/
no_shorting: boolean;
/**
* If true, new orders are blocked.
*/
suspend_trade: boolean;
trade_confirm_email: string;
/**
* all or none. If none, emails for order fills are not sent.
*/
trade_confirm_email: 'all' | 'none';
}

@@ -66,27 +249,96 @@ export interface AccountUpdate {

}
export declare type AssetExchange = 'AMEX' | 'ARCA' | 'BATS' | 'NYSE' | 'NASDAQ' | 'NYSEARCA';
export declare type AssetStatus = 'active' | 'inactive';
/**
* The assets API serves as the master list of assets available for trade and data
* consumption from Alpaca. Assets are sorted by asset class, exchange and symbol. Some
* assets are only available for data consumption via Polygon, and are not tradable with
* Alpaca. These assets will be marked with the flag tradable=false.
*/
export interface Asset {
/**
* Asset ID
*/
id: string;
/**
* "us_equity"
*/
class: string;
exchange: string;
/**
* AMEX, ARCA, BATS, NYSE, NASDAQ or NYSEARCA
*/
exchange: AssetExchange;
/**
* Asset symbol
*/
symbol: string;
status: string;
/**
* active or inactive
*/
status: AssetStatus;
/**
* Asset is tradable on Alpaca or not
*/
tradable: boolean;
/**
* Asset is marginable or not
*/
marginable: boolean;
/**
* Asset is shortable or not
*/
shortable: boolean;
/**
* Asset is easy-to-borrow or not (filtering for easy_to_borrow = True is the best way
* to check whether the name is currently available to short at Alpaca).
*/
easy_to_borrow: boolean;
}
/**
* Price and volume data during a particular time interval
*/
export interface Bar {
/**
* the beginning time of this bar as a Unix epoch in seconds
*/
t: number;
/**
* open price
*/
o: number;
/**
* high price
*/
h: number;
/**
* low price
*/
l: number;
/**
* close price
*/
c: number;
/**
* volume
*/
v: number;
}
/**
* Contains the time of open and close for a market on a particular day from 1970 to 2029
*/
export interface Calendar {
/**
* Date string in YYYY-MM-DD format
*/
date: string;
/**
* The time the market opens at on this date in HH:MM format
*/
open: string;
/**
* The time the market closes at on this date in HH:MM format
*/
close: string;
}
export interface Clock {
export interface RawClock {
timestamp: string;

@@ -97,2 +349,31 @@ is_open: boolean;

}
/**
* The clock API serves the current market timestamp, whether or not the market is
* currently open, as well as the times of the next market open and close.
*/
export interface Clock {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawClock;
/**
* Current timestamp
*/
timestamp: Date;
/**
* Whether or not the market is open
*/
is_open: boolean;
/**
* Next market open timestamp
*/
next_open: Date;
/**
* Next market close timestamp
*/
next_close: Date;
}
/**
* Last quote details for a symbol
*/
export interface LastQuote {

@@ -102,11 +383,35 @@ status: string;

last: {
/**
* the current ask price
*/
askprice: number;
/**
* the current ask size
*/
asksize: number;
/**
* the exchange code of the ask quote
*/
askexchange: number;
/**
* the current bid price
*/
bidprice: number;
/**
* the current bid size
*/
bidsize: number;
/**
* the exchange code of the bid quote
*/
bidexchange: number;
/**
* epoch timestamp in nanoseconds
*/
timestamp: number;
};
}
/**
* Last trade details for a symbol
*/
export interface LastTrade {

@@ -116,13 +421,41 @@ status: string;

last: {
/**
* last trade price
*/
price: number;
/**
* last trade volume size
*/
size: number;
/**
* exchange code where the last trade was made
*/
exchange: number;
/**
* condition flag 1
*/
cond1: number;
/**
* condition flag 2
*/
cond2: number;
/**
* condition flag 3
*/
cond3: number;
/**
* condition flag 4
*/
cond4: number;
/**
* epoch timestamp in nanoseconds
*/
timestamp: number;
};
}
export interface Order {
/**
* The order entity with unparsed fields, exactly as Alpaca provides it.
* We encourage you to use the Order interface, which has many of these fields parsed.
*/
export interface RawOrder {
id: string;

@@ -139,3 +472,3 @@ client_order_id: string;

replaced_by: string;
replaces: any;
replaces: string;
asset_id: string;

@@ -154,13 +487,297 @@ symbol: string;

extended_hours: boolean;
legs: any;
legs: RawOrder[];
trail_price: string;
trail_percent: string;
hwm: string;
}
export declare type OrderType = 'market' | 'limit' | 'stop' | 'stop_limit' | 'trailing_stop';
export declare type OrderSide = 'buy' | 'sell';
export declare type OrderTimeInForce =
/**
* A day order is eligible for execution only on the day it is live. By default, the
* order is only valid during Regular Trading Hours (9:30am - 4:00pm ET). If unfilled
* after the closing auction, it is automatically canceled. If submitted after the
* close, it is queued and submitted the following trading day. However, if marked as
* eligible for extended hours, the order can also execute during supported extended
* hours.
*/
'day'
/**
* The order is good until canceled. Non-marketable GTC limit orders are subject to
* price adjustments to offset corporate actions affecting the issue. We do not
* currently support Do Not Reduce(DNR) orders to opt out of such price adjustments.
*/
| 'gtc'
/**
* Use this TIF with a market/limit order type to submit "market on open" (MOO) and
* "limit on open" (LOO) orders. This order is eligible to execute only in the market
* opening auction. Any unfilled orders after the open will be cancelled. OPG orders
* submitted after 9:28am but before 7:00pm ET will be rejected. OPG orders submitted
* after 7:00pm will be queued and routed to the following day's opening auction. On
* open/on close orders are routed to the primary exchange. Such orders do not
* necessarily execute exactly at 9:30am / 4:00pm ET but execute per the exchange's
* auction rules.
*/
| 'opg'
/**
* Use this TIF with a market/limit order type to submit "market on close" (MOC) and
* "limit on close" (LOC) orders. This order is eligible to execute only in the market
* closing auction. Any unfilled orders after the close will be cancelled. CLS orders
* submitted after 3:50pm but before 7:00pm ET will be rejected. CLS orders submitted
* after 7:00pm will be queued and routed to the following day's closing auction. Only
* available with API v2.
*/
| 'cls'
/**
* An Immediate Or Cancel (IOC) order requires all or part of the order to be executed
* immediately. Any unfilled portion of the order is canceled. Only available with API
* v2.
*/
| 'ioc'
/**
* A Fill or Kill (FOK) order is only executed if the entire order quantity can be
* filled, otherwise the order is canceled. Only available with API v2.
*/
| 'fok';
export declare type OrderStatus =
/**
* The order has been received by Alpaca, and routed to exchanges for execution. This
* is the usual initial state of an order.
*/
'new'
/**
* The order has been partially filled.
*/
| 'partially_filled'
/**
* The order has been filled, and no further updates will occur for the order.
*/
| 'filled'
/**
* The order is done executing for the day, and will not receive further updates until
* the next trading day.
*/
| 'done_for_day'
/**
* The order has been canceled, and no further updates will occur for the order. This
* can be either due to a cancel request by the user, or the order has been canceled by
* the exchanges due to its time-in-force.
*/
| 'canceled'
/**
* The order has expired, and no further updates will occur for the order.
*/
| 'expired'
/**
* The order was replaced by another order, or was updated due to a market event such
* as corporate action.
*/
| 'replaced'
/**
* The order is waiting to be canceled.
*/
| 'pending_cancel'
/**
* The order is waiting to be replaced by another order. The order will reject cancel
* request while in this state.
*/
| 'pending_replace'
/**
* (Uncommon) The order has been received by Alpaca, but hasn't yet been routed to the
* execution venue. This could be seen often out side of trading session hours.
*/
| 'accepted'
/**
* (Uncommon) The order has been received by Alpaca, and routed to the exchanges, but
* has not yet been accepted for execution. This state only occurs on rare occasions.
*/
| 'pending_new'
/**
* (Uncommon) The order has been received by exchanges, and is evaluated for pricing.
* This state only occurs on rare occasions.
*/
| 'accepted_for_bidding'
/**
* (Uncommon) The order has been stopped, and a trade is guaranteed for the order,
* usually at a stated price or better, but has not yet occurred. This state only
* occurs on rare occasions.
*/
| 'stopped'
/**
* (Uncommon) The order has been rejected, and no further updates will occur for the
* order. This state occurs on rare occasions and may occur based on various conditions
* decided by the exchanges.
*/
| 'rejected'
/**
* (Uncommon) The order has been suspended, and is not eligible for trading. This state
* only occurs on rare occasions.
*/
| 'suspended'
/**
* (Uncommon) The order has been completed for the day (either filled or done for day),
* but remaining settlement calculations are still pending. This state only occurs on
* rare occasions.
*/
| 'calculated';
/**
* An Order in Alpaca
*/
export interface Order {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawOrder;
/**
* Order id
*/
id: string;
/**
* Client unique order id
*/
client_order_id: string;
/**
* When the order was created
*/
created_at: Date;
/**
* When the order was last updated
*/
updated_at: Date;
/**
* When the order was submitted
*/
submitted_at: Date;
/**
* When the order was filled
*/
filled_at: Date;
/**
* When the order expired
*/
expired_at: Date;
/**
* When the order was canceled
*/
canceled_at: Date;
/**
* When the order failed
*/
failed_at: Date;
/**
* When the order was last replaced
*/
replaced_at: Date;
/**
* The order ID that this order was replaced by
*/
replaced_by: string;
/**
* The order ID that this order replaces
*/
replaces: string;
/**
* Asset ID
*/
asset_id: string;
/**
* Asset symbol
*/
symbol: string;
/**
* Asset class
*/
asset_class: string;
/**
* Ordered quantity
*/
qty: number;
/**
* Filled quantity
*/
filled_qty: number;
/**
* Order type (market, limit, stop, stop_limit, trailing_stop)
*/
type: OrderType;
/**
* Buy or sell
*/
side: OrderSide;
/**
* Order Time in Force
*/
time_in_force: OrderTimeInForce;
/**
* Limit price
*/
limit_price: number;
/**
* Stop price
*/
stop_price: number;
/**
* Filled average price
*/
filled_avg_price: number;
/**
* The status of the order
*/
status: OrderStatus;
/**
* If true, eligible for execution outside regular trading hours.
*/
extended_hours: boolean;
/**
* When querying non-simple order_class orders in a nested style, an array of Order
* entities associated with this order. Otherwise, null.
*/
legs: Order[];
/**
* The dollar value away from the high water mark for trailing stop orders.
*/
trail_price: number;
/**
* The percent value away from the high water mark for trailing stop orders.
*/
trail_percent: number;
/**
* The highest (lowest) market price seen since the trailing stop order was submitted.
*/
hwm: number;
}
/**
* Timeseries data for equity and profit loss information of the account
*/
export interface PortfolioHistory {
/**
* time of each data element, left-labeled (the beginning of time window)
*/
timestamp: number[];
/**
* equity value of the account in dollar amount as of the end of each time window
*/
equity: number[];
/**
* profit/loss in dollar from the base value
*/
profit_loss: number[];
/**
* profit/loss in percentage from the base value
*/
profit_loss_pct: number[];
/**
* basis in dollar of the profit loss calculation
*/
base_value: number;
/**
* time window size of each data element
*/
timeframe: string;
}
export interface Position {
/**
* A position with unparsed fields, exactly as Alpaca provides it.
* We encourage you to use the Position interface, which has many of these fields parsed.
*/
export interface RawPosition {
asset_id: string;

@@ -183,2 +800,76 @@ symbol: string;

}
export declare type PositionSide = 'long' | 'short';
/**
* A position in Alpaca
*/
export interface Position {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawPosition;
/**
* Asset ID
*/
asset_id: string;
/**
* Symbol name of the asset
*/
symbol: string;
/**
* Exchange name of the asset
*/
exchange: string;
/**
* Asset class name
*/
asset_class: string;
/**
* Average entry price of the position
*/
avg_entry_price: number;
/**
* The number of shares
*/
qty: number;
/**
* long or short
*/
side: PositionSide;
/**
* Total dollar amount of the position
*/
market_value: number;
/**
* Total cost basis in dollar
*/
cost_basis: number;
/**
* Unrealized profit/loss in dollars
*/
unrealized_pl: number;
/**
* Unrealized profit/loss percent (by a factor of 1)
*/
unrealized_plpc: number;
/**
* Unrealized profit/loss in dollars for the day
*/
unrealized_intraday_pl: number;
/**
* Unrealized profit/loss percent (by a factor of 1)
*/
unrealized_intraday_plpc: number;
/**
* Current asset price per share
*/
current_price: number;
/**
* Last day's asset price per share based on the closing value of the last trading day
*/
lastday_price: number;
/**
* Percent change from last day price (by a factor of 1)
*/
change_today: number;
}
export interface Quote {

@@ -207,4 +898,138 @@ ev: string;

}
export interface TradeActivity {
activity_type: string;
export declare type ActivityType =
/**
* Order fills (both partial and full fills)
*/
'FILL'
/**
* Cash transactions (both CSD and CSR)
*/
| 'TRANS'
/**
* Miscellaneous or rarely used activity types (All types except those in TRANS, DIV,
* or FILL)
*/
| 'MISC'
/**
* ACATS IN/OUT (Cash)
*/
| 'ACATC'
/**
* ACATS IN/OUT (Securities)
*/
| 'ACATS'
/**
* Cash disbursement(+)
*/
| 'CSD'
/**
* Cash receipt(-)
*/
| 'CSR'
/**
* Dividends
*/
| 'DIV'
/**
* Dividend (capital gain long term)
*/
| 'DIVCGL'
/**
* Dividend (capital gain short term)
*/
| 'DIVCGS'
/**
* Dividend fee
*/
| 'DIVFEE'
/**
* Dividend adjusted (Foreign Tax Withheld)
*/
| 'DIVFT'
/**
* Dividend adjusted (NRA Withheld)
*/
| 'DIVNRA'
/**
* Dividend return of capital
*/
| 'DIVROC'
/**
* Dividend adjusted (Tefra Withheld)
*/
| 'DIVTW'
/**
* Dividend (tax exempt)
*/
| 'DIVTXEX'
/**
* Interest (credit/margin)
*/
| 'INT'
/**
* Interest adjusted (NRA Withheld)
*/
| 'INTNRA'
/**
* Interest adjusted (Tefra Withheld)
*/
| 'INTTW'
/**
* Journal entry
*/
| 'JNL'
/**
* Journal entry (cash)
*/
| 'JNLC'
/**
* Journal entry (stock)
*/
| 'JNLS'
/**
* Merger/Acquisition
*/
| 'MA'
/**
* Name change
*/
| 'NC'
/**
* Option assignment
*/
| 'OPASN'
/**
* Option expiration
*/
| 'OPEXP'
/**
* Option exercise
*/
| 'OPXRC'
/**
* Pass Thru Charge
*/
| 'PTC'
/**
* Pass Thru Rebate
*/
| 'PTR'
/**
* Reorg CA
*/
| 'REORG'
/**
* Symbol change
*/
| 'SC'
/**
* Stock spinoff
*/
| 'SSO'
/**
* Stock split
*/
| 'SSP';
export interface RawTradeActivity {
activity_type: Extract<ActivityType, 'FILL'>;
cum_qty: string;

@@ -221,4 +1046,4 @@ id: string;

}
export interface NonTradeActivity {
activity_type: string;
export interface RawNonTradeActivity {
activity_type: Exclude<ActivityType, 'FILL'>;
id: string;

@@ -231,2 +1056,96 @@ date: string;

}
export declare type TradeActivityType = 'fill' | 'partial_fill';
export declare type TradeActivitySide = 'buy' | 'sell';
export interface TradeActivity {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawTradeActivity;
/**
* FILL
*/
activity_type: Extract<ActivityType, 'FILL'>;
/**
* The cumulative quantity of shares involved in the execution.
*/
cum_qty: number;
/**
* An id for the activity. Always in "::" format. Can be sent as page_token in requests
* to facilitate the paging of results.
*/
id: string;
/**
* For partially_filled orders, the quantity of shares that are left to be filled.
*/
leaves_qty: number;
/**
* The per-share price that the trade was executed at.
*/
price: number;
/**
* The number of shares involved in the trade execution.
*/
qty: number;
/**
* buy or sell
*/
side: TradeActivitySide;
/**
* The symbol of the security being traded.
*/
symbol: string;
/**
* The time at which the execution occurred.
*/
transaction_time: string;
/**
* The id for the order that filled.
*/
order_id: string;
/**
* fill or partial_fill
*/
type: TradeActivityType;
}
export interface NonTradeActivity {
/**
* Get the raw data, exactly as it came from Alpaca
*/
raw(): RawNonTradeActivity;
/**
* Activity type
*/
activity_type: Exclude<ActivityType, 'FILL'>;
/**
* An ID for the activity, always in "::" format. Can be sent as page_token in requests
* to facilitate the paging of results.
*/
id: string;
/**
* The date on which the activity occurred or on which the transaction associated with
* the activity settled.
*/
date: string;
/**
* The net amount of money (positive or negative) associated with the activity.
*/
net_amount: number;
/**
* The symbol of the security involved with the activity. Not present for all activity
* types.
*/
symbol: string;
/**
* For dividend activities, the number of shares that contributed to the payment. Not
* present for other activity types.
*/
qty: number;
/**
* For dividend activities, the average amount paid per share. Not present for other
* activity types.
*/
per_share_amount: number;
}
export declare type RawActivity = RawTradeActivity | RawNonTradeActivity;
export declare type Activity = TradeActivity | NonTradeActivity;
export interface TradeUpdate {

@@ -248,8 +1167,26 @@ event: string;

export interface Watchlist {
/**
* account ID
*/
account_id: string;
/**
* the content of this watchlist, in the order as registered by the client
*/
assets: Asset[];
/**
* When the watchlist was created
*/
created_at: string;
/**
* watchlist id
*/
id: string;
/**
* user-defined watchlist name (up to 64 characters)
*/
name: string;
/**
* When the watchlist was last updated
*/
updated_at: string;
}

@@ -0,1 +1,2 @@

import { OrderSide, OrderType, OrderTimeInForce } from './entities.js';
export interface AddToWatchList {

@@ -59,7 +60,7 @@ uuid: string;

export interface GetOrders {
status?: string;
status?: 'open' | 'closed' | 'all';
limit?: number;
after?: Date;
until?: Date;
direction?: string;
direction?: 'asc' | 'desc';
nested?: boolean;

@@ -82,11 +83,11 @@ }

qty: number;
side: 'buy' | 'sell';
type: 'market' | 'limit' | 'stop' | 'stop_limit' | 'trailing_stop';
time_in_force: 'day' | 'gtc' | 'opg' | 'cls' | 'ioc' | 'fok';
side: OrderSide;
type: OrderType;
time_in_force: OrderTimeInForce;
limit_price?: number;
stop_price?: number;
extended_hours?: boolean;
client_order_id?: string;
trail_price?: number;
trail_percent?: number;
extended_hours?: boolean;
client_order_id?: string;
order_class?: 'simple' | 'bracket' | 'oco' | 'oto';

@@ -108,3 +109,3 @@ take_profit?: {

qty?: number;
time_in_force?: string;
time_in_force?: OrderTimeInForce;
limit_price?: number;

@@ -111,0 +112,0 @@ stop_price?: number;

/// <reference types="node" />
import { EventEmitter } from 'events';
import { Credentials } from './entities.js';
export declare interface Stream {
on<U extends keyof StreamEvents>(event: U, listener: StreamEvents[U]): this;
emit<U extends keyof StreamEvents>(event: U, ...args: Parameters<StreamEvents[U]>): boolean;
export declare interface AlpacaStream {
on<U extends keyof AlpacaStreamEvents>(event: U, listener: AlpacaStreamEvents[U]): this;
emit<U extends keyof AlpacaStreamEvents>(event: U, ...args: Parameters<AlpacaStreamEvents[U]>): boolean;
}
export declare interface StreamEvents {
open: (connection: Stream) => void;
close: (connection: Stream) => void;
authenticated: (connection: Stream) => void;
export declare interface AlpacaStreamEvents {
open: (connection: AlpacaStream) => void;
close: (connection: AlpacaStream) => void;
authenticated: (connection: AlpacaStream) => void;
error: (error: Error) => void;

@@ -20,3 +20,3 @@ message: (data: Object) => void;

}
export declare class Stream extends EventEmitter {
export declare class AlpacaStream extends EventEmitter {
protected params: {

@@ -23,0 +23,0 @@ credentials: Credentials;

Sorry, the diff of this file is not supported yet

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