· 4 years ago · Jun 14, 2021, 10:58 PM
1from ndax.api import Api
2from datetime import datetime
3import time
4
5class Ndax:
6
7 def __init__(self, api_key, secret_key, user_id, user_name):
8 self.__api = Api(api_key, secret_key, user_id, user_name)
9 self.products = {}
10 self.instruments = {}
11
12 self.wallet = {}
13 self.wallet_update_timestamp = None
14
15 self.trades = []
16 self.trades_update_timestamp = None
17
18 def init(self):
19 self.__api.init()
20
21 self.load_products()
22 self.load_instruments()
23 self.update_wallet()
24 self.update_trades()
25
26 def load_products(self):
27 loaded_products = self.__api.get_products()
28 if loaded_products is None:
29 return False
30 self.products = {}
31 for product in loaded_products:
32 id = product["ProductId"]
33 self.products[id] = {
34 "id": id,
35 "name": product["Product"],
36 "longName": product["ProductFullName"],
37 "type": product["ProductType"],
38 }
39
40 def get_product_by_name(self, name):
41 for product in self.products.values():
42 if product["name"] == name:
43 return product
44 return None
45
46 def load_instruments(self):
47 loaded_instruments = self.__api.get_instruments()
48 if loaded_instruments is None:
49 return False
50 self.instruments = {}
51 for instrument in loaded_instruments:
52 id = instrument["InstrumentId"]
53 data = {
54 "id": id,
55 "symbol": instrument["Symbol"],
56 "product1": self.products[instrument["Product1"]],
57 "product2": self.products[instrument["Product2"]],
58 "snapshot": {}
59 }
60 data["name"] = "%s/%s" % (data["product1"]["name"], data["product2"]["name"])
61 self.instruments[id] = data
62 return True
63
64 def get_instrument_by_name(self, name):
65 for instrument in self.instruments.values():
66 if instrument["name"] == name:
67 return instrument
68 return None
69
70 def get_instrument_by_product_pair(self, product1, product2):
71 for instrument in self.instruments.values():
72 if instrument["product1"]["id"] == product1["id"] and instrument["product2"]["id"] == product2["id"]:
73 return instrument
74 return None
75
76 def update_instrument_snapshot(self, instrument):
77 snapshot = self.__api.get_instrument_snapshot(instrument)
78 if not snapshot:
79 return False
80
81 instrument["snapshot"] = {
82 "timestamp": self.__convert_to_local_timestamp(int(snapshot["TimeStamp"]) / 1000),
83 "sellPrice": snapshot["BestBid"],
84 "buyPrice": snapshot["BestOffer"],
85 "open": snapshot["SessionOpen"],
86 "high": snapshot["SessionHigh"],
87 "low": snapshot["SessionLow"],
88 "close": snapshot["SessionClose"],
89 "volume": snapshot["CurrentDayVolume"],
90 "trades": snapshot["CurrentDayNumTrades"],
91 "priceChange": snapshot["CurrentDayPxChange"]
92 }
93 return True
94
95 def update_wallet(self):
96 loaded_account_positions = self.__api.get_account_positions()
97 if loaded_account_positions is None:
98 return False
99
100 cad_product = self.get_product_by_name("CAD")
101 timestamp = self.__format_timestamp(datetime.now())
102
103 for position in loaded_account_positions:
104 product_id = position["ProductId"]
105 product = self.products[product_id]
106 instrument = self.get_instrument_by_product_pair(product, cad_product)
107 if instrument is None:
108 continue
109 self.update_instrument_snapshot(instrument)
110 self.wallet[product_id] = {
111 "product": product,
112 "instrument": instrument,
113 "timestamp": timestamp,
114 "amount": position["Amount"],
115 "onHold": position["Hold"],
116 "value": instrument["snapshot"]["sellPrice"] * position["Amount"]
117 }
118 self.wallet_update_timestamp = timestamp
119 return True
120
121 def update_trades(self):
122 loaded_trades = self.__api.get_account_trades()
123
124 if loaded_trades is None:
125 return False
126
127 self.trades.clear()
128
129 for trade in loaded_trades:
130 instrument = self.instruments[trade["InstrumentId"]]
131 self.trades.append({
132 "id": trade["TradeId"],
133 "orderId": trade["OrderId"],
134 "timestamp": self.__convert_to_local_timestamp(trade["TradeTimeMS"] / 1000, False),
135 "instrument": instrument,
136 "type": trade["Side"],
137 "orderType": trade["OrderType"],
138 "amount": trade["Quantity"],
139 "price": trade["Price"],
140 "value": trade["Value"],
141 "feeAmount": trade["Fee"],
142 "feeValue": trade["Fee"] * trade["Price"]
143 })
144 self.trades_update_timestamp = self.__format_timestamp(datetime.now())
145 return True
146
147 def __format_timestamp(self, timestamp):
148 return timestamp.strftime("%m/%d/%Y %I:%M:%S %p")
149
150 def __convert_to_local_timestamp(self, time_seconds, localize = True):
151 timestamp = datetime.utcfromtimestamp(time_seconds)
152 if localize:
153 timestamp = timestamp + (datetime.fromtimestamp(time.time()) - timestamp)
154 return self.__format_timestamp(timestamp)