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,86 +0,0 @@
class FundingCreditModel:
ID = 0
SYMBOL = 1
SIDE = 2
MTS_CREATE = 3
MTS_UPDATE = 4
AMOUNT = 5
FLAGS = 6
STATUS = 7
RATE = 11
PERIOD = 12
MTS_OPENING = 13
MTS_LAST_PAYOUT = 14
NOTIFY = 15
HIDDEN = 16
RENEW = 18
NO_CLOSE = 20
POSITION_PAIR = 21
class FundingLoan:
"""
ID integer Offer ID
SYMBOL string The currency of the offer (fUSD, etc)
SIDE string "Lend" or "Loan"
MTS_CREATE int Millisecond Time Stamp when the offer was created
MSG_UPDATE int Millisecond Time Stamp when the offer was updated
AMOUNT float Amount the offer is for
FLAGS object future params object (stay tuned)
STATUS string Offer Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
RATE float Rate of the offer
PERIOD int Period of the offer
MTS_OPENING int Millisecond Time Stamp when funding opened
MTS_LAST_PAYOUT int Millisecond Time Stamp when last payout received
NOTIFY int 0 if false, 1 if true
HIDDEN int 0 if false, 1 if true
RENEW int 0 if false, 1 if true
NO_CLOSE int 0 if false, 1 if true Whether the funding will be closed when the position is closed
POSITION_PAIR string Pair of the position that the funding was used for
"""
def __init__(self, id, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close, position_pair):
self.id = id
self.symbol = symbol
self.side = side
self.mts_create = mts_create
self.mts_update = mts_update
self.amount = amount
self.flags = flags
self.status = status
self.rate = rate
self.period = period
self.mts_opening = mts_opening
self.mts_last_payout = mts_last_payout
self.notify = notify
self.hidden = hidden
self.renew = renew
self.no_close = no_close
self.position_pair = position_pair
@staticmethod
def from_raw_credit(raw_credit):
id = raw_credit[FundingCreditModel.ID]
symbol = raw_credit[FundingCreditModel.SYMBOL]
side = raw_credit[FundingCreditModel.SIDE]
mts_create = raw_credit[FundingCreditModel.MTS_CREATE]
mts_update = raw_credit[FundingCreditModel.MTS_UPDATE]
amount = raw_credit[FundingCreditModel.AMOUNT]
flags = raw_credit[FundingCreditModel.FLAGS]
status = raw_credit[FundingCreditModel.STATUS]
rate = raw_credit[FundingCreditModel.RATE]
period = raw_credit[FundingCreditModel.PERIOD]
mts_opening = raw_credit[FundingCreditModel.MTS_OPENING]
mts_last_payout = raw_credit[FundingCreditModel.MTS_LAST_PAYOUT]
notify = raw_credit[FundingCreditModel.NOTIFY]
hidden = raw_credit[FundingCreditModel.HIDDEN]
renew = raw_credit[FundingCreditModel.RENEW]
no_close = raw_credit[FundingCreditModel.NO_CLOSE]
position_pair = raw_credit[FundingCreditModel.POSITION_PAIR]
return FundingLoan(id, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close, position_pair)
def __str__(self):
return "FundingCredit '{}' <id={} rate={} amount={} period={} status='{}'>".format(
self.symbol, self.id, self.rate, self.amount, self.period, self.status)

View File

@@ -1,82 +0,0 @@
class FundingLoanModel:
ID = 0
SYMBOL = 1
SIDE = 2
MTS_CREATE = 3
MTS_UPDATE = 4
AMOUNT = 5
FLAGS = 6
STATUS = 7
RATE = 11
PERIOD = 12
MTS_OPENING = 13
MTS_LAST_PAYOUT = 14
NOTIFY = 15
HIDDEN = 16
RENEW = 18
NO_CLOSE = 20
class FundingLoan:
"""
ID integer Offer ID
SYMBOL string The currency of the offer (fUSD, etc)
SIDE string "Lend" or "Loan"
MTS_CREATE int Millisecond Time Stamp when the offer was created
MTS_UPDATE int Millisecond Time Stamp when the offer was created
AMOUNT float Amount the offer is for
FLAGS object future params object (stay tuned)
STATUS string Offer Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
RATE float Rate of the offer
PERIOD int Period of the offer
MTS_OPENING int Millisecond Time Stamp for when the loan was opened
MTS_LAST_PAYOUT int Millisecond Time Stamp for when the last payout was made
NOTIFY int 0 if false, 1 if true
HIDDEN int 0 if false, 1 if true
RENEW int 0 if false, 1 if true
NO_CLOSE int If funding will be returned when position is closed. 0 if false, 1 if true
"""
def __init__(self, id, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close):
self.id = id
self.symbol = symbol
self.side = side
self.mts_create = mts_create
self.mts_update = mts_update
self.amount = amount
self.flags = flags
self.status = status
self.rate = rate
self.period = period
self.mts_opening = mts_opening
self.mts_last_payout = mts_last_payout
self.notify = notify
self.hidden = hidden
self.renew = renew
self.no_close = no_close
@staticmethod
def from_raw_loan(raw_loan):
id = raw_loan[FundingLoanModel.ID]
symbol = raw_loan[FundingLoanModel.SYMBOL]
side = raw_loan[FundingLoanModel.SIDE]
mts_create = raw_loan[FundingLoanModel.MTS_CREATE]
mts_update = raw_loan[FundingLoanModel.MTS_UPDATE]
amount = raw_loan[FundingLoanModel.AMOUNT]
flags = raw_loan[FundingLoanModel.FLAGS]
status = raw_loan[FundingLoanModel.STATUS]
rate = raw_loan[FundingLoanModel.RATE]
period = raw_loan[FundingLoanModel.PERIOD]
mts_opening = raw_loan[FundingLoanModel.MTS_OPENING]
mts_last_payout = raw_loan[FundingLoanModel.MTS_LAST_PAYOUT]
notify = raw_loan[FundingLoanModel.NOTIFY]
hidden = raw_loan[FundingLoanModel.HIDDEN]
renew = raw_loan[FundingLoanModel.RENEW]
no_close = raw_loan[FundingLoanModel.NO_CLOSE]
return FundingLoan(id, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close)
def __str__(self):
return "FundingLoan '{}' <id={} rate={} amount={} period={} status='{}'>".format(
self.symbol, self.id, self.rate, self.amount, self.period, self.status)

View File

