예제 #1
0
def stubbed(*coins):
    tickers = []
    for coin in coins:
        last_ticker = (Ticker
            .select()
            .where(Ticker.coin == coin)
            .order_by(Ticker.captured_at.desc())
            .limit(1))
        if last_ticker.count() == 0:
            price = random.uniform(500, 12000)
            print(f'Creating first ticker for {coin.symbol}: {price} 0%')
            ticker = Ticker.create(
                coin=coin,
                price=price,
                price_change_day_pct=0,
            )
            tickers.append(ticker)
        else:
            last_ticker = last_ticker.get()
            new_price = last_ticker.price * Decimal(random.uniform(0.98, 1.02))
            price_change_day_pct = (new_price - last_ticker.price) / last_ticker.price
            print(f'{coin.symbol}: {new_price} {price_change_day_pct}%')
            ticker = Ticker.create(coin=coin, price=new_price, price_change_day_pct=price_change_day_pct)
            check_price_alerts(ticker)
            check_global_timed_game()
            tickers.append(ticker)
    return tickers
예제 #2
0
def save_insider_trades(tmp_file: IO):
    """Прочитать данные о торгах инсайдеров из файла и сохранить их в базу.

    :param tmp_file: временный файл, откуда откуда будут прочитаны данные и сохранены в файл
    """
    for chunk in chunked(tmp_file.readlines(), Config.CHUNK_SIZE):
        insider_trades = [json.loads(line) for line in chunk]

        insiders: Set[InsiderTuple] = set(
            InsiderTuple(
                id=insider_trade['insider_id'],
                name=insider_trade['insider_name'],
            ) for insider_trade in insider_trades)
        Insider.insert_insiders(insiders)

        symbols: Set[str] = set(insider_trade['symbol']
                                for insider_trade in insider_trades)
        Ticker.insert_tickers(symbols)
        symbol_to_uuid: Dict[str, UUID] = Ticker.get_uuids_by_symbol()

        InsiderTrade.bulk_insert([
            dict(ticker_id=symbol_to_uuid[insider_trade['symbol']],
                 **{
                     k: v
                     for k, v in insider_trade.items()
                     if k != 'symbol' and k != 'insider_name'
                 }) for insider_trade in insider_trades
        ])

        session.commit()
예제 #3
0
def calc_change_percent(sess, ticker, start_time, now, peak=True):
    if peak:
        start = Ticker.peak(sess, ticker, start_time=start_time, now=now)
    else:
        start = Ticker.current_ask(sess, ticker, start_time)
    current = Ticker.current_ask(sess, ticker, now)
    if current is None or start is None:
        log.debug(f"Could not get current/start for {ticker} at s={start_time} n={now}: c={current}, p={start}")
        return 0, current

    return round(100 * (current - start) / start, 2), current
예제 #4
0
 def test_parsing_with_many_coins(self):
     ping('BTC', 'ETH')
     btc = Coin.get(Coin.symbol == 'BTC')
     eth = Coin.get(Coin.symbol == 'ETH')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     eth_ticker = Ticker.get(Ticker.coin == eth)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-1.23456789'))
     self.assertEqual(eth_ticker.price, Decimal('42.98765432'))
     self.assertEqual(eth_ticker.price_change_day_pct,
                      Decimal('-8.98765432'))
예제 #5
0
 def test_parsing_with_many_ping_calls(self):
     ping('BTC')
     btc = Coin.get(Coin.symbol == 'BTC')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-2.33334567'))
     Ticker.delete().execute()
     ping('BTC')
     btc = Coin.get(Coin.symbol == 'BTC')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-2.33334567'))
예제 #6
0
 def test_buy_coin_without_cash(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     GameProfile.create(game=1, profile=profile, cash=0)
     GameCoin.create(game=1, coin=1)
     Ticker.create(coin=1, price=10, price_change_day_pct=1.1)
     res = self.client.post(
         '/game/1/coin',
         data=json.dumps({
             'coinId': '1',
             'coinAmount': '1',
         }),
         content_type='application/json',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.BAD_REQUEST), res._status_code)
예제 #7
0
 def test_parsing_with_four_character_symbol(self):
     coin = Coin.create(name='foocoin', symbol='DASH')
     ping('DASH')
     dash = Coin.get(Coin.symbol == 'DASH')
     ticker = Ticker.get(Ticker.coin == dash)
     self.assertEqual(ticker.price, Decimal('56.12345678'))
     self.assertEqual(ticker.price_change_day_pct, Decimal('-1.23456789'))
