Пример #1
0
class Runner:
    def __init__(self,
                 h5filename='test.h5',
                 prime1=20,
                 run_steps=10000,
                 write_interval=5000,
                 **kwargs):
        self.signal = Signal()
        self.exchange = orderbook.Orderbook(self.signal)
        self.h5filename = h5filename
        self.run_steps = run_steps + 1
        self.liquidity_providers = {}
        self.noise = kwargs.pop('Noise')
        # Set up noise traders
        if self.noise:
            self.noise_traders = self.buildNoiseTraders(
                kwargs['numNoise'], kwargs["NoiseSigma"])
            self.Lambda_nt = kwargs['Lambda_nt']
        # Set up fundamental traders
        self.fundamental = kwargs.pop("Fundamental")
        if self.fundamental:
            self.fundamentals = self.buildFundamentalTraders(
                kwargs['numFund'], kwargs["omega_Fund"], kwargs["FundSigma"])
            self.Lambda_ft = kwargs["Lambda_ft"]
        # Set up momentum traders
        self.momentum = kwargs.pop("Momentum")
        if self.momentum:
            self.momentums = self.buildMomentumTraders(kwargs["numMom"],
                                                       kwargs["omega_Mom"],
                                                       kwargs["MomInvLim"],
                                                       kwargs["MomTimeWindow"],
                                                       kwargs["shapeMom"])
            self.Lambda_mt = kwargs["Lambda_mt"]
        # Set up Market Makers
        self.marketmaker = kwargs.pop("MarketMaker")
        if self.marketmaker:
            self.marketmakers = self.buildMarketMakers(
                kwargs["numMMs"], kwargs["KatRisk"], kwargs["MMgamma"],
                kwargs["K"], kwargs["MMa"], kwargs["MMr"], kwargs["MMn"],
                kwargs["MMs"], kwargs["MMdelta"], kwargs["MMwindow"],
                kwargs["MMc"])
            self.Lambda_mm = kwargs["Lambda_mm"]

        self.traders, self.num_traders = self.makeAll()
        self.seedOrderbook()
        #        if self.provider:
        #            self.makeSetup(prime1, kwargs['Lambda0'])
        #        if self.pj:
        #            self.runMcsPJ(prime1, write_interval)
        #        else:
        self.runMcs(prime1, write_interval)
        self.exchange.trade_book_to_h5(h5filename)
        self.qTakeToh5()
        self.mmProfitabilityToh5()

    def buildNoiseTraders(self, numNoise, NoiseSigma):
        ''' Noise trader id starts with 1'''
        noise_ids = [1000 + i for i in range(numNoise)]
        noise_list = [NoiseTrader(n, NoiseSigma) for n in noise_ids]
        #self.liquidity_providers.update(dict(zip(noise_ids, noise_list)))
        return noise_list

    def buildFundamentalTraders(self, numFunds, omega, sigma):
        ''' Fundamental id starts with 2'''
        fundamentals_ids = [2000 + i for i in range(numFunds)]
        return [FundamentalTrader(f, omega, sigma) for f in fundamentals_ids]

    def buildMomentumTraders(self, numMoms, omega, inv_limit, time_window, h):
        ''' Momentum trader id starts with 5'''
        momentum_ids = [5000 + i for i in range(numMoms)]
        return [
            MomentumTrader(mt, omega, inv_limit, time_window, h)
            for mt in momentum_ids
        ]

    def buildMarketMakers(self, numMMs, KatRisk, gamma, K, alpha, reduction, n,
                          s, delta, window, c):
        ''' MM id starts with 4'''
        mm_ids = [4000 + i for i in range(numMMs)]
        #self.liquidity_providers.update({4000: jumper})
        maker_list = [
            MarketMaker(mm_id=mm,
                        omega=KatRisk,
                        gamma=gamma,
                        kap=K,
                        a=alpha,
                        r=reduction,
                        n=n,
                        s=s,
                        d=delta,
                        l=window,
                        c=0.03) for mm in mm_ids
        ]
        self.liquidity_providers.update(dict(zip(mm_ids, maker_list)))
        return maker_list

    def makeAll(self):
        trader_list = []
        if self.noise:
            trader_list.extend(self.noise_traders)
        if self.fundamental:
            trader_list.extend(self.fundamentals)
        if self.momentum:
            trader_list.extend(self.momentums)
        if self.marketmaker:
            trader_list.extend(self.marketmakers)
        return trader_list, len(trader_list)

    def seedOrderbook(self):
        seed_mm = MarketMaker(9999, 1, 0.05, 10000, 0.15, 1000, 4, 0.00001,
                              0.0001, 10, 0.03)
        self.liquidity_providers.update({9999: seed_mm})
        oid = 1
        for _ in range(100):
            ba = round(random.uniform(50., 50.1), 2)
            bb = round(random.uniform(49.9, 49.99), 2)

            qask = {
                'order_id': oid,
                'trader_id': 9999,
                'timestamp': 0,
                'type': OType.ADD,
                'quantity': 1,
                'side': Side.ASK,
                'price': ba
            }
            oid += 1
            qbid = {
                'order_id': oid,
                'trader_id': 9999,
                'timestamp': 0,
                'type': OType.ADD,
                'quantity': 1,
                'side': Side.BID,
                'price': bb
            }
            seed_mm.local_book[1] = qask
            self.exchange.add_order_to_book(qask)
            self.exchange.add_order_to_history(qask)
            seed_mm.local_book[2] = qbid
            self.exchange.add_order_to_book(qbid)
            self.exchange.add_order_to_history(qbid)
            self.signal.calculate_mid_price(
                self.exchange.report_top_of_book(0))
            oid += 1

