Пример #1
0
    async def on_signal(self, action, update):
        strp_time = update['timestamp'].split('.')[0].split('+')[0]
        curr_time = time.mktime(
            dt.datetime.strptime(strp_time, '%Y-%m-%d %H:%M:%S').timetuple())

        book = update['book']
        if action == 'BUY':
            if self._pnl_manager.get_cash_value() <= Decimal(1.00):
                return

            price = make_price(book['asks'][0]['price'])
            cash = self._pnl_manager.get_cash_value()
            qty = cash / price

            await self._trader.submit_order(side=Side.BID,
                                            price=price,
                                            qty=make_qty(Decimal(qty)),
                                            ioc=True,
                                            quote=True)
            self._last_buy_ts = curr_time
        else:
            if self._pnl_manager.get_crypto_value(book) <= Decimal(0.01):
                return

            price = make_price(book['bids'][0]['price'])
            qty = self._pnl_manager.crypto_coins

            await self._trader.submit_order(side=Side.ASK,
                                            price=price,
                                            qty=make_qty(Decimal(qty)),
                                            ioc=True,
                                            quote=True)
            self._last_sell_ts = curr_time
Пример #2
0
    async def persistent_submit(self, side, price, qty, ioc, quote):
        tries = 0
        unsuccessful_submit = True

        p = price
        q = qty

        while (tries < 5 and unsuccessful_submit):
            try:
                await self._trader.submit_order(side=side,
                                                price=p,
                                                qty=q,
                                                ioc=ioc,
                                                quote=quote)
                unsuccessful_submit = False
            except PostOnlyException:
                previous_price = p
                previous_qty = q

                if side == Side.BID:
                    p = previous_price - make_price(0.01)
                    q = make_qty(
                        Decimal(round((previous_qty * previous_price) / p, 8)))
                else:
                    p = previous_price + make_price(0.01)
                    q = make_qty(
                        Decimal(round((previous_qty * previous_price) / p, 8)))
                tries += 1

        if unsuccessful_submit:
            log.warning('Tried to place order 5x. Giving up...')
Пример #3
0
def main(args):
    params = {
        'api_url': gdax.OrderEntryGateway.SANDBOX_URL,
        'api_key': args['<API_KEY>'],
        'api_secret': args['<API_SECRET>'],
        'passphrase': args['<PASSPHRASE>'],
        'ip': args['<IP>'],
        'port': args['<PORT>'],
        'sandbox': False if (args['<SANDBOX>'] == "False") else True,
        'instrument': args['<INSTRUMENT>']
    }

    log.info('Starting Anchor Strategy for {} in {} mode',
             params['instrument'],
             'SANDBOX' if params['sandbox'] else 'PRODUCTION')

    # TODO: Set up limits through configuration
    StrategyConfig['limits'] = {}
    StrategyConfig['limits']['max_order_qty'] = make_qty('2')
    StrategyConfig['limits']['max_order_value'] = make_price('1000')
    StrategyConfig['limits']['max_open_value'] = 1000

    loop = asyncio.get_event_loop()
    anchor_strategy = Anchor(loop)
    loop.run_until_complete(anchor_strategy.run(params))
Пример #4
0
    async def socket_handler(self, request):
        resp = aiohttp.web.WebSocketResponse()
        ok, protocol = resp.can_prepare(request)
        if not ok:
            return aiohttp.web.Response(text='Somthing went wrong')

        await resp.prepare(request)

        try:
            request.app['sockets'].append(resp)
            async for msg in resp:
                if msg.type == aiohttp.web.WSMsgType.TEXT:
                    req = json.loads(msg.data)
                    if 'submit' in req:
                        logging.info('Recieved request: {}'.format(req))
                        if is_valid_submit(req['submit']):
                            submit = req['submit']
                            side = Side.BUY \
                                if submit['side'] == 'BUY' else Side.SELL

                            submit = await self.trader.submit_order(
                                side=side,
                                price=make_price(submit['price']),
                                qty=make_qty(submit['qty']),
                                ioc=submit['ioc'],
                                quote=submit['quote'])
                        else:
                            self.broadcast(
                                'submit_nack', {
                                    'trigger': {
                                        'msg': 'submit',
                                        'args': req
                                    },
                                    'error': 'One+ fields are invalid!'
                                })
                    elif 'cancel_session' in req:
                        await self.trader.cancel_session()
                    elif 'cancel_all' in req:
                        await self.trader.cancel_all()
                    elif 'admin' in req:
                        if req['admin'] == 'GetBalance':
                            msg = await self.get_balance_msg()
                            resp.send_str(json.dumps(msg))
                        elif req['admin'] == 'ListOrders':
                            await self.trader.broadcast_orders()
                        elif req['admin'] == 'GetFills':
                            msg = await self.get_fills_msg()
                            resp.send_str(json.dumps(msg))
                else:
                    pass
        except Exception as e:
            self.broadcast('UnexpectedError', e)
            logging.error('Unexpected Error: {}'.format(e))
        finally:
            try:
                request.app['sockets'].remove(resp)
            except ValueError:
                pass

            return resp