예제 #8
0
 def test_liquefy_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     game_profile = GameProfile.create(game=1, profile=profile, cash=0)
     GameCoin.create(game=1, coin=1)
     GameProfileCoin.create(game_profile=game_profile,
                            coin=1,
                            coin_amount=2)
     Ticker.create(
         coin=1,
         price=10,
         captured_at=(datetime.utcnow()).isoformat(),
         price_change_day_pct=1.1,
     )
     res = self.client.delete(
         '/game/1/coins', headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
예제 #9
0
 def test_parsing_with_one_coin(self):
     ping('BTC')
     btc = Coin.get(Coin.symbol == 'BTC')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-2.33334567'))
예제 #10
0
 def get_allowed_diff(self, sess, coin):
     if coin == 'BTC':
         return BTC_DIFF_THRESH
     now = datetime.datetime.utcnow()
     current = Ticker.current_ask(sess, coin, now)
     if current is None:
         current = 1
     return BTC_DIFF_THRESH / current  # in terms of the coin
예제 #11
0
 def test_get_coins_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     GameProfile.create(game=1, profile=profile, cash=10000)
     GameCoin.create(
         game=1,
         coin=1,
     )
     for coin in Coin.select():
         Ticker.create(
             coin=coin,
             price=30.0,
             captured_at=(datetime.utcnow()).isoformat(),
             price_change_day_pct=1.1,
         )
     res = self.client.get(
         '/game/1/coins?timeSpan=1&sortBy=0&numPerPage=10&pageNum=1',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
예제 #12
0
파일: bot.py 프로젝트: octicalpha/coinbot
def account_value_btc(sess, account, now):
    # TODO: remove this duplicate
    btc = account.balance('BTC')
    for coin in account.coins:
        if coin == 'BTC':
            continue  # BTC is priced in USD, everything else in BTC
        units = account.balance(coin)
        unit_price = Ticker.current_ask(sess, coin, now)
        btc += units * unit_price
    return btc
예제 #13
0
def close_alt_positions(sess, account, period):
    for coin in account.coins:
        if coin == 'BTC':
            continue
        price = Ticker.current_ask(sess, coin, period)
        assert price is not None, f"no price for {coin} at {period}"
        proceeds = account.trade(coin, -account.balance(coin), price, period)
        assert proceeds >= 0, f"got {proceeds} when selling {coin}"
        current = account.balance('BTC')
        assert current >= 0, f"negative BTC in account"
        current += proceeds
        account.balances['BTC'] = current
예제 #14
0
def save_historical_prices(tmp_file: IO) -> None:
    """Прочитать исторические данные из файла и сохранить их в базу.

    :param tmp_file: временный файл, откуда откуда будут прочитаны данные и сохранены в файл
    """
    for chunk in chunked(tmp_file.readlines(), Config.CHUNK_SIZE):
        historical_prices = [json.loads(line) for line in chunk]

        symbols: Set[str] = set(historical_price['symbol']
                                for historical_price in historical_prices)
        Ticker.insert_tickers(symbols)
        symbol_to_uuid: Dict[str, UUID] = Ticker.get_uuids_by_symbol()

        HistoricalPrice.bulk_insert([
            dict(
                ticker_id=symbol_to_uuid[historical_price['symbol']],
                **{k: v
                   for k, v in historical_price.items() if k != 'symbol'})
            for historical_price in historical_prices
        ])

        session.commit()
예제 #15
0
def ping(*coins):
    res = requests.get(get_api_url(*coins))
    tickers = []
    for coin_res in res.json():
        symbol = coin_res['symbol']
        coin = Coin.get(Coin.symbol == symbol)
        price = Decimal(coin_res['price'])
        price_change_day_pct = Decimal(coin_res['1d']['price_change_pct'])
        ticker = Ticker.create(coin=coin, price=price, price_change_day_pct=price_change_day_pct)
        tickers.append(ticker)
        check_price_alerts(ticker)
        check_global_timed_game()
    return tickers
예제 #16
0
 def test_sell_coin_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     game_profile = GameProfile.create(game=1, profile=profile, cash=0)
     GameCoin.create(game=1, coin=1)
     GameProfileCoin.create(game_profile=game_profile,
                            coin=1,
                            coin_amount=2)
     Ticker.create(
         coin=1,
         price=10,
         captured_at=(datetime.utcnow()).isoformat(),
         price_change_day_pct=1.1,
     )
     res = self.client.post(
         '/game/1/coin',
         data=json.dumps({
             'coinId': '1',
             'coinAmount': '-1',
         }),
         content_type='application/json',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
예제 #17
0
    def __init__(self, sess, db_loc, step=timedelta(minutes=10)):
        self.db_loc = db_loc
        self.balances = {'BTC': 5}
        self.step = step
        self.coins = Ticker.coins(sess)
        self.start_data = fetch_data_timestamp(sess, oldest=True)
        self.end_data = fetch_data_timestamp(sess, oldest=False)

        # quiet other logs down to avoid spam
        default = logging.getLogger('default')
        default.setLevel(logging.ERROR)
        txns = logging.getLogger('txns')
        txns.setLevel(logging.ERROR)
예제 #18
0
 def value_btc(self, sess, now=None):
     btc = self.balance('BTC')
     self.values_in_btc['BTC'] = btc
     for coin in self.coins:
         if coin == 'BTC':
             continue  # BTC is priced in USD, everything else in BTC
         units = self.balance(coin)
         unit_price = Ticker.current_ask(sess, coin, now)
         if not unit_price:
             continue
         value = units * unit_price
         self.values_in_btc[coin] = value
         btc += value
     return btc
예제 #19
0
def get_pricing_by_coins(coins, start_time):
    coins_and_prices = []
    for currentCoin in coins:
        prices_query = Ticker.select()\
            .join(Coin)\
            .where(Coin.id == currentCoin.id, Ticker.captured_at > start_time)\
            .order_by(-Ticker.captured_at)
        if prices_query.count() == 0:
            raise BadRequest("Coin's prices not found")

        prices = []
        for price in prices_query:
            prices.append(price)
        coins_and_prices.append({'coin': currentCoin, 'prices': prices})
    return coins_and_prices
예제 #20
0
    def calculate_strengths(self, now, ticker, allow_missing=False):
        if self.prices.get(ticker) is None:
            self.fetch_data(ticker, now)

        hour_avgs = self.avg_by_hour(now, ticker, allow_missing)
        if hour_avgs is None:
            return None
        log.debug("Averages by hour: {}".format(hour_avgs))

        current_price = Ticker.current_ask(self.sess, ticker, now)

        if current_price is None or hour_avgs.get(1) is None:
            log.debug("No price for {} @ {}".format(ticker, now))
            return None

        return current_price, [hour_avgs[hour] / current_price
                               for hour in self.HOURS[1:]]
예제 #21
0
파일: cron.py 프로젝트: octicalpha/coinbot
def update(sess, config):
    """"Pull data from the exchanges and store it in our database"""
    exchanges = {
        'Bittrex': Bittrex(config),
    }
    start = datetime.datetime.utcnow()
    for name, exch in exchanges.items():
        print(name)
        for coin in exch.COINS:
            data = exch.fetch_ticker(coin)
            if data is None:
                continue
            sess.add(Ticker(data))

    sess.commit()
    elapsed = datetime.datetime.utcnow() - start
    if elapsed.seconds > 30:
        log.warn("Ran update in {}s".format(elapsed.seconds))
예제 #22
0
def sell_coin(coin_id, coin_amount, game_profile):
    gameProfileCoin = GameProfileCoin.get_or_none(
        GameProfileCoin.game_profile == game_profile.id,
        GameProfileCoin.coin == coin_id)
    if gameProfileCoin is None or gameProfileCoin.coin_amount < coin_amount:
        raise BadRequest('Not enough of these coins to sell')
    ticker = Ticker.select().where(Ticker.coin == coin_id).order_by(
        Ticker.captured_at.desc())
    if ticker.count() == 0:
        raise BadRequest('Coin has no prices')
    ticker = ticker.get()
    new_cash = game_profile.cash + (ticker.price * coin_amount)
    new_coin_amount = gameProfileCoin.coin_amount - coin_amount
    GameProfileCoin.update(coin_amount=new_coin_amount).where(
        GameProfileCoin.id == gameProfileCoin.id).execute()
    GameProfile.update(cash=new_cash).where(
        GameProfile.id == game_profile.id).execute()
    return new_coin_amount
예제 #23
0
def get_net_worth_by_game_profile_id(game_profile_id):
    gameProfile = GameProfile.get_or_none(GameProfile.id == game_profile_id)
    if not gameProfile:
        raise BadRequest('User not in game')

    netWorth = gameProfile.cash

    gameProfileCoins = get_game_profile_coins_by_game_profile_id(
        game_profile_id)
    for gameProfileCoin in gameProfileCoins:
        ticker = Ticker.select().where(
            Ticker.coin == gameProfileCoin.coin).order_by(
                Ticker.captured_at.desc())
        if ticker.count() == 0:
            raise BadRequest('One coin did not have prices')
        ticker = ticker.get()
        if not ticker:
            raise BadRequest('One coin did not exist')
        netWorth += ticker.price * gameProfileCoin.coin_amount
    return netWorth
예제 #24
0
def buy_and_hold(interval, coins, db_loc, step, balances):
    start, stop = interval
    account = Account(balances)
    # one share of each alt, one share of BTC
    btc_per_coin = account.balance('BTC') / (len(coins) + 1)
    with_fees = btc_per_coin - (btc_per_coin * 0.0025)

    db = create_db(db_loc)
    sess = new_session(db)

    for coin in coins:
        price = Ticker.current_ask(sess, coin, now=start)
        if not price:
            continue
        to_buy = with_fees / price
        cost = account.trade(coin, to_buy, price, start)
        account.update('BTC', cost, start)

    start_value = account_value_btc(sess, account, now=start)
    finish_value = account_value_btc(sess, account, stop)
    low = min(start_value, finish_value)
    high = max(start_value, finish_value)

    results = BacktestResult(start,
                             stop,
                             step,
                             start_value,
                             finish_value,
                             account.fees,
                             account.txns,
                             gain_txns=[],
                             loss_txns=[],
                             out_of_btc=0,
                             hit_coin_limit=0,
                             high=high,
                             low=low)
    log.debug("\nBuy and hold\n")
    results.print_results()

    return results
예제 #25
0
def buy_coin(coin_id, coin_amount, game_profile):
    ticker = Ticker.select().where(Ticker.coin == coin_id).order_by(
        Ticker.captured_at.desc())
    if ticker.count() == 0:
        raise BadRequest('Coin has no prices')
    ticker = ticker.get()
    new_cash = game_profile.cash - (ticker.price * coin_amount)
    if new_cash < 0:
        raise BadRequest('Not enough cash to buy this coin amount')
    game_coin = GameCoin.get_or_none(GameCoin.game == game_profile.game,
                                     GameCoin.coin == coin_id)
    if game_coin is None:
        raise BadRequest('Coin does not exist in this game')
    gameProfileCoin = GameProfileCoin.get_or_none(
        GameProfileCoin.game_profile == game_profile.id,
        GameProfileCoin.coin == coin_id)

    if gameProfileCoin is None:
        GameProfileCoin.create(game_profile=game_profile.id,
                               coin=coin_id,
                               coin_amount=coin_amount)

        rows = GameProfile.update(cash=new_cash).where(
            GameProfile == game_profile).execute()

        if rows == 0:
            raise BadRequest('Money could not be removed from your account')
        return coin_amount
    else:
        new_coin_amount = gameProfileCoin.coin_amount + coin_amount
        rows = GameProfile.update(cash=new_cash).where(
            GameProfile == game_profile).execute()
        if rows == 0:
            raise BadRequest('Money could not be removed from your account')
        GameProfileCoin.update(coin_amount=new_coin_amount).where(
            GameProfileCoin.id == gameProfileCoin.id).execute()
        return new_coin_amount
def get_ticker_price_by_coin_id(coin_id):
    return Ticker.select(Ticker.price).where(coin_id == Ticker.coin)
예제 #27
0
 def from_db(sess, name, exchange, ccxt):
     if not name or not exchange:
         raise ValueError("Must specify acount name and exchange")
     balances, opens = DurableAccount.fetch_balances(sess, name, exchange)
     coins = Ticker.coins(sess)
     return DurableAccount(name, exchange, ccxt, balances, opens, coins)
예제 #28
0
def get_tickers_24hr():
    yesterday = datetime.utcnow() - timedelta(days=1)
    tickers = Ticker.select().where(Ticker.captured_at > yesterday)
    if not tickers:
        return []
    return tickers
예제 #29
0
 def test_parsing_with_no_coins(self):
     num_tickers_before = Ticker.select().count()
     ping()
     num_tickers_after = Ticker.select().count()
     self.assertEqual(num_tickers_before, num_tickers_after)