Skip to content

Commit

Permalink
commence deduplication efforts
Browse files Browse the repository at this point in the history
  • Loading branch information
matiaskotlik committed May 2, 2022
1 parent ad59490 commit 6eab87b
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 699 deletions.
116 changes: 40 additions & 76 deletions blankly/exchanges/interfaces/alpaca/alpaca_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@
class AlpacaInterface(ExchangeInterface):
def __init__(self, exchange_name, authenticated_api):
self.__unique_assets = None
super().__init__(exchange_name, authenticated_api, valid_resolutions=[60, 60*5, 60*15,
60*60*24])
super().__init__(exchange_name, authenticated_api, valid_resolutions=[60, 60 * 5, 60 * 15,
60 * 60 * 24])
assert isinstance(self.calls, alpaca_trade_api.REST)

def init_exchange(self):
try:
account_info = self.calls.get_account()
except alpaca_trade_api.rest.APIError as e:
raise APIException(e.__str__() + ". Are you trying to use your normal exchange keys "
"while in sandbox mode? \nTry toggling the \'sandbox\' setting "
"in your keys.json or check if the keys were input correctly into your "
"keys.json.")
"while in sandbox mode? \nTry toggling the \'sandbox\' setting "
"in your keys.json or check if the keys were input correctly into your "
"keys.json.")
try:
if account_info['account_blocked']:
warnings.warn('Your alpaca account is indicated as blocked for trading....')
Expand Down Expand Up @@ -215,117 +215,81 @@ def __parse_iso(response):
@utils.order_protection
def market_order(self, symbol, side, size) -> MarketOrder:
assert isinstance(self.calls, alpaca_trade_api.REST)
needed = self.needed['market_order']

renames = [
['qty', 'size']
]
needed = self.needed['market_order']
order = utils.build_order_info(0, side, size, symbol, 'market')

order = {
'size': size,
'side': side,
'symbol': symbol,
'type': 'market'
}
response = self.calls.submit_order(symbol, side=side, type='market', time_in_force='day', qty=size)

response = self.__parse_iso(response)

response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response = self._fix_response(needed, response)
return MarketOrder(order, response, self)

@utils.order_protection
def take_profit_order(self, symbol: str, price: float, size: float) -> TakeProfitOrder:
needed = self.needed['take_profit']
def limit_order(self, symbol: str, side: str, price: float, size: float) -> LimitOrder:
needed = self.needed['limit_order']
order = utils.build_order_info(price, side, size, symbol, 'limit')

renames = [
['limit_price', 'price'],
['qty', 'size']
]
response = self.calls.submit_order(symbol,
side=side,
type='limit',
time_in_force='gtc',
qty=size,
limit_price=price)

response = self._fix_response(needed, response)
return LimitOrder(order, response, self)

@utils.order_protection
def take_profit_order(self, symbol: str, price: float, size: float) -> TakeProfitOrder:
side = 'sell'
order = {
'quantity': size,
'side': side,
'price': price,
'symbol': symbol,
'type': 'limit'
}
needed = self.needed['take_profit']
order = utils.build_order_info(price, side, size, symbol, 'take_profit')

response = self.calls.submit_order(symbol,
side=side,
type='limit',
time_in_force='gtc',
qty=size,
limit_price=price)

response = self.__parse_iso(response)

response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response['time_in_force'] = response['time_in_force'].upper()
response = self._fix_response(needed, response)
return TakeProfitOrder(order, response, self)

@utils.order_protection
def stop_loss_order(self, symbol: str, price: float, size: float) -> StopLossOrder:
needed = self.needed['stop_loss']
side = 'sell'
needed = self.needed['stop_loss']
order = utils.build_order_info(price, side, size, symbol, 'stop_loss')

renames = [
['limit_price', 'price'],
['qty', 'size']
]

