npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@master-chief/alpaca

v6.3.20

Published

A TypeScript Node.js library for the https://alpaca.markets REST API and WebSocket streams.

Downloads

634

Readme

alpaca

version code build prettier

A TypeScript Node.js library for the https://alpaca.markets REST API and WebSocket streams.

Contents

Features

  • [x] Fully typed.
  • [x] Fully asynchronous promise based API.
  • [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.
  • [x] Auto-transpiled modern ESM alternative.
  • [x] OAuth integration support.
  • [x] Minified and non-minified bundles.
  • [x] Various bundles provided:
    • alpaca.js - ESM bundle (for node)
    • alpaca.bundle.js - ESM bundle with dependencies (for node)
    • alpaca.browser.js - UMD bundle (for browser)
    • alpaca.browser.modern.js - ESM modern bundle (for browser)

Install

From NPM:

> npm i @master-chief/alpaca

From GitHub:

From these popular CDNs:

Import

Import with CommonJS:

let { AlpacaClient, AlpacaStream } = require('@master-chief/alpaca');

Import with ESM:

import { AlpacaClient, AlpacaStream } from '@master-chief/alpaca';

Import as script:

<script src="https://unpkg.com/@master-chief/alpaca/dist/alpaca.browser.min.js"></script>

Import as module:

<script type="module">
  import alpaca from 'alpaca.browser.modern.min.js';
</script>

Client

Creating a new client

If you wish to use env vars, populate these fields with process.env on your own. Paper account key detection is automatic. Using OAuth? Simply pass an access_token in the credentials object.

const client = new AlpacaClient({
  credentials: {
    key: 'xxxxxx',
    secret: 'xxxxxxxxxxxx',
    // access_token: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
    paper: true,
  },
  rate_limit: true,
});

Built-in parsing

Alpaca provides numbers as strings. From their docs:

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.

const account = await client.getAccount();

console.log(typeof account.buying_power); // number
console.log(typeof account.raw().buying_power); // string

Methods

The following methods are available on the client.

Account

Market Data v1

Market Data v2

isAuthenticated

await client.isAuthenticated();

getAccount

await client.getAccount();

getOrder

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

getOrders

await client.getOrders({ limit: 25, status: 'all' });

placeOrder

await client.placeOrder({
  symbol: 'SPY',
  qty: 1,
  // or
  // notional: 100,
  side: 'buy',
  type: 'market',
  time_in_force: 'day',
});

replaceOrder

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

cancelOrder

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

cancelOrders

await client.cancelOrders();

getPosition

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

getPositions

await client.getPositions();

closePosition

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

closePositions

await client.closePositions();

getAsset

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

getAssets

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

getWatchlist

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

getWatchlists

await client.getWatchlists();

createWatchlist

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

updateWatchlist

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

addToWatchlist

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

removeFromWatchlist

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

deleteWatchlist

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

getCalendar

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

getClock

await client.getClock();

getAccountConfigurations

await client.getAccountConfigurations();

updateAccountConfigurations

await client.updateAccountConfigurations({
  no_shorting: true,
  suspend_trade: true,
});

getAccountActivities

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

getPortfolioHistory

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

getLastTrade_v1

await client.getLastTrade_v1({ symbol: 'SPY' });

getLastQuote_v1

await client.getLastQuote_v1({ symbol: 'SPY' });

getBars_v1

await client.getBars_v1({ symbols: ['SPY', 'DIA', 'XLF'], timeframe: '1Min' });

getLatestTrade

await client.getLatestTrade({ symbol: 'SPY' });

getTrades

Basic
await client.getTrades({
  symbol: 'SPY',
  start: new Date('2021-02-26T14:30:00.007Z'),
  end: new Date('2021-02-26T14:35:00.007Z'),
});
Paginated
let trades = []
let page_token = ''

// until the next token we receive is null
while (page_token != null) {
  let resp = await client.getTrades({ ..., page_token })
  trades.push(...resp.trades)
  page_token = resp.next_page_token
}

// wooh! we have collected trades from multiple pages
console.log(trades.length)

getQuotes

Basic
await client.getQuotes({
  symbol: 'SPY',
  start: new Date('2021-02-26T14:30:00.007Z'),
  end: new Date('2021-02-26T14:35:00.007Z'),
});
Paginated
let quotes = []
let page_token = ''

// until the next token we receive is null
while (page_token != null) {
  let resp = await client.getQuotes({ ..., page_token })
  quotes.push(...resp.quotes)
  page_token = resp.next_page_token
}

// wooh! we have collected quotes from multiple pages
console.log(quotes.length)

getBars

Basic
await client.getBars({
  symbol: 'SPY',
  start: new Date('2021-02-26T14:30:00.007Z'),
  end: new Date('2021-02-26T14:35:00.007Z'),
  timeframe: '1Min',
  // page_token: "MjAyMS0wMi0wNlQxMzowOTo0Mlo7MQ=="
});
Paginated
let bars = []
let page_token = ''

// until the next token we receive is null
while (page_token != null) {
  let resp = await client.getBars({ ..., page_token })
  bars.push(...resp.bars)
  page_token = resp.next_page_token
}

// wooh! we have collected bars from multiple pages
console.log(bars.length)

getSnapshot

await client.getSnapshot({ symbol: 'SPY' });

getSnapshots

await client.getSnapshots({ symbols: ['SPY', 'DIA'] });

getNews

await client.getNews({ symbols: ['SPY'] });

Stream

Creating a new stream

If you wish to use env vars, populate these fields with process.env on your own.

import { AlpacaStream } from '@master-chief/alpaca';

const stream = new AlpacaStream({
  credentials: {
    key: 'xxxxxx',
    secret: 'xxxxxxxxxxxx',
    paper: true,
  },
  type: 'market_data', // or "account"
  source: 'iex', // or "sip" depending on your subscription
});

Methods

The following methods are available on the stream.

Channels

| Channel | Type | | :-------------- | :------------ | | trade_updates | account | | trades | market_data | | quotes | market_data | | bars | market_data |

subscribe

stream.once('authenticated', () =>
  stream.subscribe('bars', ['SPY', 'AAPL', 'TSLA']),
);

unsubscribe

stream.unsubscribe('bars', ['SPY']);

on

stream.on('message', (message) => console.log(message));
stream.on('trade', (trade) => console.log(trade));
stream.on('bar', (bar) => console.log(bar));
stream.on('quote', (quote) => console.log(quote));
stream.on('trade_updates', (update) => console.log(update));
stream.on('error', (error) => console.warn(error));

getConnection

stream.getConnection();

Common Issues

If you are having difficulty getting Jest to work with this library, add this to your configuration:

moduleNameMapper: {
  '@master-chief/alpaca': '<rootDir>/node_modules/@master-chief/alpaca/dist/cjs/index.cjs',
},

Credit to @calvintwr and @wailinkyaww for finding this solution.

Examples

Don't know where to start? Check out our community-made examples here.

Contributing

Feel free to contribute and PR to your 💖's content.