@@ -1,74 +0,0 @@
class FundingOfferModel:
ID = 0
SYMBOL = 1
MTS_CREATE = 2
MTS_UPDATED = 3
AMOUNT = 4
AMOUNT_ORIG = 5
TYPE = 6
FLAGS = 9
STATUS = 10
RATE = 14
PERIOD = 15
NOTFIY = 16
HIDDEN = 17
RENEW = 19
class FundingOffer:
"""
ID integer Offer ID
SYMBOL string The currency of the offer (fUSD, etc)
MTS_CREATED int Millisecond Time Stamp when the offer was created
MSG_UPDATED int Millisecond Time Stamp when the offer was created
AMOUNT float Amount the offer is for
AMOUNT_ORIG float Amount the offer was entered with originally
TYPE string "lend" or "loan"
FLAGS object future params object (stay tuned)
STATUS string Offer Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
RATE float Rate of the offer
PERIOD int Period of the offer
NOTIFY int 0 if false, 1 if true
HIDDEN int 0 if false, 1 if true
RENEW int 0 if false, 1 if true
"""
def __init__(self, id, symbol, mts_create, mts_updated, amount, amount_orig, f_type,
flags, status, rate, period, notify, hidden, renew):
self.id = id
self.symbol = symbol
self.mts_create = mts_create
self.mts_updated = mts_updated
self.amount = amount
self.amount_orig = amount_orig
self.f_type = f_type
self.flags = flags
self.status = status
self.rate = rate
self.period = period
self.notify = notify
self.hidden = hidden
self.renew = renew
@staticmethod
def from_raw_offer(raw_offer):
id = raw_offer[FundingOfferModel.ID]
symbol = raw_offer[FundingOfferModel.SYMBOL]
mts_create = raw_offer[FundingOfferModel.MTS_CREATE]
mts_updated = raw_offer[FundingOfferModel.MTS_UPDATED]
amount = raw_offer[FundingOfferModel.AMOUNT]
amount_orig = raw_offer[FundingOfferModel.AMOUNT_ORIG]
f_type = raw_offer[FundingOfferModel.TYPE]
flags = raw_offer[FundingOfferModel.FLAGS]
status = raw_offer[FundingOfferModel.STATUS]
rate = raw_offer[FundingOfferModel.RATE]
period = raw_offer[FundingOfferModel.PERIOD]
notify = raw_offer[FundingOfferModel.NOTFIY]
hidden = raw_offer[FundingOfferModel.HIDDEN]
renew = raw_offer[FundingOfferModel.RENEW]
return FundingOffer(id, symbol, mts_create, mts_updated, amount,
amount_orig, f_type,flags, status, rate, period, notify, hidden, renew)
def __str__(self):
return "FundingOffer '{}' <id={} rate={} period={} status='{}'>".format(
self.symbol, self.id, self.rate, self.period, self.status)

View File

