Ejemplo n.º 1
0
    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]
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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')
Ejemplo n.º 4
0
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,
        )
Ejemplo n.º 5
0
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')
    })
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
 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)
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
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()