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

schwab-client-js

v1.0.3

Published

Javascript client for the Schwab API

Downloads

174

Readme

schwab-client-js

A modern wrapper around the Schwab financial API for Typescript and Javascript projects

Donate Paypal Donate Venmo GitHub license Node.js supported npm Downloads

Disclaimer: This project is not affiliated with, endorsed by, or associated with The Charles Schwab Corporation. All registered trademarks are the property of their respective owners. Use of these names, logos, and brands is for identification purposes only. This project is licensed under the MIT license, and acts in accordance with Schwab's API terms and conditions.

Two Streaming Dashboards From The Examples Directory

schwab-client-js gives you complete access to the Schwab REST API using convenient classes and methods. You can stream real-time market data, create and track orders, and retrieve information about your account as well as retrieve different types of market data.

Note: This project only supports nodejs. Although technically you could tweak schwab-client-js to run in a web browser, security concerns make that a poor choice.

Installation

Software prerequisites: nodejs version 18 or newer.

Install the package:

npm install schwab-client-js

or

yarn add schwab-client-js

Schwab Prerequisites

  1. You need a Schwab brokerage account. Even if you're not executing any stock or other trades with the API, you still need to be able to login to your Schwab account in order to create an API access token. ▪ Login to your Schwab account and turn on thinkorswim. If thinkorswim is already enabled, you won't see instructions on how to enable it.

  2. You need to signup for a Schwab developer account. The account is free. ▪ Login to your developer account and create an "app" which is really just a web page where you configure the metadata for your API calls. ▪ Create a new app and where it says "Select an API product" add both: "Accounts and Trading Production" and "Market Data Production". ▪ You will probably want to use the callback url https://127.0.0.1 ▪ You may have to wait a day or two for Schwab to approve your app. You cannot do anything while the status of your app is Pending or Approved - Pending. When the status of your app is Ready for use, you can proceed. ▪ Once your app is approved, go to the apps section and click on View Details for your app. At the bottom you should see your App Key and Secret.

Configuring the package

Schwab uses three-legged OAuth for authentication. The details are on developer.schwab.com here and here.

  1. Create a .env file at the root of your project and add the App Key and Secret from developer.schwab.com. If your callback URL is anything besides https://127.0.0.1 (for example, you added a port number), also add it to your .env file like this:
