Exemplo n.º 1
0
 def testIsTimeBetweenParamsEmpty(self):
     c = self.setup()
     c.from_time = ""
     c.to_time = ""
     c.on_days_of_week = ""
     rv = Utils.is_time_between(c, datetime.time(5, 0))
     self.assertTrue(rv)
async def deliver(ws, coin: str):
    repo_market = coin + '-USD-REPO-LIN'
    swap_market = coin + '-USD-SWAP-LIN'
    min_size = 10**-TD.size_inc[repo_market]
    total_balance = TD.total[coin]
    delivery_imbalance = TD.net_imbal[swap_market]
    ask = TD.asks[repo_market]['6']  # [placed, size, price, orderId]
    placed, o_id = ask[0], ask[3]
    if (utils.is_time_between(TD.noon_deliv_start, TD.noon_deliv_end)
            or utils.is_time_between(TD.am_deliv_start, TD.am_deliv_end)
            or utils.is_time_between(TD.pm_deliv_start, TD.pm_deliv_end)):
        # Deliver outstanding positions prior to the 30 minute auction cut-off.
        if total_balance != 0:
            if placed:
                await cfws.cancel_order(TD, ws, o_id, repo_market)
            TD.net_imbal[
                swap_market] -= total_balance  # Subtract because shorts are being delivered.
            delivery = {
                'instrumentId': swap_market,
                'qtyDeliver': str(abs(total_balance))
            }
            TD.logger.info(f'{delivery}')
            resp = rest.deliver(delivery)
            await asyncio.sleep(5)
            if 'data' in resp:
                if resp['data']:
                    TD.total[coin] = 0
                    TD.delivery_timer[repo_market] = time.time()

    # Deliver early if there is an opposite delivery outstanding.
    elif (delivery_imbalance >= min_size and total_balance >= min_size
          and time.time() > TD.delivery_timer[repo_market] + 8 * 60 + 1):
        size = delivery_imbalance if abs(
            delivery_imbalance) < total_balance else total_balance
        if placed:
            await cfws.cancel_order(TD, ws, o_id, repo_market)
        delivery = {'instrumentId': swap_market, 'qtyDeliver': str(abs(size))}
        TD.logger.info(f'{delivery}')
        resp = rest.deliver(delivery)
        await asyncio.sleep(5)
        if 'data' in resp:
            if resp['data']:
                TD.delivery_timer[repo_market] = time.time()
    return
Exemplo n.º 3
0
def should_we_sleep():
  
    best_schedule=[]

    first_run = [x for x in db_dates.all() if x == Dates.first_run][0]['first_run']
    # log.info("first run: {}".format(first_run))
    log.info('choosing schedule')
    sorted_schedules = sorted(BOT_SCHEDULES, key=lambda k: k['days'])
    for day in sorted_schedules:
      day_epoch = first_run + (int(day['days']) * DAY)
      current_epoch = int(time.time())
      if current_epoch > day_epoch:
        log.info("using schedule: {}".format(day))
        best_schedule=day['schedule']
        break

    CHECKS = []
    for schedule in best_schedule:
      if is_time_between(schedule[0], schedule[1]):
        if SHOW_SLEEP_LOGGING:
          log.info("sleep?: {} awake: {}, sleep: {}, current: {}".format(False, schedule[0], schedule[1], datetime.datetime.utcnow().time()))
        CHECKS.append(True)
      else:
        if SHOW_SLEEP_LOGGING:
          log.info("sleep?: {} awake: {}, sleep: {}, current: {}".format(True, schedule[0], schedule[1], datetime.datetime.utcnow().time()))
        CHECKS.append(False)
    
    # check if any of the time between checks returned true.
    # if there's a True in the list, it means we're between one of the scheduled times
    # and so this function returns False so the bot doesn't sleep
    log.info("check list: {}".format(CHECKS))
    if True in CHECKS:
      log.info("no need to sleep")
      return False
    else:
      log.info("it's sleepy time")
      return True
Exemplo n.º 4
0
 def can_send_alert(self):
     dt = Utils.get_date_time()
     if self.use_alerts:
         return Utils.is_day_of_week(
             self, dt.weekday()) and Utils.is_time_between(self, dt.time())
     return False
Exemplo n.º 5
0
 def testIsTimeBetween0000_2359Valid(self):
     c = self.setup()
     c.from_time = '00:01'
     c.to_time = '23:59'
     rv = Utils.is_time_between(c, datetime.time(3, 1))
     self.assertTrue(rv)
Exemplo n.º 6
0
 def testIsTimeBetweenInvalid(self):
     c = self.setup()
     c.from_time = '00:01'
     c.to_time = '02:00'
     rv = Utils.is_time_between(c, datetime.time(2, 2))
     self.assertFalse(rv)