@@ -1,161 +1,221 @@
"""
Module used to describe all of the different data types
"""
import time
import datetime
class OrderType:
MARKET = 'MARKET'
LIMIT = 'LIMIT'
STOP = 'STOP'
STOP_LIMIT = 'STOP LIMIT'
TRAILING_STOP = 'TRAILING STOP'
FILL_OR_KILL = 'FOK'
EXCHANGE_MARKET = 'EXCHANGE MARKET'
EXCHANGE_LIMIT = 'EXCHANGE LIMIT'
EXCHANGE_STOP = 'EXCHANGE STOP'
EXCHANGE_STOP_LIMIT = 'EXCHANGE STOP LIMIT'
EXCHANGE_TRAILING_STOP = 'EXCHANGE TRAILING STOP'
EXCHANGE_FILL_OR_KILL = 'EXCHANGE FOK'
"""
Enum used to describe all of the different order types available for use
"""
MARKET = 'MARKET'
LIMIT = 'LIMIT'
STOP = 'STOP'
STOP_LIMIT = 'STOP LIMIT'
TRAILING_STOP = 'TRAILING STOP'
FILL_OR_KILL = 'FOK'
EXCHANGE_MARKET = 'EXCHANGE MARKET'
EXCHANGE_LIMIT = 'EXCHANGE LIMIT'
EXCHANGE_STOP = 'EXCHANGE STOP'
EXCHANGE_STOP_LIMIT = 'EXCHANGE STOP LIMIT'
EXCHANGE_TRAILING_STOP = 'EXCHANGE TRAILING STOP'
EXCHANGE_FILL_OR_KILL = 'EXCHANGE FOK'
LIMIT_ORDERS = [OrderType.LIMIT, OrderType.STOP_LIMIT, OrderType.EXCHANGE_LIMIT,
OrderType.EXCHANGE_STOP_LIMIT, OrderType.FILL_OR_KILL, OrderType.EXCHANGE_FILL_OR_KILL]
OrderType.EXCHANGE_STOP_LIMIT, OrderType.FILL_OR_KILL,
OrderType.EXCHANGE_FILL_OR_KILL]
class OrderSide:
BUY = 'buy'
SELL = 'sell'
"""
Enum used to describe the different directions of an order
"""
BUY = 'buy'
SELL = 'sell'
class OrderClosedModel:
ID = 0
GID = 1
CID = 2
SYMBOL = 3
MTS_CREATE = 4
MTS_UPDATE = 5
AMOUNT = 6
AMOUNT_ORIG = 7
TYPE = 8
TYPE_PREV = 9
FLAGS = 12
STATUS = 13
PRICE = 16
PRIVE_AVG = 17
PRICE_TRAILING = 18
PRICE_AUX_LIMIT = 19
NOTIFY = 23
PLACE_ID = 25
"""
Enum used ad an index match to locate the different values in a
raw order array
"""
ID = 0
GID = 1
CID = 2
SYMBOL = 3
MTS_CREATE = 4
MTS_UPDATE = 5
AMOUNT = 6
AMOUNT_ORIG = 7
TYPE = 8
TYPE_PREV = 9
FLAGS = 12
STATUS = 13
PRICE = 16
PRIVE_AVG = 17
PRICE_TRAILING = 18
PRICE_AUX_LIMIT = 19
NOTIFY = 23
PLACE_ID = 25
class OrderFlags:
HIDDEN = 64
CLOSE = 12
REDUCE_ONLY = 1024
POST_ONLY = 4096
OCO = 16384
"""
Enum used to explain the different values that can be passed in
as flags
"""
HIDDEN = 64
CLOSE = 12
REDUCE_ONLY = 1024
POST_ONLY = 4096
OCO = 16384
def now_in_mills():
return int(round(time.time() * 1000))
"""
Gets the current time in milliseconds
"""
return int(round(time.time() * 1000))
class Order:
"""
ID int64 Order ID
GID int Group ID
CID int Client Order ID
SYMBOL string Pair (tBTCUSD, )
MTS_CREATE int Millisecond timestamp of creation
MTS_UPDATE int Millisecond timestamp of update
AMOUNT float Positive means buy, negative means sell.
AMOUNT_ORIG float Original amount
TYPE string The type of the order: LIMIT, MARKET, STOP, TRAILING STOP, EXCHANGE MARKET, EXCHANGE LIMIT, EXCHANGE STOP, EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK.
TYPE_PREV string Previous order type
FLAGS int Upcoming Params Object (stay tuned)
ORDER_STATUS string Order Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
PRICE float Price
PRICE_AVG float Average price
PRICE_TRAILING float The trailing price
PRICE_AUX_LIMIT float Auxiliary Limit price (for STOP LIMIT)
HIDDEN int 1 if Hidden, 0 if not hidden
PLACED_ID int If another order caused this order to be placed (OCO) this will be that other order's ID
"""
"""
ID int64 Order ID
GID int Group ID
CID int Client Order ID
SYMBOL string Pair (tBTCUSD, ...)
MTS_CREATE int Millisecond timestamp of creation
MTS_UPDATE int Millisecond timestamp of update
AMOUNT float Positive means buy, negative means sell.
AMOUNT_ORIG float Original amount
TYPE string The type of the order: LIMIT, MARKET, STOP, TRAILING STOP,
EXCHANGE MARKET, EXCHANGE LIMIT, EXCHANGE STOP, EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK.
TYPE_PREV string Previous order type
FLAGS int Upcoming Params Object (stay tuned)
ORDER_STATUS string Order Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
PRICE float Price
PRICE_AVG float Average price
PRICE_TRAILING float The trailing price
PRICE_AUX_LIMIT float Auxiliary Limit price (for STOP LIMIT)
HIDDEN int 1 if Hidden, 0 if not hidden
PLACED_ID int If another order caused this order to be placed (OCO) this will be that other
order's ID
"""
Type = OrderType()
Side = OrderSide()
Flags = OrderFlags()
Type = OrderType()
Side = OrderSide()
Flags = OrderFlags()
def __init__(self, id, gId, cId, symbol, mtsCreate, mtsUpdate, amount, amountOrig, oType,
typePrev, flags, status, price, priceAvg, priceTrailing, priceAuxLimit, notfiy, placeId):
self.id = id
self.gId = gId
self.cId = cId
self.symbol = symbol
self.mtsCreate = mtsCreate
self.mtsUpdate = mtsUpdate
# self.amount = amount
self.amount = amount
self.amountOrig = amountOrig
self.type = oType
self.typePrev = typePrev
self.flags = flags
self.status = status
self.price = price
self.priceAvg = priceAvg
self.priceTrailing = priceTrailing
self.priceAuxLimit = priceAuxLimit
self.notfiy = notfiy
self.placeId = placeId
self.tag = ""
self.fee = 0
def __init__(self, oid, gid, cid, symbol, mts_create, mts_update, amount,
amount_orig, o_type, typePrev, flags, status, price, price_avg,
price_trailing, price_aux_limit, notfiy, place_id):
# pylint: disable=invalid-name
self.id = oid
self.gid = gid
self.cid = cid
self.symbol = symbol
self.mts_create = mts_create
self.mts_update = mts_update
# self.amount = amount
self.amount = amount
self.amount_orig = amount_orig
self.type = o_type
self.type_prev = typePrev
self.flags = flags
self.status = status
self.price = price
self.price_avg = price_avg
self.price_trailing = price_trailing
self.price_aux_limit = price_aux_limit
self.notfiy = notfiy
self.place_id = place_id
self.tag = ""
self.fee = 0
self.is_pending_bool = True
self.is_confirmed_bool = False
self.is_open_bool = False
self.is_pending_bool = True
self.is_confirmed_bool = False
self.is_open_bool = False
self.date = datetime.datetime.fromtimestamp(mtsCreate/1000.0)
## if cancelled then priceAvg wont exist
if priceAvg:
## check if order is taker or maker
if self.type in LIMIT_ORDERS:
self.fee = (priceAvg * abs(amount)) * 0.001
else:
self.fee = (priceAvg * abs(amount)) * 0.002
self.date = datetime.datetime.fromtimestamp(mts_create/1000.0)
# if cancelled then priceAvg wont exist
if price_avg:
# check if order is taker or maker
if self.type in LIMIT_ORDERS:
self.fee = (price_avg * abs(amount)) * 0.001
else:
self.fee = (price_avg * abs(amount)) * 0.002
@staticmethod
def from_raw_order(raw_order):
oid = raw_order[OrderClosedModel.ID]
gId = raw_order[OrderClosedModel.GID]
cId = raw_order[OrderClosedModel.CID]
symbol = raw_order[OrderClosedModel.SYMBOL]
mtsCreate = raw_order[OrderClosedModel.MTS_CREATE]
mtsUpdate = raw_order[OrderClosedModel.MTS_UPDATE]
amount = raw_order[OrderClosedModel.AMOUNT]
amountOrig = raw_order[OrderClosedModel.AMOUNT_ORIG]
oType = raw_order[OrderClosedModel.TYPE]
typePrev = raw_order[OrderClosedModel.TYPE_PREV]
flags = raw_order[OrderClosedModel.FLAGS]
status = raw_order[OrderClosedModel.STATUS]
price = raw_order[OrderClosedModel.PRICE]
priceAvg = raw_order[OrderClosedModel.PRIVE_AVG]
priceTrailing = raw_order[OrderClosedModel.PRICE_TRAILING]
priceAuxLimit = raw_order[OrderClosedModel.PRICE_AUX_LIMIT]
notfiy = raw_order[OrderClosedModel.NOTIFY]
placeId = raw_order[OrderClosedModel.PLACE_ID]
@staticmethod
def from_raw_order(raw_order):
"""
Parse a raw order object into an Order oject
return Order(oid, gId, cId, symbol, mtsCreate, mtsUpdate, amount, amountOrig, oType,
typePrev, flags, status, price, priceAvg, priceTrailing, priceAuxLimit, notfiy, placeId)
@return Order
"""
oid = raw_order[OrderClosedModel.ID]
gid = raw_order[OrderClosedModel.GID]
cid = raw_order[OrderClosedModel.CID]
symbol = raw_order[OrderClosedModel.SYMBOL]
mts_create = raw_order[OrderClosedModel.MTS_CREATE]
mts_update = raw_order[OrderClosedModel.MTS_UPDATE]
amount = raw_order[OrderClosedModel.AMOUNT]
amount_orig = raw_order[OrderClosedModel.AMOUNT_ORIG]
o_type = raw_order[OrderClosedModel.TYPE]
type_prev = raw_order[OrderClosedModel.TYPE_PREV]
flags = raw_order[OrderClosedModel.FLAGS]
status = raw_order[OrderClosedModel.STATUS]
price = raw_order[OrderClosedModel.PRICE]
price_avg = raw_order[OrderClosedModel.PRIVE_AVG]
price_trailing = raw_order[OrderClosedModel.PRICE_TRAILING]
price_aux_limit = raw_order[OrderClosedModel.PRICE_AUX_LIMIT]
notfiy = raw_order[OrderClosedModel.NOTIFY]
place_id = raw_order[OrderClosedModel.PLACE_ID]
def set_confirmed(self):
self.is_pending_bool = False
self.is_confirmed_bool = True
return Order(oid, gid, cid, symbol, mts_create, mts_update, amount,
amount_orig, o_type, type_prev, flags, status, price, price_avg,
price_trailing, price_aux_limit, notfiy, place_id)
def set_open_state(self, isOpen):
self.is_open_bool = isOpen
def set_confirmed(self):
"""
Set the state of the order to be confirmed
"""
self.is_pending_bool = False
self.is_confirmed_bool = True
def isOpen(self):
return self.is_open_bool
def set_open_state(self, is_open):
"""
Set the is_open state of the order
"""
self.is_open_bool = is_open
def isPending(self):
return self.is_pending_bool
def is_open(self):
"""
Check if the order is still open
def isConfirmed(self):
return self.is_confirmed_bool
def __str__(self):
''' Allow us to print the Order object in a pretty format '''
return "Order <'{}' mtsCreate={} status='{}' id={}>".format(self.symbol, self.mtsCreate,
self.status, self.id)
@return bool: Ture if order open else False
"""
return self.is_open_bool
def is_pending(self):
"""
Check if the state of the order is still pending
@return bool: True if is pending else False
"""
return self.is_pending_bool
def is_confirmed(self):
"""
Check if the order has been confirmed by the bitfinex api
@return bool: True if has been confirmed else False
"""
return self.is_confirmed_bool
def __str__(self):
''' Allow us to print the Order object in a pretty format '''
text = "Order <'{}' mts_create={} status='{}' id={}>"
return text.format(self.symbol, self.mts_create, self.status, self.id)

View File

