def get_trading_cryptocurrencies(self) -> List[Cryptocurrency]: ignored_coinbase_currencies_data = server_get('ignored_coinbase_currencies', default_data={'items': []}).data ignored_coinbase_currencies = ignored_coinbase_currencies_data.get('items') now_ts = pytz.utc.localize(datetime.utcnow()).timestamp() trading_cryptocurrencies_data = server_get('trading_cryptocurrencies', default_data={}).data last_ts = trading_cryptocurrencies_data.get('ts', None) cryptocurrencies = trading_cryptocurrencies_data.get('cryptocurrencies', []) if last_ts is None or now_ts - (3600*24) > last_ts: print(f'REFRESING ACCOUNTS {now_ts} - {last_ts}') accounts = self._client.get_accounts(limit=100).data cryptocurrencies = [] for account in accounts: symbol = account.balance.currency if symbol in ignored_coinbase_currencies: continue cryptocurrencies.append({ 'symbol': symbol, 'metadata': {'id': account.id} }) server_set('trading_cryptocurrencies', { 'ts': now_ts, 'cryptocurrencies': cryptocurrencies }) return [Cryptocurrency(**c) for c in cryptocurrencies]
def get_last_month_prices(self, cryptocurrency: Cryptocurrency) -> List[CryptocurrencyPrice]: if cryptocurrency is None: return [] # return self._get_last_month_prices_remote(cryptocurrency) now = pytz.utc.localize(datetime.utcnow()) current_prices_data = server_get(_get_current_prices_key(), default_data={}).data previous_prices_data = server_get(_get_previous_prices_key(), default_data={}).data current_prices = current_prices_data.get('current_prices', []) current_prices += previous_prices_data.get('current_prices', []) native_prices = [] for price in current_prices: if price['symbol'] != cryptocurrency.symbol: continue instant = pytz.utc.localize(datetime.utcfromtimestamp(price['instant'])) if instant < now - timedelta(days=30): continue native_prices.append(CryptocurrencyPrice( symbol=price['symbol'], instant=instant, sell_price=price['sell_price'], buy_price=price['buy_price'], )) native_prices.sort(key=lambda p: p.instant) return native_prices
def test_server_configurations(self): server_set('key1', {'value': 13}) configuration = server_get('key1') self.assertIn('value', configuration.data) self.assertEqual(configuration.data['value'], 13) self.assertEqual(configuration.key, 'key1')
def fetch_prices(): now = pytz.utc.localize(datetime.utcnow()) if now.minute % 5 != 0: return enable_fetch_prices_data = server_get('enable_fetch_prices', default_data={'activated': False}).data enable_fetch_prices = enable_fetch_prices_data.get('activated') if not enable_fetch_prices: return trading_source: ICryptoCurrencySource = dependency_dispatcher.request_implementation(ICryptoCurrencySource) from trading.application.django_models import DCryptocurrencyPrice for cryptocurrency in trading_source.get_trading_cryptocurrencies(): try: sell_price = trading_source.get_current_sell_price(cryptocurrency) buy_price = trading_source.get_current_buy_price(cryptocurrency) except JSONDecodeError: continue if sell_price is None or buy_price is None: continue now = pytz.utc.localize(datetime.utcnow()) DCryptocurrencyPrice.objects.create( symbol=cryptocurrency.symbol, instant=now, sell_price=sell_price, buy_price=buy_price, )
def reset_trading(): enable_trading_data = server_get('enable_trading', default_data={'activated': False}).data server_set('enable_trading', { 'activated': False }) trading_source: ICryptoCurrencySource = dependency_dispatcher.request_implementation(ICryptoCurrencySource) storage: ILocalStorage = dependency_dispatcher.request_implementation(ILocalStorage) now = pytz.utc.localize(datetime.utcnow()) trading_cryptocurrencies = trading_source.get_trading_cryptocurrencies() trading_source.start_conversions() for currency in trading_cryptocurrencies: amount = trading_source.get_amount_owned(currency) if round(amount) == 0.0: continue prices = trading_source.get_last_month_prices(currency) qs = PricesQueryset(prices) if len(qs.filter_by_last(timedelta(days=30), now=now)) == 0: continue packages = storage.get_cryptocurrency_packages(currency) amount = two_decimals_floor(amount) target = trading_source.get_stable_cryptocurrency() trading_source.convert(currency, amount, target) for package in packages: storage.delete_package(package) trading_source.finish_conversions() server_set('enable_trading', { 'activated': enable_trading_data.get('activated') })
def get_stable_cryptocurrency(self) -> Cryptocurrency: stable_cryptocurrency = server_get('stable_cryptocurrency', default_data={}).data if len(stable_cryptocurrency.keys()) > 0: return Cryptocurrency(**stable_cryptocurrency) account = self._client.get_account('DAI') stable_cryptocurrency = { 'symbol': account.balance.currency, 'metadata': { 'id': account.id } } server_set('stable_cryptocurrency', stable_cryptocurrency) return Cryptocurrency(**stable_cryptocurrency)
def test_non_existent_key(self): configuration = user_get(1, 'non-existent-key') self.assertIsNone(configuration) configuration = server_get('non-existent-server-key') self.assertIsNone(configuration)
def purchase(): enable_trading_data = server_get('enable_trading', default_data={'activated': False}).data enable_trading = enable_trading_data.get('activated') if not enable_trading: return trading_source: ICryptoCurrencySource = dependency_dispatcher.request_implementation(ICryptoCurrencySource) storage: ILocalStorage = dependency_dispatcher.request_implementation(ILocalStorage) source_cryptocurrency = trading_source.get_stable_cryptocurrency() source_amount = trading_source.get_amount_owned(source_cryptocurrency) if round(source_amount) <= 1: return now = pytz.utc.localize(datetime.utcnow()) trading_cryptocurrencies = trading_source.get_trading_cryptocurrencies() purchase_currency_data = [] for currency in trading_cryptocurrencies: prices = trading_source.get_last_month_prices(currency) qs = PricesQueryset(prices) if len(qs.filter_by_last(timedelta(days=30), now=now)) == 0: continue packages = storage.get_cryptocurrency_packages(currency) current_sell_price = prices[-1].sell_price native_total = 0 for package in packages: native_total += package.currency_amount * current_sell_price if native_total == 0: native_total = 1 profitability = qs.profit_percentage(timedelta(days=7), now=now) score = profitability / native_total if score < 0: purchase_currency_data.append({ 'score': score, 'currency': currency }) purchase_currency_data.sort(key=lambda item: item['score']) for_purchase = [item['currency'] for item in purchase_currency_data[0: 10]] parts = len(for_purchase) if parts == 0: parts = 1 source_fragment_amount = math.floor((source_amount / parts) * 100.0) / 100.0 # max of 10 DAI if source_fragment_amount > 10: source_fragment_amount = 10 trading_source.start_conversions() for target_currency in for_purchase: prices = trading_source.get_last_month_prices(target_currency) current_buy_price = prices[-1].buy_price trading_source.convert(source_cryptocurrency, source_fragment_amount, target_currency) package = Package( currency_symbol=target_currency.symbol, currency_amount=source_fragment_amount, bought_at_price=current_buy_price, operation_datetime=pytz.utc.localize(datetime.utcnow()), ) storage.save_package(package) add_system_log(f'BUY', f'BUY {target_currency.symbol} {source_fragment_amount}') trading_source.finish_conversions()
def sell(): enable_trading_data = server_get('enable_trading', default_data={'activated': False}).data enable_trading = enable_trading_data.get('activated') if not enable_trading: return trading_source: ICryptoCurrencySource = dependency_dispatcher.request_implementation(ICryptoCurrencySource) storage: ILocalStorage = dependency_dispatcher.request_implementation(ILocalStorage) now = pytz.utc.localize(datetime.utcnow()) trading_cryptocurrencies = trading_source.get_trading_cryptocurrencies() trading_source.start_conversions() for currency in trading_cryptocurrencies: prices = trading_source.get_last_month_prices(currency) qs = PricesQueryset(prices) if len(qs.filter_by_last(timedelta(days=30), now=now)) == 0: continue current_sell_price = prices[-1].sell_price packages = storage.get_cryptocurrency_packages(currency) """ 1.- Para vender, rentabilidad últimas 4h tendría que ser < -5 y tener paquetes que cumplan: + Que alguno ofrezca una rentabilidad de > 20% + Que alguno tenga 2 semanas o más con rentabilidad entre 5% y 20% + Que tengan más de n meses de antiguedad. Que sea configurable. """ profit_4d = qs.profit_percentage(timedelta(days=4), now=now) if profit_4d < -5: amount = 0.0 remove_packages = [] profits = [] for package in packages: package_profit = profit_difference_percentage(package.bought_at_price, current_sell_price) sell_it = False if package_profit > 20: sell_it = True elif 5 <= package_profit <= 20 and now - timedelta(days=7) >= package.operation_datetime: sell_it = True # TODO add auto_sell if sell_it: profits.append(package_profit) remove_packages.append(package) amount += package.currency_amount if len(profits) == 0: profits = [0.0] if round(amount) > 0.0: amount = two_decimals_floor(amount) target = trading_source.get_stable_cryptocurrency() trading_source.convert(currency, amount, target) for package in remove_packages: storage.delete_package(package) add_system_log(f'SELL', f'SELL {currency.symbol} {amount} profit: {statistics.mean(profits)}%') trading_source.finish_conversions()