UNPKG

sfccxt

Version:

A JavaScript / Python / PHP cryptocurrency trading library with support for 130+ exchanges

1,034 lines (992 loc) 11.6 MB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ /* A entry point for the browser bundle version. This gets compiled by: browserify --debug ./ccxt.browser.js > ./dist/ccxt.browser.js */ // self works in webworkers too self.ccxt = require ('./ccxt') },{"./ccxt":2}],2:[function(require,module,exports){ "use strict"; /* MIT License Copyright (c) 2017 Igor Kroitor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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. */ //----------------------------------------------------------------------------- const Exchange = require ('./js/base/Exchange') , wsExchange = require ('./js/pro/base/Exchange') , Precise = require ('./js/base/Precise') , functions = require ('./js/base/functions') , errors = require ('./js/base/errors') //----------------------------------------------------------------------------- // this is updated by vss.js when building const version = '2.4.47' Exchange.ccxtVersion = version //----------------------------------------------------------------------------- const exchanges = { 'alpaca': require ('./js/alpaca.js'), 'ascendex': require ('./js/ascendex.js'), 'bequant': require ('./js/bequant.js'), 'bigone': require ('./js/bigone.js'), 'binance': require ('./js/binance.js'), 'binancecoinm': require ('./js/binancecoinm.js'), 'binanceus': require ('./js/binanceus.js'), 'binanceusdm': require ('./js/binanceusdm.js'), 'bit2c': require ('./js/bit2c.js'), 'bitbank': require ('./js/bitbank.js'), 'bitbay': require ('./js/bitbay.js'), 'bitbns': require ('./js/bitbns.js'), 'bitcoincom': require ('./js/bitcoincom.js'), 'bitfinex': require ('./js/bitfinex.js'), 'bitfinex2': require ('./js/bitfinex2.js'), 'bitflyer': require ('./js/bitflyer.js'), 'bitforex': require ('./js/bitforex.js'), 'bitget': require ('./js/bitget.js'), 'bithumb': require ('./js/bithumb.js'), 'bitmart': require ('./js/bitmart.js'), 'bitmex': require ('./js/bitmex.js'), 'bitopro': require ('./js/bitopro.js'), 'bitpanda': require ('./js/bitpanda.js'), 'bitrue': require ('./js/bitrue.js'), 'bitso': require ('./js/bitso.js'), 'bitstamp': require ('./js/bitstamp.js'), 'bitstamp1': require ('./js/bitstamp1.js'), 'bittrex': require ('./js/bittrex.js'), 'bitvavo': require ('./js/bitvavo.js'), 'bkex': require ('./js/bkex.js'), 'bl3p': require ('./js/bl3p.js'), 'blockchaincom': require ('./js/blockchaincom.js'), 'btcalpha': require ('./js/btcalpha.js'), 'btcbox': require ('./js/btcbox.js'), 'btcex': require ('./js/btcex.js'), 'btcmarkets': require ('./js/btcmarkets.js'), 'btctradeua': require ('./js/btctradeua.js'), 'btcturk': require ('./js/btcturk.js'), 'buda': require ('./js/buda.js'), 'bybit': require ('./js/bybit.js'), 'cex': require ('./js/cex.js'), 'coinbase': require ('./js/coinbase.js'), 'coinbaseprime': require ('./js/coinbaseprime.js'), 'coinbasepro': require ('./js/coinbasepro.js'), 'coincheck': require ('./js/coincheck.js'), 'coinex': require ('./js/coinex.js'), 'coinfalcon': require ('./js/coinfalcon.js'), 'coinmate': require ('./js/coinmate.js'), 'coinone': require ('./js/coinone.js'), 'coinspot': require ('./js/coinspot.js'), 'cryptocom': require ('./js/cryptocom.js'), 'currencycom': require ('./js/currencycom.js'), 'delta': require ('./js/delta.js'), 'deribit': require ('./js/deribit.js'), 'digifinex': require ('./js/digifinex.js'), 'egera': require ('./js/egera.js'), 'exmo': require ('./js/exmo.js'), 'flowbtc': require ('./js/flowbtc.js'), 'fmfwio': require ('./js/fmfwio.js'), 'gate': require ('./js/gate.js'), 'gateio': require ('./js/gateio.js'), 'gemini': require ('./js/gemini.js'), 'hitbtc': require ('./js/hitbtc.js'), 'hitbtc3': require ('./js/hitbtc3.js'), 'hollaex': require ('./js/hollaex.js'), 'huobi': require ('./js/huobi.js'), 'huobijp': require ('./js/huobijp.js'), 'huobipro': require ('./js/huobipro.js'), 'idex': require ('./js/idex.js'), 'independentreserve': require ('./js/independentreserve.js'), 'indodax': require ('./js/indodax.js'), 'itbit': require ('./js/itbit.js'), 'kraken': require ('./js/kraken.js'), 'kucoin': require ('./js/kucoin.js'), 'kucoinfutures': require ('./js/kucoinfutures.js'), 'kuna': require ('./js/kuna.js'), 'latoken': require ('./js/latoken.js'), 'lbank': require ('./js/lbank.js'), 'lbank2': require ('./js/lbank2.js'), 'luno': require ('./js/luno.js'), 'lykke': require ('./js/lykke.js'), 'mercado': require ('./js/mercado.js'), 'mexc': require ('./js/mexc.js'), 'mexc3': require ('./js/mexc3.js'), 'ndax': require ('./js/ndax.js'), 'novadax': require ('./js/novadax.js'), 'oceanex': require ('./js/oceanex.js'), 'okcoin': require ('./js/okcoin.js'), 'okex': require ('./js/okex.js'), 'okex5': require ('./js/okex5.js'), 'okx': require ('./js/okx.js'), 'paymium': require ('./js/paymium.js'), 'phemex': require ('./js/phemex.js'), 'poloniex': require ('./js/poloniex.js'), 'probit': require ('./js/probit.js'), 'qtrade': require ('./js/qtrade.js'), 'ripio': require ('./js/ripio.js'), 'stex': require ('./js/stex.js'), 'therock': require ('./js/therock.js'), 'tidex': require ('./js/tidex.js'), 'timex': require ('./js/timex.js'), 'tokocrypto': require ('./js/tokocrypto.js'), 'upbit': require ('./js/upbit.js'), 'wavesexchange': require ('./js/wavesexchange.js'), 'wazirx': require ('./js/wazirx.js'), 'whitebit': require ('./js/whitebit.js'), 'woo': require ('./js/woo.js'), 'yobit': require ('./js/yobit.js'), 'zaif': require ('./js/zaif.js'), 'zb': require ('./js/zb.js'), 'zipmex': require ('./js/zipmex.js'), 'zonda': require ('./js/zonda.js'), } const pro = { 'ascendex': require ('./js/pro/ascendex.js'), 'bequant': require ('./js/pro/bequant.js'), 'binance': require ('./js/pro/binance.js'), 'binancecoinm': require ('./js/pro/binancecoinm.js'), 'binanceus': require ('./js/pro/binanceus.js'), 'binanceusdm': require ('./js/pro/binanceusdm.js'), 'bitcoincom': require ('./js/pro/bitcoincom.js'), 'bitfinex': require ('./js/pro/bitfinex.js'), 'bitfinex2': require ('./js/pro/bitfinex2.js'), 'bitget': require ('./js/pro/bitget.js'), 'bitmart': require ('./js/pro/bitmart.js'), 'bitmex': require ('./js/pro/bitmex.js'), 'bitopro': require ('./js/pro/bitopro.js'), 'bitrue': require ('./js/pro/bitrue.js'), 'bitstamp': require ('./js/pro/bitstamp.js'), 'bittrex': require ('./js/pro/bittrex.js'), 'bitvavo': require ('./js/pro/bitvavo.js'), 'bybit': require ('./js/pro/bybit.js'), 'cex': require ('./js/pro/cex.js'), 'coinbaseprime': require ('./js/pro/coinbaseprime.js'), 'coinbasepro': require ('./js/pro/coinbasepro.js'), 'coinex': require ('./js/pro/coinex.js'), 'cryptocom': require ('./js/pro/cryptocom.js'), 'currencycom': require ('./js/pro/currencycom.js'), 'deribit': require ('./js/pro/deribit.js'), 'exmo': require ('./js/pro/exmo.js'), 'gate': require ('./js/pro/gate.js'), 'gateio': require ('./js/pro/gateio.js'), 'hitbtc': require ('./js/pro/hitbtc.js'), 'hollaex': require ('./js/pro/hollaex.js'), 'huobi': require ('./js/pro/huobi.js'), 'huobijp': require ('./js/pro/huobijp.js'), 'huobipro': require ('./js/pro/huobipro.js'), 'idex': require ('./js/pro/idex.js'), 'kraken': require ('./js/pro/kraken.js'), 'kucoin': require ('./js/pro/kucoin.js'), 'luno': require ('./js/pro/luno.js'), 'mexc': require ('./js/pro/mexc.js'), 'ndax': require ('./js/pro/ndax.js'), 'okcoin': require ('./js/pro/okcoin.js'), 'okex': require ('./js/pro/okex.js'), 'okx': require ('./js/pro/okx.js'), 'phemex': require ('./js/pro/phemex.js'), 'ripio': require ('./js/pro/ripio.js'), 'upbit': require ('./js/pro/upbit.js'), 'wazirx': require ('./js/pro/wazirx.js'), 'whitebit': require ('./js/pro/whitebit.js'), 'woo': require ('./js/pro/woo.js'), 'zb': require ('./js/pro/zb.js'), 'zipmex': require ('./js/pro/zipmex.js'), } for (const exchange in pro) { const ccxtExchange = exchanges[exchange] const baseExchange = Object.getPrototypeOf (ccxtExchange) if (baseExchange.name === 'Exchange') { Object.setPrototypeOf (ccxtExchange, wsExchange) Object.setPrototypeOf (ccxtExchange.prototype, wsExchange.prototype) } } pro.exchanges = Object.keys (pro) //----------------------------------------------------------------------------- module.exports = Object.assign ({ version, Exchange, Precise, 'exchanges': Object.keys (exchanges), pro }, exchanges, functions, errors) //----------------------------------------------------------------------------- },{"./js/alpaca.js":3,"./js/ascendex.js":4,"./js/base/Exchange":5,"./js/base/Precise":6,"./js/base/errors":8,"./js/base/functions":9,"./js/bequant.js":20,"./js/bigone.js":21,"./js/binance.js":22,"./js/binancecoinm.js":23,"./js/binanceus.js":24,"./js/binanceusdm.js":25,"./js/bit2c.js":26,"./js/bitbank.js":27,"./js/bitbay.js":28,"./js/bitbns.js":29,"./js/bitcoincom.js":30,"./js/bitfinex.js":31,"./js/bitfinex2.js":32,"./js/bitflyer.js":33,"./js/bitforex.js":34,"./js/bitget.js":35,"./js/bithumb.js":36,"./js/bitmart.js":37,"./js/bitmex.js":38,"./js/bitopro.js":39,"./js/bitpanda.js":40,"./js/bitrue.js":41,"./js/bitso.js":42,"./js/bitstamp.js":43,"./js/bitstamp1.js":44,"./js/bittrex.js":45,"./js/bitvavo.js":46,"./js/bkex.js":47,"./js/bl3p.js":48,"./js/blockchaincom.js":49,"./js/btcalpha.js":50,"./js/btcbox.js":51,"./js/btcex.js":52,"./js/btcmarkets.js":53,"./js/btctradeua.js":54,"./js/btcturk.js":55,"./js/buda.js":56,"./js/bybit.js":57,"./js/cex.js":58,"./js/coinbase.js":59,"./js/coinbaseprime.js":60,"./js/coinbasepro.js":61,"./js/coincheck.js":62,"./js/coinex.js":63,"./js/coinfalcon.js":64,"./js/coinmate.js":65,"./js/coinone.js":66,"./js/coinspot.js":67,"./js/cryptocom.js":68,"./js/currencycom.js":69,"./js/delta.js":70,"./js/deribit.js":71,"./js/digifinex.js":72,"./js/egera.js":73,"./js/exmo.js":74,"./js/flowbtc.js":75,"./js/fmfwio.js":76,"./js/gate.js":77,"./js/gateio.js":78,"./js/gemini.js":79,"./js/hitbtc.js":80,"./js/hitbtc3.js":81,"./js/hollaex.js":82,"./js/huobi.js":83,"./js/huobijp.js":84,"./js/huobipro.js":85,"./js/idex.js":86,"./js/independentreserve.js":87,"./js/indodax.js":88,"./js/itbit.js":89,"./js/kraken.js":90,"./js/kucoin.js":91,"./js/kucoinfutures.js":92,"./js/kuna.js":93,"./js/latoken.js":94,"./js/lbank.js":95,"./js/lbank2.js":96,"./js/luno.js":97,"./js/lykke.js":98,"./js/mercado.js":99,"./js/mexc.js":100,"./js/mexc3.js":101,"./js/ndax.js":102,"./js/novadax.js":103,"./js/oceanex.js":104,"./js/okcoin.js":105,"./js/okex.js":106,"./js/okex5.js":107,"./js/okx.js":108,"./js/paymium.js":109,"./js/phemex.js":110,"./js/poloniex.js":111,"./js/pro/ascendex.js":112,"./js/pro/base/Exchange":115,"./js/pro/bequant.js":121,"./js/pro/binance.js":122,"./js/pro/binancecoinm.js":123,"./js/pro/binanceus.js":124,"./js/pro/binanceusdm.js":125,"./js/pro/bitcoincom.js":126,"./js/pro/bitfinex.js":127,"./js/pro/bitfinex2.js":128,"./js/pro/bitget.js":129,"./js/pro/bitmart.js":130,"./js/pro/bitmex.js":131,"./js/pro/bitopro.js":132,"./js/pro/bitrue.js":133,"./js/pro/bitstamp.js":134,"./js/pro/bittrex.js":135,"./js/pro/bitvavo.js":136,"./js/pro/bybit.js":137,"./js/pro/cex.js":138,"./js/pro/coinbaseprime.js":139,"./js/pro/coinbasepro.js":140,"./js/pro/coinex.js":141,"./js/pro/cryptocom.js":142,"./js/pro/currencycom.js":143,"./js/pro/deribit.js":144,"./js/pro/exmo.js":145,"./js/pro/gate.js":146,"./js/pro/gateio.js":147,"./js/pro/hitbtc.js":148,"./js/pro/hollaex.js":149,"./js/pro/huobi.js":150,"./js/pro/huobijp.js":151,"./js/pro/huobipro.js":152,"./js/pro/idex.js":153,"./js/pro/kraken.js":154,"./js/pro/kucoin.js":155,"./js/pro/luno.js":156,"./js/pro/mexc.js":157,"./js/pro/ndax.js":158,"./js/pro/okcoin.js":159,"./js/pro/okex.js":160,"./js/pro/okx.js":161,"./js/pro/phemex.js":162,"./js/pro/ripio.js":163,"./js/pro/upbit.js":164,"./js/pro/wazirx.js":165,"./js/pro/whitebit.js":166,"./js/pro/woo.js":167,"./js/pro/zb.js":168,"./js/pro/zipmex.js":169,"./js/probit.js":170,"./js/qtrade.js":171,"./js/ripio.js":172,"./js/stex.js":213,"./js/therock.js":214,"./js/tidex.js":215,"./js/timex.js":216,"./js/tokocrypto.js":217,"./js/upbit.js":218,"./js/wavesexchange.js":219,"./js/wazirx.js":220,"./js/whitebit.js":221,"./js/woo.js":222,"./js/yobit.js":223,"./js/zaif.js":224,"./js/zb.js":225,"./js/zipmex.js":226,"./js/zonda.js":227}],3:[function(require,module,exports){ 'use strict'; // --------------------------------------------------------------------------- const Exchange = require ('./base/Exchange'); const { ExchangeError, BadRequest, PermissionDenied, BadSymbol, NotSupported, InsufficientFunds, InvalidOrder } = require ('./base/errors'); const { TICK_SIZE } = require ('./base/functions/number'); // ---------------------------------------------------------------------------xs module.exports = class alpaca extends Exchange { describe () { return this.deepExtend (super.describe (), { 'id': 'alpaca', 'name': 'Alpaca', 'countries': [ 'US' ], 'rateLimit': 333, // 3 req per second 'hostname': 'alpaca.markets', 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/187234005-b864db3d-f1e3-447a-aaf9-a9fc7b955d07.jpg', 'www': 'https://alpaca.markets', 'api': { 'public': 'https://api.{hostname}/{version}', 'private': 'https://api.{hostname}/{version}', 'cryptoPublic': 'https://data.{hostname}/{version}', 'markets': 'https://api.{hostname}/{version}', }, 'test': { 'public': 'https://paper-api.{hostname}/{version}', 'private': 'https://paper-api.{hostname}/{version}', 'cryptoPublic': 'https://data.{hostname}/{version}', 'markets': 'https://api.{hostname}/{version}', }, 'doc': 'https://alpaca.markets/docs/', 'fees': 'https://alpaca.markets/support/what-are-the-fees-associated-with-crypto-trading/', }, 'has': { 'CORS': false, 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'cancelAllOrders': true, 'cancelOrder': true, 'createOrder': true, 'fetchBalance': true, 'fetchBidsAsks': false, 'fetchClosedOrders': false, 'fetchCurrencies': false, 'fetchDepositAddress': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': false, 'fetchFundingHistory': false, 'fetchFundingRate': false, 'fetchFundingRates': false, 'fetchL1OrderBook': true, 'fetchL2OrderBook': false, 'fetchMarkets': true, 'fetchMyTrades': false, 'fetchOHLCV': false, 'fetchOpenOrder': false, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': false, 'fetchPositions': false, 'fetchStatus': false, 'fetchTicker': false, 'fetchTickers': false, 'fetchTime': false, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTransactionFees': false, 'fetchTransactions': false, 'fetchTransfers': false, 'fetchWithdrawals': false, 'setLeverage': false, 'setMarginMode': false, 'transfer': false, 'withdraw': false, }, 'api': { 'markets': { 'get': [ 'assets/public/beta', ], }, 'private': { 'get': [ 'account', 'orders', 'orders/{order_id}', 'positions', 'positions/{symbol}', 'account/activities/{activity_type}', ], 'post': [ 'orders', ], 'delete': [ 'orders', 'orders/{order_id}', ], }, 'cryptoPublic': { 'get': [ 'crypto/latest/orderbooks', 'crypto/trades', 'crypto/quotes', 'crypto/latest/quotes', 'crypto/bars', 'crypto/snapshots', ], }, }, 'timeframes': { '1m': '1min', '3m': '3min', '5m': '5min', '15m': '15min', '30m': '30min', '1h': '1H', '2h': '2H', '4h': '4H', '6h': '6H', '8h': '8H', '12h': '12H', '1d': '1D', '3d': '3D', '1w': '1W', '1M': '1M', }, 'precisionMode': TICK_SIZE, 'requiredCredentials': { 'apiKey': true, 'secret': true, }, 'fees': { 'trading': { 'tierBased': true, 'percentage': true, 'maker': this.parseNumber ('0.003'), 'taker': this.parseNumber ('0.003'), 'tiers': { 'taker': [ [ this.parseNumber ('0'), this.parseNumber ('0.003') ], [ this.parseNumber ('500000'), this.parseNumber ('0.0028') ], [ this.parseNumber ('1000000'), this.parseNumber ('0.0025') ], [ this.parseNumber ('5000000'), this.parseNumber ('0.002') ], [ this.parseNumber ('10000000'), this.parseNumber ('0.0018') ], [ this.parseNumber ('25000000'), this.parseNumber ('0.0015') ], [ this.parseNumber ('50000000'), this.parseNumber ('0.00125') ], [ this.parseNumber ('100000000'), this.parseNumber ('0.001') ], ], 'maker': [ [ this.parseNumber ('0'), this.parseNumber ('0.003') ], [ this.parseNumber ('500000'), this.parseNumber ('0.0028') ], [ this.parseNumber ('1000000'), this.parseNumber ('0.0025') ], [ this.parseNumber ('5000000'), this.parseNumber ('0.002') ], [ this.parseNumber ('10000000'), this.parseNumber ('0.0018') ], [ this.parseNumber ('25000000'), this.parseNumber ('0.0015') ], [ this.parseNumber ('50000000'), this.parseNumber ('0.00125') ], [ this.parseNumber ('100000000'), this.parseNumber ('0.001') ], ], }, }, }, 'headers': { 'APCA-PARTNER-ID': 'ccxt', }, 'options': { 'fetchTradesMethod': 'cryptoPublicGetCryptoTrades', // or cryptoPublicGetCryptoLatestTrades 'fetchOHLCVMethod': 'cryptoPublicGetCryptoBars', // or cryptoPublicGetCryptoLatestBars 'versions': { 'public': 'v2', 'private': 'v2', 'cryptoPublic': 'v1beta2', // crypto beta 'markets': 'v2', // crypto beta }, 'defaultExchange': 'CBSE', 'exchanges': [ 'CBSE', // Coinbase 'FTX', // FTXUS 'GNSS', // Genesis 'ERSX', // ErisX ], 'defaultTimeInForce': 'gtc', // fok, gtc, ioc 'clientOrderId': 'ccxt_{id}', }, 'exceptions': { 'exact': { 'forbidden.': PermissionDenied, // {"message": "forbidden."} '40410000': InvalidOrder, // { "code": 40410000, "message": "order is not found."} '40010001': BadRequest, // {"code":40010001,"message":"invalid order type for crypto order"} '40110000': PermissionDenied, // { "code": 40110000, "message": "request is not authorized"} '40310000': InsufficientFunds, // {"available":"0","balance":"0","code":40310000,"message":"insufficient balance for USDT (requested: 221.63, available: 0)","symbol":"USDT"} }, 'broad': { 'Invalid format for parameter': BadRequest, // {"message":"Invalid format for parameter start: error parsing '0' as RFC3339 or 2006-01-02 time: parsing time \"0\" as \"2006-01-02\": cannot parse \"0\" as \"2006\""} 'Invalid symbol': BadSymbol, // {"message":"Invalid symbol(s): BTC/USDdsda does not match ^[A-Z]+/[A-Z]+$"} }, }, }); } async fetchMarkets (params = {}) { /** * @method * @name alpaca#fetchMarkets * @description retrieves data on all markets for alpaca * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const request = { 'asset_class': 'crypto', 'tradeable': true, }; const assets = await this.marketsGetAssetsPublicBeta (this.extend (request, params)); // // [ // { // "id":"a3ba8ac0-166d-460b-b17a-1f035622dd47", // "class":"crypto", // "exchange":"FTXU", // "symbol":"DOGEUSD", // "name":"Dogecoin", // "status":"active", // "tradable":true, // "marginable":false, // "shortable":false, // "easy_to_borrow":false, // "fractionable":true, // "min_order_size":"1", // "min_trade_increment":"1", // "price_increment":"0.0000005" // } // ] // const markets = []; for (let i = 0; i < assets.length; i++) { const asset = assets[i]; const marketId = this.safeString (asset, 'symbol'); const parts = marketId.split ('/'); const baseId = this.safeString (parts, 0); const quoteId = this.safeString (parts, 1); const base = this.safeCurrencyCode (baseId); const quote = this.safeCurrencyCode (quoteId); const symbol = base + '/' + quote; const status = this.safeString (asset, 'status'); const active = (status === 'active'); const minAmount = this.safeNumber (asset, 'min_order_size'); const amount = this.safeNumber (asset, 'min_trade_increment'); const price = this.safeNumber (asset, 'price_increment'); markets.push ({ 'id': marketId, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'type': 'spot', 'spot': true, 'margin': undefined, 'swap': false, 'future': false, 'option': false, 'active': active, 'contract': false, 'linear': undefined, 'inverse': undefined, 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': amount, 'price': price, }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': minAmount, 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'info': asset, }); } return markets; } async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name alpaca#fetchTrades * @description get the list of most recent trades for a particular symbol * @param {string} symbol unified symbol of the market to fetch trades for * @param {int|undefined} since timestamp in ms of the earliest trade to fetch * @param {int|undefined} limit the maximum amount of trades to fetch * @param {object} params extra parameters specific to the alpaca api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ await this.loadMarkets (); const market = this.market (symbol); const id = market['id']; const request = { 'symbols': id, }; if (since !== undefined) { request['start'] = this.iso8601 (since); } if (limit !== undefined) { request['limit'] = parseInt (limit); } const method = this.safeString (this.options, 'fetchTradesMethod', 'cryptoPublicGetCryptoTrades'); const response = await this[method] (this.extend (request, params)); // // { // "next_page_token":null, // "trades":{ // "BTC/USD":[ // { // "i":36440704, // "p":22625, // "s":0.0001, // "t":"2022-07-21T11:47:31.073391Z", // "tks":"B" // } // ] // } // } // const trades = this.safeValue (response, 'trades', {}); const symbolTrades = this.safeValue (trades, market['id'], {}); return this.parseTrades (symbolTrades, market, since, limit); } async fetchOrderBook (symbol, limit = undefined, params = {}) { /** * @method * @name alpaca#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int|undefined} limit the maximum amount of order book entries to return * @param {object} params extra parameters specific to the alpaca api endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/en/latest/manual.html#order-book-structure} indexed by market symbols */ await this.loadMarkets (); const market = this.market (symbol); const id = market['id']; const request = { 'symbols': id, }; const response = await this.cryptoPublicGetCryptoLatestOrderbooks (this.extend (request, params)); // // { // "orderbooks":{ // "BTC/USD":{ // "a":[ // { // "p":22208, // "s":0.0051 // }, // { // "p":22209, // "s":0.1123 // }, // { // "p":22210, // "s":0.2465 // } // ], // "b":[ // { // "p":22203, // "s":0.395 // }, // { // "p":22202, // "s":0.2465 // }, // { // "p":22201, // "s":0.6455 // } // ], // "t":"2022-07-19T13:41:55.13210112Z" // } // } // } // const orderbooks = this.safeValue (response, 'orderbooks', {}); const rawOrderbook = this.safeValue (orderbooks, id, {}); const timestamp = this.parse8601 (this.safeString (rawOrderbook, 't')); return this.parseOrderBook (rawOrderbook, market['symbol'], timestamp, 'b', 'a', 'p', 's'); } async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { /** * @method * @name alpaca#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int|undefined} since timestamp in ms of the earliest candle to fetch * @param {int|undefined} limit the maximum amount of candles to fetch * @param {object} params extra parameters specific to the alpha api endpoint * @returns {[[int]]} A list of candles ordered as timestamp, open, high, low, close, volume */ await this.loadMarkets (); const market = this.market (symbol); const request = { 'symbols': market['id'], 'timeframe': this.timeframes[timeframe], }; if (limit !== undefined) { request['limit'] = limit; } if (since !== undefined) { request['start'] = parseInt (since / 1000); } const method = this.safeString (this.options, 'fetchOHLCVMethod', 'cryptoPublicGetCryptoBars'); const response = await this[method] (this.extend (request, params)); // // { // "bars":{ // "BTC/USD":[ // { // "c":22887, // "h":22888, // "l":22873, // "n":11, // "o":22883, // "t":"2022-07-21T05:00:00Z", // "v":1.1138, // "vw":22883.0155324116 // }, // { // "c":22895, // "h":22895, // "l":22884, // "n":6, // "o":22884, // "t":"2022-07-21T05:01:00Z", // "v":0.001, // "vw":22889.5 // } // ] // }, // "next_page_token":"QlRDL1VTRHxNfDIwMjItMDctMjFUMDU6MDE6MDAuMDAwMDAwMDAwWg==" // } // const bars = this.safeValue (response, 'bars', {}); const ohlcvs = this.safeValue (bars, market['id'], {}); return this.parseOHLCVs (ohlcvs, market, timeframe, since, limit); } parseOHLCV (ohlcv, market = undefined) { // // { // "c":22895, // "h":22895, // "l":22884, // "n":6, // "o":22884, // "t":"2022-07-21T05:01:00Z", // "v":0.001, // "vw":22889.5 // } // const datetime = this.safeString (ohlcv, 't'); const timestamp = this.parse8601 (datetime); return [ timestamp, // timestamp this.safeNumber (ohlcv, 'o'), // open this.safeNumber (ohlcv, 'h'), // high this.safeNumber (ohlcv, 'l'), // low this.safeNumber (ohlcv, 'c'), // close this.safeNumber (ohlcv, 'v'), // volume ]; } async createOrder (symbol, type, side, amount, price = undefined, params = {}) { /** * @method * @name alpaca#createOrder * @description create a trade order * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market', 'limit' or 'stop_limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of currency you want to trade in units of base currency * @param {float} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders * @param {object} params extra parameters specific to the alpaca api endpoint * @param {float} params.triggerPrice The price at which a trigger order is triggered at * @returns {object} an [order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure} */ await this.loadMarkets (); const market = this.market (symbol); const id = market['id']; const request = { 'symbol': id, 'qty': this.amountToPrecision (symbol, amount), 'side': side, 'type': type, // market, limit, stop_limit }; const triggerPrice = this.safeStringN (params, [ 'triggerPrice', 'stop_price' ]); if (triggerPrice !== undefined) { let newType = undefined; if (type.indexOf ('limit') >= 0) { newType = 'stop_limit'; } else { throw new NotSupported (this.id + ' createOrder() does not support stop orders for ' + type + ' orders, only stop_limit orders are supported'); } request['stop_price'] = this.priceToPrecision (symbol, triggerPrice); request['type'] = newType; } if (type.indexOf ('limit') >= 0) { request['limit_price'] = this.priceToPrecision (symbol, price); } const defaultTIF = this.safeString (this.options, 'defaultTimeInForce'); request['time_in_force'] = this.safeString (params, 'timeInForce', defaultTIF); params = this.omit (params, [ 'timeInForce', 'triggerPrice' ]); const clientOrderIdprefix = this.safeString (this.options, 'clientOrderId'); const uuid = this.uuid (); const parts = uuid.split ('-'); const random_id = parts.join (''); const defaultClientId = this.implodeParams (clientOrderIdprefix, { 'id': random_id }); const clientOrderId = this.safeString (params, 'clientOrderId', defaultClientId); request['client_order_id'] = clientOrderId; params = this.omit (params, [ 'clientOrderId' ]); const order = await this.privatePostOrders (this.extend (request, params)); // // { // "id": "61e69015-8549-4bfd-b9c3-01e75843f47d", // "client_order_id": "eb9e2aaa-f71a-4f51-b5b4-52a6c565dad4", // "created_at": "2021-03-16T18:38:01.942282Z", // "updated_at": "2021-03-16T18:38:01.942282Z", // "submitted_at": "2021-03-16T18:38:01.937734Z", // "filled_at": null, // "expired_at": null, // "canceled_at": null, // "failed_at": null, // "replaced_at": null, // "replaced_by": null, // "replaces": null, // "asset_id": "b0b6dd9d-8b9b-48a9-ba46-b9d54906e415", // "symbol": "AAPL", // "asset_class": "us_equity", // "notional": "500", // "qty": null, // "filled_qty": "0", // "filled_avg_price": null, // "order_class": "", // "order_type": "market", // "type": "market", // "side": "buy", // "time_in_force": "day", // "limit_price": null, // "stop_price": null, // "status": "accepted", // "extended_hours": false, // "legs": null, // "trail_percent": null, // "trail_price": null, // "hwm": null // } // return this.parseOrder (order, market); } async cancelOrder (id, symbol = undefined, params = {}) { /** * @method * @name alpaca#cancelOrder * @description cancels an open order * @param {string} id order id * @param {string|undefined} symbol unified symbol of the market the order was made in * @param {object} params extra parameters specific to the alpaca api endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure} */ const request = { 'order_id': id, }; const response = await this.privateDeleteOrdersOrderId (this.extend (request, params)); // // { // "code": 40410000, // "message": "order is not found." // } // return this.safeValue (response, 'message', {}); } async fetchOrder (id, symbol = undefined, params = {}) { /** * @method * @name alpaca#fetchOrder * @description fetches information on an order made by the user * @param {string|undefined} symbol unified symbol of the market the order was made in * @param {object} params extra parameters specific to the alpaca api endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure} */ await this.loadMarkets (); const request = { 'order_id': id, }; const order = await this.privateGetOrdersOrderId (this.extend (request, params)); const marketId = this.safeString (order, 'symbol'); const market = this.safeMarket (marketId); return this.parseOrder (order, market); } async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name alpaca#fetchOpenOrders * @description fetch all unfilled currently open orders * @param {string|undefined} symbol unified market symbol * @param {int|undefined} since the earliest time in ms to fetch open orders for * @param {int|undefined} limit the maximum number of open orders structures to retrieve * @param {object} params extra parameters specific to the alpaca api endpoint * @returns {[object]} a list of [order structures]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure} */ await this.loadMarkets (); let market = undefined; if (symbol !== undefined) { market = this.market (symbol); } const orders = await this.privateGetOrders (params); return this.parseOrders (orders, market, since, limit); } parseOrder (order, market = undefined) { // // { // "id":"6ecfcc34-4bed-4b53-83ba-c564aa832a81", // "client_order_id":"ccxt_1c6ceab0b5e84727b2f1c0394ba17560", // "created_at":"2022-06-14T13:59:30.224037068Z", // "updated_at":"2022-06-14T13:59:30.224037068Z", // "submitted_at":"2022-06-14T13:59:30.221856828Z", // "filled_at":null, // "expired_at":null, // "canceled_at":null, // "failed_at":null, // "replaced_at":null, // "replaced_by":null, // "replaces":null, // "asset_id":"64bbff51-59d6-4b3c-9351-13ad85e3c752", // "symbol":"BTCUSD", // "asset_class":"crypto", // "notional":null, // "qty":"0.01", // "filled_qty":"0", // "filled_avg_price":null, // "order_class":"", // "order_type":"limit", // "type":"limit", // "side":"buy", // "time_in_force":"day", // "limit_price":"14000", // "stop_price":null, // "status":"accepted", // "extended_hours":false, // "legs":null, // "trail_percent":null, // "trail_price":null, // "hwm":null, // "commission":"0.42", // "source":null // } // const marketId = this.safeString (order, 'symbol'); market = this.safeMarket (marketId, market); const symbol = market['symbol']; const alpacaStatus = this.safeString (order, 'status'); const status = this.parseOrderStatus (alpacaStatus); const feeValue = this.safeString (order, 'commission'); let fee = undefined; if (feeValue !== undefined) { fee = { 'cost': feeValue, 'currency': 'USD', }; } let orderType = this.safeString (order, 'order_type'); if (orderType.indexOf ('limit') >= 0) { // might be limit or stop-limit orderType = 'limit'; } const datetime = this.safeString (order, 'submitted_at'); const timestamp = this.parse8601 (datetime); return this.safeOrder ({ 'id': this.safeString (order, 'id'), 'clientOrderId': this.safeString (order, 'client_order_id'), 'timestamp': timestamp, 'datetime': datetime, 'lastTradeTimeStamp': undefined, 'status': status, 'symbol': symbol, 'type': orderType, 'timeInForce': this.parseTimeInForce (this.safeString (order, 'time_in_force')), 'postOnly': undefined, 'side': this.safeString (order, 'side'), 'price': this.safeNumber (order, 'limit_price'), 'stopPrice': this.safeNumber (order, 'stop_price'), 'cost': undefined, 'average': this.safeNumber (order, 'filled_avg_price'), 'amount': this.safeNumber (order, 'qty'), 'filled': this.safeNumber (order, 'filled_qty'), 'remaining': undefined, 'trades': undefined, 'fee': fee, 'info': order, }, market); } parseOrderStatus (status) { const statuses = { 'pending_new': 'open', 'accepted': 'open', 'new': 'open', 'partially_filled': 'open', 'activated': 'open', 'filled': 'closed', }; return this.safeString (statuses, status, status); } parseTimeInForce (timeInForce) { const timeInForces = { 'day': 'Day', }; return this.safeString (timeInForces, timeInForce, timeInForce); } parseTrade (trade, market = undefined) { // // { // "t":"2022-06-14T05:00:00.027869Z", // "x":"CBSE", // "p":"21942.15", // "s":"0.0001", // "tks":"S", // "i":"355681339" // } // const symbol = this.safeSymbol (undefined, market); const datetime = this.safeString (trade, 't'); const timestamp = this.parse8601 (datetime); const alpacaSide = this.safeString (trade, 'tks'); let side = undefined; if (alpacaSide === 'B') { side = 'buy'; } else if (alpacaSide === 'S') { side = 'sell'; } const priceString = this.safeString (trade, 'p'); const amountString = this.safeString (trade, 's'); return this.safeTrade ({ 'info': trade, 'id': this.safeString (trade, 'i'), 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'symbol': symbol, 'order': undefined, 'type': undefined, 'side': side, 'takerOrMaker': 'taker', 'price': priceString, 'amount': amountString, 'cost': undefined, 'fee': undefined, }, market); } sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) { const versions = this.safeValue (this.options, 'vers