Giter Site home page Giter Site logo

tiagosiebler / ftx-api Goto Github PK

View Code? Open in Web Editor NEW
123.0 2.0 49.0 772 KB

Node.js connector for the FTX.com & FTX.us APIs and WebSockets, with TypeScript & browser support.

Home Page: https://www.npmjs.com/package/ftx-api

License: MIT License

JavaScript 4.76% TypeScript 95.24%
ftx ftx-exchange ftxbot algorithmic-trading cryptocurrency-exchanges ftx-apis ftx-websockets typescript cryptocurrency

ftx-api's Introduction

ftx-api

Tests npm version npm size npm downloads last commit CodeFactor

Node.js connector for the FTX APIs and WebSockets, with TypeScript & browser support.

Installation

npm install --save ftx-api

Issues & Discussion

Related projects

Check out my related projects:

Documentation

Most methods accept JS objects, except for methods with only one parameter. These can be populated using parameters specified by FTX's API documentation.

Structure

This project uses typescript. Resources are stored in 3 key structures:

  • src - the whole connector written in typescript
  • lib - the javascript version of the project (compiled from typescript). This should not be edited directly, as it will be overwritten with each release.
  • dist - the packed bundle of the project for use in browser environments.
  • examples - demonstrations on various workflows using this library

Usage

Create API credentials at FTX

REST API Clients

Import and instance the RestClient to access all REST API methods.

  • All methods return promises.
  • Supports subaccounts.

Example

To use the REST APIs, import the `RestClient`. Click here to expand and see full sample:
const { RestClient } = require('ftx-api');

const restClientOptions = {
  // override the max size of the request window (in ms)
  recv_window?: number;

  // how often to sync time drift with FTX servers
  sync_interval_ms?: number | string;

  // Default: false. Disable above sync mechanism if true.
  disable_time_sync?: boolean;

  // Default: false. If true, we'll throw errors if any params are undefined
  strict_param_validation?: boolean;

  // Optionally override API protocol + domain
  // e.g 'https://ftx.us/api'
  baseUrl?: string;

  // Default: true. whether to try and post-process request exceptions.
  parse_exceptions?: boolean;

  // Subaccount nickname URI-encoded
  subAccountName?: string;
};

const API_KEY = 'xxx';
const PRIVATE_KEY = 'yyy';

const client = new RestClient(
  API_KEY,
  PRIVATE_KEY,

  // restClientOptions,
  // requestLibraryOptions
);

client.getMarkets()
  .then(result => {
    console.log("getMarkets result: ", result);
  })
  .catch(err => {
    console.error("getMarkets error: ", err);
  });

client.setAccountLeverage(5)
  .then(result => {
    console.log("setAccountLeverage result: ", result);
  })
  .catch(err => {
    console.error("setAccountLeverage error: ", err);
  });

See rest-client.ts for further information.

WebSockets

  • Automatically connect to FTX websockets
  • Automatically authenticate, if key & secret are provided.
  • Automatically checks connection integrity. If connection stale (no response to pings), automatically reconnects, re-authenticates and resubscribes to previous topics.
  • Supports subaccounts.
WebSocket channels can be subscribed to via the `WebsocketClient`. Click here to expand and see full sample:
const { WebsocketClient } = require('ftx-api');

const API_KEY = 'xxx';
const PRIVATE_KEY = 'yyy';

const wsConfig = {
  key: API_KEY,
  secret: PRIVATE_KEY,

  /*
    The following parameters are optional:
  */

  // Subaccount nickname
  // subAccountName: 'sub1',

  // how long to wait (in ms) before deciding the connection should be terminated & reconnected
  // pongTimeout: 1000,

  // how often to check (in ms) that WS connection is still alive
  // pingInterval: 10000,

  // how long to wait before attempting to reconnect (in ms) after connection is closed
  // reconnectTimeout: 500,

  // config options sent to RestClient (used for time sync). See RestClient docs.
  // restOptions: { },

  // config for axios used for HTTP requests. E.g for proxy support
  // requestOptions: { }

  // override which URL to use for websocket connections
  // wsUrl: 'wss://example.ftx.com/ws'
};

const ws = new WebsocketClient(wsConfig);

// subscribe to multiple topics at once
ws.subscribe(['fills', 'orders']);

// and/or subscribe to individual topics on demand
ws.subscribe('fills');

// and/or subscribe to complex topics on demand, one at a time
ws.subscribe({
  channel: 'trades',
  market: 'BTC-PERP'
});