Пример #5
0
 def __init__(self, gateway, instrument):
     limits = LimitChecker(max_order_qty=make_qty('0.8'),
                           max_order_value=make_price('200.50'),
                           max_open_value=200)
     self.session = Session(gateway=gateway,
                            instrument=instrument,
                            limits=limits)
     self.session.add_event_handler(self)
Пример #6
0
    async def on_signal(self, action, update):
        if not self._enabled:
            return

        await self._trader.cancel_all()

        at_min_spread = self._at_min_spread()

        book = update['book']
        if action == 'BUY':
            if self._pnl_manager.get_cash_value() <= Decimal(1.00):
                return

            cash = Decimal(self._pnl_manager.get_cash_value())

            if at_min_spread:
                price = make_price(float(book['asks'][0]['price']))
                qty = Decimal(round(cash / price, 8))
            else:
                price = make_price(float(book['asks'][0]['price']) - 0.01)
                qty = Decimal(round(cash / price, 8))

            await self._jarvis.persistent_submit(side=Side.BID,
                                                 price=price,
                                                 qty=make_qty(qty),
                                                 ioc=False,
                                                 quote=True)
        else:
            if self._pnl_manager.get_crypto_value(book) <= Decimal(0.01):
                return

            qty = Decimal(round(self._pnl_manager.crypto_coins, 8))
            if at_min_spread:
                price = make_price(float(book['bids'][0]['price']))
            else:
                price = make_price(float(book['bids'][0]['price']) + 0.01)

            await self._jarvis.persistent_submit(side=Side.ASK,
                                                 price=price,
                                                 qty=make_qty(Decimal(qty)),
                                                 ioc=False,
                                                 quote=True)

        # Notify dashboard listeners
        await self._broadcast_state("Flipped Signal")
Пример #7
0
 def __init__(self, gateway, instrument):
     limits = LimitChecker(max_order_qty=make_qty('100'),
                           max_order_value=make_price('20000'),
                           max_open_value=20000)
     self.session = Session(gateway=gateway,
                            instrument=instrument,
                            limits=limits)
     self.session.add_event_handler(self)
     self.orders = []
     self._broadcast_cb = None
Пример #8
0
    async def run(self):
        await self.session.wait_ready()
        order = await self.submit_order(side=Side.BUY,
                                        price=make_price(300),
                                        qty=make_qty('0.50'))
        log.info('Submitted: order={}', order)

        await asyncio.sleep(3)

        ioc = await self.submit_ioc(side=Side.BUY,
                                    price=make_price(1000),
                                    qty=make_qty('0.02'))
        log.info('Submitted IOC: order={}', ioc)

        await asyncio.sleep(3)

        try:
            if order is not None:
                await order.cancel()
        except oe_exceptions.CancelNack as cnack:
            log.error('{}: {}', cnack.order, cnack)

        await self.check_balance()
Пример #9
0
def main(args):
    loop = asyncio.get_event_loop()
    strategy_harness = StrategyHarness(loop)

    params = {
        'api_url': gdax.OrderEntryGateway.SANDBOX_URL,
        'api_key': args['<API_KEY>'],
        'api_secret': args['<API_SECRET>'],
        'passphrase': args['<PASSPHRASE>'],
        'ip': args['<IP>'],
        'port': args['<PORT>'],
        'sandbox': False if (args['<SANDBOX>'] == "False") else True,
        'instrument': args['<INSTRUMENT>']
    }

    log.info('Starting Aesop Strategy for {} in {} mode', params['instrument'],
             'SANDBOX' if params['sandbox'] else 'PRODUCTION')

    # TODO: Set up limits through configuration
    StrategyConfig['limits'] = {}
    StrategyConfig['limits']['max_order_qty'] = make_qty('3')
    StrategyConfig['limits']['max_order_value'] = make_price('1000')
    StrategyConfig['limits']['max_open_value'] = 1000

    try:
        loop.run_until_complete(strategy_harness.run(params))
    except KeyboardInterrupt:
        log.info('Keyboard Interrupt - Shutting down Aesop Strategy')

        # Cancel all running tasks
        for t in asyncio.Task.all_tasks():
            t.cancel()

        loop.run_forever()  # Wait for tasks to finish cleanup.

        # Gather exceptions.
        for t in asyncio.Task.all_tasks():
            try:
                t.exception()
            except Exception:
                log.exception('Exception during shutdown: {}', t)
    finally:
        loop.close()
Пример #10
0
    async def on_gap(self):
        # Need to manually update the state of every order in existance
        log.warn('Gapped! Need to request fill status of all orders')

        tasks = []
        for open_order in self._session.open_orders:
            task = asyncio.ensure_future(
                self._session.get_fill(open_order.order_id))
            tasks.append(task)

        order_fill_pairs = await asyncio.gather(*tasks)

        for pairs in order_fill_pairs:
            for pair in pairs:
                order = pair[0]
                fill = pair[1]
                log.info('Apply fill found after gap: [Order-{}], [Fill-{}]',
                         order, fill)

                self._session.on_order_fill(order, make_qty(fill['size']))

                if order.remaining_qty == 0:
                    self._session.notify_complete(order)