order = {
'quantity': size,
'side': side,
'price': price,
'symbol': symbol,
'type': 'stop'
}
response = self.calls.submit_order(symbol,
side=side,
type='stop',
time_in_force='gtc',
qty=size,
stop_price=price)

response = self.__parse_iso(response)

response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response['time_in_force'] = response['time_in_force'].upper()
response = self._fix_response(needed, response)
return StopLossOrder(order, response, self)

@utils.order_protection
def limit_order(self, symbol: str, side: str, price: float, size: float) -> LimitOrder:
needed = self.needed['limit_order']

renames = [
def _fix_response(self, needed, response):
response = self.__parse_iso(response)
response = utils.rename_to([
['limit_price', 'price'],
['qty', 'size']
]
], response)
response = utils.isolate_specific(needed, response)
response['time_in_force'] = response['time_in_force'].upper()
return response

def _build_order_info(self, price, side, size, symbol, type):
order = {
'quantity': size,
'side': side,
'price': price,
'symbol': symbol,
'type': 'limit'
'type': type
}
response = self.calls.submit_order(symbol,
side=side,
type='limit',
time_in_force='gtc',
qty=size,
limit_price=price)

response = self.__parse_iso(response)

response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response['time_in_force'] = response['time_in_force'].upper()
return LimitOrder(order, response, self)
return order

def cancel_order(self, symbol, order_id) -> dict:
assert isinstance(self.calls, alpaca_trade_api.REST)
Expand Down Expand Up @@ -411,7 +375,7 @@ def get_product_history(self, symbol: str, epoch_start: float, epoch_stop: float
if resolution not in supported_multiples:
utils.info_print("Granularity is not an accepted granularity...rounding to nearest valid value.")
resolution = supported_multiples[min(range(len(supported_multiples)),
key=lambda i: abs(supported_multiples[i] - resolution))]
key=lambda i: abs(supported_multiples[i] - resolution))]

found_multiple, row_divisor = super().evaluate_multiples(supported_multiples, resolution)

Expand Down
7 changes: 1 addition & 6 deletions blankly/exchanges/interfaces/alpaca/alpaca_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,7 @@ def read_websocket(self):
else:
recent_time = time.time()

if self.__log:
if counter % 100 == 0:
self.__file.close()
self.__file = open(self.__filePath, 'a')
line = self.__logging_callback(received)
self.__file.write(line)
self.log_response(self.__logging_callback, received)

# Manage price events and fire for each manager attached
interface_message = self.__interface_callback(received)
Expand Down
74 changes: 24 additions & 50 deletions blankly/exchanges/interfaces/binance/binance_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,23 @@ def get_account(self, symbol=None) -> utils.AttributeDict:
})
return utils.AttributeDict(parsed_dictionary)

def _fix_response(self, needed, response):
response['side'] = response['side'].lower()
response['type'] = response['type'].lower()
response['status'] = super().homogenize_order_status('binance', response['status'].lower())
response['symbol'] = utils.to_blankly_symbol(response['symbol'], 'binance')
if 'transactTime' in response:
response["transactTime"] /= 1000
response = utils.rename_to([
["orderId", "id"],
["transactTime", "created_at"],
["origQty", "size"],
["timeInForce", "time_in_force"],
["cummulativeQuoteQty", "funds"]
], response)
response = utils.isolate_specific(needed, response)
return response