// or as a list of complex topics
ws.subscribe([
  {
    channel: 'trades',
    market: 'BTC-PERP'
  },
  {
    channel: 'orderbookGrouped',
    market: 'BTC-PERP',
    grouping: 500
  }
]);

// Listen to events coming from websockets. This is the primary data source
ws.on('update', data => {
  console.log('update', data);
});

// Optional: Listen to websocket connection open event (automatic after subscribing to one or more topics)
ws.on('open', ({ event }) => {
  console.log('connection opened');
});

// Optional: Listen to responses to websocket queries (e.g. the response after subscribing to a topic)
ws.on('response', response => {
  console.log('response', response);
});

// Optional: Listen to connection close event. Unexpected connection closes are automatically reconnected.
ws.on('close', () => {
  console.log('connection closed');
});

// Optional: Listen to raw error events.
// Note: responses to invalid topics are currently only sent in the "response" event.
ws.on('error', err => {
  console.error('ERR', err);
});

See websocket-client.ts for further information.

Examples

More demonstrations can be found in the examples folder.


Customise Logging

Pass a custom logger which supports the log methods silly, debug, notice, info, warning and error, or override methods from the default logger as desired.

Click here to expand and see full sample:
const { WebsocketClient, DefaultLogger } = require('ftx-api');

// Disable all logging on the silly level
DefaultLogger.silly = () => {};

const ws = new WebsocketClient(
  { key: 'xxx', secret: 'yyy' },
  DefaultLogger
);

Browser Usage

Build a bundle using webpack:

  • npm install
  • npm build
  • npm pack

The bundle can be found in dist/. Altough usage should be largely consistent, smaller differences will exist. Documentation is still TODO.


FTX.US

This client also supports the US FTX exchange. Simply set the "domain" to "ftxus" in both the RestClient and the WebsocketClient. See examples/ftxus.ts for a demonstration.

Contributions & Thanks

Donations

tiagosiebler

If you found this project interesting or useful, create accounts with my referral links:

Or buy me a coffee using any of these:

  • BTC: 1C6GWZL1XW3jrjpPTS863XtZiXL1aTK7Jk
  • ETH (ERC20): 0xd773d8e6a50758e1ada699bb6c4f98bb4abf82da

Contributions & Pull Requests

Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items.

ftx-api's People

Contributors

camel113 avatar d3c0d3dpt avatar dannyhines avatar davdag avatar dependabot[bot] avatar enitrat avatar for04 avatar kenchambers avatar ndroo avatar qbkjovfnek avatar thedonmon avatar tiagosiebler avatar yoeria avatar zhe-t avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ftx-api's Issues

Support for "dust" endpoints

On the FTX website you're able to convert "dust" (coins with a balance less than the Minimum order size) to USD on the Wallet page. The closest functionality in the API is the .../otc/quotes endpoint which requires you to retrieve a quote for each balance individually.

After looking at the network logs I noticed there's a separate endpoint for "dust" that functions the same as the otc endpoint, except it can convert all balances to USD at once. It's not on their documentation, but this worked for me locally:
https://github.com/tiagosiebler/ftx-api/compare/master...danielchines:dust-endpoint?expand=1

Let me know if I can make a PR

Add funding rates params

To have funding rates history of an unique coin, i want to add the future param :

    getFundingRates(futureName) {
        console.log('getFundingRates', futureName);
        if (futureName === null) {
            return this.requestWrapper.get('funding_rates');
        } else {
            return this.requestWrapper.get(`funding_rates?future=${futureName}`);
        }
    }

Is it possible to completely disconnect?

I noticed that after I instantiate (the websocket) client, and then try to ws.close I am still connected. Is it possible to terminate connection completely? I am asking because I am opening WS inside of a background job and I am trying to avoid memory leaks:

pseudo code repro:

class FtxUS {
  constructor({ apiKey, apiSecret, market = null }) {
    this.market = market;
    this.apiKey = apiKey;
    this.apiSecret = apiSecret;
    this.client = this.initializeRestClient();
  }
  async initializeWsClient() {
    let wsClient = new WebsocketClient({
      key: this.apiKey,
      secret: this.apiSecret,
      wsUrl: 'wss://ftx.us/ws/',
    });
    return await wsClient;
  }

  testCurrentCoinPriceStream() {
    this.turnOnStream(['BAT/USD']);

    setTimeout(async () => {
      await this.turnOffStream(['BAT/USD']);
    }, 10000);
  }