async def distribute_bids(ws):
    for repo_market in TD.repo_market:
        if TD.available['USD'] > 0:
            coin = utils.market_to_coin(repo_market)
            if coin not in TD.coin_allocation:
                continue
            spot_market = coin + '-USD'

            filled = TD.total[coin]
            size_inc = TD.size_inc[repo_market]
            min_size = 10**-size_inc

            coin_alloc = TD.coin_allocation[coin]

            # Determine which distribution the coin is in.
            if coin in TD.coin_definition['large']:
                distribution = TD.large_cap_distribution
            elif coin in TD.coin_definition['medium']:
                distribution = TD.medium_cap_distribution
            else:
                distribution = TD.small_cap_distribution

            # Place or edit orders according to the distribution.
            for order in distribution:
                bid = TD.bids[repo_market][
                    order]  # [placed, size, price, orderId]
                placed, o_size, o_price, o_id = bid[0], bid[1], bid[2], bid[3]
                price = distribution[order][0]
                bid_fraction = distribution[order][1]

                # Cancel bids if a buy auction is coming up
                if (utils.is_time_between(TD.noon_deliv_end, TD.noon_bid_end)
                        or utils.is_time_between(TD.am_deliv_end,
                                                 TD.am_bid_end) or
                        utils.is_time_between(TD.pm_deliv_end, TD.pm_bid_end)
                    ) and TD.net_imbal[coin + '-USD-SWAP-LIN'] >= min_size:
                    if placed:
                        await cfws.cancel_order(TD, ws, o_id, repo_market)
                    continue

                # expected_size = Original bid size
                expected_size = (TD.total['USD'] * bid_fraction * coin_alloc *
                                 TD.safety_buffer)
                expected_size /= TD.mark_prices[spot_market]

                if filled > 0:
                    size = math.floor(
                        (expected_size - filled) * 10**size_inc) / 10**size_inc
                    filled -= expected_size
                else:
                    size = math.floor(
                        expected_size * 10**size_inc) / 10**size_inc

                if not placed and size >= min_size:
                    await cfws.place_order(TD, ws, order, repo_market, 'BUY',
                                           'LIMIT', size, 'GTC', price)
                    await asyncio.sleep(0.075)

                elif (size * 1.001 < o_size or size * 0.999 > o_size
                      or price != o_price) and size >= min_size:
                    await cfws.cancel_order(TD, ws, o_id, repo_market)
                    await cfws.place_order(TD, ws, order, repo_market, 'BUY',
                                           'LIMIT', size, 'GTC', price)
                    # await cfws.ModifyOrder(TD, ws, count, o_id, market, 'BUY', size, price)
                    await asyncio.sleep(0.075)

                elif size < min_size and placed:
                    await cfws.cancel_order(TD, ws, o_id, repo_market)

        elif TD.available['USD'] < 0:
            for count in range(1, 3):
                count = str(count)
                o_id = TD.bids[repo_market][count][3]
                if int(count) >= 3:
                    break
                await cfws.cancel_order(TD, ws, o_id, repo_market)
    return
async def trade():
    while True:
        while not TD.repo_market:
            await asyncio.sleep(3)
        # Initialise parameters using rest.
        await trade_prep()
        # Connect to CoinFLEX's WebSocket.
        async with websockets.connect(Conn.WS_URL) as ws:
            # Authenticate the WebSocket connection.
            await ws.send(
                json.dumps(await cfws.auth(Conn.API_KEY, Conn.API_SECRET)))
            # Subscribe to the order book, order, position, and balance channels.
            await ws.send(json.dumps(TD.subscription))
            # Confirm all of the markets are subscribed to.
            await subscribe(ws)

            # This is where the trading logic starts.
            while TD.WS_FLAG and ws.open:
                try:
                    # Await a message from CoinFLEX's WebSocket.
                    response = await ws.recv()
                    msg = json.loads(response)
                    # Output the message from CoinFLEX's WebSocket.
                    # TD.logger.info(str(msg))

                    if 'table' in msg:
                        if msg['table'] == 'order':
                            skip = await cfws.parse_message(TD, msg)
                            if skip:
                                continue

                        if msg['table'] == 'balance':
                            # TD.logger.info(str(msg))
                            data = msg['data']
                            TD.logger.info(str(msg))
                            for asset in data:
                                TD.total[asset['instrumentId']] = float(
                                    asset['total'])
                                TD.available[
                                    asset['instrumentId']] = math.floor(
                                        float(asset['available']) *
                                        1000) / 1000

                            # Start trading
                            # Get the total amount of USD originally input into the system.
                            for asset in TD.total:
                                spot_market = asset + '-USD'
                                if asset != 'USD' and spot_market in TD.mark_prices:
                                    TD.total['USD'] += TD.total[
                                        asset] * TD.mark_prices[spot_market]
                                    # Check for opportunities to match deliveries and deliver before each auction
                                    await deliver(ws, asset)

                            # Distribute bids and asks at the pre-defined levels from TradeData.
                            for asset in TD.total:
                                if asset == 'USD':
                                    await distribute_bids(ws)
                                else:
                                    await distribute_asks(ws, asset)

                                if (utils.is_time_between(
                                        TD.noon_bid_start, TD.noon_bid_end)
                                        or utils.is_time_between(
                                            TD.am_bid_start, TD.am_bid_end)
                                        or utils.is_time_between(
                                            TD.pm_bid_start, TD.pm_bid_end)):

                                    # Wait for the auction, yield calculations, and interest payments to be processed.
                                    await asyncio.sleep(120)
                                    # Reset allocations after the auction.
                                    TD.coin_allocation = TD.reset_coin_alloc()
                                    TD.bids = {
                                        str(i): TD.reset_bids()
                                        for i in TD.bids
                                    }
                                    TD.asks = {
                                        str(i): TD.reset_asks()
                                        for i in TD.asks
                                    }
                                    await trade_prep()
                                    continue

                except Exception:
                    TD.logger.exception('trade caught this error')
                    TD.WS_FLAG = False
                    await ws.close()