Working on Bittrex implementation and unit tests

This commit is contained in:
fredfortier
2017-08-28 22:50:46 -04:00
parent 753881bade
commit f4db9f7b1e
6 changed files with 119 additions and 44 deletions
+11 -9
View File
@@ -1,11 +1,11 @@
import base64
import numpy as np
import hashlib
import hmac
import json
import re
import time
import numpy as np
import pandas as pd
import pytz
import requests
@@ -18,11 +18,9 @@ from catalyst.exchange.exchange import Exchange
from catalyst.exchange.exchange_errors import (
ExchangeRequestError,
InvalidHistoryFrequencyError,
InvalidOrderType)
from catalyst.finance.execution import (MarketOrder,
LimitOrder,
StopOrder,
StopLimitOrder)
InvalidOrderStyle)
from catalyst.exchange.exchange_execution import ExchangeLimitOrder, \
ExchangeStopLimitOrder, ExchangeStopOrder
from catalyst.finance.order import Order, ORDER_STATUS
from catalyst.protocol import Account
@@ -368,14 +366,18 @@ class Bitfinex(Exchange):
:return:
"""
exchange_symbol = self.get_symbol(asset)
if isinstance(style, LimitOrder) or isinstance(style, StopLimitOrder):
if isinstance(style, ExchangeLimitOrder) \
or isinstance(style, ExchangeStopLimitOrder):
price = style.get_limit_price(is_buy)
order_type = 'limit'
elif isinstance(style, StopOrder):
elif isinstance(style, ExchangeStopOrder):
price = style.get_stop_price(is_buy)
order_type = 'stop'
else:
raise InvalidOrderType()
raise InvalidOrderStyle(exchange=self.name,
style=style.__class__.__name__)
req = dict(
symbol=exchange_symbol,
+32 -8
View File
@@ -1,13 +1,15 @@
from catalyst.exchange.exchange_errors import InvalidHistoryFrequencyError, \
ExchangeRequestError
import json
import pandas as pd
from catalyst.assets._assets import TradingPair
from logbook import Logger
from six.moves import urllib
import json
import pandas as pd
from catalyst.exchange.exchange import Exchange
from catalyst.exchange.bittrex.bittrex_api import Bittrex_api
from catalyst.assets._assets import TradingPair
from catalyst.exchange.exchange import Exchange
from catalyst.exchange.exchange_errors import InvalidHistoryFrequencyError, \
ExchangeRequestError, InvalidOrderStyle
from catalyst.finance.execution import LimitOrder, StopLimitOrder
log = Logger('Bittrex')
@@ -16,8 +18,10 @@ URL2 = 'https://bittrex.com/Api/v2.0'
class Bittrex(Exchange):
def __init__(self, key, secret, base_currency, portfolio=None):
self.api = Bittrex_api(key=key, secret=secret)
self.api = Bittrex_api(key=key, secret=secret.encode('UTF-8'))
self.name = 'bittrex'
self.base_currency = base_currency
self._portfolio = portfolio
self.assets = dict()
self.load_assets()
@@ -78,7 +82,27 @@ class Bittrex(Exchange):
def create_order(self, asset, amount, is_buy, style):
log.info('creating order')
pass
exchange_symbol = self.get_symbol(asset)
if isinstance(style, LimitOrder) or isinstance(style, StopLimitOrder):
if isinstance(style, StopLimitOrder):
log.warn('{} will ignore the stop price'.format(self.name))
price = style.get_limit_price(is_buy)
try:
if is_buy:
order = self.api.buylimit(exchange_symbol, amount, price)
else:
order = self.api.selllimit(exchange_symbol, amount, price)
except Exception as e:
raise ExchangeRequestError(error=e)
if 'uuid' in order:
return order['uuid']
else:
raise ExchangeRequestError(error='Order uuid not found.')
else:
raise InvalidOrderStyle(exchange=self.name,
style=style.__class__.__name__)
def get_open_orders(self, asset):
pass
+24 -19
View File
@@ -1,9 +1,8 @@
import abc
import random
from time import sleep
import collections
import random
from abc import ABCMeta, abstractmethod, abstractproperty
from datetime import timedelta
from time import sleep
import numpy as np
import pandas as pd
@@ -14,15 +13,14 @@ from catalyst.data.data_portal import BASE_FIELDS
from catalyst.errors import (
SymbolNotFound,
)
from catalyst.exchange.exchange_errors import InvalidOrderType
from catalyst.exchange.exchange_errors import MismatchingBaseCurrencies, \
InvalidOrderStyle
from catalyst.exchange.exchange_execution import ExchangeStopLimitOrder, \
ExchangeLimitOrder, ExchangeStopOrder
from catalyst.exchange.exchange_portfolio import ExchangePortfolio
from catalyst.exchange.exchange_utils import get_exchange_symbols
from catalyst.finance.order import ORDER_STATUS
from catalyst.finance.transaction import Transaction
from catalyst.exchange.exchange_utils import get_exchange_symbols
from catalyst.exchange.exchange_portfolio import ExchangePortfolio
from catalyst.finance.execution import (MarketOrder,
LimitOrder,
StopOrder,
StopLimitOrder)
log = Logger('Exchange')
@@ -385,7 +383,8 @@ class Exchange:
def create_order(self, asset, amount, is_buy, style):
pass
def order(self, asset, amount, limit_price, stop_price, style=None):
def order(self, asset, amount, limit_price=None, stop_price=None,
style=None):
"""Place an order.
Parameters
@@ -430,21 +429,27 @@ class Exchange:
return None
if asset.base_currency != self.base_currency.lower():
raise NotImplementedError(
'Currency pairs must share their base with the exchange.'
raise MismatchingBaseCurrencies(
base_currency=asset.base_currency,
algo_currency=self.base_currency
)
is_buy = (amount > 0)
if limit_price is not None and stop_price is not None:
style = StopLimitOrder(limit_price, stop_price,
exchange=self.name)
style = ExchangeStopLimitOrder(limit_price, stop_price,
exchange=self.name)
elif limit_price is not None:
style = LimitOrder(limit_price, exchange=self.name)
style = ExchangeLimitOrder(limit_price, exchange=self.name)
elif stop_price is not None:
style = StopOrder(stop_price, exchange=self.name)
elif style is None:
raise InvalidOrderType()
style = ExchangeStopOrder(stop_price, exchange=self.name)
elif style is not None:
raise InvalidOrderStyle(exchange=self.name,
style=style.__class__.__name__)
else:
raise ValueError('Incomplete order data.')
display_price = limit_price if limit_price is not None else stop_price
log.debug(
+9 -2
View File
@@ -69,9 +69,9 @@ class InvalidSymbolError(ZiplineError):
).strip()
class InvalidOrderType(ZiplineError):
class InvalidOrderStyle(ZiplineError):
msg = (
'Order type not found.'
'Order style {style} not supported by exchange {exchange}.'
).strip()
@@ -79,3 +79,10 @@ class SidHashError(ZiplineError):
msg = (
'Unable to hash sid from symbol {symbol}.'
).strip()
class MismatchingBaseCurrencies(ZiplineError):
msg = (
'Unable to trade with base currency {base_currency} when the '
'algorithm uses {algo_currency}.'
).strip()
+39
View File
@@ -0,0 +1,39 @@
from catalyst.finance.execution import LimitOrder, StopOrder, StopLimitOrder
class ExchangeLimitOrder(LimitOrder):
def get_limit_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
"""
return self.limit_price
class ExchangeStopOrder(StopOrder):
def get_stop_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
"""
return self.stop_price
class ExchangeStopLimitOrder(StopLimitOrder):
def get_limit_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
"""
return self.limit_price
def get_stop_price(self, is_buy):
"""
We may be trading Satoshis with 8 decimals, we cannot round numbers
:param is_buy:
:return:
"""
return self.stop_price
+4 -6
View File
@@ -19,18 +19,16 @@ class BittrexTestCase(BaseExchangeTestCase):
self.exchange = Bittrex(
key=auth['key'],
secret=auth['secret'],
base_currency='usd'
base_currency='btc'
)
def test_order(self):
log.info('creating order')
asset = self.exchange.get_asset('neo_eth')
asset = self.exchange.get_asset('neo_btc')
order_id = self.exchange.order(
asset=asset,
style=LimitOrder(limit_price=200),
limit_price=200,
amount=0.5,
stop_price=None
limit_price=0.00055,
amount=1,
)
log.info('order created {}'.format(order_id))
pass