Esempio n. 1
0
    async def on_parameters(self, parameters):
        delta_crypto = parameters['change_crypto']
        delta_cash = parameters['change_cash']

        if (delta_cash != 0 or delta_crypto != 0):
            self._pnl_manager.update_reserves(delta_cash, delta_crypto)

        # Reset the change parameters
        parameters['change_crypto'] = 0
        parameters['change_cash'] = 0

        self._pnl_manager.update_refresh_interval(parameters['state_refresh'])
        # TODO: Validate parameters
        log.info('Updating strategy parameters from: {} to {}', self._params,
                 parameters)

        old_params = self._params
        self._params = parameters

        if (self._prev_book is not None) and self._trader._session.open_orders:
            # We have orders in the market, and parameters were changed by
            # the user. Recompute and update orders
            if old_params['orders'] != self._params['orders']:
                # Cancel all existing orders and recreate the orders
                # TODO: come up with a better way that doesn't require
                #       cancelling all orders.
                #       Perhaps implement revises
                await self._trader.cancel_session()
                await self.create_orders(self._prev_book)
            else:
                await self.update_orders(self._prev_book)
Esempio n. 2
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))
Esempio n. 3
0
    async def socket_handler(self, request):
        ws = aiohttp.web.WebSocketResponse()
        ok, protocol = ws.can_prepare(request)
        if not ok:
            return aiohttp.web.Response(text='Somthing went wrong')

        await ws.prepare(request)

        request.app['sockets'].add(ws)

        try:
            async for msg in ws:
                if msg.type == aiohttp.WSMsgType.TEXT:
                    try:
                        req = json.loads(msg.data)
                        if 'admin' in req:
                            await self.cb(req)
                        elif 'config' in req:
                            log.info('Recieved new configuration: {}', req)
                            await self.cb(req)
                    except Exception as e:
                        log.exception('Unexpected Error: {}', e)
                        await ws.close()
                elif msg.type == aiohttp.WSMsgType.ERROR:
                    log.info('Conn closed w/ exception: {}', ws.exception())
                    await ws.close()
        finally:
            request.app['sockets'].remove(ws)

        return ws
    def apply_trade(self, order, trade, side):
        # Trade impacted one of our outstanding orders!
        log.info('{} [{}] - {}', TRADE_IMPACT, trade, side)
        self._session.on_order_fill(order, trade.qty)

        if order.remaining_qty == 0:
            self._session.notify_complete(order)
Esempio n. 5
0
    async def _log_orders(self):
        orders = await self._session.exch_orders()

        open_orders = ""
        for o in orders:
            open_orders = " " + str(o.price) + ", " + \
                str(o.remaining_qty) + ", " + str(o.original_qty) + "|"

        log.info('Open Orders: {}', open_orders)
Esempio n. 6
0
    async def initialize_state(self, update):
        log.info("Initializing state: Cancelling outstanding orders...")

        # Cancel all outstanding ordes
        await self.trader.cancel_all()
        await self.init_balances()
        await self.init_pnl(update)
        await self.broadcast_config()

        log.info('Strategy Params: {}', to_json(StrategyConfig))
Esempio n. 7
0
    async def init_balances(self):
        # Get balances
        balance = await self.trader.get_balance()
        log.info('Initial Balance: {}', balance)

        StrategyConfig["last_update_time"] = datetime.now()
        StrategyConfig["initial_state"] = {
            "start_time": datetime.now(),
            "balances": balance
        }
Esempio n. 8
0
    async def init(self, loop, ip, port, instrument):
        self._app = aiohttp.web.Application(loop=loop)
        self._app['sockets'] = set()
        self._app.router.add_get('/ws', self.socket_handler)
        self._handler = self._app.make_handler()

        self._srv = await loop.create_server(self._handler, ip, port)
        self._session = aiohttp.ClientSession()

        log.info('Running web server at {}:{}', ip, port)
Esempio n. 9
0
    async def _dispatch_cancel_actions(self, to_cancel, open_orders_map):
        cancel_tasks = []
        canceling_orders = ""
        for o in to_cancel:
            open_order = open_orders_map[round(o.price, 2)]
            if open_order.is_open:
                canceling_orders += " " + str(o.price) + ", " + str(
                    o.qty) + "|"

                task = asyncio.ensure_future(
                    self._trader.cancel_order(open_order))
                cancel_tasks.append(task)

        await asyncio.gather(*cancel_tasks)

        if to_cancel:
            log.info('Cancelled Orders: {}', canceling_orders)
Esempio n. 10
0
    async def _dispatch_submit_actions(self, to_add, open_orders_map):
        submit_tasks = []
        adding_orders = ""
        for o in to_add:
            adding_orders += " " + str(round(o.price, 2)) + \
                             ", " + str(round(o.qty, 2)) + "|"

            task = asyncio.ensure_future(
                self._trader.submit_order(side=o.side,
                                          price=round(o.price, 2),
                                          qty=round(o.qty, 2),
                                          ioc=False,
                                          quote=True))
            submit_tasks.append(task)

        await asyncio.gather(*submit_tasks)

        if to_add:
            log.info('Added Orders: {}', adding_orders)
Esempio n. 11
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)
Esempio n. 12
0
    async def poll_sub(self, sub, web_server):
        log.info('Starting Anchor Strategy')
        await asyncio.sleep(3)

        is_valid_book = False
        while not is_valid_book:
            update = await sub.fetch()
            if len(update.book.bids) > 0 and len(update.book.asks) > 0:
                await self.initialize_state(update)
                await self.strategy.on_parameters(StrategyConfig['parameters'])
                await self.strategy.on_market_data(update)
                is_valid_book = True
            else:
                await asyncio.sleep(1)

        while True:
            update = await sub.fetch()
            await self.strategy.on_market_data(update)

            # TODO: if we get traded against, we would want to
            # let the startegy take an action - poll at a faster rate
            # and check to see if anything happened, otherwise, yield control
            # at the configured interval
            await asyncio.sleep(StrategyConfig['parameters']['md_refresh'])
Esempio n. 13
0
 def _log_error(self, error_type, error, trigger):
     log.error(error)
     msg = {'error': str(error), 'trigger': trigger}
     log.info('Error Msg: [{}] {}', error_type, msg)
Esempio n. 14
0
 async def _log_balance(self):
     balance = await self.get_balance()
     log.info('Balances: base=avail:{}|hold:{}, quote=avail:{}|hold:{}',
              balance['base']['available'], balance['base']['hold'],
              balance['quote']['available'], balance['quote']['hold'])
Esempio n. 15
0
 async def _log_ack(self, msg_type, order):
     log.info('Submitted order for {}', str(order))