Skip to content

Commit a9a38b3

Browse files
authored
Merge pull request #190 from itsdeka/movement
Combined all old unmerged PRs
2 parents ca85fe2 + 04ef752 commit a9a38b3

File tree

9 files changed

+142
-21
lines changed

9 files changed

+142
-21
lines changed

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2.0.0
2+
-) Implemented Movement endpoints (REST)
3+
-) Fixed unawaited stop
4+
-) Changed account's trade execution (te) and trade update (tu) handling
5+
16
1.3.4
27
-) Fixed undefined p_sub issue in subscription_manager.py
38
-) Added submit cancel all funding orders endpoint (REST)

bfxapi/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from .version import __version__
66
from .client import Client
77
from .models import (Order, Trade, OrderBook, Subscription, Wallet,
8-
Position, FundingLoan, FundingOffer, FundingCredit)
8+
Position, FundingLoan, FundingOffer, FundingCredit,
9+
Movement)
910
from .websockets.generic_websocket import GenericWebsocket, Socket
1011
from .websockets.bfx_websocket import BfxWebsocket
1112
from .utils.decimal import Decimal

bfxapi/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
from .funding_trade import FundingTrade
2323
from .margin_info import MarginInfo
2424
from .margin_info_base import MarginInfoBase
25+
from .movement import Movement
2526

2627
NAME = "models"

bfxapi/models/movement.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
Module used to describe movement data types
3+
"""
4+
5+
import time
6+
import datetime
7+
8+
class MovementModel:
9+
"""
10+
Enum used index the different values in a raw movement array
11+
"""
12+
13+
ID = 0
14+
CURRENCY = 1
15+
CURRENCY_NAME = 2
16+
MTS_STARTED = 5
17+
MTS_UPDATED = 6
18+
STATUS = 9
19+
AMOUNT = 12
20+
FEES = 13
21+
DESTINATION_ADDRESS = 16
22+
TRANSACTION_ID = 20
23+
24+
class Movement:
25+
26+
"""
27+
ID String Movement identifier
28+
CURRENCY String The symbol of the currency (ex. "BTC")
29+
CURRENCY_NAME String The extended name of the currency (ex. "BITCOIN")
30+
MTS_STARTED Date Movement started at
31+
MTS_UPDATED Date Movement last updated at
32+
STATUS String Current status
33+
AMOUNT String Amount of funds moved
34+
FEES String Tx Fees applied
35+
DESTINATION_ADDRESS String Destination address
36+
TRANSACTION_ID String Transaction identifier
37+
"""
38+
39+
def __init__(self, mid, currency, mts_started, mts_updated, status, amount, fees, dst_address, tx_id):
40+
self.id = mid
41+
self.currency = currency
42+
self.mts_started = mts_started
43+
self.mts_updated = mts_updated
44+
self.status = status
45+
self.amount = amount
46+
self.fees = fees
47+
self.dst_address = dst_address
48+
self.tx_id = tx_id
49+
50+
self.date = datetime.datetime.fromtimestamp(mts_started/1000.0)
51+
52+
53+
@staticmethod
54+
def from_raw_movement(raw_movement):
55+
"""
56+
Parse a raw movement object into a Movement object
57+
@return Movement
58+
"""
59+
60+
mid = raw_movement[MovementModel.ID]
61+
currency = raw_movement[MovementModel.CURRENCY]
62+
mts_started = raw_movement[MovementModel.MTS_STARTED]
63+
mts_updated = raw_movement[MovementModel.MTS_UPDATED]
64+
status = raw_movement[MovementModel.STATUS]
65+
amount = raw_movement[MovementModel.AMOUNT]
66+
fees = raw_movement[MovementModel.FEES]
67+
dst_address = raw_movement[MovementModel.DESTINATION_ADDRESS]
68+
tx_id = raw_movement[MovementModel.TRANSACTION_ID]
69+
70+
return Movement(mid, currency, mts_started, mts_updated, status, amount, fees, dst_address, tx_id)
71+
72+
def __str__(self):
73+
''' Allow us to print the Movement object in a pretty format '''
74+
text = "Movement <'{}' amount={} fees={} mts_created={} mts_updated={} status='{}' destination_address={} transaction_id={}>"
75+
return text.format(self.currency, self.amount, self.fees,
76+
self.mts_started, self.mts_updated, self.status, self.dst_address, self.tx_id)

bfxapi/rest/bfx_rest.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ..utils.custom_logger import CustomLogger
1212
from ..utils.auth import generate_auth_headers, calculate_order_flags, gen_unique_cid
1313
from ..models import Wallet, Order, Position, Trade, FundingLoan, FundingOffer, FundingTrade, MarginInfoBase, MarginInfo
14-
from ..models import FundingCredit, Notification, Ledger
14+
from ..models import FundingCredit, Notification, Ledger, Movement
1515

1616

1717
class BfxRest:
@@ -609,6 +609,22 @@ async def get_ledgers(self, symbol, start, end, limit=25, category=None):
609609
raw_ledgers = await self.post(endpoint, params=params)
610610
return [Ledger.from_raw_ledger(rl) for rl in raw_ledgers]
611611

612+
async def get_movement_history(self, currency, start="", end="", limit=25):
613+
"""
614+
Get all of the deposits and withdraws between the start and end period associated with API_KEY
615+
- Requires authentication.
616+
# Attributes
617+
@param currency string: pair symbol i.e BTC
618+
@param start int: millisecond start time
619+
@param end int: millisecond end time
620+
@param limit int: max number of items in response
621+
@return Array <models.Movement>
622+
"""
623+
endpoint = "auth/r/movements/{}/hist".format(currency)
624+
params = "?start={}&end={}&limit={}".format(start, end, limit)
625+
raw_movements = await self.post(endpoint, params=params)
626+
return [Movement.from_raw_movement(rm) for rm in raw_movements]
627+
612628
async def submit_funding_offer(self, symbol, amount, rate, period,
613629
funding_type=FundingOffer.Type.LIMIT, hidden=False):
614630
"""

