diff options
Diffstat (limited to 'portfolio.py')
-rw-r--r-- | portfolio.py | 230 |
1 files changed, 175 insertions, 55 deletions
diff --git a/portfolio.py b/portfolio.py index 0ab16fd..b3065b8 100644 --- a/portfolio.py +++ b/portfolio.py | |||
@@ -3,6 +3,11 @@ import time | |||
3 | from decimal import Decimal as D, ROUND_DOWN | 3 | from decimal import Decimal as D, ROUND_DOWN |
4 | # Put your poloniex api key in market.py | 4 | # Put your poloniex api key in market.py |
5 | from market import market | 5 | from market import market |
6 | from json import JSONDecodeError | ||
7 | import requests | ||
8 | |||
9 | # FIXME: correctly handle web call timeouts | ||
10 | |||
6 | 11 | ||
7 | class Portfolio: | 12 | class Portfolio: |
8 | URL = "https://cryptoportfolio.io/wp-content/uploads/portfolio/json/cryptoportfolio.json" | 13 | URL = "https://cryptoportfolio.io/wp-content/uploads/portfolio/json/cryptoportfolio.json" |
@@ -18,20 +23,13 @@ class Portfolio: | |||
18 | 23 | ||
19 | @classmethod | 24 | @classmethod |
20 | def get_cryptoportfolio(cls): | 25 | def get_cryptoportfolio(cls): |
21 | import json | ||
22 | import urllib3 | ||
23 | urllib3.disable_warnings() | ||
24 | http = urllib3.PoolManager() | ||
25 | |||
26 | try: | 26 | try: |
27 | r = http.request("GET", cls.URL) | 27 | r = requests.get(cls.URL) |
28 | except Exception: | 28 | except Exception: |
29 | return None | 29 | return |
30 | try: | 30 | try: |
31 | cls.data = json.loads(r.data, | 31 | cls.data = r.json(parse_int=D, parse_float=D) |
32 | parse_int=D, | 32 | except JSONDecodeError: |
33 | parse_float=D) | ||
34 | except json.JSONDecodeError: | ||
35 | cls.data = None | 33 | cls.data = None |
36 | 34 | ||
37 | @classmethod | 35 | @classmethod |
@@ -79,9 +77,6 @@ class Amount: | |||
79 | self.ticker = ticker | 77 | self.ticker = ticker |
80 | self.rate = rate | 78 | self.rate = rate |
81 | 79 | ||
82 | self.ticker_cache = {} | ||
83 | self.ticker_cache_timestamp = time.time() | ||
84 | |||
85 | def in_currency(self, other_currency, market, rate=None, action=None, compute_value="average"): | 80 | def in_currency(self, other_currency, market, rate=None, action=None, compute_value="average"): |
86 | if other_currency == self.currency: | 81 | if other_currency == self.currency: |
87 | return self | 82 | return self |
@@ -141,9 +136,6 @@ class Amount: | |||
141 | def __truediv__(self, value): | 136 | def __truediv__(self, value): |
142 | return self.__floordiv__(value) | 137 | return self.__floordiv__(value) |
143 | 138 | ||
144 | def __le__(self, other): | ||
145 | return self == other or self < other | ||
146 | |||
147 | def __lt__(self, other): | 139 | def __lt__(self, other): |
148 | if other == 0: | 140 | if other == 0: |
149 | return self.value < 0 | 141 | return self.value < 0 |
@@ -151,6 +143,9 @@ class Amount: | |||
151 | raise Exception("Comparing amounts must be done with same currencies") | 143 | raise Exception("Comparing amounts must be done with same currencies") |
152 | return self.value < other.value | 144 | return self.value < other.value |
153 | 145 | ||
146 | def __le__(self, other): | ||
147 | return self == other or self < other | ||
148 | |||
154 | def __gt__(self, other): | 149 | def __gt__(self, other): |
155 | return not self <= other | 150 | return not self <= other |
156 | 151 | ||
@@ -192,9 +187,9 @@ class Balance: | |||
192 | "margin_total", "margin_borrowed", "margin_free"]: | 187 | "margin_total", "margin_borrowed", "margin_free"]: |
193 | setattr(self, key, Amount(currency, hash_.get(key, 0))) | 188 | setattr(self, key, Amount(currency, hash_.get(key, 0))) |
194 | 189 | ||
195 | self.margin_position_type = hash_["margin_position_type"] | 190 | self.margin_position_type = hash_.get("margin_position_type") |
196 | 191 | ||
197 | if hash_["margin_borrowed_base_currency"] is not None: | 192 | if hash_.get("margin_borrowed_base_currency") is not None: |
198 | base_currency = hash_["margin_borrowed_base_currency"] | 193 | base_currency = hash_["margin_borrowed_base_currency"] |
199 | for key in [ | 194 | for key in [ |
200 | "margin_liquidation_price", | 195 | "margin_liquidation_price", |
@@ -227,7 +222,6 @@ class Balance: | |||
227 | cls.known_balances[currency] = cls(currency, balance) | 222 | cls.known_balances[currency] = cls(currency, balance) |
228 | return cls.known_balances | 223 | return cls.known_balances |
229 | 224 | ||
230 | |||
231 | @classmethod | 225 | @classmethod |
232 | def dispatch_assets(cls, amount, repartition=None): | 226 | def dispatch_assets(cls, amount, repartition=None): |
233 | if repartition is None: | 227 | if repartition is None: |
@@ -239,34 +233,34 @@ class Balance: | |||
239 | if trade_type == "short": | 233 | if trade_type == "short": |
240 | amounts[currency] = - amounts[currency] | 234 | amounts[currency] = - amounts[currency] |
241 | if currency not in cls.known_balances: | 235 | if currency not in cls.known_balances: |
242 | cls.known_balances[currency] = cls(currency, 0, 0, 0) | 236 | cls.known_balances[currency] = cls(currency, {}) |
243 | return amounts | 237 | return amounts |
244 | 238 | ||
245 | @classmethod | 239 | @classmethod |
246 | def prepare_trades(cls, market, base_currency="BTC", compute_value="average"): | 240 | def prepare_trades(cls, market, base_currency="BTC", compute_value="average", debug=False): |
247 | cls.fetch_balances(market) | 241 | cls.fetch_balances(market) |
248 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) | 242 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) |
249 | total_base_value = sum(values_in_base.values()) | 243 | total_base_value = sum(values_in_base.values()) |
250 | new_repartition = cls.dispatch_assets(total_base_value) | 244 | new_repartition = cls.dispatch_assets(total_base_value) |
251 | # Recompute it in case we have new currencies | 245 | # Recompute it in case we have new currencies |
252 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) | 246 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) |
253 | Trade.compute_trades(values_in_base, new_repartition, market=market) | 247 | Trade.compute_trades(values_in_base, new_repartition, market=market, debug=debug) |
254 | 248 | ||
255 | @classmethod | 249 | @classmethod |
256 | def update_trades(cls, market, base_currency="BTC", compute_value="average", only=None): | 250 | def update_trades(cls, market, base_currency="BTC", compute_value="average", only=None, debug=False): |
257 | cls.fetch_balances(market) | 251 | cls.fetch_balances(market) |
258 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) | 252 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) |
259 | total_base_value = sum(values_in_base.values()) | 253 | total_base_value = sum(values_in_base.values()) |
260 | new_repartition = cls.dispatch_assets(total_base_value) | 254 | new_repartition = cls.dispatch_assets(total_base_value) |
261 | Trade.compute_trades(values_in_base, new_repartition, only=only, market=market) | 255 | Trade.compute_trades(values_in_base, new_repartition, only=only, market=market, debug=debug) |
262 | 256 | ||
263 | @classmethod | 257 | @classmethod |
264 | def prepare_trades_to_sell_all(cls, market, base_currency="BTC", compute_value="average"): | 258 | def prepare_trades_to_sell_all(cls, market, base_currency="BTC", compute_value="average", debug=False): |
265 | cls.fetch_balances(market) | 259 | cls.fetch_balances(market) |
266 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) | 260 | values_in_base = cls.in_currency(base_currency, market, compute_value=compute_value) |
267 | total_base_value = sum(values_in_base.values()) | 261 | total_base_value = sum(values_in_base.values()) |
268 | new_repartition = cls.dispatch_assets(total_base_value, repartition={ base_currency: (1, "long") }) | 262 | new_repartition = cls.dispatch_assets(total_base_value, repartition={ base_currency: (1, "long") }) |
269 | Trade.compute_trades(values_in_base, new_repartition, market=market) | 263 | Trade.compute_trades(values_in_base, new_repartition, market=market, debug=debug) |
270 | 264 | ||
271 | def __repr__(self): | 265 | def __repr__(self): |
272 | if self.exchange_total > 0: | 266 | if self.exchange_total > 0: |
@@ -309,6 +303,7 @@ class Computation: | |||
309 | } | 303 | } |
310 | 304 | ||
311 | class Trade: | 305 | class Trade: |
306 | debug = False | ||
312 | trades = [] | 307 | trades = [] |
313 | 308 | ||
314 | def __init__(self, value_from, value_to, currency, market=None): | 309 | def __init__(self, value_from, value_to, currency, market=None): |
@@ -370,7 +365,8 @@ class Trade: | |||
370 | return cls.get_ticker(c1, c2, market) | 365 | return cls.get_ticker(c1, c2, market) |
371 | 366 | ||
372 | @classmethod | 367 | @classmethod |
373 | def compute_trades(cls, values_in_base, new_repartition, only=None, market=None): | 368 | def compute_trades(cls, values_in_base, new_repartition, only=None, market=None, debug=False): |
369 | cls.debug = cls.debug or debug | ||
374 | base_currency = sum(values_in_base.values()).currency | 370 | base_currency = sum(values_in_base.values()).currency |
375 | for currency in Balance.currencies(): | 371 | for currency in Balance.currencies(): |
376 | if currency == base_currency: | 372 | if currency == base_currency: |
@@ -402,7 +398,7 @@ class Trade: | |||
402 | trade.prepare_order(compute_value=compute_value) | 398 | trade.prepare_order(compute_value=compute_value) |
403 | 399 | ||
404 | @classmethod | 400 | @classmethod |
405 | def move_balances(cls, market, debug=False): | 401 | def move_balances(cls, market): |
406 | needed_in_margin = {} | 402 | needed_in_margin = {} |
407 | for trade in cls.trades: | 403 | for trade in cls.trades: |
408 | if trade.trade_type == "short": | 404 | if trade.trade_type == "short": |
@@ -414,12 +410,12 @@ class Trade: | |||
414 | delta = (needed - current_balance).value | 410 | delta = (needed - current_balance).value |
415 | # FIXME: don't remove too much if there are open margin position | 411 | # FIXME: don't remove too much if there are open margin position |
416 | if delta > 0: | 412 | if delta > 0: |
417 | if debug: | 413 | if cls.debug: |
418 | print("market.transfer_balance({}, {}, 'exchange', 'margin')".format(currency, delta)) | 414 | print("market.transfer_balance({}, {}, 'exchange', 'margin')".format(currency, delta)) |
419 | else: | 415 | else: |
420 | market.transfer_balance(currency, delta, "exchange", "margin") | 416 | market.transfer_balance(currency, delta, "exchange", "margin") |
421 | elif delta < 0: | 417 | elif delta < 0: |
422 | if debug: | 418 | if cls.debug: |
423 | print("market.transfer_balance({}, {}, 'margin', 'exchange')".format(currency, -delta)) | 419 | print("market.transfer_balance({}, {}, 'margin', 'exchange')".format(currency, -delta)) |
424 | else: | 420 | else: |
425 | market.transfer_balance(currency, -delta, "margin", "exchange") | 421 | market.transfer_balance(currency, -delta, "margin", "exchange") |
@@ -449,6 +445,37 @@ class Trade: | |||
449 | else: | 445 | else: |
450 | return "long" | 446 | return "long" |
451 | 447 | ||
448 | @property | ||
449 | def filled_amount(self): | ||
450 | filled_amount = 0 | ||
451 | for order in self.orders: | ||
452 | filled_amount += order.filled_amount | ||
453 | return filled_amount | ||
454 | |||
455 | def update_order(self, order, tick): | ||
456 | new_order = None | ||
457 | if tick in [0, 1, 3, 4, 6]: | ||
458 | print("{}, tick {}, waiting".format(order, tick)) | ||
459 | elif tick == 2: | ||
460 | self.prepare_order(compute_value=lambda x, y: (x[y] + x["average"]) / 2) | ||
461 | new_order = self.orders[-1] | ||
462 | print("{}, tick {}, cancelling and adjusting to {}".format(order, tick, new_order)) | ||
463 | elif tick ==5: | ||
464 | self.prepare_order(compute_value=lambda x, y: (x[y]*2 + x["average"]) / 3) | ||
465 | new_order = self.orders[-1] | ||
466 | print("{}, tick {}, cancelling and adjusting to {}".format(order, tick, new_order)) | ||
467 | elif tick >= 7: | ||
468 | if tick == 7: | ||
469 | print("{}, tick {}, fallbacking to market value".format(order, tick)) | ||
470 | if (tick - 7) % 3 == 0: | ||
471 | self.prepare_order(compute_value="default") | ||
472 | new_order = self.orders[-1] | ||
473 | print("{}, tick {}, market value, cancelling and adjusting to {}".format(order, tick, new_order)) | ||
474 | |||
475 | if new_order is not None: | ||
476 | order.cancel() | ||
477 | new_order.run() | ||
478 | |||
452 | def prepare_order(self, compute_value="default"): | 479 | def prepare_order(self, compute_value="default"): |
453 | if self.action is None: | 480 | if self.action is None: |
454 | return | 481 | return |
@@ -492,12 +519,20 @@ class Trade: | |||
492 | # buy: | 519 | # buy: |
493 | # I want to buy 9 / 0.1 FOO | 520 | # I want to buy 9 / 0.1 FOO |
494 | # Action: "sell" "9 BTC" at rate "1/0.1" "FOO" on "market" | 521 | # Action: "sell" "9 BTC" at rate "1/0.1" "FOO" on "market" |
522 | if self.value_to == 0: | ||
523 | rate = self.value_from.linked_to.value / self.value_from.value | ||
524 | # Recompute the rate to avoid any rounding error | ||
495 | 525 | ||
496 | close_if_possible = (self.value_to == 0) | 526 | close_if_possible = (self.value_to == 0) |
497 | 527 | ||
528 | if delta <= self.filled_amount: | ||
529 | print("Less to do than already filled: {} <= {}".format(delta, | ||
530 | self.filled_amount)) | ||
531 | return | ||
532 | |||
498 | self.orders.append(Order(self.order_action(inverted), | 533 | self.orders.append(Order(self.order_action(inverted), |
499 | delta, rate, currency, self.trade_type, self.market, | 534 | delta - self.filled_amount, rate, currency, self.trade_type, |
500 | close_if_possible=close_if_possible)) | 535 | self.market, self, close_if_possible=close_if_possible)) |
501 | 536 | ||
502 | @classmethod | 537 | @classmethod |
503 | def compute_value(cls, ticker, action, compute_value="default"): | 538 | def compute_value(cls, ticker, action, compute_value="default"): |
@@ -523,18 +558,19 @@ class Trade: | |||
523 | order.run() | 558 | order.run() |
524 | 559 | ||
525 | @classmethod | 560 | @classmethod |
526 | def follow_orders(cls, verbose=True, sleep=30): | 561 | def follow_orders(cls, verbose=True, sleep=None): |
527 | orders = cls.all_orders() | 562 | if sleep is None: |
528 | finished_orders = [] | 563 | sleep = 7 if cls.debug else 30 |
529 | while len(orders) != len(finished_orders): | 564 | tick = 0 |
565 | while len(cls.all_orders(state="open")) > 0: | ||
530 | time.sleep(sleep) | 566 | time.sleep(sleep) |
531 | for order in orders: | 567 | tick += 1 |
532 | if order in finished_orders: | 568 | for order in cls.all_orders(state="open"): |
533 | continue | ||
534 | if order.get_status() != "open": | 569 | if order.get_status() != "open": |
535 | finished_orders.append(order) | ||
536 | if verbose: | 570 | if verbose: |
537 | print("finished {}".format(order)) | 571 | print("finished {}".format(order)) |
572 | else: | ||
573 | order.trade.update_order(order, tick) | ||
538 | if verbose: | 574 | if verbose: |
539 | print("All orders finished") | 575 | print("All orders finished") |
540 | 576 | ||
@@ -562,16 +598,19 @@ class Trade: | |||
562 | 598 | ||
563 | class Order: | 599 | class Order: |
564 | def __init__(self, action, amount, rate, base_currency, trade_type, market, | 600 | def __init__(self, action, amount, rate, base_currency, trade_type, market, |
565 | close_if_possible=False): | 601 | trade, close_if_possible=False): |
566 | self.action = action | 602 | self.action = action |
567 | self.amount = amount | 603 | self.amount = amount |
568 | self.rate = rate | 604 | self.rate = rate |
569 | self.base_currency = base_currency | 605 | self.base_currency = base_currency |
570 | self.market = market | 606 | self.market = market |
571 | self.trade_type = trade_type | 607 | self.trade_type = trade_type |
572 | self.result = None | 608 | self.results = [] |
609 | self.mouvements = [] | ||
573 | self.status = "pending" | 610 | self.status = "pending" |
611 | self.trade = trade | ||
574 | self.close_if_possible = close_if_possible | 612 | self.close_if_possible = close_if_possible |
613 | self.debug = trade.debug | ||
575 | 614 | ||
576 | def __repr__(self): | 615 | def __repr__(self): |
577 | return "Order({} {} {} at {} {} [{}]{})".format( | 616 | return "Order({} {} {} at {} {} [{}]{})".format( |
@@ -599,16 +638,22 @@ class Order: | |||
599 | def finished(self): | 638 | def finished(self): |
600 | return self.status == "closed" or self.status == "canceled" or self.status == "error" | 639 | return self.status == "closed" or self.status == "canceled" or self.status == "error" |
601 | 640 | ||
602 | def run(self, debug=False): | 641 | @property |
642 | def id(self): | ||
643 | return self.results[0]["id"] | ||
644 | |||
645 | def run(self): | ||
603 | symbol = "{}/{}".format(self.amount.currency, self.base_currency) | 646 | symbol = "{}/{}".format(self.amount.currency, self.base_currency) |
604 | amount = round(self.amount, self.market.order_precision(symbol)).value | 647 | amount = round(self.amount, self.market.order_precision(symbol)).value |
605 | 648 | ||
606 | if debug: | 649 | if self.debug: |
607 | print("market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format( | 650 | print("market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format( |
608 | symbol, self.action, amount, self.rate, self.account)) | 651 | symbol, self.action, amount, self.rate, self.account)) |
652 | self.status = "open" | ||
653 | self.results.append({"debug": True, "id": -1}) | ||
609 | else: | 654 | else: |
610 | try: | 655 | try: |
611 | self.result = self.market.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account) | 656 | self.results.append(self.market.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account)) |
612 | self.status = "open" | 657 | self.status = "open" |
613 | except Exception as e: | 658 | except Exception as e: |
614 | self.status = "error" | 659 | self.status = "error" |
@@ -618,22 +663,84 @@ class Order: | |||
618 | print(self.error_message) | 663 | print(self.error_message) |
619 | 664 | ||
620 | def get_status(self): | 665 | def get_status(self): |
666 | if self.debug: | ||
667 | return self.status | ||
621 | # other states are "closed" and "canceled" | 668 | # other states are "closed" and "canceled" |
622 | if self.status == "open": | 669 | if self.status == "open": |
623 | result = self.market.fetch_order(self.result['id']) | 670 | self.fetch() |
624 | if result["status"] != "open": | 671 | if self.status != "open": |
625 | self.mark_finished_order(result["status"]) | 672 | self.mark_finished_order() |
626 | return self.status | 673 | return self.status |
627 | 674 | ||
628 | def mark_finished_order(self, status): | 675 | def mark_finished_order(self): |
629 | if status == "closed": | 676 | if self.debug: |
677 | return | ||
678 | if self.status == "closed": | ||
630 | if self.trade_type == "short" and self.action == "buy" and self.close_if_possible: | 679 | if self.trade_type == "short" and self.action == "buy" and self.close_if_possible: |
631 | self.market.close_margin_position(self.amount.currency, self.base_currency) | 680 | self.market.close_margin_position(self.amount.currency, self.base_currency) |
632 | 681 | ||
682 | fetch_cache_timestamp = None | ||
683 | def fetch(self, force=False): | ||
684 | if self.debug or (not force and self.fetch_cache_timestamp is not None | ||
685 | and time.time() - self.fetch_cache_timestamp < 10): | ||
686 | return | ||
687 | self.fetch_cache_timestamp = time.time() | ||
688 | |||
689 | self.results.append(self.market.fetch_order(self.id)) | ||
690 | result = self.results[-1] | ||
633 | self.status = result["status"] | 691 | self.status = result["status"] |
692 | # Time at which the order started | ||
693 | self.timestamp = result["datetime"] | ||
694 | self.fetch_mouvements() | ||
695 | |||
696 | # FIXME: consider open order with dust remaining as closed | ||
697 | |||
698 | @property | ||
699 | def dust_amount_remaining(self): | ||
700 | return self.remaining_amount < 0.001 | ||
701 | |||
702 | @property | ||
703 | def remaining_amount(self): | ||
704 | if self.status == "open": | ||
705 | self.fetch() | ||
706 | return self.amount - self.filled_amount | ||
707 | |||
708 | @property | ||
709 | def filled_amount(self): | ||
710 | if self.status == "open": | ||
711 | self.fetch() | ||
712 | filled_amount = Amount(self.amount.currency, 0) | ||
713 | for mouvement in self.mouvements: | ||
714 | filled_amount += mouvement.total | ||
715 | return filled_amount | ||
716 | |||
717 | def fetch_mouvements(self): | ||
718 | mouvements = self.market.privatePostReturnOrderTrades({"orderNumber": self.id}) | ||
719 | self.mouvements = [] | ||
720 | |||
721 | for mouvement_hash in mouvements: | ||
722 | self.mouvements.append(Mouvement(self.amount.currency, | ||
723 | self.base_currency, mouvement_hash)) | ||
634 | 724 | ||
635 | def cancel(self): | 725 | def cancel(self): |
726 | if self.debug: | ||
727 | self.status = "canceled" | ||
728 | return | ||
636 | self.market.cancel_order(self.result['id']) | 729 | self.market.cancel_order(self.result['id']) |
730 | self.fetch() | ||
731 | |||
732 | class Mouvement: | ||
733 | def __init__(self, currency, base_currency, hash_): | ||
734 | self.currency = currency | ||
735 | self.base_currency = base_currency | ||
736 | self.id = hash_["id"] | ||
737 | self.action = hash_["type"] | ||
738 | self.fee_rate = D(hash_["fee"]) | ||
739 | self.date = datetime.strptime(hash_["date"], '%Y-%m-%d %H:%M:%S') | ||
740 | self.rate = D(hash_["rate"]) | ||
741 | self.total = Amount(currency, hash_["amount"]) | ||
742 | # rate * total = total_in_base | ||
743 | self.total_in_base = Amount(base_currency, hash_["total"]) | ||
637 | 744 | ||
638 | def print_orders(market, base_currency="BTC"): | 745 | def print_orders(market, base_currency="BTC"): |
639 | Balance.prepare_trades(market, base_currency=base_currency, compute_value="average") | 746 | Balance.prepare_trades(market, base_currency=base_currency, compute_value="average") |
@@ -650,14 +757,27 @@ def make_orders(market, base_currency="BTC"): | |||
650 | print("\t", order, sep="") | 757 | print("\t", order, sep="") |
651 | order.run() | 758 | order.run() |
652 | 759 | ||
653 | def sell_all(market, base_currency="BTC"): | 760 | def process_sell_all_sell(market, base_currency="BTC", debug=False): |
654 | Balance.prepare_trades_to_sell_all(market) | 761 | Balance.prepare_trades_to_sell_all(market, debug=debug) |
655 | Trade.prepare_orders(compute_value="average") | 762 | Trade.prepare_orders(compute_value="average") |
763 | print("------------------") | ||
764 | for currency, balance in Balance.known_balances.items(): | ||
765 | print(balance) | ||
766 | print("------------------") | ||
767 | Trade.print_all_with_order() | ||
768 | print("------------------") | ||
656 | Trade.run_orders() | 769 | Trade.run_orders() |
657 | Trade.follow_orders() | 770 | Trade.follow_orders() |
658 | 771 | ||
659 | Balance.update_trades(market, only="acquire") | 772 | def process_sell_all_buy(market, base_currency="BTC", debug=False): |
660 | Trade.prepare_orders(only="acquire") | 773 | Balance.prepare_trades(market, debug=debug) |
774 | Trade.prepare_orders() | ||
775 | print("------------------") | ||
776 | for currency, balance in Balance.known_balances.items(): | ||
777 | print(balance) | ||
778 | print("------------------") | ||
779 | Trade.print_all_with_order() | ||
780 | print("------------------") | ||
661 | Trade.move_balances(market) | 781 | Trade.move_balances(market) |
662 | Trade.run_orders() | 782 | Trade.run_orders() |
663 | Trade.follow_orders() | 783 | Trade.follow_orders() |