@utils.order_protection
def market_order(self, symbol, side, size) -> MarketOrder:
"""
Expand Down Expand Up @@ -310,13 +327,6 @@ def market_order(self, symbol, side, size) -> MarketOrder:
"""
if self.should_auto_trunc:
size = utils.trunc(size, self.get_asset_precision(symbol))
renames = [
["orderId", "id"],
["transactTime", "created_at"],
["origQty", "size"],
["timeInForce", "time_in_force"],
["cummulativeQuoteQty", "funds"]
]
order = {
'size': size,
'side': side,
Expand All @@ -327,14 +337,8 @@ def market_order(self, symbol, side, size) -> MarketOrder:
# The interface here will be the query of order status from this object, because orders are dynamic
# creatures
response = self.calls.order_market(symbol=modified_symbol, side=side, quantity=size)
response['side'] = response['side'].lower()
response['type'] = response['type'].lower()
response['status'] = super().homogenize_order_status('binance', response['status'].lower())
response["transactTime"] = response["transactTime"] / 1000
response['symbol'] = utils.to_blankly_symbol(response['symbol'], 'binance',
quote_guess=utils.get_quote_asset(symbol))
response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response = self._fix_response(needed, response)
return MarketOrder(order, response, self)

@utils.order_protection
Expand Down Expand Up @@ -391,18 +395,7 @@ def limit_order(self, symbol, side, price, size) -> LimitOrder:
}
modified_symbol = utils.to_exchange_symbol(symbol, 'binance')
response = self.calls.order_limit(symbol=modified_symbol, side=side, price=price, quantity=size)
renames = [
["orderId", "id"],
["transactTime", "created_at"],
["origQty", "size"],
["timeInForce", "time_in_force"],
]
response['side'] = response['side'].lower()
response['type'] = response['type'].lower()
response['status'] = super().homogenize_order_status('binance', response['status'].lower())
response['symbol'] = utils.to_blankly_symbol(response['symbol'], 'binance')
response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response = self._fix_response(needed, response)
return LimitOrder(order, response, self)

@utils.order_protection
Expand Down Expand Up @@ -458,18 +451,7 @@ def take_profit_order(self, symbol, price, size) -> TakeProfitOrder:
}
modified_symbol = utils.to_exchange_symbol(symbol, 'binance')
response = self.calls.create_order(symbol=modified_symbol, side=side, stopPrice=price, quantity=size, type=type)
renames = [
["orderId", "id"],
["transactTime", "created_at"],
["origQty", "size"],
["timeInForce", "time_in_force"],
]
response['side'] = response['side'].lower()
response['type'] = response['type'].lower()
response['status'] = super().homogenize_order_status('binance', response['status'].lower())
response['symbol'] = utils.to_blankly_symbol(response['symbol'], 'binance')
response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response = self._fix_response(needed, response)
return TakeProfitOrder(order, response, self)

@utils.order_protection
Expand Down Expand Up @@ -525,18 +507,7 @@ def stop_loss_order(self, symbol, price, size) -> StopLossOrder:
}
modified_symbol = utils.to_exchange_symbol(symbol, 'binance')
response = self.calls.create_order(symbol=modified_symbol, side=side, stopPrice=price, quantity=size, type=type)
renames = [
["orderId", "id"],
["transactTime", "created_at"],
["origQty", "size"],
["timeInForce", "time_in_force"],
]
response['side'] = response['side'].lower()
response['type'] = response['type'].lower()
response['status'] = super().homogenize_order_status('binance', response['status'].lower())
response['symbol'] = utils.to_blankly_symbol(response['symbol'], 'binance')
response = utils.rename_to(renames, response)
response = utils.isolate_specific(needed, response)
response = self._fix_response(needed, response)
return StopLossOrder(order, response, self)

def cancel_order(self, symbol, order_id) -> dict:
Expand Down Expand Up @@ -729,7 +700,10 @@ def get_product_history(self, symbol, epoch_start, epoch_stop, resolution):
Returns:
Dataframe with *at least* 'time (epoch)', 'low', 'high', 'open', 'close', 'volume' as columns.
"""
self._binance_get_product_history(symbol, epoch_start, epoch_stop, resolution)

@staticmethod
def _binance_get_product_history(symbol, epoch_start, epoch_stop, resolution):
resolution = blankly.time_builder.time_interval_to_seconds(resolution)

# epoch_start, epoch_stop = super().get_product_history(symbol, epoch_start, epoch_stop, resolution)
Expand Down
Loading

0 comments on commit 6eab87b

Please sign in to comment.