@@ -1,90 +0,0 @@
import zlib
def preparePrice(price):
# convert to 4 significant figures
prepPrice = '{0:.4f}'.format(price)
# remove decimal place if zero float
return '{0:g}'.format(float(prepPrice))
class OrderBook:
def __init__(self):
self.asks = []
self.bids = []
def get_bids(self):
return self.bids
def get_asks(self):
return self.asks
def updateFromSnapshot(self, data):
# [[4642.3, 1, 4.192], [4641.5, 1, 1]]
for order in data:
if len(order) is 4:
if order[3] < 0:
self.bids += [order]
else:
self.asks += [order]
else:
if order[2] < 0:
self.asks += [order]
else:
self.bids += [order]
def updateWith(self, order):
if len(order) is 4:
amount = order[3]
count = order[2]
side = self.bids if amount < 0 else self.asks
else:
amount = order[2]
side = self.asks if amount < 0 else self.bids
count = order[1]
price = order[0]
# if first item in ordebook
if len(side) is 0:
side += [order]
return
# match price level
for index, sOrder in enumerate(side):
sPrice = sOrder[0]
if sPrice == price:
if count is 0:
del side[index]
return
else:
# remove but add as new below
del side[index]
# if ob is initialised w/o all price levels
if count is 0:
return
# add to book and sort lowest to highest
side += [order]
side.sort(key=lambda x: x[0], reverse=not amount < 0)
return
def checksum(self):
data = []
# take set of top 25 bids/asks
for index in range(0, 25):
if index < len(self.bids):
bid = self.bids[index]
price = bid[0]
amount = bid[3] if len(bid) is 4 else bid[2]
data += [preparePrice(price)]
data += [str(amount)]
if index < len(self.asks):
ask = self.asks[index]
price = ask[0]
amount = ask[3] if len(ask) is 4 else ask[2]
data += [preparePrice(price)]
data += [str(amount)]
checksumStr = ':'.join(data)
# calculate checksum and force signed integer
checksum = zlib.crc32(checksumStr.encode('utf8')) & 0xffffffff
return checksum

View File

@@ -1,36 +1,47 @@
"""
Module used to describe all of the different data types
"""
class Position:
"""
SYMBOL string Pair (tBTCUSD, ).
STATUS string Status (ACTIVE, CLOSED).
±AMOUNT float Size of the position. Positive values means a long position, negative values means a short position.
BASE_PRICE float The price at which you entered your position.
MARGIN_FUNDING float The amount of funding being used for this position.
MARGIN_FUNDING_TYPE int 0 for daily, 1 for term.
PL float Profit & Loss
PL_PERC float Profit & Loss Percentage
PRICE_LIQ float Liquidation price
LEVERAGE float Beta value
"""
"""
SYMBOL string Pair (tBTCUSD, ...).
STATUS string Status (ACTIVE, CLOSED).
AMOUNT float Size of the position. Positive values means a long position,
negative values means a short position.
BASE_PRICE float The price at which you entered your position.
MARGIN_FUNDING float The amount of funding being used for this position.
MARGIN_FUNDING_TYPE int 0 for daily, 1 for term.
PL float Profit & Loss
PL_PERC float Profit & Loss Percentage
PRICE_LIQ float Liquidation price
LEVERAGE float Beta value
"""
def __init__(self, symbol, status, amount, bPrice, mFunding, mFundingType,
profit_loss, profit_loss_perc, lPrice, lev):
self.symbol = symbol
self.status = status
self.amount = amount
self.base_price = bPrice
self.margin_funding = mFunding
self.margin_funding_type = mFundingType
self.profit_loss = profit_loss
self.profit_loss_percentage = profit_loss_perc
self.liquidation_price = lPrice
self.leverage = lev
def __init__(self, symbol, status, amount, b_price, m_funding, m_funding_type,
profit_loss, profit_loss_perc, l_price, lev):
self.symbol = symbol
self.status = status
self.amount = amount
self.base_price = b_price
self.margin_funding = m_funding
self.margin_funding_type = m_funding_type
self.profit_loss = profit_loss
self.profit_loss_percentage = profit_loss_perc
self.liquidation_price = l_price
self.leverage = lev
@staticmethod
def from_raw_rest_position(raw_position):
return Position(*raw_position)
def __str__(self):
''' Allow us to print the Trade object in a pretty format '''
return "Position '{}' {} x {} <Sstatus='{}' p&l={}>".format(
self.symbol, self.base_price, self.amount, self.status, self.profit_loss)
@staticmethod
def from_raw_rest_position(raw_position):
"""
Generate a Position object from a raw position array
@return Position
"""
return Position(*raw_position)
def __str__(self):
''' Allow us to print the Trade object in a pretty format '''
text = "Position '{}' {} x {} <status='{}' pl={}>"
return text.format(self.symbol, self.base_price, self.amount,
self.status, self.profit_loss)

View File

@@ -1,45 +1,74 @@
"""
Module used to describe all of the different data types
"""
import time
import json
class Subscription:
"""
Object used to represent an individual subscription to the websocket.
This class also exposes certain functions which helps to manage the subscription
such as unsibscribe and subscribe.
"""
def __init__(self, ws, channel_name, symbol, timeframe=None, **kwargs):
self.ws = ws
self.channel_name = channel_name
self.symbol = symbol
self.timeframe = timeframe
self.is_subscribed_bool = False
self.key = None
if timeframe:
self.key = 'trade:{}:{}'.format(self.timeframe, self.symbol)
self.sub_id = int(round(time.time() * 1000))
self.send_payload = self._generate_payload(**kwargs)
def __init__(self, ws, channel_name, symbol, timeframe=None, **kwargs):
self._ws = ws
self.channel_name = channel_name
self.symbol = symbol
self.timeframe = timeframe
self.is_subscribed_bool = False
self.key = None
self.chan_id = None
if timeframe:
self.key = 'trade:{}:{}'.format(self.timeframe, self.symbol)
self.sub_id = int(round(time.time() * 1000))
self.send_payload = self._generate_payload(**kwargs)
async def subscribe(self):
await self.ws.send(json.dumps(self.get_send_payload()))
def confirm_subscription(self, chan_id):
"""
Update the subscription to confirmed state
"""
self.is_subscribed_bool = True
self.chan_id = chan_id
async def unsubscribe(self):
if not self.is_subscribed():
raise Exception("Subscription is not subscribed to websocket")
payload = { 'event': 'unsubscribe', 'chanId': self.chanId }
await self.ws.send(json.dumps(payload))
async def unsubscribe(self):
"""
Send an unsubscription request to the bitfinex socket
"""
if not self.is_subscribed():
raise Exception("Subscription is not subscribed to websocket")
payload = {'event': 'unsubscribe', 'chan_id': self.chan_id}
await self._ws.send(json.dumps(payload))
def confirm_subscription(self, chanId):
self.is_subscribed_bool = True
self.chanId = chanId
async def subscribe(self):
"""
Send a subscription request to the bitfinex socket
"""
await self._ws.send(json.dumps(self._get_send_payload()))
def confirm_unsubscribe(self):
self.is_subscribed_bool = False
def confirm_unsubscribe(self):
"""
Update the subscription to unsubscribed state
"""
self.is_subscribed_bool = False
def is_subscribed(self):
return self.is_subscribed_bool
def is_subscribed(self):
"""
Check if the subscription is currently subscribed
def _generate_payload(self, **kwargs):
payload = { 'event': 'subscribe', 'channel': self.channel_name, 'symbol': self.symbol }
if self.timeframe:
payload['key'] = self.key
payload.update(**kwargs)
return payload
@return bool: True if subscribed else False
"""
return self.is_subscribed_bool
def get_send_payload(self):
return self.send_payload
def _generate_payload(self, **kwargs):
payload = {'event': 'subscribe',
'channel': self.channel_name, 'symbol': self.symbol}
if self.timeframe:
payload['key'] = self.key
payload.update(**kwargs)
return payload
def _get_send_payload(self):
return self.send_payload

View File