SCHWAB_CALLBACK_URL=https://127.0.0.1:5556
SCHWAB_APP_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SCHWAB_SECRET=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
  1. Run schwab-authorize . After installing schwab-client-js, you should run the helper app named schwab-authorize. On MacOS and Linux, you should be able to run it from the command line when you're at the root of your project by typing schwab-authorize (see Note1 below). It will construct a special Schwab login URL using your SCHWAB_APP_KEY and will try to open your desktop web browser at that URL. You will need to login with your schwab.com credentials (NOT your developer.schwab.com credentials). When you get to the final step, your browser will likely give you a warning because schwab-authorize dynamically generates a self-signed SSL certificate in order to retrieve the returned HTTPS URL. Allow schwab-authorize to do its job and it will add the resulting SCHWAB_REFRESH_TOKEN to your .env file. ▪ Note1: On Windows, you may have to run it directly:
    C:\> node node_modules/schwab-client-js/bin/schwab-authorize.js ▪ Note2: Schwab only lets you have one SCHWAB_REFRESH_TOKEN working per Schwab login. So, if you have multiple projects using schwab-client-js, you'll need to use the same SCHWAB_REFRESH_TOKEN for all of them. Creating a new SCHWAB_REFRESH_TOKEN invalidates the old ones. ▪ Note3: When you get the warning from your web browser about the self-signed cert, you'll have 30 seconds to click through before the retrieved token expires and you'll have to run schwab-authorize again. ▪ Note4: schwab-authorize is written in Javascript. You can review the source at node_modules/schwab-client-js/bin/schwab-authorize.js.

  2. Your .env file should now look like this (as previously mentioned, the SCHWAB_CALLBACK_URL is optional and will default to https://127.0.0.1 if not provided):

SCHWAB_CALLBACK_URL=https://somewhere.blahhhh
SCHWAB_APP_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SCHWAB_SECRET=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
SCHWAB_REFRESH_TOKEN=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

Congratulations! You are now ready to make API calls.

The SCHWAB_REFRESH_TOKEN lasts for seven days. It then expires and you will no longer be able to make API calls. You must run schwab-authorize again to get a new SCHWAB_REFRESH_TOKEN (sorry folks, I don't make these rules).

Usage

For complete details on returned JSON objects, error codes, order objects, and other API request details, see the documentation on developer.schwab.com.

Getting Market Data (see the examples directory for more examples)

import { MarketApiClient } from  "schwab-client-js";
const mktclient = new MarketApiClient();

// Get stock information by ticker symbol
const data1 =  await mktclient.quoteById("AMD", "quote,fundamental");
console.log("quoteById DATA=", JSON.stringify(data1));

// Get security information by cusip
const data2 =  await mktclient.instrumentsCusip("023135106");
console.log("instrumentsCusip DATA=", JSON.stringify(data2));

// Get market information
const data3 await mktclient.markets("bond,option,forex");
console.log("markets DATA=", JSON.stringify(data3));

Trading And Trading Data (see the examples directory for more examples)

import { TradingApiClient } from  "schwab-client-js";
const trdclient = new TradingApiClient();

// Get your authorized Schwab account numbers and hashed account numbers
const data1 = await trdclient.accountsNumbers();
console.log("accountsNumbers DATA=", JSON.stringify(data1));

// Get orders (all statuses) withing the specified date range
const accountHash="4B9A9B50B7886A574E2A793DFE9B944EA2DAB9"; // Your encrypted account number
const fromDate="2024-01-10T12:17:41+02:00";
const toDate="2024-09-10T12:17:41.000Z";
const data2 = await trdclient.ordersByAccount(accountHash, fromDate, toDate);
console.log("ordersByAccount DATA=", JSON.stringify(data2));

// Create an order
const orderObj = {
         "orderType": "LIMIT",
         "session": "NORMAL",
         "duration": "DAY",
         "orderStrategyType": "SINGLE",
         "price": '1.00',
         "orderLegCollection": [
            {
              "instruction": "BUY",
              "quantity": 1,
              "instrument": {
                 "symbol": "CTRN",
                 "assetType": "EQUITY"
              }
            }
         ]
};

// Place a trade on a specified Schwab account
const accountHash="4B9A9B50B7886A574E2A793DFE9B944EA2DAB9"; // Your encrypted account number
const data3 = await trdclient.placeOrderByAcct(accountHash, orderObj);
console.log("placeOrderByAcct DATA=", JSON.stringify(data3));

// Delete an existing order
const accountHash="4B9A9B50B7886A574E2A793DFE9B944EA2DAB9";
const orderID="435234523452345";
const data4 = await trdclient.orderDelete(accountHash, orderId);
console.log("orderDelete DATA=", JSON.stringify(data4));

Streaming (see the examples directory for more examples)

  • Streaming may not work well outside of normal market hours. Use the marketById() or markets() calls to get the market hours.
import { StreamingApiClient } from  "schwab-client-js";

// Create your streaming client object
const streamclient = new StreamingApiClient();

// Listen for the "open" request
streamclient.streamListen('open', () => {
    console.log("Received open message: webSocket connection opened.");
});

// Listen for messages from Schwab. This is where your data arreves
streamclient.streamListen('message', (message) => {
    console.log("Received data message:", message);
});

// Listen for close
streamclient.streamListen('close', (code, reason) => {
    console.log(`Connection closed: Code=${code}, Reason=${reason}`);
});

// Listen for errors
streamclient.streamListen('error', (error) => {
    console.error("Received error message:", error);
});

// Initialize the stream
await streamclient.streamInit();

// Login to the Schwab stream
await streamclient.streamSchwabLogin();

// Subscribe to some stock prices
let params = { keys: "AMD,TSLA,GOOG", fields: "0,1,2,3,4,5" };
await streamclient.streamSchwabRequest("ADD", "LEVELONE_EQUITIES", params);

// LOGOUT of the stream
await streamclient.streamSchwabLogout()
streamclient.streamClose();

Subclasses and Methods for Class SchwabAPIclient

| Subclass | Method | Description | | ---------------------- | ----------------------- | ---------------------------------------------------- | | MarketApiClient | | | | | chains() | Get option chain for an optionable symbol. | | | expirationChain() | Get Option Expiration info for an optionable symbol. | | | instrumentsCusip() | Get instrument details by CUSIP ID. | | | instrumentsSymbol() | Get instrument details by symbol and projection. | | | marketById() | Get market hours for a single market. | | | markets() | Get market hours for a list of markets. | | | movers() | Get a list of top 10 securities movers by index. | | | priceHistory() | Get price history for a given symbol ID. | | | quoteById() | Get a quote by symbol ID. | | | quotes() | Get multiple quotes for a list of symbols. | | TradingApiClient | | | | | accountsAll() | Get balances and positions for all your accounts. | | | accountsDetails() | Get balance and positions for a specific account. | | | accountsNumbers() | Get all authorized account numbers with hashes. | | | orderAll() | Get all orders for all your authorized accounts. | | | orderById() | Get details of a specific order by its ID. | | | orderDelete() | Delete an order by its ID. | | | orderPreview() | Preview an order [Schwab has not released this yet]. | | | ordersByAccount() | Get orders for a specific account. | | | placeOrderByAcct() | Place an order for a specific account. | | | prefs() | Get user preferences and streaming parameters. | | | transactByAcct() | Get transactions for a specific account. | | | transactById() | Get details of a specific transaction by its ID. | | | updateOrderById() | Update an order by its ID. | | StreamingApiClient | | | | | streamInit() | Initialize the WebSocket stream. | | | streamSchwabLogin() | Log in to the Schwab streaming service. | | | streamSchwabLogout() | Log out of the Schwab streaming service. | | | streamSchwabRequest() | Send a request to the Schwab streaming service. | | | streamListen() | Listen for events from the WebSocket stream. | | | streamClose() | Close the WebSocket stream. |

Debugging

schwab-client-js uses the debug package for quick and easy debugging. Simply add the DEBUG environment var to your .env file or as an environment variable, and debugging info will show up on the console.

Available DEBUG namespaces

  • DEBUG=streaming:msgs Displays all streaming messages and events
  • DEBUG=fetch:args Displays arguments to fetch() calls
  • DEBUG=fetch:raw-response Displays raw response object from fetch() calls

Other ways to use DEBUG

  • DEBUG=streaming:msgs,fetch:raw-response Display both of these
  • DEBUG=fetch:* Display both fetch:args and fetch:raw-response
  • DEBUG=* Display everything

When fetch() calls throw an exception, the error is printed on the console.

Examples

The examples directory contains sample invocations including two different streaming dashboards

  • schwab-dashboard-react A React-based stock dashboard using recharts
  • schwab-dashboard-forex A pure HTML/CSS forex dashboard using lightweight-charts

MIT License

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.