  turnOnStream = async (pairs = []) => {
    this.ws = await this.initializeWsClient();

    let channelArray = [];
    pairs.forEach(pair => {
      channelArray.push({ channel: 'ticker', market: pair });
    });

    try {
      this.ws.on('response', msg => {});
      this.ws.on('update', msg => {
        this.parseWebSockets(msg);
      });
      // this.ws.on('error', msg => console.log('err: ', msg));
      this.ws.subscribe(channelArray);
    } catch (err) {
      goodError(err);
    }
  };

  async turnOffStream(pairs = []) {
    let channelArray = [];
    pairs.forEach(pair => {
      channelArray.push({ channel: 'ticker', market: pair });
    });
    await this.ws.unsubscribe(channelArray);
    await this.ws.close('update');
    await this.ws.close('ticker');
    await this.ws.close('response');
  }
}

as you can see, connection is not closing:

Screen Shot 2022-05-12 at 4 18 56 AM

Unauthorized on cancelOrder

Hi,

I'm getting a 401 Unauthorized, 'Not logged in' message on cancelOrder. I'm able to retrieve and place orders with no issue. I am connected to a subaccount. Thanks.

async cancelOrder(id: number): Promise<boolean> { let response = await this.client.cancelOrder(id.toString()); return response.success; }

[ReferenceError: RestClient is not defined] Using webpacked ftxapi

I encountered this error while trying to integrate this package in browser. After running webpack and put it in browser script, I got ReferenceError: RestClient is not defined error.

Below is a snippet of code that I run:

<script type="module" src="./src/ftxapi.js"></script> <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

const test_client = new RestClient(credential.test[0], credential.test[1], {subAccountName: 'test'});

The webpacked .js file is as following:
https://gist.githubusercontent.com/0x520x650x78/cc6538ac9c6b913ac4ebba72a876c0df/raw/cd0f4f2afaf8b129341e2f7855ccb18615f7c9b8/ftxapi

Thanks!

Initialising a RestClient causes program never to terminate

Executing this script with npx ts-node test.ts for example never terminates.

const { RestClient } = require("ftx-api");
const init = async () => {
  new RestClient("credentials.key", "credentials.secret");
};

init()

Sample tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "importHelpers": true,
    "module": "commonjs",
    "outDir": "lib",
    "rootDir": "src",
    "strict": true,
    "target": "es2017"
  },
  "include": [
    "src/**/*"
  ]
}

Bug in `getPositions()` (401 Unauthorized)

Not sure if this is a bug or I'm doing something wrong but getPositions() fails with a 401.

If I bypass and call directly via client.requestWrapper.get('positions'); it works correctly.

react/preact: TypeError: crypto_1.createHmac is not a function

Same issue produced as tiagosiebler/binance#141.

So i follwed your binance edit. Is this gonna work?

https://github.com/for04/ftx-api/blob/edffe1ce97deedc563a0c16a34c0da6549e5d40e/src/util/node-support.ts#L2-L10

node-support.ts

import { createHmac } from 'crypto';
import * as browserMethods from './browser-support';

export async function signMessage(message: string, secret: string): Promise<string> {
   if (typeof createHmac === 'function') { 
  return createHmac('sha256', secret)
    .update(message)
    .digest('hex');
}
};

export async function signWsAuthenticate(timestamp: number, secret: string): Promise<string> {
  return signMessage(timestamp + 'websocket_login', secret);
};

Test net for ftx US?

I'm having a lot of trouble finding a testnet for FTX US, do you guys know if it exists?

I see livenet: true option fot the WS client, so It seems like there might be one.

WebsocketClient Invalid login credentials, did I hash the secret

Hi,
I try to use pirivate channel for websoket, but I recieved
{"type":"error","code":400,"msg":"Invalid login credentials"}

I use this code
const params = { key: '{api_key}', secret: '{my_secret}', subAccountName: '{subname}', } const ws = new WebsocketClient(params);

Do I have to use signature ( SHA256 HMAC of my secret) ?

Exclusive $TKB airdrop for members of the Node.js Algo Traders community on telegram

Hello everyone,

TokenBot is partnering with our Node.js Algo Traders community for an exclusive $TKB airdrop ahead of their exchange listings.

TokenBot is a tokenized blockchain-enabled network for algorithmic traders.

  1. The TokenBot Network integrates with top centralized exchanges to enable cross-exchange copy trading for social trading communities.
  2. The TokenBot DAO enables algo traders to submit grant proposals for funding of their strategies by the community.

To participate:

  1. Join the Node.js Algo Traders channel on telegram if you haven't already (it's free and full of likeminded professionals building trading systems with node.js).
  2. Check the pinned message in the channel for further details.