@@ -1,44 +1,54 @@
"""
Module used to describe all of the different data types
"""
import datetime
class Trade:
"""
ID integer Trade database id
PAIR string Pair (BTCUSD, )
MTS_CREATE integer Execution timestamp
ORDER_ID integer Order id
EXEC_AMOUNT float Positive means buy, negative means sell
EXEC_PRICE float Execution price
ORDER_TYPE string Order type
ORDER_PRICE float Order price
MAKER int 1 if true, 0 if false
FEE float Fee
FEE_CURRENCY string Fee currency
"""
"""
ID integer Trade database id
PAIR string Pair (BTCUSD, ...)
MTS_CREATE integer Execution timestamp
ORDER_ID integer Order id
EXEC_AMOUNT float Positive means buy, negative means sell
EXEC_PRICE float Execution price
ORDER_TYPE string Order type
ORDER_PRICE float Order price
MAKER int 1 if true, 0 if false
FEE float Fee
FEE_CURRENCY string Fee currency
"""
SHORT = 'SHORT'
LONG = 'LONG'
SHORT = 'SHORT'
LONG = 'LONG'
def __init__(self, id, pair, mts_create, order_id, amount, price, order_type,
order_price, maker, fee, fee_currency):
self.id = id
self.pair = pair
self.mts_create = mts_create
self.date = datetime.datetime.fromtimestamp(mts_create/1000.0)
self.order_id = order_id
self.amount = amount
self.direction = Trade.SHORT if amount < 0 else Trade.LONG
self.price = price
self.order_type = order_type
self.order_price = order_price
self.maker = maker
self.fee = fee
self.fee_currency = fee_currency
def __init__(self, tid, pair, mts_create, order_id, amount, price, order_type,
order_price, maker, fee, fee_currency):
# pylint: disable=invalid-name
self.id = tid
self.pair = pair
self.mts_create = mts_create
self.date = datetime.datetime.fromtimestamp(mts_create/1000.0)
self.order_id = order_id
self.amount = amount
self.direction = Trade.SHORT if amount < 0 else Trade.LONG
self.price = price
self.order_type = order_type
self.order_price = order_price
self.maker = maker
self.fee = fee
self.fee_currency = fee_currency
@staticmethod
def from_raw_rest_trade(raw_trade):
# [24224048, 'tBTCUSD', 1542800024000, 1151353484, 0.09399997, 19963, None, None, -1, -0.000188, 'BTC']
return Trade(*raw_trade)
def __str__(self):
return "Trade '{}' x {} @ {} <direction='{}' fee={}>".format(
self.pair, self.amount, self.price, self.direction, self.fee)
@staticmethod
def from_raw_rest_trade(raw_trade):
"""
Generate a Trade object from a raw trade array
"""
# [24224048, 'tBTCUSD', 1542800024000, 1151353484, 0.09399997, 19963, None, None,
# -1, -0.000188, 'BTC']
return Trade(*raw_trade)
def __str__(self):
return "Trade '{}' x {} @ {} <direction='{}' fee={}>".format(
self.pair, self.amount, self.price, self.direction, self.fee)

View File

@@ -1,19 +1,33 @@
"""
Module used to describe all of the different data types
"""
class Wallet:
"""
Stores data relevant to a users wallet such as balance and
currency
"""
def __init__(self, wType, currency, balance, unsettled_interest):
self.type = wType
self.currency = currency
self.balance = balance
self.unsettled_interest = unsettled_interest
self.key = "{}_{}".format(wType, currency)
def __init__(self, wType, currency, balance, unsettled_interest):
self.type = wType
self.currency = currency
self.balance = balance
self.unsettled_interest = unsettled_interest
self.key = "{}_{}".format(wType, currency)
def set_balance(self, data):
self.balance = data
def set_balance(self, data):
"""
Set the balance of the wallet
"""
self.balance = data
def set_unsettled_interest(self, data):
self.unsettled_interest = data
def set_unsettled_interest(self, data):
"""
Set the unsettled interest of the wallet
"""
self.unsettled_interest = data
def __str__(self):
return "Wallet <'{}_{}' balance='{}' unsettled='{}'>".format(
self.type, self.currency, self.balance, self.unsettled_interest)
def __str__(self):
return "Wallet <'{}_{}' balance='{}' unsettled='{}'>".format(
self.type, self.currency, self.balance, self.unsettled_interest)

View File

@@ -1,11 +1,16 @@
name = 'models'
"""
This module contains a group of different models which
are used to define data types
"""
from .Order import *
from .Trade import *
from .OrderBook import *
from .Subscription import *
from .Wallet import *
from .Position import *
from .FundingLoan import *
from .FundingOffer import *
from .FundingCredit import *
from .order import Order
from .trade import Trade
from .order_book import OrderBook
from .subscription import Subscription
from .wallet import Wallet
from .position import Position
from .funding_loan import FundingLoan
from .funding_offer import FundingOffer
from .funding_credit import FundingCredit
NAME = 'models'

View File

@@ -0,0 +1,104 @@
"""
Module used to describe all of the different data types
"""
class FundingCreditModel:
"""
Enum used to index the location of each value in a raw array
"""
ID = 0
SYMBOL = 1
SIDE = 2
MTS_CREATE = 3
MTS_UPDATE = 4
AMOUNT = 5
FLAGS = 6
STATUS = 7
RATE = 11
PERIOD = 12
MTS_OPENING = 13
MTS_LAST_PAYOUT = 14
NOTIFY = 15
HIDDEN = 16
RENEW = 18
NO_CLOSE = 20
POSITION_PAIR = 21
class FundingCredit:
"""
ID integer Offer ID
SYMBOL string The currency of the offer (fUSD, etc)
SIDE string "Lend" or "Loan"
MTS_CREATE int Millisecond Time Stamp when the offer was created
MSG_UPDATE int Millisecond Time Stamp when the offer was updated
AMOUNT float Amount the offer is for
FLAGS object future params object (stay tuned)
STATUS string Offer Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
RATE float Rate of the offer
PERIOD int Period of the offer
MTS_OPENING int Millisecond Time Stamp when funding opened
MTS_LAST_PAYOUT int Millisecond Time Stamp when last payout received
NOTIFY int 0 if false, 1 if true
HIDDEN int 0 if false, 1 if true
RENEW int 0 if false, 1 if true
NO_CLOSE int 0 if false, 1 if true Whether the funding will be closed when the
position is closed
POSITION_PAIR string Pair of the position that the funding was used for
"""
def __init__(self, fid, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close,
position_pair):
# pylint: disable=invalid-name
self.id = fid
self.symbol = symbol
self.side = side
self.mts_create = mts_create
self.mts_update = mts_update
self.amount = amount
self.flags = flags
self.status = status
self.rate = rate
self.period = period
self.mts_opening = mts_opening
self.mts_last_payout = mts_last_payout
self.notify = notify
self.hidden = hidden
self.renew = renew
self.no_close = no_close
self.position_pair = position_pair
@staticmethod
def from_raw_credit(raw_credit):
"""
Parse a raw credit object into a FundingCredit object
@return FundingCredit
"""
fid = raw_credit[FundingCreditModel.ID]
symbol = raw_credit[FundingCreditModel.SYMBOL]
side = raw_credit[FundingCreditModel.SIDE]
mts_create = raw_credit[FundingCreditModel.MTS_CREATE]
mts_update = raw_credit[FundingCreditModel.MTS_UPDATE]
amount = raw_credit[FundingCreditModel.AMOUNT]
flags = raw_credit[FundingCreditModel.FLAGS]
status = raw_credit[FundingCreditModel.STATUS]
rate = raw_credit[FundingCreditModel.RATE]
period = raw_credit[FundingCreditModel.PERIOD]
mts_opening = raw_credit[FundingCreditModel.MTS_OPENING]
mts_last_payout = raw_credit[FundingCreditModel.MTS_LAST_PAYOUT]
notify = raw_credit[FundingCreditModel.NOTIFY]
hidden = raw_credit[FundingCreditModel.HIDDEN]
renew = raw_credit[FundingCreditModel.RENEW]
no_close = raw_credit[FundingCreditModel.NO_CLOSE]
position_pair = raw_credit[FundingCreditModel.POSITION_PAIR]
return FundingCredit(fid, symbol, side, mts_create, mts_update, amount,
flags, status, rate, period, mts_opening, mts_last_payout,
notify, hidden, renew, no_close, position_pair)
def __str__(self):
string = "FundingCredit '{}' <id={} rate={} amount={} period={} status='{}'>"
return string.format(self.symbol, self.id, self.rate, self.amount,
self.period, self.status)

