diff options
Diffstat (limited to 'market.py')
-rw-r--r-- | market.py | 69 |
1 files changed, 36 insertions, 33 deletions
@@ -1,7 +1,8 @@ | |||
1 | from ccxt import ExchangeError | 1 | from ccxt import ExchangeError, NotSupported |
2 | import ccxt_wrapper as ccxt | 2 | import ccxt_wrapper as ccxt |
3 | import time | 3 | import time |
4 | from store import * | 4 | from store import * |
5 | from cachetools.func import ttl_cache | ||
5 | 6 | ||
6 | class Market: | 7 | class Market: |
7 | debug = False | 8 | debug = False |
@@ -42,19 +43,17 @@ class Market: | |||
42 | needed_in_margin = {} | 43 | needed_in_margin = {} |
43 | moving_to_margin = {} | 44 | moving_to_margin = {} |
44 | 45 | ||
45 | for currency in self.balances.all: | 46 | for currency, balance in self.balances.all.items(): |
46 | if self.balances.all[currency].margin_free != 0: | 47 | needed_in_margin[currency] = balance.margin_in_position - balance.margin_pending_gain |
47 | needed_in_margin[currency] = 0 | 48 | for trade in self.trades.pending: |
48 | for trade in self.trades.all: | 49 | needed_in_margin.setdefault(trade.base_currency, 0) |
49 | if trade.value_to.currency not in needed_in_margin: | ||
50 | needed_in_margin[trade.value_to.currency] = 0 | ||
51 | if trade.trade_type == "short": | 50 | if trade.trade_type == "short": |
52 | needed_in_margin[trade.value_to.currency] += abs(trade.value_to) | 51 | needed_in_margin[trade.base_currency] -= trade.delta |
53 | for currency, needed in needed_in_margin.items(): | 52 | for currency, needed in needed_in_margin.items(): |
54 | current_balance = self.balances.all[currency].margin_free | 53 | current_balance = self.balances.all[currency].margin_available |
55 | moving_to_margin[currency] = (needed - current_balance) | 54 | moving_to_margin[currency] = (needed - current_balance) |
56 | delta = moving_to_margin[currency].value | 55 | delta = moving_to_margin[currency].value |
57 | if self.debug: | 56 | if self.debug and delta != 0: |
58 | self.report.log_debug_action("Moving {} from exchange to margin".format(moving_to_margin[currency])) | 57 | self.report.log_debug_action("Moving {} from exchange to margin".format(moving_to_margin[currency])) |
59 | continue | 58 | continue |
60 | if delta > 0: | 59 | if delta > 0: |
@@ -65,14 +64,18 @@ class Market: | |||
65 | 64 | ||
66 | self.balances.fetch_balances() | 65 | self.balances.fetch_balances() |
67 | 66 | ||
68 | fees_cache = {} | 67 | @ttl_cache(ttl=3600) |
69 | def fetch_fees(self): | 68 | def fetch_fees(self): |
70 | if self.ccxt.__class__ not in self.fees_cache: | 69 | return self.ccxt.fetch_fees() |
71 | self.fees_cache[self.ccxt.__class__] = self.ccxt.fetch_fees() | 70 | |
72 | return self.fees_cache[self.ccxt.__class__] | 71 | @ttl_cache(maxsize=20, ttl=5) |
72 | def get_tickers(self, refresh=False): | ||
73 | try: | ||
74 | return self.ccxt.fetch_tickers() | ||
75 | except NotSupported: | ||
76 | return None | ||
73 | 77 | ||
74 | ticker_cache = {} | 78 | @ttl_cache(maxsize=20, ttl=5) |
75 | ticker_cache_timestamp = time.time() | ||
76 | def get_ticker(self, c1, c2, refresh=False): | 79 | def get_ticker(self, c1, c2, refresh=False): |
77 | def invert(ticker): | 80 | def invert(ticker): |
78 | return { | 81 | return { |
@@ -86,25 +89,25 @@ class Market: | |||
86 | "average": (ticker["bid"] + ticker["ask"] ) / 2, | 89 | "average": (ticker["bid"] + ticker["ask"] ) / 2, |
87 | }) | 90 | }) |
88 | 91 | ||
89 | if time.time() - self.ticker_cache_timestamp > 5: | 92 | tickers = self.get_tickers() |
90 | self.ticker_cache = {} | 93 | if tickers is None: |
91 | self.ticker_cache_timestamp = time.time() | ||
92 | elif not refresh: | ||
93 | if (c1, c2, self.ccxt.__class__) in self.ticker_cache: | ||
94 | return self.ticker_cache[(c1, c2, self.ccxt.__class__)] | ||
95 | if (c2, c1, self.ccxt.__class__) in self.ticker_cache: | ||
96 | return invert(self.ticker_cache[(c2, c1, self.ccxt.__class__)]) | ||
97 | |||
98 | try: | ||
99 | self.ticker_cache[(c1, c2, self.ccxt.__class__)] = self.ccxt.fetch_ticker("{}/{}".format(c1, c2)) | ||
100 | augment_ticker(self.ticker_cache[(c1, c2, self.ccxt.__class__)]) | ||
101 | except ExchangeError: | ||
102 | try: | 94 | try: |
103 | self.ticker_cache[(c2, c1, self.ccxt.__class__)] = self.ccxt.fetch_ticker("{}/{}".format(c2, c1)) | 95 | ticker = self.ccxt.fetch_ticker("{}/{}".format(c1, c2)) |
104 | augment_ticker(self.ticker_cache[(c2, c1, self.ccxt.__class__)]) | 96 | augment_ticker(ticker) |
105 | except ExchangeError: | 97 | except ExchangeError: |
106 | self.ticker_cache[(c1, c2, self.ccxt.__class__)] = None | 98 | try: |
107 | return self.get_ticker(c1, c2) | 99 | ticker = invert(self.ccxt.fetch_ticker("{}/{}".format(c2, c1))) |
100 | except ExchangeError: | ||
101 | ticker = None | ||
102 | else: | ||
103 | if "{}/{}".format(c1, c2) in tickers: | ||
104 | ticker = tickers["{}/{}".format(c1, c2)] | ||
105 | augment_ticker(ticker) | ||
106 | elif "{}/{}".format(c2, c1) in tickers: | ||
107 | ticker = invert(tickers["{}/{}".format(c2, c1)]) | ||
108 | else: | ||
109 | ticker = None | ||
110 | return ticker | ||
108 | 111 | ||
109 | def follow_orders(self, sleep=None): | 112 | def follow_orders(self, sleep=None): |
110 | if sleep is None: | 113 | if sleep is None: |