diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-01-20 13:44:30 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-01-20 14:15:53 +0100 |
commit | 5ab23e1c86de4caf0a34b9b91e5b9eddb0efa222 (patch) | |
tree | b44fffede07dfde6d832f533a877e156d4e0dc2d | |
parent | 089d5d9df3d9d93e3ce789be16ee6cdd99dc2b52 (diff) | |
download | Trader-5ab23e1c86de4caf0a34b9b91e5b9eddb0efa222.tar.gz Trader-5ab23e1c86de4caf0a34b9b91e5b9eddb0efa222.tar.zst Trader-5ab23e1c86de4caf0a34b9b91e5b9eddb0efa222.zip |
Change integer to decimals
-rw-r--r-- | market.py | 51 | ||||
-rw-r--r-- | portfolio.py | 50 | ||||
-rw-r--r-- | test.py | 100 |
3 files changed, 118 insertions, 83 deletions
@@ -1,5 +1,56 @@ | |||
1 | import ccxt | 1 | import ccxt |
2 | import decimal | ||
2 | 3 | ||
4 | def exchange_sum(self, *args): | ||
5 | return sum([arg for arg in args if isinstance(arg, (float, int, decimal.Decimal))]) | ||
6 | ccxt.Exchange.sum = exchange_sum | ||
7 | def poloniex_fetch_balance(self, params={}): | ||
8 | self.load_markets() | ||
9 | balances = self.privatePostReturnCompleteBalances(self.extend({ | ||
10 | 'account': 'all', | ||
11 | }, params)) | ||
12 | result = {'info': balances} | ||
13 | currencies = list(balances.keys()) | ||
14 | for c in range(0, len(currencies)): | ||
15 | id = currencies[c] | ||
16 | balance = balances[id] | ||
17 | currency = self.common_currency_code(id) | ||
18 | account = { | ||
19 | 'free': decimal.Decimal(balance['available']), | ||
20 | 'used': decimal.Decimal(balance['onOrders']), | ||
21 | 'total': decimal.Decimal(0.0), | ||
22 | } | ||
23 | account['total'] = self.sum(account['free'], account['used']) | ||
24 | result[currency] = account | ||
25 | return self.parse_balance(result) | ||
26 | ccxt.poloniex.fetch_balance = poloniex_fetch_balance | ||
27 | |||
28 | def poloniex_parse_ticker(self, ticker, market=None): | ||
29 | timestamp = self.milliseconds() | ||
30 | symbol = None | ||
31 | if market: | ||
32 | symbol = market['symbol'] | ||
33 | return { | ||
34 | 'symbol': symbol, | ||
35 | 'timestamp': timestamp, | ||
36 | 'datetime': self.iso8601(timestamp), | ||
37 | 'high': decimal.Decimal(ticker['high24hr']), | ||
38 | 'low': decimal.Decimal(ticker['low24hr']), | ||
39 | 'bid': decimal.Decimal(ticker['highestBid']), | ||
40 | 'ask': decimal.Decimal(ticker['lowestAsk']), | ||
41 | 'vwap': None, | ||
42 | 'open': None, | ||
43 | 'close': None, | ||
44 | 'first': None, | ||
45 | 'last': decimal.Decimal(ticker['last']), | ||
46 | 'change': decimal.Decimal(ticker['percentChange']), | ||
47 | 'percentage': None, | ||
48 | 'average': None, | ||
49 | 'baseVolume': decimal.Decimal(ticker['quoteVolume']), | ||
50 | 'quoteVolume': decimal.Decimal(ticker['baseVolume']), | ||
51 | 'info': ticker, | ||
52 | } | ||
53 | ccxt.poloniex.parse_ticker = poloniex_parse_ticker | ||
3 | market = ccxt.poloniex({ | 54 | market = ccxt.poloniex({ |
4 | "apiKey": "XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX", | 55 | "apiKey": "XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX", |
5 | "secret": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", | 56 | "secret": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", |
diff --git a/portfolio.py b/portfolio.py index b0f9256..e1ee1f8 100644 --- a/portfolio.py +++ b/portfolio.py | |||
@@ -1,5 +1,6 @@ | |||
1 | import ccxt | 1 | import ccxt |
2 | import time | 2 | import time |
3 | from decimal import Decimal as D | ||
3 | # Put your poloniex api key in market.py | 4 | # Put your poloniex api key in market.py |
4 | from market import market | 5 | from market import market |
5 | 6 | ||
@@ -37,7 +38,9 @@ class Portfolio: | |||
37 | except Exception: | 38 | except Exception: |
38 | return | 39 | return |
39 | try: | 40 | try: |
40 | cls.data = json.loads(r.data) | 41 | cls.data = json.loads(r.data, |
42 | parse_int=D, | ||
43 | parse_float=D) | ||
41 | except json.JSONDecodeError: | 44 | except json.JSONDecodeError: |
42 | cls.data = None | 45 | cls.data = None |
43 | 46 | ||
@@ -83,22 +86,15 @@ class Portfolio: | |||
83 | class Amount: | 86 | class Amount: |
84 | MAX_DIGITS = 18 | 87 | MAX_DIGITS = 18 |
85 | 88 | ||
86 | def __init__(self, currency, value, int_val=None, linked_to=None, ticker=None): | 89 | def __init__(self, currency, value, linked_to=None, ticker=None): |
87 | self.currency = currency | 90 | self.currency = currency |
88 | if int_val is None: | 91 | self.value = D(value) |
89 | self._value = int(value * 10**self.MAX_DIGITS) | ||
90 | else: | ||
91 | self._value = int_val | ||
92 | self.linked_to = linked_to | 92 | self.linked_to = linked_to |
93 | self.ticker = ticker | 93 | self.ticker = ticker |
94 | 94 | ||
95 | self.ticker_cache = {} | 95 | self.ticker_cache = {} |
96 | self.ticker_cache_timestamp = time.time() | 96 | self.ticker_cache_timestamp = time.time() |
97 | 97 | ||
98 | @property | ||
99 | def value(self): | ||
100 | return self._value / 10 ** self.MAX_DIGITS | ||
101 | |||
102 | def in_currency(self, other_currency, market, action="average"): | 98 | def in_currency(self, other_currency, market, action="average"): |
103 | if other_currency == self.currency: | 99 | if other_currency == self.currency: |
104 | return self | 100 | return self |
@@ -106,20 +102,19 @@ class Amount: | |||
106 | if asset_ticker is not None: | 102 | if asset_ticker is not None: |
107 | return Amount( | 103 | return Amount( |
108 | other_currency, | 104 | other_currency, |
109 | 0, | 105 | self.value * asset_ticker[action], |
110 | int_val=int(self._value * asset_ticker[action]), | ||
111 | linked_to=self, | 106 | linked_to=self, |
112 | ticker=asset_ticker) | 107 | ticker=asset_ticker) |
113 | else: | 108 | else: |
114 | raise Exception("This asset is not available in the chosen market") | 109 | raise Exception("This asset is not available in the chosen market") |
115 | 110 | ||
116 | def __abs__(self): | 111 | def __abs__(self): |
117 | return Amount(self.currency, 0, int_val=abs(self._value)) | 112 | return Amount(self.currency, abs(self.value)) |
118 | 113 | ||
119 | def __add__(self, other): | 114 | def __add__(self, other): |
120 | if other.currency != self.currency and other._value * self._value != 0: | 115 | if other.currency != self.currency and other.value * self.value != 0: |
121 | raise Exception("Summing amounts must be done with same currencies") | 116 | raise Exception("Summing amounts must be done with same currencies") |
122 | return Amount(self.currency, 0, int_val=self._value + other._value) | 117 | return Amount(self.currency, self.value + other.value) |
123 | 118 | ||
124 | def __radd__(self, other): | 119 | def __radd__(self, other): |
125 | if other == 0: | 120 | if other == 0: |
@@ -128,25 +123,22 @@ class Amount: | |||
128 | return self.__add__(other) | 123 | return self.__add__(other) |
129 | 124 | ||
130 | def __sub__(self, other): | 125 | def __sub__(self, other): |
131 | if other.currency != self.currency and other._value * self._value != 0: | 126 | if other.currency != self.currency and other.value * self.value != 0: |
132 | raise Exception("Summing amounts must be done with same currencies") | 127 | raise Exception("Summing amounts must be done with same currencies") |
133 | return Amount(self.currency, 0, int_val=self._value - other._value) | 128 | return Amount(self.currency, self.value - other.value) |
134 | |||
135 | def __int__(self): | ||
136 | return self._value | ||
137 | 129 | ||
138 | def __mul__(self, value): | 130 | def __mul__(self, value): |
139 | if type(value) != int and type(value) != float: | 131 | if type(value) != int and type(value) != float and type(value) != D: |
140 | raise TypeError("Amount may only be multiplied by numbers") | 132 | raise TypeError("Amount may only be multiplied by numbers") |
141 | return Amount(self.currency, 0, int_val=(self._value * value)) | 133 | return Amount(self.currency, self.value * value) |
142 | 134 | ||
143 | def __rmul__(self, value): | 135 | def __rmul__(self, value): |
144 | return self.__mul__(value) | 136 | return self.__mul__(value) |
145 | 137 | ||
146 | def __floordiv__(self, value): | 138 | def __floordiv__(self, value): |
147 | if type(value) != int: | 139 | if type(value) != int and type(value) != float and type(value) != D: |
148 | raise TypeError("Amount may only be multiplied by integers") | 140 | raise TypeError("Amount may only be multiplied by integers") |
149 | return Amount(self.currency, 0, int_val=(self._value // value)) | 141 | return Amount(self.currency, self.value / value) |
150 | 142 | ||
151 | def __truediv__(self, value): | 143 | def __truediv__(self, value): |
152 | return self.__floordiv__(value) | 144 | return self.__floordiv__(value) |
@@ -154,14 +146,14 @@ class Amount: | |||
154 | def __lt__(self, other): | 146 | def __lt__(self, other): |
155 | if self.currency != other.currency: | 147 | if self.currency != other.currency: |
156 | raise Exception("Comparing amounts must be done with same currencies") | 148 | raise Exception("Comparing amounts must be done with same currencies") |
157 | return self._value < other._value | 149 | return self.value < other.value |
158 | 150 | ||
159 | def __eq__(self, other): | 151 | def __eq__(self, other): |
160 | if other == 0: | 152 | if other == 0: |
161 | return self._value == 0 | 153 | return self.value == 0 |
162 | if self.currency != other.currency: | 154 | if self.currency != other.currency: |
163 | raise Exception("Comparing amounts must be done with same currencies") | 155 | raise Exception("Comparing amounts must be done with same currencies") |
164 | return self._value == other._value | 156 | return self.value == other.value |
165 | 157 | ||
166 | def __str__(self): | 158 | def __str__(self): |
167 | if self.linked_to is None: | 159 | if self.linked_to is None: |
@@ -266,7 +258,7 @@ class Trade: | |||
266 | def invert(ticker): | 258 | def invert(ticker): |
267 | return { | 259 | return { |
268 | "inverted": True, | 260 | "inverted": True, |
269 | "average": (float(1/ticker["bid"]) + float(1/ticker["ask"]) ) / 2, | 261 | "average": (1/ticker["bid"] + 1/ticker["ask"]) / 2, |
270 | "original": ticker, | 262 | "original": ticker, |
271 | } | 263 | } |
272 | def augment_ticker(ticker): | 264 | def augment_ticker(ticker): |
@@ -416,6 +408,8 @@ class Order: | |||
416 | 408 | ||
417 | def print_orders(market, base_currency="BTC"): | 409 | def print_orders(market, base_currency="BTC"): |
418 | Balance.prepare_trades(market, base_currency=base_currency) | 410 | Balance.prepare_trades(market, base_currency=base_currency) |
411 | for currency, balance in Balance.known_balances.items(): | ||
412 | print(balance) | ||
419 | for currency, trade in Trade.trades.items(): | 413 | for currency, trade in Trade.trades.items(): |
420 | print(trade) | 414 | print(trade) |
421 | for order in trade.orders: | 415 | for order in trade.orders: |
@@ -1,16 +1,14 @@ | |||
1 | import portfolio | 1 | import portfolio |
2 | import unittest | 2 | import unittest |
3 | from decimal import Decimal as D | ||
3 | from unittest import mock | 4 | from unittest import mock |
4 | 5 | ||
5 | class AmountTest(unittest.TestCase): | 6 | class AmountTest(unittest.TestCase): |
6 | def test_values(self): | 7 | def test_values(self): |
7 | amount = portfolio.Amount("BTC", 0.65) | 8 | amount = portfolio.Amount("BTC", "0.65") |
8 | self.assertEqual(0.65, amount.value) | 9 | self.assertEqual(D("0.65"), amount.value) |
9 | self.assertEqual("BTC", amount.currency) | 10 | self.assertEqual("BTC", amount.currency) |
10 | 11 | ||
11 | amount = portfolio.Amount("BTC", 10, int_val=2000000000000000) | ||
12 | self.assertEqual(0.002, amount.value) | ||
13 | |||
14 | def test_in_currency(self): | 12 | def test_in_currency(self): |
15 | amount = portfolio.Amount("ETC", 10) | 13 | amount = portfolio.Amount("ETC", 10) |
16 | 14 | ||
@@ -24,12 +22,12 @@ class AmountTest(unittest.TestCase): | |||
24 | 22 | ||
25 | with mock.patch.object(portfolio.Trade, 'get_ticker', new=ticker_mock): | 23 | with mock.patch.object(portfolio.Trade, 'get_ticker', new=ticker_mock): |
26 | ticker_mock.return_value = { | 24 | ticker_mock.return_value = { |
27 | "average": 0.3, | 25 | "average": D("0.3"), |
28 | "foo": "bar", | 26 | "foo": "bar", |
29 | } | 27 | } |
30 | converted_amount = amount.in_currency("ETH", None) | 28 | converted_amount = amount.in_currency("ETH", None) |
31 | 29 | ||
32 | self.assertEqual(3.0, converted_amount.value) | 30 | self.assertEqual(D("3.0"), converted_amount.value) |
33 | self.assertEqual("ETH", converted_amount.currency) | 31 | self.assertEqual("ETH", converted_amount.currency) |
34 | self.assertEqual(amount, converted_amount.linked_to) | 32 | self.assertEqual(amount, converted_amount.linked_to) |
35 | self.assertEqual("bar", converted_amount.ticker["foo"]) | 33 | self.assertEqual("bar", converted_amount.ticker["foo"]) |
@@ -44,13 +42,13 @@ class AmountTest(unittest.TestCase): | |||
44 | self.assertEqual("SC", abs(amount).currency) | 42 | self.assertEqual("SC", abs(amount).currency) |
45 | 43 | ||
46 | def test__add(self): | 44 | def test__add(self): |
47 | amount1 = portfolio.Amount("XVG", 12.9) | 45 | amount1 = portfolio.Amount("XVG", "12.9") |
48 | amount2 = portfolio.Amount("XVG", 13.1) | 46 | amount2 = portfolio.Amount("XVG", "13.1") |
49 | 47 | ||
50 | self.assertEqual(26, (amount1 + amount2).value) | 48 | self.assertEqual(26, (amount1 + amount2).value) |
51 | self.assertEqual("XVG", (amount1 + amount2).currency) | 49 | self.assertEqual("XVG", (amount1 + amount2).currency) |
52 | 50 | ||
53 | amount3 = portfolio.Amount("ETH", 1.6) | 51 | amount3 = portfolio.Amount("ETH", "1.6") |
54 | with self.assertRaises(Exception): | 52 | with self.assertRaises(Exception): |
55 | amount1 + amount3 | 53 | amount1 + amount3 |
56 | 54 | ||
@@ -58,35 +56,31 @@ class AmountTest(unittest.TestCase): | |||
58 | self.assertEqual(amount1, amount1 + amount4) | 56 | self.assertEqual(amount1, amount1 + amount4) |
59 | 57 | ||
60 | def test__radd(self): | 58 | def test__radd(self): |
61 | amount = portfolio.Amount("XVG", 12.9) | 59 | amount = portfolio.Amount("XVG", "12.9") |
62 | 60 | ||
63 | self.assertEqual(amount, 0 + amount) | 61 | self.assertEqual(amount, 0 + amount) |
64 | with self.assertRaises(Exception): | 62 | with self.assertRaises(Exception): |
65 | 4 + amount | 63 | 4 + amount |
66 | 64 | ||
67 | def test__sub(self): | 65 | def test__sub(self): |
68 | amount1 = portfolio.Amount("XVG", 13.3) | 66 | amount1 = portfolio.Amount("XVG", "13.3") |
69 | amount2 = portfolio.Amount("XVG", 13.1) | 67 | amount2 = portfolio.Amount("XVG", "13.1") |
70 | 68 | ||
71 | self.assertEqual(0.2, (amount1 - amount2).value) | 69 | self.assertEqual(D("0.2"), (amount1 - amount2).value) |
72 | self.assertEqual("XVG", (amount1 - amount2).currency) | 70 | self.assertEqual("XVG", (amount1 - amount2).currency) |
73 | 71 | ||
74 | amount3 = portfolio.Amount("ETH", 1.6) | 72 | amount3 = portfolio.Amount("ETH", "1.6") |
75 | with self.assertRaises(Exception): | 73 | with self.assertRaises(Exception): |
76 | amount1 - amount3 | 74 | amount1 - amount3 |
77 | 75 | ||
78 | amount4 = portfolio.Amount("ETH", 0.0) | 76 | amount4 = portfolio.Amount("ETH", 0.0) |
79 | self.assertEqual(amount1, amount1 - amount4) | 77 | self.assertEqual(amount1, amount1 - amount4) |
80 | 78 | ||
81 | def test__int(self): | ||
82 | amount = portfolio.Amount("XMR", 0.1) | ||
83 | self.assertEqual(100000000000000000, int(amount)) | ||
84 | |||
85 | def test__mul(self): | 79 | def test__mul(self): |
86 | amount = portfolio.Amount("XEM", 11) | 80 | amount = portfolio.Amount("XEM", 11) |
87 | 81 | ||
88 | self.assertEqual(38.5, (amount * 3.5).value) | 82 | self.assertEqual(D("38.5"), (amount * D("3.5")).value) |
89 | self.assertEqual(33, (amount * 3).value) | 83 | self.assertEqual(D("33"), (amount * 3).value) |
90 | 84 | ||
91 | with self.assertRaises(Exception): | 85 | with self.assertRaises(Exception): |
92 | amount * amount | 86 | amount * amount |
@@ -94,24 +88,20 @@ class AmountTest(unittest.TestCase): | |||
94 | def test__rmul(self): | 88 | def test__rmul(self): |
95 | amount = portfolio.Amount("XEM", 11) | 89 | amount = portfolio.Amount("XEM", 11) |
96 | 90 | ||
97 | self.assertEqual(38.5, (3.5 * amount).value) | 91 | self.assertEqual(D("38.5"), (D("3.5") * amount).value) |
98 | self.assertEqual(33, (3 * amount).value) | 92 | self.assertEqual(D("33"), (3 * amount).value) |
99 | 93 | ||
100 | def test__floordiv(self): | 94 | def test__floordiv(self): |
101 | amount = portfolio.Amount("XEM", 11) | 95 | amount = portfolio.Amount("XEM", 11) |
102 | 96 | ||
103 | self.assertEqual(5.5, (amount // 2).value) | 97 | self.assertEqual(D("5.5"), (amount / 2).value) |
104 | with self.assertRaises(TypeError): | 98 | self.assertEqual(D("4.4"), (amount / D("2.5")).value) |
105 | amount // 2.5 | ||
106 | self.assertEqual(1571428571428571428, (amount // 7)._value) | ||
107 | 99 | ||
108 | def test__div(self): | 100 | def test__div(self): |
109 | amount = portfolio.Amount("XEM", 11) | 101 | amount = portfolio.Amount("XEM", 11) |
110 | 102 | ||
111 | with self.assertRaises(TypeError): | 103 | self.assertEqual(D("5.5"), (amount / 2).value) |
112 | amount / 2.5 | 104 | self.assertEqual(D("4.4"), (amount / D("2.5")).value) |
113 | self.assertEqual(5.5, (amount / 2).value) | ||
114 | self.assertEqual(1571428571428571428, (amount / 7)._value) | ||
115 | 105 | ||
116 | def test__lt(self): | 106 | def test__lt(self): |
117 | amount1 = portfolio.Amount("BTD", 11.3) | 107 | amount1 = portfolio.Amount("BTD", 11.3) |
@@ -290,32 +280,32 @@ class BalanceTest(unittest.TestCase): | |||
290 | @mock.patch.object(portfolio.Trade, "get_ticker") | 280 | @mock.patch.object(portfolio.Trade, "get_ticker") |
291 | def test_in_currency(self, get_ticker): | 281 | def test_in_currency(self, get_ticker): |
292 | portfolio.Balance.known_balances = { | 282 | portfolio.Balance.known_balances = { |
293 | "BTC": portfolio.Balance("BTC", 0.65, 0.35, 0.30), | 283 | "BTC": portfolio.Balance("BTC", "0.65", "0.35", "0.30"), |
294 | "ETH": portfolio.Balance("ETH", 3, 3, 0), | 284 | "ETH": portfolio.Balance("ETH", 3, 3, 0), |
295 | } | 285 | } |
296 | market = mock.Mock() | 286 | market = mock.Mock() |
297 | get_ticker.return_value = { | 287 | get_ticker.return_value = { |
298 | "bid": 0.09, | 288 | "bid": D("0.09"), |
299 | "ask": 0.11, | 289 | "ask": D("0.11"), |
300 | "average": 0.1, | 290 | "average": D("0.1"), |
301 | } | 291 | } |
302 | 292 | ||
303 | amounts = portfolio.Balance.in_currency("BTC", market) | 293 | amounts = portfolio.Balance.in_currency("BTC", market) |
304 | self.assertEqual("BTC", amounts["ETH"].currency) | 294 | self.assertEqual("BTC", amounts["ETH"].currency) |
305 | self.assertEqual(0.65, amounts["BTC"].value) | 295 | self.assertEqual(D("0.65"), amounts["BTC"].value) |
306 | self.assertEqual(0.30, amounts["ETH"].value) | 296 | self.assertEqual(D("0.30"), amounts["ETH"].value) |
307 | 297 | ||
308 | amounts = portfolio.Balance.in_currency("BTC", market, action="bid") | 298 | amounts = portfolio.Balance.in_currency("BTC", market, action="bid") |
309 | self.assertEqual(0.65, amounts["BTC"].value) | 299 | self.assertEqual(D("0.65"), amounts["BTC"].value) |
310 | self.assertEqual(0.27, amounts["ETH"].value) | 300 | self.assertEqual(D("0.27"), amounts["ETH"].value) |
311 | 301 | ||
312 | amounts = portfolio.Balance.in_currency("BTC", market, action="bid", type="used") | 302 | amounts = portfolio.Balance.in_currency("BTC", market, action="bid", type="used") |
313 | self.assertEqual(0.30, amounts["BTC"].value) | 303 | self.assertEqual(D("0.30"), amounts["BTC"].value) |
314 | self.assertEqual(0, amounts["ETH"].value) | 304 | self.assertEqual(0, amounts["ETH"].value) |
315 | 305 | ||
316 | def test_currencies(self): | 306 | def test_currencies(self): |
317 | portfolio.Balance.known_balances = { | 307 | portfolio.Balance.known_balances = { |
318 | "BTC": portfolio.Balance("BTC", 0.65, 0.35, 0.30), | 308 | "BTC": portfolio.Balance("BTC", "0.65", "0.35", "0.30"), |
319 | "ETH": portfolio.Balance("ETH", 3, 3, 0), | 309 | "ETH": portfolio.Balance("ETH", 3, 3, 0), |
320 | } | 310 | } |
321 | self.assertListEqual(["BTC", "ETH"], list(portfolio.Balance.currencies())) | 311 | self.assertListEqual(["BTC", "ETH"], list(portfolio.Balance.currencies())) |
@@ -341,10 +331,10 @@ class BalanceTest(unittest.TestCase): | |||
341 | "BTC": 2600, | 331 | "BTC": 2600, |
342 | } | 332 | } |
343 | 333 | ||
344 | amounts = portfolio.Balance.dispatch_assets(portfolio.Amount("BTC", 10.1)) | 334 | amounts = portfolio.Balance.dispatch_assets(portfolio.Amount("BTC", "10.1")) |
345 | self.assertIn("XEM", portfolio.Balance.currencies()) | 335 | self.assertIn("XEM", portfolio.Balance.currencies()) |
346 | self.assertEqual(2.6, amounts["BTC"].value) | 336 | self.assertEqual(D("2.6"), amounts["BTC"].value) |
347 | self.assertEqual(7.5, amounts["XEM"].value) | 337 | self.assertEqual(D("7.5"), amounts["XEM"].value) |
348 | 338 | ||
349 | @mock.patch.object(portfolio.Portfolio, "repartition_pertenthousand") | 339 | @mock.patch.object(portfolio.Portfolio, "repartition_pertenthousand") |
350 | @mock.patch.object(portfolio.Trade, "get_ticker") | 340 | @mock.patch.object(portfolio.Trade, "get_ticker") |
@@ -355,20 +345,20 @@ class BalanceTest(unittest.TestCase): | |||
355 | "BTC": 2500, | 345 | "BTC": 2500, |
356 | } | 346 | } |
357 | get_ticker.side_effect = [ | 347 | get_ticker.side_effect = [ |
358 | { "average": 0.0001 }, | 348 | { "average": D("0.0001") }, |
359 | { "average": 0.000001 } | 349 | { "average": D("0.000001") } |
360 | ] | 350 | ] |
361 | market = mock.Mock() | 351 | market = mock.Mock() |
362 | market.fetch_balance.return_value = { | 352 | market.fetch_balance.return_value = { |
363 | "USDT": { | 353 | "USDT": { |
364 | "free": 10000.0, | 354 | "free": D("10000.0"), |
365 | "used": 0.0, | 355 | "used": D("0.0"), |
366 | "total": 10000.0 | 356 | "total": D("10000.0") |
367 | }, | 357 | }, |
368 | "XVG": { | 358 | "XVG": { |
369 | "free": 10000.0, | 359 | "free": D("10000.0"), |
370 | "used": 0.0, | 360 | "used": D("0.0"), |
371 | "total": 10000.0 | 361 | "total": D("10000.0") |
372 | }, | 362 | }, |
373 | } | 363 | } |
374 | portfolio.Balance.prepare_trades(market) | 364 | portfolio.Balance.prepare_trades(market) |
@@ -377,9 +367,9 @@ class BalanceTest(unittest.TestCase): | |||
377 | call = compute_trades.call_args | 367 | call = compute_trades.call_args |
378 | self.assertEqual(market, call[1]["market"]) | 368 | self.assertEqual(market, call[1]["market"]) |
379 | self.assertEqual(1, call[0][0]["USDT"].value) | 369 | self.assertEqual(1, call[0][0]["USDT"].value) |
380 | self.assertEqual(0.01, call[0][0]["XVG"].value) | 370 | self.assertEqual(D("0.01"), call[0][0]["XVG"].value) |
381 | self.assertEqual(0.2525, call[0][1]["BTC"].value) | 371 | self.assertEqual(D("0.2525"), call[0][1]["BTC"].value) |
382 | self.assertEqual(0.7575, call[0][1]["XEM"].value) | 372 | self.assertEqual(D("0.7575"), call[0][1]["XEM"].value) |
383 | 373 | ||
384 | def test__repr(self): | 374 | def test__repr(self): |
385 | balance = portfolio.Balance("BTX", 3, 1, 2) | 375 | balance = portfolio.Balance("BTX", 3, 1, 2) |