View File

@@ -0,0 +1,96 @@
"""
Module used to describe all of the different data types
"""
class FundingLoanModel:
"""
Enum used to index the location of each value in a raw array
"""
ID = 0
SYMBOL = 1
SIDE = 2
MTS_CREATE = 3
MTS_UPDATE = 4
AMOUNT = 5
FLAGS = 6
STATUS = 7
RATE = 11
PERIOD = 12
MTS_OPENING = 13
MTS_LAST_PAYOUT = 14
NOTIFY = 15
HIDDEN = 16
RENEW = 18
NO_CLOSE = 20
class FundingLoan:
"""
ID integer Offer ID
SYMBOL string The currency of the offer (fUSD, etc)
SIDE string "Lend" or "Loan"
MTS_CREATE int Millisecond Time Stamp when the offer was created
MTS_UPDATE int Millisecond Time Stamp when the offer was created
AMOUNT float Amount the offer is for
FLAGS object future params object (stay tuned)
STATUS string Offer Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
RATE float Rate of the offer
PERIOD int Period of the offer
MTS_OPENING int Millisecond Time Stamp for when the loan was opened
MTS_LAST_PAYOUT int Millisecond Time Stamp for when the last payout was made
NOTIFY int 0 if false, 1 if true
HIDDEN int 0 if false, 1 if true
RENEW int 0 if false, 1 if true
NO_CLOSE int If funding will be returned when position is closed. 0 if false, 1 if true
"""
def __init__(self, fid, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close):
# pylint: disable=invalid-name
self.id = fid
self.symbol = symbol
self.side = side
self.mts_create = mts_create
self.mts_update = mts_update
self.amount = amount
self.flags = flags
self.status = status
self.rate = rate
self.period = period
self.mts_opening = mts_opening
self.mts_last_payout = mts_last_payout
self.notify = notify
self.hidden = hidden
self.renew = renew
self.no_close = no_close
@staticmethod
def from_raw_loan(raw_loan):
"""
Parse a raw funding load into a FundingLoan object
@return FundingLoan
"""
fid = raw_loan[FundingLoanModel.ID]
symbol = raw_loan[FundingLoanModel.SYMBOL]
side = raw_loan[FundingLoanModel.SIDE]
mts_create = raw_loan[FundingLoanModel.MTS_CREATE]
mts_update = raw_loan[FundingLoanModel.MTS_UPDATE]
amount = raw_loan[FundingLoanModel.AMOUNT]
flags = raw_loan[FundingLoanModel.FLAGS]
status = raw_loan[FundingLoanModel.STATUS]
rate = raw_loan[FundingLoanModel.RATE]
period = raw_loan[FundingLoanModel.PERIOD]
mts_opening = raw_loan[FundingLoanModel.MTS_OPENING]
mts_last_payout = raw_loan[FundingLoanModel.MTS_LAST_PAYOUT]
notify = raw_loan[FundingLoanModel.NOTIFY]
hidden = raw_loan[FundingLoanModel.HIDDEN]
renew = raw_loan[FundingLoanModel.RENEW]
no_close = raw_loan[FundingLoanModel.NO_CLOSE]
return FundingLoan(fid, symbol, side, mts_create, mts_update, amount, flags, status, rate,
period, mts_opening, mts_last_payout, notify, hidden, renew, no_close)
def __str__(self):
return "FundingLoan '{}' <id={} rate={} amount={} period={} status='{}'>".format(
self.symbol, self.id, self.rate, self.amount, self.period, self.status)

View File

@@ -0,0 +1,88 @@
"""
Module used to describe all of the different data types
"""
class FundingOfferModel:
"""
Enum used to index the location of each value in a raw array
"""
ID = 0
SYMBOL = 1
MTS_CREATE = 2
MTS_UPDATED = 3
AMOUNT = 4
AMOUNT_ORIG = 5
TYPE = 6
FLAGS = 9
STATUS = 10
RATE = 14
PERIOD = 15
NOTFIY = 16
HIDDEN = 17
RENEW = 19
class FundingOffer:
"""
ID integer Offer ID
SYMBOL string The currency of the offer (fUSD, etc)
MTS_CREATED int Millisecond Time Stamp when the offer was created
MSG_UPDATED int Millisecond Time Stamp when the offer was created
AMOUNT float Amount the offer is for
AMOUNT_ORIG float Amount the offer was entered with originally
TYPE string "lend" or "loan"
FLAGS object future params object (stay tuned)
STATUS string Offer Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
RATE float Rate of the offer
PERIOD int Period of the offer
NOTIFY int 0 if false, 1 if true
HIDDEN int 0 if false, 1 if true
RENEW int 0 if false, 1 if true
"""
def __init__(self, fid, symbol, mts_create, mts_updated, amount, amount_orig, f_type,
flags, status, rate, period, notify, hidden, renew):
# pylint: disable=invalid-name
self.id = fid
self.symbol = symbol
self.mts_create = mts_create
self.mts_updated = mts_updated
self.amount = amount
self.amount_orig = amount_orig
self.f_type = f_type
self.flags = flags
self.status = status
self.rate = rate
self.period = period
self.notify = notify
self.hidden = hidden
self.renew = renew
@staticmethod
def from_raw_offer(raw_offer):
"""
Parse a raw funding offer into a RawFunding object
@return FundingOffer
"""
oid = raw_offer[FundingOfferModel.ID]
symbol = raw_offer[FundingOfferModel.SYMBOL]
mts_create = raw_offer[FundingOfferModel.MTS_CREATE]
mts_updated = raw_offer[FundingOfferModel.MTS_UPDATED]
amount = raw_offer[FundingOfferModel.AMOUNT]
amount_orig = raw_offer[FundingOfferModel.AMOUNT_ORIG]
f_type = raw_offer[FundingOfferModel.TYPE]
flags = raw_offer[FundingOfferModel.FLAGS]
status = raw_offer[FundingOfferModel.STATUS]
rate = raw_offer[FundingOfferModel.RATE]
period = raw_offer[FundingOfferModel.PERIOD]
notify = raw_offer[FundingOfferModel.NOTFIY]
hidden = raw_offer[FundingOfferModel.HIDDEN]
renew = raw_offer[FundingOfferModel.RENEW]
return FundingOffer(oid, symbol, mts_create, mts_updated, amount,
amount_orig, f_type, flags, status, rate, period, notify, hidden, renew)
def __str__(self):
return "FundingOffer '{}' <id={} rate={} period={} status='{}'>".format(
self.symbol, self.id, self.rate, self.period, self.status)

221
bfxapi/models/order.py Normal file
View File

