def tearDown(self): # Remove any orders placed on the book api_base = 'https://api-public.sandbox.pro.coinbase.com' auth_client = AuthenticatedClient(self.api_key, self.secret_key, self.passphrase, api_url=api_base) auth_client.cancel_all('BTC-USD') df = pd.DataFrame(columns=[ 'product_id', 'side', 'price', 'size', 'filled_size', 'corresponding_order', 'time', 'spread' ]) df.to_csv(CSV_PATH)
class CoinbasePro: def __init__(self, key, secret, passphrase): self.logger = Logger(__name__) try: self.client = Client(key, secret, passphrase) except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e) def getBalances(self): try: result = self.client.get_accounts() balances = {} if 'message' in result: raise Exception(result['message']) for currency in result: name = currency["currency"].upper() value = float(currency["balance"]) if value > Config.BALANCE_ZERO: balances[name] = value return balances except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e)
def cbpro_auth_client(self): """ Simply create and return the cbpro authenticated client. This should suffice for most usecases, since DCAbot doesn't need to maintain open connections. """ return AuthenticatedClient(key=self.api_key, b64secret=self.api_secret, passphrase=self.api_password)
def __init__(self, key, secret, passphrase): self.logger = Logger(__name__) try: self.client = Client(key, secret, passphrase) except Exception as e: self.logger.log(e) raise ExchangeException(self.__class__.__name__, e)
def __init__(self, api_key: str=None, secret_key: str=None, passphrase: str=None): super().__init__() if any(i is None for i in [api_key, secret_key, passphrase]): self.client = PublicClient() else: self.client = AuthenticatedClient(api_key, secret_key, passphrase) self.products = self.client.get_products() self.filters = {product['id']: { 'min_order_size': Decimal(product['base_min_size']), 'max_order_size': Decimal(product['base_max_size']), 'order_step': Decimal('1e-8'), 'price_step': Decimal(product['quote_increment']), 'base': product['quote_currency'], 'commodity': product['base_currency'] } for product in self.products}
def login(): error = None if request.method == 'POST': if request.form['username'] != 'admin' or request.form[ 'password'] != 'admin': error = 'Invalid Credentials. Please try again.' else: private_client = AuthenticatedClient(Data.API_Public_Key, Data.API_Secret_Key, Data.Passphrase) new_order = Order(private_client) return new_order.get_details() return render_template('login.html', error=error)
def __init__(self, trading_type, verbose, api_key='', api_secret='', api_passphrase='', **kwargs): self._trading_type = trading_type self._verbose = verbose if trading_type == TradingType.BACKTEST: raise NotImplementedError() if self._trading_type == TradingType.SANDBOX: super().__init__(ExchangeType('coinbaseprosandbox')) else: super().__init__(ExchangeType('coinbasepro')) auth = api_key and api_secret and api_passphrase self._public_client = PublicClient() if trading_type == TradingType.SANDBOX: self._auth_client = AuthenticatedClient( api_key, api_secret, api_passphrase, api_url="https://api-public.sandbox.pro.coinbase.com" ) if auth else None else: self._auth_client = AuthenticatedClient( api_key, api_secret, api_passphrase) if auth else None # TODO self._subscriptions = [] self._ws_client = WebsocketClient(url="wss://ws-feed.pro.coinbase.com", products="BTC-USD")
def __init__(self): super(CoinbaseClient, self).__init__() self.public_client = PublicClient() api_key = self.settings['api_key'] secret = self.settings['api_secret'] passphrase = self.settings['api_pass'] api_url = self.settings['api_url'] if api_key and secret and passphrase and api_url: auth_client = AuthenticatedClient(api_key, secret, passphrase, api_url=api_url) if auth_client: self.auth_client = auth_client else: return Exception( "Error while loading the authenticated client") self._load_accounts()
new_reader = None try: data = open(f"../../data_5m/{token}_5m.csv", "r") new_reader = csv.reader(data) except FileNotFoundError as fnfe: continue listener = open("../txt_files/data.txt", "w") listener.close() candles = [] for line in new_reader: candles.append(line) capital = 100 private_client = AuthenticatedClient(Data.API_Public_Key, Data.API_Secret_Key, Data.Passphrase) new_order = Order(private_client) position = OpenPosition(new_order) indicator = Indicator() bands_1dev = BB(ndbevup=1, nbdevdn=1) indicator_list = [indicator, bands_1dev] for new_indicator in indicator_list: new_indicator.candles = candles[1:] new_indicator.get_data_set() new_indicator.reverse_data() new_indicator.get_dates() new_indicator.get_np_array() new_indicator.set_indicator() # verifies that the data and dates was extracted successfully
class CoinbaseProExchange(Exchange): '''Coinbase Pro Exchange''' def __init__(self, trading_type, verbose, api_key='', api_secret='', api_passphrase='', **kwargs): self._trading_type = trading_type self._verbose = verbose if trading_type == TradingType.BACKTEST: raise NotImplementedError() if self._trading_type == TradingType.SANDBOX: super().__init__(ExchangeType('coinbaseprosandbox')) else: super().__init__(ExchangeType('coinbasepro')) auth = api_key and api_secret and api_passphrase self._public_client = PublicClient() if trading_type == TradingType.SANDBOX: self._auth_client = AuthenticatedClient( api_key, api_secret, api_passphrase, api_url="https://api-public.sandbox.pro.coinbase.com" ) if auth else None else: self._auth_client = AuthenticatedClient( api_key, api_secret, api_passphrase) if auth else None # TODO self._subscriptions = [] self._ws_client = WebsocketClient(url="wss://ws-feed.pro.coinbase.com", products="BTC-USD") # *************** # # General methods # # *************** # async def connect(self): '''connect to exchange. should be asynchronous.''' # instantiate instruments _get_instruments(self._public_client, self.exchange()) async def lookup(self, instrument): '''lookup an instrument on the exchange''' # TODO raise NotImplementedError() # ******************* # # Market Data Methods # # ******************* # async def tick(self): '''return data from exchange''' async def subscribe(self, instrument): self._subscriptions.append(instrument) # ******************* # # Order Entry Methods # # ******************* # async def accounts(self): '''get accounts from source''' # TODO raise NotImplementedError() async def newOrder(self, order): '''submit a new order to the exchange. should set the given order's `id` field to exchange-assigned id''' if not self._auth_client: raise NotImplementedError() if order.instrument.type != InstrumentType.PAIR: raise NotImplementedError() if order.type == OrderType.LIMIT: time_in_force = 'GTC' if order.flag == OrderFlag.FILL_OR_KILL: time_in_force = 'FOK' elif order.flag == OrderFlag.IMMEDIATE_OR_CANCEL: time_in_force = 'IOC' ret = self._auth_client.place_limit_order( product_id='{}-{}'.format(order.instrument.leg1.name, order.instrument.leg2.name), side=order.side.value.lower(), price=order.price, size=order.volume, time_in_force=time_in_force) elif order.type == OrderType.MARKET: ret = self._auth_client.place_limit_order( product_id='{}-{}'.format(order.instrument.leg1.name, order.instrument.leg2.name), side=order.side.value.lower(), funds=order.price * order.volume) elif order.type == OrderType.STOP: # TODO raise NotImplementedError() # self._auth_client.place_stop_order(product_id='BTC-USD', # side='buy', # price='200.00', # size='0.01') # Set ID order.id = ret['id'] return order async def cancelOrder(self, order: Order): '''cancel a previously submitted order to the exchange.''' self._auth_client.cancel_order(order.id) return order
class CoinbasePro(Exchange): def __init__(self, api_key: str=None, secret_key: str=None, passphrase: str=None): super().__init__() if any(i is None for i in [api_key, secret_key, passphrase]): self.client = PublicClient() else: self.client = AuthenticatedClient(api_key, secret_key, passphrase) self.products = self.client.get_products() self.filters = {product['id']: { 'min_order_size': Decimal(product['base_min_size']), 'max_order_size': Decimal(product['base_max_size']), 'order_step': Decimal('1e-8'), 'price_step': Decimal(product['quote_increment']), 'base': product['quote_currency'], 'commodity': product['base_currency'] } for product in self.products} def through_trade_currencies(self): return {'BTC', 'USD'} def get_taker_fee(self, product): return Decimal('0.003') def get_maker_fee(self, product): return Decimal('0') def get_resources(self): return {account['currency']: Decimal(account['available']) for account in self.client.get_accounts()} def place_market_order(self, order: Order, price_estimates: Dict[str, Decimal]): logger.info("creating market order - {}".format(str(order))) order = self.validate_order(order, price_estimates) symbol = order.product.replace('_', '-') logger.info("validated order - {}".format(str(order))) resp = self.client.place_market_order( symbol, order._action.name.lower(), size=order._quantity) parsed_response = self.parse_market_order_response(resp) parsed_response['price_estimates'] = price_estimates parsed_response['product'] = parsed_response['symbol'].replace( '-', '_') logger.info("parsed order response - {}".format(str(parsed_response))) return parsed_response def place_limit_order(self, order: Order): logger.info("creating limit order - {}".format(str(order))) order = self.validate_order(order) logger.info("validated order - {}".format(str(order))) symbol = order.product.replace('_', '-') resp = self.client.place_market_order(symbol, order._action.name.lower(), order._price, order._quantity, post_only=True) logger.info("order response - {}".format(str(resp))) return {'order_id': resp['id']} def _validate_order(self, order, price_estimates=None): resources = self.get_resources() symbol = order.product.replace('_', '-') filt = self.filters[symbol] base, commodity = filt['base'], filt['commodity'] # quantity if order._quantity < filt['min_order_size']: return if order._quantity > filt['max_order_size']: order._quantity = filt['max_order_size'] if order._quantity % filt['order_step'] > 0: order._quantity = quantize(order._quantity, filt['order_step']) # price if order._price is not None: if order._price % filt['price_step'] > 0: order._price = quantize(order._price, filt['price_step'], down=(order._action.name == 'BUY')) # resources if order._action.name == 'SELL': if order._quantity > resources[commodity]: order._quantity = resources[commodity] order = self._validate_order(order, price_estimates) else: epsilon = Decimal('1.0001') if order._price is not None: price = order._price if price * order._quantity > resources[base]: order._quantity = resources[base] / ( price * epsilon) order = self._validate_order(order, price_estimates) else: price = price_estimates[commodity] / price_estimates[base] fee = self.get_taker_fee(order.product) + 1 if price * order._quantity * fee > resources[base]: order._quantity = resources[base] / (price * fee * epsilon) order = self._validate_order(order, price_estimates) return order def parse_market_order_response(self, response): fills = self.client.get_fills(response['id']) total_size = [Decimal(fill['size']) for fill in fills] total_money = [Decimal(fill['size']) * Decimal(fill['price']) for fill in fills] fee_asset = response['product_id'].split('-')[-1] product = response['product_id'].replace('-', '_') fee = self.get_taker_fee(product) * total_money return {'symbol': response['product_id'], 'orderId': response['id'], 'executed_quantity': Decimal(response['executed_value']), 'mean_price': total_money / total_size, 'commission_' + fee_asset: fee, 'side': response['side']} def cancel_limit_order(self, response): logger.info("canceled order - {}".format(response)) order_id = response['order_id'] return self.client.cancel_order(order_id) def get_order(self, response): logger.info("get order = {}".format(str(response))) order_id = response['order_id'] resp = self.client.get_order(order_id) # TODO: executed quantity and orig_quantity resp.update({'executed_quantity': Decimal(resp['executed_value']), 'orig_quantity': Decimal(resp['size'])}) logger.info("get order response - {}".format(str(resp))) return resp def get_orderbooks(self, products: List[str]=None, depth: int=1): if not isinstance(self.client, AuthenticatedClient): raise Exception('Client not authenticated') if products is None: owned = list(self.get_resources().keys()) products = [product['id'].replace('-', '_') for product in self.products if product['id'].split('-')[0] in owned] orderbooks = [] for product in products: symbol = product.replace('_', '-') raw_orderbook = self.client.get_product_order_book(symbol) logger.info(f'Parsing orderbook data: {str(raw_orderbook)} for symbol {str(symbol)} (client is {str(self.client)})') if len(raw_orderbook['bids']) == 0 or len(raw_orderbook['asks']) == 0: continue orderbook = OrderBook(product, {'bid': Decimal(raw_orderbook['bids'][0][0]), 'ask': Decimal(raw_orderbook['asks'][0][0])}) orderbooks.append(orderbook) time.sleep(1.0/3) # TODO figure out how to do this more efficiently return orderbooks
def application(): if request.method == 'POST': new_request = request.get_json(force=True) new_ticker = get_ticker(new_request) private_client = AuthenticatedClient(Data.API_Public_Key, Data.API_Secret_Key, Data.Passphrase) new_order = Order(private_client) position = OpenPosition(new_order) funds = Capital(private_client) indicator = Indicator() macd = MACD() candle_ticker: str stop_time: int candle_gra = int if position.get_position() and last_instance(): candle_ticker = new_order.get_key("product_id") stop_time = get_time(27976) candle_gra = 300 writer = open(Data.Time, "w") writer.write(str(time.time() + 5.0)) writer.close() elif position.get_position() is False: candle_ticker = new_ticker stop_time = get_time(83925) candle_gra = 900 try: indicator.set_candles(product=candle_ticker, callback=stop_time, begin=get_time(0), granularity=candle_gra) except ValueError as ve: print(ve.with_traceback()) except NameError as ne: print(ne.with_traceback()) indicator_list = [indicator, macd] try: for value in indicator_list: value.candles = indicator.candles value.set_indicator() value.set_dates() except Exception as e: print(e.with_traceback()) indicator_5m = Indicator() macd_5m = MACD() if position.get_position() is False: if macd.hist[-1] > macd.hist[-2]: try: indicator_5m.set_candles(product=new_ticker, callback=get_time(27976), begin=get_time(0), granularity=900) except ValueError as ve: print(ve.with_traceback()) else: indicator_5m = indicator macd_5m = macd volume_5m = VolSMA(timeperiod=20) bands2dev_5m = BB() bands1dev_5m = BB(ndbevup=1, nbdevdn=1) rsi_5m = RSI() ema_5m = EMA() momentum_5m = Momentum() indicators = [ indicator_5m, macd_5m, volume_5m, bands1dev_5m, bands2dev_5m, rsi_5m, ema_5m, momentum_5m ] try: for value in indicators: value.candles = indicator_5m.candles value.set_indicator() value.set_dates() except Exception as e: print(e.with_traceback()) strategy_5m = Strategy(indicator_5m, macd_5m, bands1dev_5m, bands2dev_5m, volume_5m, rsi_5m, ema_5m, new_order) try: strategy_5m.strategy(-1) except Exception as e: print(e.with_traceback()) trade_side: str trade_product: str trade_funds: str if (new_order.is_bottom()) and (position.get_position() is False): trade_side = "buy" trade_product = new_ticker trade_funds = funds.get_capital() elif (new_order.is_top()) and (position.get_position()): trade_side = "sell" trade_product = new_order.get_key("product_id") trade_funds = get_size(trade_product, new_order.get_key("filled_size")) try: new_trade = private_client.place_market_order( product_id=trade_product, side=trade_side, funds=trade_funds) writer = open(Data.Path, "w") writer.write(new_trade['id']) writer.close() writer = open(Data.Time, "w") writer.write(new_trade['done_at']) writer.close() except NameError as ne: print(ne.with_traceback()) except KeyError as ke: print(ke.with_traceback()) return 'success', 200 elif request.method == 'GET': return redirect('http://3.218.228.129/login') else: abort(400)