bfxapi/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
This module contains the current version of the bfxapi lib
33
"""
44

5-
__version__ = '1.3.4'
5+
__version__ = '2.0.0'

bfxapi/websockets/bfx_websocket.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,37 @@ def _parse_trade(tData, symbol):
6666
'symbol': symbol
6767
}
6868

69+
def _parse_account_trade(tData):
70+
return {
71+
'id': tData[0],
72+
'symbol': tData[1],
73+
'mts_create': tData[2],
74+
'order_id': tData[3],
75+
'exec_amount': tData[4],
76+
'exec_price': tData[5],
77+
'order_type': tData[6],
78+
'order_price': tData[7],
79+
'maker': tData[8],
80+
'cid': tData[11],
81+
}
82+
83+
84+
def _parse_account_trade_update(tData):
85+
return {
86+
'id': tData[0],
87+
'symbol': tData[1],
88+
'mts_create': tData[2],
89+
'order_id': tData[3],
90+
'exec_amount': tData[4],
91+
'exec_price': tData[5],
92+
'order_type': tData[6],
93+
'order_price': tData[7],
94+
'maker': tData[8],
95+
'fee': tData[9],
96+
'fee_currency': tData[10],
97+
'cid': tData[11],
98+
}
99+
69100
def _parse_deriv_status_update(sData, symbol):
70101
return {
71102
'symbol': symbol,
@@ -278,19 +309,15 @@ async def _system_auth_handler(self, socketId, data):
278309

279310
async def _trade_update_handler(self, data):
280311
tData = data[2]
281-
# [209, 'tu', [312372989, 1542303108930, 0.35, 5688.61834032]]
282-
if self.subscriptionManager.is_subscribed(data[0]):
283-
symbol = self.subscriptionManager.get(data[0]).symbol
284-
tradeObj = _parse_trade(tData, symbol)
285-
self._emit('trade_update', tradeObj)
312+
# [0,"tu",[738045455,"tTESTBTC:TESTUSD",1622169615771,66635385225,0.001,38175,"EXCHANGE LIMIT",39000,-1,-0.000002,"TESTBTC",1622169615685]]
313+
tradeObj = _parse_account_trade_update(tData)
314+
self._emit('trade_update', tradeObj)
286315

287316
async def _trade_executed_handler(self, data):
288317
tData = data[2]
289-
# [209, 'te', [312372989, 1542303108930, 0.35, 5688.61834032]]
290-
if self.subscriptionManager.is_subscribed(data[0]):
291-
symbol = self.subscriptionManager.get(data[0]).symbol
292-
tradeObj = _parse_trade(tData, symbol)
293-
self._emit('new_trade', tradeObj)
318+
# [0,"te",[738045455,"tTESTBTC:TESTUSD",1622169615771,66635385225,0.001,38175,"EXCHANGE LIMIT",39000,-1,null,null,1622169615685]]
319+
tradeObj = _parse_account_trade(tData)
320+
self._emit('new_trade', tradeObj)
294321

295322
async def _wallet_update_handler(self, data):
296323
# [0,"wu",["exchange","USD",89134.66933283,0]]
@@ -409,12 +436,7 @@ async def _trade_handler(self, data):
409436
# connection
410437
data.reverse()
411438
for t in data:
412-
trade = {
413-
'mts': t[1],
414-
'amount': t[2],
415-
'price': t[3],
416-
'symbol': symbol
417-
}
439+
trade = _parse_trade(t, symbol)
418440
self._emit('seed_trade', trade)
419441

420442
async def _candle_handler(self, data):

bfxapi/websockets/generic_websocket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ async def on_close(self):
208208
"""
209209
This is used by the HF data server.
210210
"""
211-
self.stop()
211+
await self.stop()
212212

213213
async def on_open(self):
214214
"""

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
here = path.abspath(path.dirname(__file__))
1212
setup(
1313
name='bitfinex-api-py',
14-
version='1.3.4',
14+
version='2.0.0',
1515
description='Official Bitfinex Python API',
1616
long_description='A Python reference implementation of the Bitfinex API for both REST and websocket interaction',
1717
long_description_content_type='text/markdown',

0 commit comments

Comments
 (0)