@@ -0,0 +1,221 @@
"""
Module used to describe all of the different data types
"""
import time
import datetime
class OrderType:
"""
Enum used to describe all of the different order types available for use
"""
MARKET = 'MARKET'
LIMIT = 'LIMIT'
STOP = 'STOP'
STOP_LIMIT = 'STOP LIMIT'
TRAILING_STOP = 'TRAILING STOP'
FILL_OR_KILL = 'FOK'
EXCHANGE_MARKET = 'EXCHANGE MARKET'
EXCHANGE_LIMIT = 'EXCHANGE LIMIT'
EXCHANGE_STOP = 'EXCHANGE STOP'
EXCHANGE_STOP_LIMIT = 'EXCHANGE STOP LIMIT'
EXCHANGE_TRAILING_STOP = 'EXCHANGE TRAILING STOP'
EXCHANGE_FILL_OR_KILL = 'EXCHANGE FOK'
LIMIT_ORDERS = [OrderType.LIMIT, OrderType.STOP_LIMIT, OrderType.EXCHANGE_LIMIT,
OrderType.EXCHANGE_STOP_LIMIT, OrderType.FILL_OR_KILL,
OrderType.EXCHANGE_FILL_OR_KILL]
class OrderSide:
"""
Enum used to describe the different directions of an order
"""
BUY = 'buy'
SELL = 'sell'
class OrderClosedModel:
"""
Enum used ad an index match to locate the different values in a
raw order array
"""
ID = 0
GID = 1
CID = 2
SYMBOL = 3
MTS_CREATE = 4
MTS_UPDATE = 5
AMOUNT = 6
AMOUNT_ORIG = 7
TYPE = 8
TYPE_PREV = 9
FLAGS = 12
STATUS = 13
PRICE = 16
PRIVE_AVG = 17
PRICE_TRAILING = 18
PRICE_AUX_LIMIT = 19
NOTIFY = 23
PLACE_ID = 25
class OrderFlags:
"""
Enum used to explain the different values that can be passed in
as flags
"""
HIDDEN = 64
CLOSE = 12
REDUCE_ONLY = 1024
POST_ONLY = 4096
OCO = 16384
def now_in_mills():
"""
Gets the current time in milliseconds
"""
return int(round(time.time() * 1000))
class Order:
"""
ID int64 Order ID
GID int Group ID
CID int Client Order ID
SYMBOL string Pair (tBTCUSD, ...)
MTS_CREATE int Millisecond timestamp of creation
MTS_UPDATE int Millisecond timestamp of update
AMOUNT float Positive means buy, negative means sell.
AMOUNT_ORIG float Original amount
TYPE string The type of the order: LIMIT, MARKET, STOP, TRAILING STOP,
EXCHANGE MARKET, EXCHANGE LIMIT, EXCHANGE STOP, EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK.
TYPE_PREV string Previous order type
FLAGS int Upcoming Params Object (stay tuned)
ORDER_STATUS string Order Status: ACTIVE, EXECUTED, PARTIALLY FILLED, CANCELED
PRICE float Price
PRICE_AVG float Average price
PRICE_TRAILING float The trailing price
PRICE_AUX_LIMIT float Auxiliary Limit price (for STOP LIMIT)
HIDDEN int 1 if Hidden, 0 if not hidden
PLACED_ID int If another order caused this order to be placed (OCO) this will be that other
order's ID
"""
Type = OrderType()
Side = OrderSide()
Flags = OrderFlags()
def __init__(self, oid, gid, cid, symbol, mts_create, mts_update, amount,
amount_orig, o_type, typePrev, flags, status, price, price_avg,
price_trailing, price_aux_limit, notfiy, place_id):
# pylint: disable=invalid-name
self.id = oid
self.gid = gid
self.cid = cid
self.symbol = symbol
self.mts_create = mts_create
self.mts_update = mts_update
# self.amount = amount
self.amount = amount
self.amount_orig = amount_orig
self.type = o_type
self.type_prev = typePrev
self.flags = flags
self.status = status
self.price = price
self.price_avg = price_avg
self.price_trailing = price_trailing
self.price_aux_limit = price_aux_limit
self.notfiy = notfiy
self.place_id = place_id
self.tag = ""
self.fee = 0
self.is_pending_bool = True
self.is_confirmed_bool = False
self.is_open_bool = False
self.date = datetime.datetime.fromtimestamp(mts_create/1000.0)
# if cancelled then priceAvg wont exist
if price_avg:
# check if order is taker or maker
if self.type in LIMIT_ORDERS:
self.fee = (price_avg * abs(amount)) * 0.001
else:
self.fee = (price_avg * abs(amount)) * 0.002
@staticmethod
def from_raw_order(raw_order):
"""
Parse a raw order object into an Order oject
@return Order
"""
oid = raw_order[OrderClosedModel.ID]
gid = raw_order[OrderClosedModel.GID]
cid = raw_order[OrderClosedModel.CID]
symbol = raw_order[OrderClosedModel.SYMBOL]
mts_create = raw_order[OrderClosedModel.MTS_CREATE]
mts_update = raw_order[OrderClosedModel.MTS_UPDATE]
amount = raw_order[OrderClosedModel.AMOUNT]
amount_orig = raw_order[OrderClosedModel.AMOUNT_ORIG]
o_type = raw_order[OrderClosedModel.TYPE]
type_prev = raw_order[OrderClosedModel.TYPE_PREV]
flags = raw_order[OrderClosedModel.FLAGS]
status = raw_order[OrderClosedModel.STATUS]
price = raw_order[OrderClosedModel.PRICE]
price_avg = raw_order[OrderClosedModel.PRIVE_AVG]
price_trailing = raw_order[OrderClosedModel.PRICE_TRAILING]
price_aux_limit = raw_order[OrderClosedModel.PRICE_AUX_LIMIT]
notfiy = raw_order[OrderClosedModel.NOTIFY]
place_id = raw_order[OrderClosedModel.PLACE_ID]
return Order(oid, gid, cid, symbol, mts_create, mts_update, amount,
amount_orig, o_type, type_prev, flags, status, price, price_avg,
price_trailing, price_aux_limit, notfiy, place_id)
def set_confirmed(self):
"""
Set the state of the order to be confirmed
"""
self.is_pending_bool = False
self.is_confirmed_bool = True
def set_open_state(self, is_open):
"""
Set the is_open state of the order
"""
self.is_open_bool = is_open
def is_open(self):
"""
Check if the order is still open
@return bool: Ture if order open else False
"""
return self.is_open_bool
def is_pending(self):
"""
Check if the state of the order is still pending
@return bool: True if is pending else False
"""
return self.is_pending_bool
def is_confirmed(self):
"""
Check if the order has been confirmed by the bitfinex api
@return bool: True if has been confirmed else False
"""
return self.is_confirmed_bool
def __str__(self):
''' Allow us to print the Order object in a pretty format '''
text = "Order <'{}' mts_create={} status='{}' id={}>"
return text.format(self.symbol, self.mts_create, self.status, self.id)

121
bfxapi/models/order_book.py Normal file
View File