Пример #11
0
    def _compute_orders(self, book, targets):
        # TODO: Need to test and refactor!

        # Targets [[price, target crypto], []]
        # Need to compute order qty

        # Cannot send more orders than this value
        # TODO: This should be crypto coins, not value
        # TODO: When we place and order, make sure that the we
        # check to see that we have enough coin
        # to do so.
        crypto_val = self._pnl_manager.get_crypto_value(book)
        cash_val = self._pnl_manager.get_cash_value()

        mkt_price = self._pnl_manager.get_mkt_price(book)
        strat_value = self._pnl_manager.get_strategy_value(book)

        crypto_at_mkt_price = crypto_val / strat_value

        bids = []
        asks = []
        # handle bids
        previous_percentage = crypto_at_mkt_price
        # log.info("previous percentage: {}".format(previous_percentage))
        show = self._params['show']
        for t in reversed(targets):
            if t[0] < mkt_price:
                if show > 0:
                    price = t[0]
                    target_percentage = t[1]

                    # Buy more as we go below our mid point price,
                    # so target should be bigger
                    if previous_percentage > target_percentage:
                        # Need to send out 2 orders
                        # One at mid point and one at price t[0]

                        mkt_target = self._get_target_position(mkt_price)

                        mkt_diff = previous_percentage - mkt_target
                        if mkt_diff > 0:
                            ask_price = book.best_ask.price
                            qty = (mkt_diff * strat_value) / ask_price
                            if (round(make_qty(qty), 2) > 0.0):
                                asks.append(
                                    PendingOrder(
                                        self._slacked_price(ask_price),
                                        self._slacked_qty(qty), Side.ASK))

                                crypto_val -= ask_price * qty

                        # Own too much-send out an ask order at best bid price
                        diff = target_percentage - mkt_target
                        qty = (diff * strat_value) / price
                        if (round(make_qty(qty), 2) > 0.0):
                            bids.append(
                                PendingOrder(self._slacked_price(price),
                                             self._slacked_qty(qty), Side.BID))

                            cash_val -= price * qty
                    else:
                        diff = target_percentage - previous_percentage

                        qty = (diff * strat_value) / price
                        if (round(make_qty(qty), 2) > 0.0):
                            bids.append(
                                PendingOrder(self._slacked_price(price),
                                             self._slacked_qty(qty), Side.BID))

                            cash_val -= price * qty

                    previous_percentage = target_percentage
                show -= 1

        # handle asks
        previous_percentage = crypto_at_mkt_price
        show = self._params['show']
        for t in targets:
            if t[0] > mkt_price:
                if show > 0:
                    price = t[0]
                    target_percentage = Decimal(t[1])

                    # Sell more as we go above our mid point price,
                    # so target should be smaller
                    # Handle Best Ask Order Seperately
                    if previous_percentage < target_percentage:
                        # Need to send out 2 orders
                        # one at mid point and one at price t[0]

                        mkt_target = self._get_target_position(mkt_price)

                        mkt_diff = mkt_target - previous_percentage
                        if mkt_diff > 0:
                            bid_price = book.best_bid.price
                            qty = (mkt_diff * strat_value) / bid_price
                            if (round(make_qty(qty), 2) > 0.0):
                                bids.append(
                                    PendingOrder(
                                        self._slacked_price(bid_price),
                                        self._slacked_qty(qty), Side.BID))

                                cash_val -= bid_price * qty

                        # Own too little-send out a bid order at best bid price
                        diff = mkt_target - target_percentage
                        qty = (diff * strat_value) / price
                        if (round(make_qty(qty), 2) > 0.0):
                            asks.append(
                                PendingOrder(self._slacked_price(price),
                                             self._slacked_qty(qty), Side.ASK))

                            crypto_val -= price * qty
                    else:
                        diff = previous_percentage - target_percentage
                        qty = (diff * strat_value) / price
                        if (round(make_qty(qty), 2) > 0.0):
                            asks.append(
                                PendingOrder(self._slacked_price(price),
                                             self._slacked_qty(qty), Side.ASK))

                            crypto_val -= price * qty

                    previous_percentage = target_percentage
                show -= 1

        # log.info("Asks: {}".format(asks))
        # log.info("Bids: {}".format(bids))

        return [bids, asks]
Пример #12
0
 def _slacked_qty(self, qty):
     return round(make_qty(qty), min(self._params['slack'], 8))
Пример #13
0
 def __init__(self, instrument):
     self._instrument = instrument
     self.open_long = make_qty(0)
     self.open_short = make_qty(0)
     self.base_amount = make_qty(0)
     self.quote_amount = make_price(0)
Пример #14
0
 def __init__(self, level_side):
     self._price = make_price(level_side['price'])
     self._qty = make_qty(level_side['qty'])