fix all linting for pylint3

This commit is contained in:
Jacob Plaster
2018-12-18 11:28:04 +00:00
parent 4ef8be144b
commit 0c9a0fadbc
33 changed files with 2505 additions and 1687 deletions

View File

@@ -1,268 +1,264 @@
"""
Module used to house all of the functions/classes used to handle orders
"""
import time
import asyncio
from ..utils.CustomLogger import CustomLogger
from ..models import Order
class OrderManager:
def __init__(self, bfxapi, logLevel='INFO'):
self.bfxapi = bfxapi
self.pending_orders = {}
self.pending_callbacks = {}
self.closed_orders = {}
self.open_orders = {}
self.logger = CustomLogger('BfxOrderManager', logLevel=logLevel)
def get_open_orders(self):
return list(self.open_orders.values())
def get_closed_orders(self):
return list(self.closed_orders.values())
def get_pending_orders(self):
return list(self.pending_orders.values())
async def _confirm_order(self, order, isClosed=False):
"""
Called every time an order signal has been received. This function
manages the local list of open orders.
Handles all of the functionality for opening, updating and closing order.
Also contains state such as all of your open orders and orders that have
closed.
"""
if order.cId in self.pending_orders:
await self._execute_confirm_callback(order.cId, order)
if isClosed:
await self._execute_close_callback(order.cId, order)
order.set_confirmed()
# remove from pending orders list
del self.pending_orders[order.cId]
self.bfxapi._emit('order_confirmed', order)
else:
await self._execute_confirm_callback(order.id, order)
if isClosed:
await self._execute_close_callback(order.id, order)
async def confirm_order_closed(self, raw_ws_data):
# order created and executed
# [0,"oc",[1151349678,null,1542203391995,"tBTCUSD",1542203389940,1542203389966,0,0.1,
# "EXCHANGE MARKET",null,null,null,0,"EXECUTED @ 18922.0(0.03299997): was PARTIALLY FILLED
# @ 18909.0(0.06700003)",null,null,18909,18913.2899961,0,0,null,null,null,0,0,null,null,null,
# "API>BFX",null,null,null]]
order = Order.from_raw_order(raw_ws_data[2])
order.set_open_state(False)
if order.id in self.open_orders:
del self.open_orders[order.id]
await self._confirm_order(order, isClosed=True)
self.logger.info("Order closed: {} {}".format(order.symbol, order.status))
self.bfxapi._emit('order_closed', order)
def __init__(self, bfxapi, logLevel='INFO'):
self.bfxapi = bfxapi
self.pending_orders = {}
self.pending_callbacks = {}
self.closed_orders = {}
self.open_orders = {}
self.logger = CustomLogger('BfxOrderManager', logLevel=logLevel)
async def build_from_order_snapshot(self, raw_ws_data):
print (raw_ws_data)
#[0, 'os', [[1151363978, None, 1544460962979, 'tBTCUSD', 1544460959604, 1544460959626,
# -0.12620639, -0.12620639, 'EXCHANGE LIMIT', None, None,None, 0, 'ACTIVE', None, None, 18793,
# 0, 0, 0, None, None, None, 0, 0, None, None, None, 'API>BFX', None, None, None]]]
'''
Rebuild the user orderbook based on an incoming snapshot
'''
osData = raw_ws_data[2]
self.open_orders = {}
for raw_order in osData:
order = Order.from_raw_order(raw_order)
order.set_open_state(True)
self.open_orders[order.id] = order
self.bfxapi._emit('order_snapshot', self.get_open_orders())
def get_open_orders(self):
return list(self.open_orders.values())
async def confirm_order_update(self, raw_ws_data):
# order created but partially filled
# [0, 'ou', [1151351581, None, 1542629457873, 'tBTCUSD', 1542629458071,
# 1542629458189, 0.01, 0.01, 'EXCHANGE LIMIT', None, None, None, 0, 'ACTIVE',
# None, None, 100, 0, 0, 0, None, None, None, 0, 0, None, None, None, 'API>BFX',
# None, None, None]]
order = Order.from_raw_order(raw_ws_data[2])
order.set_open_state(True)
self.open_orders[order.id] = order
await self._confirm_order(order)
self.logger.info("Order update: {}".format(order))
self.bfxapi._emit('order_update', order)
def get_closed_orders(self):
return list(self.closed_orders.values())
async def confirm_order_new(self, raw_ws_data):
# order created but not executed / created but partially filled
# [0, 'on', [1151351563, None, 1542624024383, 'tBTCUSD', 1542624024596,
# 1542624024617, 0.01, 0.01, 'EXCHANGE LIMIT', None, None, None, 0, 'ACTIVE',
# None, None, 100, 0, 0, 0, None, None, None, 0, 0, None, None, None, 'API>BFX',
# None, None, None]]
order = Order.from_raw_order(raw_ws_data[2])
order.set_open_state(True)
self.open_orders[order.id] = order
await self._confirm_order(order)
self.logger.info("Order new: {}".format(order))
self.bfxapi._emit('order_new', order)
def get_pending_orders(self):
return list(self.pending_orders.values())
def _gen_unqiue_cid(self):
return int(round(time.time() * 1000))
async def _confirm_order(self, order, isClosed=False):
"""
Called every time an order signal has been received. This function
manages the local list of open orders.
"""
if order.cId in self.pending_orders:
await self._execute_confirm_callback(order.cId, order)
if isClosed:
await self._execute_close_callback(order.cId, order)
order.set_confirmed()
# remove from pending orders list
del self.pending_orders[order.cId]
self.bfxapi._emit('order_confirmed', order)
else:
await self._execute_confirm_callback(order.id, order)
if isClosed:
await self._execute_close_callback(order.id, order)
async def submit_order(self, symbol, price, amount, market_type=Order.Type.LIMIT,
hidden=False, price_trailing=None, price_aux_limit=None, oco_stop_price=None,
close=False, reduce_only=False, post_only=False, oco=False, time_in_force=None,
onConfirm=None, onClose=None, *args, **kwargs):
"""
Submit a new order
async def confirm_order_closed(self, raw_ws_data):
order = Order.from_raw_order(raw_ws_data[2])
order.set_open_state(False)
if order.id in self.open_orders:
del self.open_orders[order.id]
await self._confirm_order(order, isClosed=True)
self.logger.info("Order closed: {} {}".format(
order.symbol, order.status))
self.bfxapi._emit('order_closed', order)
@param symbol: the name of the symbol i.e 'tBTCUSD
@param price: the price you want to buy/sell at (must be positive)
@param amount: order size: how much you want to buy/sell,
a negative amount indicates a sell order and positive a buy order
@param market_type Order.Type: please see Order.Type enum
amount decimal string Positive for buy, Negative for sell
@param hidden: if True, order should be hidden from orderbooks
@param price_trailing: decimal trailing price
@param price_aux_limit: decimal auxiliary Limit price (only for STOP LIMIT)
@param oco_stop_price: set the oco stop price (requires oco = True)
@param close: if True, close position if position present
@param reduce_only: if True, ensures that the executed order does not flip the opened position
@param post_only: if True, ensures the limit order will be added to the order book and not
match with a pre-existing order
@param oco: cancels other order option allows you to place a pair of orders stipulating
that if one order is executed fully or partially, then the other is automatically canceled
async def build_from_order_snapshot(self, raw_ws_data):
'''
Rebuild the user orderbook based on an incoming snapshot
'''
osData = raw_ws_data[2]
self.open_orders = {}
for raw_order in osData:
order = Order.from_raw_order(raw_order)
order.set_open_state(True)
self.open_orders[order.id] = order
self.bfxapi._emit('order_snapshot', self.get_open_orders())
@param time_in_force: datetime for automatic order cancellation ie. 2020-01-01 10:45:23
@param onConfirm: function called when the bitfinex websocket receives signal that the order
was confirmed
@param onClose: function called when the bitfinex websocket receives signal that the order
was closed due to being filled or cancelled
"""
cId = self._gen_unqiue_cid()
# create base payload with required data
payload = {
"cid": cId,
"type": str(market_type),
"symbol": symbol,
"amount": str(amount),
"price": str(price),
}
# caclulate and add flags
flags = self._calculate_flags(hidden, close, reduce_only, post_only, oco)
payload['flags'] = flags
# add extra parameters
if (price_trailing):
payload['price_trailing'] = price_trailing
if (price_aux_limit):
payload['price_aux_limit'] = price_aux_limit
if (oco_stop_price):
payload['price_oco_stop'] = oco_stop_price
if (time_in_force):
payload['tif'] = time_in_force
# submit the order
self.pending_orders[cId] = payload
self._create_callback(cId, onConfirm=onConfirm, onClose=onClose)
await self.bfxapi._send_auth_command('on', payload)
self.logger.info("Order cid={} ({} {} @ {}) dispatched".format(
cId, symbol, amount, price))
async def confirm_order_update(self, raw_ws_data):
order = Order.from_raw_order(raw_ws_data[2])
order.set_open_state(True)
self.open_orders[order.id] = order
await self._confirm_order(order)
self.logger.info("Order update: {}".format(order))
self.bfxapi._emit('order_update', order)
async def update_order(self, orderId, price=None, amount=None, delta=None, price_aux_limit=None,
price_trailing=None, hidden=False, close=False, reduce_only=False, post_only=False,
time_in_force=None, onConfirm=None, onClose=None):
"""
Update an existing order
async def confirm_order_new(self, raw_ws_data):
order = Order.from_raw_order(raw_ws_data[2])
order.set_open_state(True)
self.open_orders[order.id] = order
await self._confirm_order(order)
self.logger.info("Order new: {}".format(order))
self.bfxapi._emit('order_new', order)
@param orderId: the id of the order that you want to update
@param price: the price you want to buy/sell at (must be positive)
@param amount: order size: how much you want to buy/sell,
a negative amount indicates a sell order and positive a buy order
@param delta: change of amount
@param price_trailing: decimal trailing price
@param price_aux_limit: decimal auxiliary Limit price (only for STOP LIMIT)
@param hidden: if True, order should be hidden from orderbooks
@param close: if True, close position if position present
@param reduce_only: if True, ensures that the executed order does not flip the opened position
@param post_only: if True, ensures the limit order will be added to the order book and not
match with a pre-existing order
@param time_in_force: datetime for automatic order cancellation ie. 2020-01-01 10:45:23
@param onConfirm: function called when the bitfinex websocket receives signal that the order
was confirmed
@param onClose: function called when the bitfinex websocket receives signal that the order
was closed due to being filled or cancelled
"""
order = self.open_orders[orderId]
self._create_callback(order.cId, onConfirm=onConfirm, onClose=onClose)
payload = { "id": orderId }
if price is not None:
payload['price'] = str(price)
if amount is not None:
payload['amount'] = str(amount)
if delta is not None:
payload['delta'] = str(delta)
if price_aux_limit is not None:
payload['price_aux_limit'] = str(price_aux_limit)
if price_trailing is not None:
payload['price_trailing'] = str(price_trailing)
if time_in_force is not None:
payload['time_in_force'] = str(time_in_force)
flags = self._calculate_flags(hidden, close, reduce_only, post_only, False)
payload['flags'] = flags
await self.bfxapi._send_auth_command('ou', payload)
self.logger.info("Update Order order_id={} dispatched".format(orderId))
def _gen_unqiue_cid(self):
return int(round(time.time() * 1000))
async def cancel_order(self, orderId, onConfirm=None, onClose=None):
"""
Cancel an existing open order
async def submit_order(self, symbol, price, amount, market_type=Order.Type.LIMIT,
hidden=False, price_trailing=None, price_aux_limit=None,
oco_stop_price=None, close=False, reduce_only=False,
post_only=False, oco=False, time_in_force=None,
onConfirm=None, onClose=None, *args, **kwargs):
"""
Submit a new order
@param orderId: the id of the order that you want to update
@param onConfirm: function called when the bitfinex websocket receives signal that the order
was confirmed
@param onClose: function called when the bitfinex websocket receives signal that the order
was closed due to being filled or cancelled
"""
# order = self.open_orders[orderId]
self._create_callback(orderId, onConfirm=onConfirm, onClose=onClose)
await self.bfxapi._send_auth_command('oc', { 'id': orderId })
self.logger.info("Order cancel order_id={} dispatched".format(orderId))
@param symbol: the name of the symbol i.e 'tBTCUSD
@param price: the price you want to buy/sell at (must be positive)
@param amount: order size: how much you want to buy/sell,
a negative amount indicates a sell order and positive a buy order
@param market_type Order.Type: please see Order.Type enum
amount decimal string Positive for buy, Negative for sell
@param hidden: if True, order should be hidden from orderbooks
@param price_trailing: decimal trailing price
@param price_aux_limit: decimal auxiliary Limit price (only for STOP LIMIT)
@param oco_stop_price: set the oco stop price (requires oco = True)
@param close: if True, close position if position present
@param reduce_only: if True, ensures that the executed order does not flip the opened position
@param post_only: if True, ensures the limit order will be added to the order book and not
match with a pre-existing order
@param oco: cancels other order option allows you to place a pair of orders stipulating
that if one order is executed fully or partially, then the other is automatically canceled
async def cancel_all_orders(self):
"""
Cancel all existing open orders
@param time_in_force: datetime for automatic order cancellation ie. 2020-01-01 10:45:23
@param onConfirm: function called when the bitfinex websocket receives signal that the order
was confirmed
@param onClose: function called when the bitfinex websocket receives signal that the order
was closed due to being filled or cancelled
"""
cId = self._gen_unqiue_cid()
# create base payload with required data
payload = {
"cid": cId,
"type": str(market_type),
"symbol": symbol,
"amount": str(amount),
"price": str(price),
}
# caclulate and add flags
flags = self._calculate_flags(
hidden, close, reduce_only, post_only, oco)
payload['flags'] = flags
# add extra parameters
if (price_trailing):
payload['price_trailing'] = price_trailing
if (price_aux_limit):
payload['price_aux_limit'] = price_aux_limit
if (oco_stop_price):
payload['price_oco_stop'] = oco_stop_price
if (time_in_force):
payload['tif'] = time_in_force
# submit the order
self.pending_orders[cId] = payload
self._create_callback(cId, onConfirm=onConfirm, onClose=onClose)
await self.bfxapi._send_auth_command('on', payload)
self.logger.info("Order cid={} ({} {} @ {}) dispatched".format(
cId, symbol, amount, price))
This function closes orders that have been tracked locally by the OrderManager.
"""
ids = [self.open_orders[x].id for x in self.open_orders]
await self.cancel_order_multi(ids)
async def update_order(self, orderId, price=None, amount=None, delta=None, price_aux_limit=None,
price_trailing=None, hidden=False, close=False, reduce_only=False,
post_only=False, time_in_force=None, onConfirm=None, onClose=None):
"""
Update an existing order
async def cancel_order_multi(self, orderIds):
"""
Cancel existing open orders as a batch
@param orderId: the id of the order that you want to update
@param price: the price you want to buy/sell at (must be positive)
@param amount: order size: how much you want to buy/sell,
a negative amount indicates a sell order and positive a buy order
@param delta: change of amount
@param price_trailing: decimal trailing price
@param price_aux_limit: decimal auxiliary Limit price (only for STOP LIMIT)
@param hidden: if True, order should be hidden from orderbooks
@param close: if True, close position if position present
@param reduce_only: if True, ensures that the executed order does not flip the opened position
@param post_only: if True, ensures the limit order will be added to the order book and not
match with a pre-existing order
@param time_in_force: datetime for automatic order cancellation ie. 2020-01-01 10:45:23
@param onConfirm: function called when the bitfinex websocket receives signal that the order
was confirmed
@param onClose: function called when the bitfinex websocket receives signal that the order
was closed due to being filled or cancelled
"""
order = self.open_orders[orderId]
self._create_callback(order.cId, onConfirm=onConfirm, onClose=onClose)
payload = {"id": orderId}
if price is not None:
payload['price'] = str(price)
if amount is not None:
payload['amount'] = str(amount)
if delta is not None:
payload['delta'] = str(delta)
if price_aux_limit is not None:
payload['price_aux_limit'] = str(price_aux_limit)
if price_trailing is not None:
payload['price_trailing'] = str(price_trailing)
if time_in_force is not None:
payload['time_in_force'] = str(time_in_force)
flags = self._calculate_flags(
hidden, close, reduce_only, post_only, False)
payload['flags'] = flags
await self.bfxapi._send_auth_command('ou', payload)
self.logger.info("Update Order order_id={} dispatched".format(orderId))
@param orderIds: an array of order ids
"""
task_batch = []
for oid in orderIds:
task_batch += [
asyncio.ensure_future(self.open_orders[oid].close())
]
await asyncio.wait(*[ task_batch ])
async def cancel_order(self, orderId, onConfirm=None, onClose=None):
"""
Cancel an existing open order
def _create_callback(self, order_identifier, onConfirm=None, onClose=None):
if order_identifier in self.pending_callbacks:
self.pending_callbacks[order_identifier] += [(onClose, onConfirm)]
else:
self.pending_callbacks[order_identifier] = [(onClose, onConfirm)]
@param orderId: the id of the order that you want to update
@param onConfirm: function called when the bitfinex websocket receives signal that the
order
was confirmed
@param onClose: function called when the bitfinex websocket receives signal that the order
was closed due to being filled or cancelled
"""
# order = self.open_orders[orderId]
self._create_callback(orderId, onConfirm=onConfirm, onClose=onClose)
await self.bfxapi._send_auth_command('oc', {'id': orderId})
self.logger.info("Order cancel order_id={} dispatched".format(orderId))
async def _execute_close_callback(self, order_identifier, *args, **kwargs):
if order_identifier in self.pending_callbacks:
for c in self.pending_callbacks[order_identifier]:
if c[0]:
await c[0](*args, **kwargs)
del self.pending_callbacks[order_identifier]
async def cancel_all_orders(self):
"""
Cancel all existing open orders
async def _execute_confirm_callback(self, order_identifier, *args, **kwargs):
if order_identifier in self.pending_callbacks:
for c in self.pending_callbacks[order_identifier]:
if c[1]:
await c[1](*args, **kwargs)
This function closes orders that have been tracked locally by the OrderManager.
"""
ids = [self.open_orders[x].id for x in self.open_orders]
await self.cancel_order_multi(ids)
def _calculate_flags(self, hidden, close, reduce_only, post_only, oco):
flags = 0
flags = flags + Order.Flags.HIDDEN if hidden else flags
flags = flags + Order.Flags.CLOSE if close else flags
flags = flags + Order.Flags.REDUUCE_ONLY if reduce_only else flags
flags = flags + Order.Flags.POST_ONLY if post_only else flags
flags = flags + Order.Flags.OCO if oco else flags
return flags
async def cancel_order_multi(self, orderIds):
"""
Cancel existing open orders as a batch
@param orderIds: an array of order ids
"""
task_batch = []
for oid in orderIds:
task_batch += [
asyncio.ensure_future(self.open_orders[oid].close())
]
await asyncio.wait(*[task_batch])
def _create_callback(self, order_identifier, onConfirm=None, onClose=None):
if order_identifier in self.pending_callbacks:
self.pending_callbacks[order_identifier] += [(onClose, onConfirm)]
else:
self.pending_callbacks[order_identifier] = [(onClose, onConfirm)]
async def _execute_close_callback(self, order_identifier, *args, **kwargs):
if order_identifier in self.pending_callbacks:
for c in self.pending_callbacks[order_identifier]:
if c[0]:
await c[0](*args, **kwargs)
del self.pending_callbacks[order_identifier]
async def _execute_confirm_callback(self, order_identifier, *args, **kwargs):
if order_identifier in self.pending_callbacks:
for c in self.pending_callbacks[order_identifier]:
if c[1]:
await c[1](*args, **kwargs)
def _calculate_flags(self, hidden, close, reduce_only, post_only, oco):
flags = 0
flags = flags + Order.Flags.HIDDEN if hidden else flags
flags = flags + Order.Flags.CLOSE if close else flags
flags = flags + Order.Flags.REDUUCE_ONLY if reduce_only else flags
flags = flags + Order.Flags.POST_ONLY if post_only else flags
flags = flags + Order.Flags.OCO if oco else flags
return flags