#    def makeSetup(self, prime1, lambda0):
#        top_of_book = self.exchange.report_top_of_book(0)
#        for current_time in range(1, prime1):
#            ps = random.sample(self.providers, self.num_providers)
#            for p in ps:
#                if not current_time % p.delta_t:
#                    self.exchange.process_order(p.process_signal(current_time, top_of_book, self.q_provide, -lambda0))
#                    top_of_book = self.exchange.report_top_of_book(current_time)
#
#    def doCancels(self, trader):
#        for c in trader.cancel_collector:
#            self.exchange.process_order(c)

    def confirmTrades(self):
        for c in self.exchange.confirm_trade_collector:
            contra_side = self.liquidity_providers[c['trader']]
            contra_side.confirm_trade_local(c)

    def runMcs(self, prime1, write_interval):
        top_of_book = self.exchange.report_top_of_book(1)
        self.signal.calculate_mid_price(top_of_book)
        traders = self.traders
        for current_time in range(1, self.run_steps):
            print("time ", current_time)
            self.signal.demand_updated = False
            for t in traders:
                if t.trader_type == TType.NoiseTrader:
                    if random.random() <= self.Lambda_nt:
                        order = t.process_signal(current_time)
                        print(
                            "noise trader: order {}, quantity {}, side {}, price {}"
                            .format(order["order_id"], order["quantity"],
                                    order["side"], order["price"]))
                        self.exchange.process_order(order)
                        if self.exchange.traded:
                            self.confirmTrades()
                            top_of_book = self.exchange.report_top_of_book(
                                current_time)
                            self.signal.calculate_mid_price(top_of_book)
                            self.signal.calculate_volatility()
                            if self.signal.demand_updated:
                                self.signal.demand[-1] += order["quantity"]
                            else:
                                self.signal.demand.append(order["quantity"])
                                self.signal.demand_updated = True
#                    t.bulk_cancel(current_time)
#                    if t.cancel_collector:
#                        self.doCancels(t)
#                        top_of_book = self.exchange.report_top_of_book(current_time)
                elif t.trader_type == TType.FundamentalTrader:
                    if random.random() <= self.Lambda_ft:
                        order = t.process_signal(current_time, self.signal)
                        if order is None:
                            pass
                        else:
                            print(
                                "fundamental trader: order {}, quantity {}, side {}, price {}"
                                .format(order["order_id"], order["quantity"],
                                        order["side"], order["price"]))
                            self.exchange.process_order(order)
                            if self.exchange.traded:
                                self.confirmTrades()
                                top_of_book = self.exchange.report_top_of_book(
                                    current_time)
                                self.signal.calculate_mid_price(top_of_book)
                                self.signal.calculate_volatility()
                                if self.signal.demand_updated:
                                    self.signal.demand[-1] += order["quantity"]
                                else:
                                    self.signal.demand.append(
                                        order["quantity"])
                                    self.signal.demand_updated = True


#                    t.bulk_cancel(current_time)
#                    if t.cancel_collector:
#                        self.doCancels(t)
#                        top_of_book = self.exchange.report_top_of_book(current_time)
                elif t.trader_type == TType.MomentumTrader:
                    if random.random() <= self.Lambda_mt:
                        order = t.process_signal(current_time, self.signal)
                        if order is None:
                            pass
                        else:
                            print(
                                "momentum trader: order {}, quantity {}, side {}, price {}"
                                .format(order["order_id"], order["quantity"],
                                        order["side"], order["price"]))
                            self.exchange.process_order(order)
                            if self.exchange.traded:
                                self.confirmTrades()
                                top_of_book = self.exchange.report_top_of_book(
                                    current_time)
                                self.signal.calculate_mid_price(top_of_book)
                                self.signal.calculate_volatility()
                                if self.signal.demand_updated:
                                    self.signal.demand[-1] += order["quantity"]
                                else:
                                    self.signal.demand.append(
                                        order["quantity"])
                else:  # Trader is Market Maker
                    if random.random() <= self.Lambda_mm:
                        quotes = t.process_signal(current_time, self.signal)
                        for q in quotes:
                            self.exchange.process_order(q)
                        top_of_book = self.exchange.report_top_of_book(
                            current_time)
                        self.signal.calculate_mid_price(top_of_book)
                        self.signal.calculate_volatility()
            if not current_time % write_interval:
                self.exchange.order_history_to_h5(self.h5filename)
                self.exchange.sip_to_h5(self.h5filename)

    def qTakeToh5(self):
        temp_df = pd.DataFrame({
            'qt_take': self.q_take,
            'lambda_t': self.lambda_t
        })
        temp_df.to_hdf(self.h5filename,
                       'qtl',
                       append=True,
                       format='table',
                       complevel=5,
                       complib='blosc')

    def mmProfitabilityToh5(self):
        for m in self.marketmakers:
            temp_df = pd.DataFrame(m.cash_flow_collector)
            temp_df.to_hdf(self.h5filename,
                           'mmp',
                           append=True,
                           format='table',
                           complevel=5,
                           complib='blosc')