Note that this is on a first-come first-serve basis for a maximum of 500 users.

getFundingRates should accept params

Hi,

As per FTX documentation the method getFundingRates need to accept parameters.
https://docs.ftx.com/#get-funding-rates

Here is the diff that solved my problem:

diff --git a/node_modules/ftx-api/lib/rest-client.js b/node_modules/ftx-api/lib/rest-client.js
index a257770..3dc1bb2 100644
--- a/node_modules/ftx-api/lib/rest-client.js
+++ b/node_modules/ftx-api/lib/rest-client.js
@@ -107,8 +107,8 @@ class RestClient {
     getFutureStats(futureName) {
         return this.requestWrapper.get(`futures/${futureName}/stats`);
     }
-    getFundingRates() {
-        return this.requestWrapper.get('funding_rates');
+    getFundingRates(params) {
+        return this.requestWrapper.get('funding_rates', params);
     }
     getIndexWeights(futuresIndexName) {
         return this.requestWrapper.get(`indexes/${futuresIndexName}/weights`);

getAccount() gives me 401 Unauthorized / Not logged in: Timestamp too far from current time

Using version 1.1.7

const key = 'apiKeyHere';
const secret = 'apiSecretHere';
const client = new RestClient(key, secret);
await client.getMarkets()  // this works!
await client.getAccount()  // this does NOT WORK

Errors look like this:

{
  code: 401,
  message: 'Unauthorized',
  body: { success: false, error: 'Not logged in' },
  headers: {
    ...
  },
  requestOptions: {
    ...
  }
}

Unsubscribing WS channel not removing from the collection

Hi,

This is awesome thanks. I was coding something similar myself not long ago, but no need now. How do I donate?

I am having one issue with ws. When I subscribe to a ticker, then unsubscribe then subscribe to another ticker, it doesn't seem to forget the one I unsubscribed from and resubscribes it again with the second one.

Screenshot attached. Where it says SUBBING pair I am only sending one subscribe command, but the old unsubscribed one is still in the collection. Any ideas? Thanks.

Screenshot 2021-04-30 at 14 30 42

How to handle "ping / pong" things?

After 1 hour of working, websocket connection crashes.
Do I need to response on this: [ 'Websocket event: ', '{"type":"pong"}' ] ?

Is there any method like this or something?
client.on('ping', () => { client.pong(); });

Use standard params

There are some inconsistencies between params name in the documentation and param names used in this library.
For example getOrderbook() uses "marketName" instead of market_name.
I didn't check all the paraments to have a list of all inconsistencies and maybe this is the only one.

How can I place futures order with leverage???

In my case, placeOrder function in RestClient is not working with Leverage

how can I place futures order with leverage????

This order using placeOrder function is always placed with no leverage( 1 X Leverage)

Can you help me???

Getting a 404 on client.getQuoteStatus

I can requestQuote and get the quoteId back

When I try to getQuoteStatus I am getting a 404

Is this working for you?

I have tried a variation of params.

I have tested with the following params variations without success

const market = 'BTC/USD';

const quoteParams = { quoteId: response.result.quoteId };
const quoteParams = { quoteId: response.quoteId, market: from + '/' + to };
const quoteParams = { quoteId: response.result.quoteId, market: market };

  client
    .getQuoteStatus(quoteParams)

FTX API responds

{
code: 404,
message: 'NOT FOUND',
body: {
error: '404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.',
success: false
},

Get trigger order history is calling the wrong endpoint

I think getTriggerOrderHistory is calling the wrong endpoint. According to the documentation, it should be GET /conditional_orders/history?market={market}.

rest-client.ts is calling this.requestWrapper.get('orders', params); for getTriggerOrderHistory
https://github.com/tiagosiebler/ftx-api/blob/master/src/rest-client.ts#L300

Shouldn't it be something like return this.requestWrapper.get('conditional_orders/history', params);

I can submit a PR if you agree.

Response types

Request for strongly typed response types in Typescript

`cancelOrder()` always results in "Not logged in" error [ 401 ] +fix

cancelOrder() and I'd guess any call to a non-GET http method when interal params object is undefined/null results in a quoted empty string being used to form a (bad) signature_payload. These two lines are the culprit:

https://github.com/tiagosiebler/ftx-api/blob/master/src/util/requestWrapper.ts#L191-L192

e.g. should be something like

    const paramsPayload = method == 'GET' ? params : ( params ? JSON.stringify(params) : '' );

cheers!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.