@@ -0,0 +1,121 @@
"""
Module used to describe all of the different data types
"""
import zlib
def prepare_price(price):
"""
Convert the price to an acceptable format
"""
# convert to 4 significant figures
prep_price = '{0:.4f}'.format(price)
# remove decimal place if zero float
return '{0:g}'.format(float(prep_price))
class OrderBook:
"""
Object used to store the state of the orderbook. This can then be used
in one of two ways. To get the checksum of the book or so get the bids/asks
of the book
"""
def __init__(self):
self.asks = []
self.bids = []
def get_bids(self):
"""
Get all of the bids from the orderbook
@return bids Array
"""
return self.bids
def get_asks(self):
"""
Get all of the asks from the orderbook
@return asks Array
"""
return self.asks
def update_from_snapshot(self, data):
"""
Update the orderbook with a raw orderbook snapshot
"""
for order in data:
if len(order) == 4:
if order[3] < 0:
self.bids += [order]
else:
self.asks += [order]
else:
if order[2] < 0:
self.asks += [order]
else:
self.bids += [order]
def update_with(self, order):
"""
Update the orderbook with a single update
"""
if len(order) == 4:
amount = order[3]
count = order[2]
side = self.bids if amount < 0 else self.asks
else:
amount = order[2]
side = self.asks if amount < 0 else self.bids
count = order[1]
price = order[0]
# if first item in ordebook
if len(side) == 0:
side += [order]
return
# match price level
for index, s_order in enumerate(side):
s_price = s_order[0]
if s_price == price:
if count == 0:
del side[index]
return
# remove but add as new below
del side[index]
# if ob is initialised w/o all price levels
if count == 0:
return
# add to book and sort lowest to highest
side += [order]
side.sort(key=lambda x: x[0], reverse=not amount < 0)
return
def checksum(self):
"""
Generate a CRC32 checksum of the orderbook
"""
data = []
# take set of top 25 bids/asks
for index in range(0, 25):
if index < len(self.bids):
bid = self.bids[index]
price = bid[0]
amount = bid[3] if len(bid) == 4 else bid[2]
data += [prepare_price(price)]
data += [str(amount)]
if index < len(self.asks):
ask = self.asks[index]
price = ask[0]
amount = ask[3] if len(ask) == 4 else ask[2]
data += [prepare_price(price)]
data += [str(amount)]
checksum_str = ':'.join(data)
# calculate checksum and force signed integer
checksum = zlib.crc32(checksum_str.encode('utf8')) & 0xffffffff
return checksum

47
bfxapi/models/position.py Normal file
View File

@@ -0,0 +1,47 @@
"""
Module used to describe all of the different data types
"""
class Position:
"""
SYMBOL string Pair (tBTCUSD, ...).
STATUS string Status (ACTIVE, CLOSED).
AMOUNT float Size of the position. Positive values means a long position,
negative values means a short position.
BASE_PRICE float The price at which you entered your position.
MARGIN_FUNDING float The amount of funding being used for this position.
MARGIN_FUNDING_TYPE int 0 for daily, 1 for term.
PL float Profit & Loss
PL_PERC float Profit & Loss Percentage
PRICE_LIQ float Liquidation price
LEVERAGE float Beta value
"""
def __init__(self, symbol, status, amount, b_price, m_funding, m_funding_type,
profit_loss, profit_loss_perc, l_price, lev):
self.symbol = symbol
self.status = status
self.amount = amount
self.base_price = b_price
self.margin_funding = m_funding
self.margin_funding_type = m_funding_type
self.profit_loss = profit_loss
self.profit_loss_percentage = profit_loss_perc
self.liquidation_price = l_price
self.leverage = lev
@staticmethod
def from_raw_rest_position(raw_position):
"""
Generate a Position object from a raw position array
@return Position
"""
return Position(*raw_position)
def __str__(self):
''' Allow us to print the Trade object in a pretty format '''
text = "Position '{}' {} x {} <status='{}' pl={}>"
return text.format(self.symbol, self.base_price, self.amount,
self.status, self.profit_loss)

View File

@@ -0,0 +1,74 @@
"""
Module used to describe all of the different data types
"""
import time
import json
class Subscription:
"""
Object used to represent an individual subscription to the websocket.
This class also exposes certain functions which helps to manage the subscription
such as unsibscribe and subscribe.
"""
def __init__(self, ws, channel_name, symbol, timeframe=None, **kwargs):
self._ws = ws
self.channel_name = channel_name
self.symbol = symbol
self.timeframe = timeframe
self.is_subscribed_bool = False
self.key = None
self.chan_id = None
if timeframe:
self.key = 'trade:{}:{}'.format(self.timeframe, self.symbol)
self.sub_id = int(round(time.time() * 1000))
self.send_payload = self._generate_payload(**kwargs)
def confirm_subscription(self, chan_id):
"""
Update the subscription to confirmed state
"""
self.is_subscribed_bool = True
self.chan_id = chan_id
async def unsubscribe(self):
"""
Send an unsubscription request to the bitfinex socket
"""
if not self.is_subscribed():
raise Exception("Subscription is not subscribed to websocket")
payload = {'event': 'unsubscribe', 'chan_id': self.chan_id}
await self._ws.send(json.dumps(payload))
async def subscribe(self):
"""
Send a subscription request to the bitfinex socket
"""
await self._ws.send(json.dumps(self._get_send_payload()))
def confirm_unsubscribe(self):
"""
Update the subscription to unsubscribed state
"""
self.is_subscribed_bool = False
def is_subscribed(self):
"""
Check if the subscription is currently subscribed
@return bool: True if subscribed else False
"""
return self.is_subscribed_bool
def _generate_payload(self, **kwargs):
payload = {'event': 'subscribe',
'channel': self.channel_name, 'symbol': self.symbol}
if self.timeframe:
payload['key'] = self.key
payload.update(**kwargs)
return payload
def _get_send_payload(self):
return self.send_payload

54
bfxapi/models/trade.py Normal file
View File

@@ -0,0 +1,54 @@
"""
Module used to describe all of the different data types
"""
import datetime
class Trade:
"""
ID integer Trade database id
PAIR string Pair (BTCUSD, ...)
MTS_CREATE integer Execution timestamp
ORDER_ID integer Order id
EXEC_AMOUNT float Positive means buy, negative means sell
EXEC_PRICE float Execution price
ORDER_TYPE string Order type
ORDER_PRICE float Order price
MAKER int 1 if true, 0 if false
FEE float Fee
FEE_CURRENCY string Fee currency
"""
SHORT = 'SHORT'
LONG = 'LONG'
def __init__(self, tid, pair, mts_create, order_id, amount, price, order_type,
order_price, maker, fee, fee_currency):
# pylint: disable=invalid-name
self.id = tid
self.pair = pair
self.mts_create = mts_create
self.date = datetime.datetime.fromtimestamp(mts_create/1000.0)
self.order_id = order_id
self.amount = amount
self.direction = Trade.SHORT if amount < 0 else Trade.LONG
self.price = price
self.order_type = order_type
self.order_price = order_price
self.maker = maker
self.fee = fee
self.fee_currency = fee_currency
@staticmethod
def from_raw_rest_trade(raw_trade):
"""
Generate a Trade object from a raw trade array
"""
# [24224048, 'tBTCUSD', 1542800024000, 1151353484, 0.09399997, 19963, None, None,
# -1, -0.000188, 'BTC']
return Trade(*raw_trade)
def __str__(self):
return "Trade '{}' x {} @ {} <direction='{}' fee={}>".format(
self.pair, self.amount, self.price, self.direction, self.fee)

33
bfxapi/models/wallet.py Normal file
View File

@@ -0,0 +1,33 @@
"""
Module used to describe all of the different data types
"""
class Wallet:
"""
Stores data relevant to a users wallet such as balance and
currency
"""
def __init__(self, wType, currency, balance, unsettled_interest):
self.type = wType
self.currency = currency
self.balance = balance
self.unsettled_interest = unsettled_interest
self.key = "{}_{}".format(wType, currency)
def set_balance(self, data):
"""
Set the balance of the wallet
"""
self.balance = data
def set_unsettled_interest(self, data):
"""
Set the unsettled interest of the wallet
"""
self.unsettled_interest = data
def __str__(self):
return "Wallet <'{}_{}' balance='{}' unsettled='{}'>".format(
self.type, self.currency, self.balance, self.unsettled_interest)