Ejemplo n.º 1
0
    def set_initial_holdings(self, user_holdings):
        """
        Initialize each bot with the same base endowment + additional endowment in U[0, 5].
        All bots have the same cash holding.
        :param user_holdings:
        :return:
        """
        try:
            markets = []
            for item in self.market_items:
                markets.append(Market.get_by_item(item))
            for email, holdings in user_holdings.items():
                for market in markets:
                    if email not in self.endow:
                        holdings.assets[market].units_initial = 0
                    else:
                        holdings.assets[market].units_initial = int(
                            self.endow[email][market.item][0])
                    holdings.cash_initial = self.base_cash
        except Exception as e:
            self.error(e)

        try:
            self.update_holdings(user_holdings,
                                 self.initial_holdings_updated_callback)
        except Exception as e:
            self.error(e)
Ejemplo n.º 2
0
    def set_initial_holdings(self, user_holdings):
        """
        Initialize each bot with the same base endowment + additional endowment in U[0, 5].
        All bots have the same cash holding.
        :param user_holdings:
        :return:
        """
        self.inform(
            "I have received old holdings. I will now calculate the initial holdings."
        )
        markets = []
        for item in self.market_items:
            markets.append(Market.get_by_item(item))
        # Calculate the base endowment for the next round
        round_endow = random.randint(0, self.upper_endow)
        self.inform("Base endowment for round 1 is: {}".format(round_endow))
        for email, holdings in user_holdings.items():
            for market in markets:
                holdings.assets[
                    market].units_initial = round_endow + random.randint(
                        0, self.upper_endow)
                holdings.cash_initial = self.base_cash

        try:
            self.update_holdings(user_holdings,
                                 self.initial_holdings_updated_callback)
        except Exception as e:
            self.error(e)
Ejemplo n.º 3
0
    def _send_valid_mm_orders(self):
        """
        Executes list of valid market maker orders
        :return: List[Order] of valid orders
        """
        for key in self._mm_orders:

            order = Order.create_new()
            order.market = Market(self._market_ids[key[0]])
            price_tick = order.market.price_tick

            price = self._mm_orders[key] - \
                          (self._mm_orders[key] % price_tick)

            if price <= order.market.min_price:
                price = order.market.min_price
            elif price >= order.market.max_price:
                price = order.market.max_price

            order.price = price

            order.order_side = key[-1]
            order.order_type = OrderType.LIMIT
            order.units = 1

            if order.market.min_price <= order.price <= order.market.max_price:
                self._order_id += 1
                self._num_orders_sent += 1
                self._num_active_mm_orders += 1
                self.send_order(order)
        return
Ejemplo n.º 4
0
    def _create_new_order(self,
                          price: int,
                          units: int,
                          order_side: OrderSide,
                          order_type: OrderType,
                          ref: str,
                          is_private: bool):
        """
        :param price: determined price
        :param units: # of units to be submitted, fixed to 1
        :param order_side: buy or sell
        :param order_type: limit or market, fixed to limit
        :param ref: customer string of format "Order: {self._sent_order_count} - SM"
        :return:
        """
        new_order = Order.create_new()

        if is_private:
            market = self._private_market_id
            new_order.owner_or_target = "M000"
        else:
            market = self._public_market_id

        new_order.market = Market(market)
        new_order.price = price
        new_order.units = units
        new_order.order_side = order_side
        new_order.order_type = order_type
        new_order.ref = ref

        self.send_order(new_order)
        self._waiting_for_server = True
Ejemplo n.º 5
0
    def set_initial_holdings(self, user_holdings):
        """
        Initialize each bot with the same base endowment + additional endowment in U[0, 5].
        All bots have the same cash holding.
        :param user_holdings:
        :return:
        """
        self.inform("Starting run " + str(self.label) + " of simulations.")
        try:
            market = Market.get_by_item(MARKET_1)
            for email, holdings in user_holdings.items():
                print(email)
                if email not in self.endow:
                    holdings.assets[market].units_initial = 0
                else:
                    holdings.assets[market].units_initial = int(
                        self.endow[email][0])
                holdings.cash_initial = self.base_cash
        except Exception as e:
            self.inform(e)

        try:
            self.update_holdings(user_holdings,
                                 self.initial_holdings_updated_callback)
        except Exception as e:
            self.inform(e)
Ejemplo n.º 6
0
    def received_holdings(self, holdings):
        """
        Updates to necessary information whenever a trade is executed
        """
        # Informs of initial details 
        if self._find_time_elapsed() < 1/30: 
            # Trader ID
            self.inform(holdings.name)

            # Initial allocation of holdings
            self.inform('---')
            self.inform(f'Total cash: {holdings.cash}, Available cash: {holdings.cash_available}')
            for market, assets in (sorted(holdings.assets.items(), key = lambda x: x[0].item)):
                self.inform(f'{market.name} - Total units: {assets.units}, Available units: {assets.units_available}')

        #Update fair prices whenever holdings change
        for market_id, market_info in sorted(self.markets.items()):
            security = market_info.item
            self._fair_buy_prices[security] = self._find_fair_price(market_id, holdings, OrderSide.BUY)
            self._fair_sell_prices[security] = self._find_fair_price(market_id, holdings, OrderSide.SELL)
        
        # Trade notes for cash if cash is below $10.00 and there are 
        # sufficient notes. Taking a small decrease in performance.
        # Assumes the note market is the one with the highest market id
        note_id = sorted(self._market_ids.values())[-1]
        if holdings.cash < 1000 and holdings.assets[Market(note_id)].units \
            > 2 and self._order_count == 0:
            order = self._make_order(note_id, OrderSide.SELL, 495, units = 2)
            if self._check_holdings(order, holdings, True):
                self.send_order(order)
                self._order_count += 2
Ejemplo n.º 7
0
    def received_orders(self, orders: List[Order]):
        orders_avail = orders
        for o in orders_avail:
            # inform method just logs the messages
            self.inform(o)
            if o.mine:
                self.inform(o.owner, o.owner_or_target)

            # cancelling an order, make sure to check all orders sent are accepted
            # if o.mine:
            #     cancel_order = copy.copy(o)
            #     cancel_order.order_type = OrderType.CANCEL
            #     self.send_order(cancel_order)

        # order has attribute mine (bool) to know if our order or not

        # order.all() fetches all previous orders, and we don't need to physically track all changes,
        # we can query this order.all() data to find the status of the order
        # all_orders = Order.all()

        if not self._order_sent:
            order = Order.create_new()
            order.market = Market(1573)
            order.order_side = OrderSide.BUY
            order.order_type = OrderType.LIMIT
            order.price = 100
            order.ref = "rip"
            order.units = 1

            # we will know this owner/target from the private orders we receive
            # Manager is always M000

            order.owner_or_target = "T002"  # sending private orders, the market code should be changed to 1573
            self.send_order(order)
            self._order_sent = True
Ejemplo n.º 8
0
    def order_rejected(self, info, order: Order):

        price = order.price
        units = order.units

        if order.is_private:
            market = Market(self._private_market_id)
        else:
            market = Market(self._public_market_id)

        #possible reasons for a rejected order
        if price > market.max_price or price < market.min_price:
            self.inform("Order rejected, price out of range")
        elif units > market.max_units or price < market.min_units:
            self.inform("Order rejected, units out of range")
        elif price % market.price_tick != 0:
            self.inform("Order rejected, price not divisible by price tick")
        elif units % market.unit_tick != 0:
            self.inform("Order rejected, units not divisible by unit tick")

        self._waiting_for_order = False
Ejemplo n.º 9
0
 def _make_order(self, market_id, oside, price, otype = OrderType.LIMIT, \
     units = 1):
     """
     Makes and returns Order object with the defined parameters
     """
     new_order = Order.create_new()
     new_order.mine = True
     new_order.market = Market(market_id)
     new_order.order_side = oside
     new_order.order_type = otype
     new_order.price = price
     new_order.units = units
     new_order.ref = f'{otype} Order in {new_order.market.fm_id} \
          for {new_order.units}@{new_order.price}'
     return new_order
Ejemplo n.º 10
0
    def  Go_create_new_order(self,
                          price: int,
                          units: int,
                          order_side: OrderSide,
                          order_type: OrderType,
                          ref: str,
                          is_private: bool):
        """
        Creates a new order given the parameters
        :param price: determined price
        :param units: # of units to be submitted, fixed to 1
        :param order_side: buy or sell
        :param order_type: limit or market, fixed to limit
        :param ref: customer string of format "Order: {self._sent_order_count} - SM"
        :return:
        """

        new_order = Order.create_new()

        # derive order attributes
        if is_private:
            market = self._private_market_id
            new_order.owner_or_target = MANAGER_ID
        else:
            market = self._public_market_id

            # make sure price is rounded in the public market
            price -= price % self._price_tick

            # in case price goes less than the tick, or more than ten
            # set prices to the bounds
            if price < self._price_tick:
                price = self._price_tick
            elif price > MAX_PRICE:
                price = MAX_PRICE

        new_order.market = Market(market)
        new_order.price = price
        new_order.units = units
        new_order.order_side = order_side
        new_order.order_type = order_type
        new_order.ref = ref

        # send order through
        self._waiting_for_server = True
        self.send_order(new_order)

        self._tradeID += 1
Ejemplo n.º 11
0
    def _market_making_strategy(self):
        """
        MARKET MAKER STRATEGY
        =====================
        Simulate acquiring/disposing off one unit of each security to calculate
        the change in performance because of this balancing.

        This change in performance is determined to be the price the security
        should by bought/sold for (accounts for changing variance and
        changing expected return)

        That price is then adjusted by a PROFIT MARGIN, and submitted to the
        market
        """
        # do nothing if sending through orders
        if self._waiting or (len(self._asset_units.keys()) == 0):
            return

        self._mm_orders = {}

        # acquire list of all securities
        securities = list(self._payoffs.keys())

        # for each security, determine the prices of valid buys and sells that
        # can be created in the market
        order = Order.create_new()
        order.price = 0

        for security in securities:

            order.market = Market(self._market_ids[security])

            # create quasi buy order
            order.order_side = OrderSide.BUY
            self.is_portfolio_optimal([order])

            # create quasi sell order
            order.order_side = OrderSide.SELL
            self.is_portfolio_optimal([order])

        # filter out orders from potential orders that can't be executed
        # due to not enough cash / units
        self._remove_invalid_mm_orders()

        # # send valid market maker orders in the market
        if not self._waiting:
            self._waiting = True
            self._send_valid_mm_orders()
Ejemplo n.º 12
0
    def make_order(self, market_id, oside, price, otype = OrderType.LIMIT, \
        units = 1):
        """
        Makes and returns Order object with the defined parameters
        """
        new_order = Order.create_new()
        new_order.market = Market(market_id)
        new_order.order_side = oside
        new_order.order_type = otype
        new_order.price = price
        new_order.units = units
        new_order.ref = f'{otype} Order in {new_order.market} \
             for {new_order.units}@{new_order.price}'

        if market_id == self._private_market_id:
            new_order.owner_or_target = "M000"
        return new_order
Ejemplo n.º 13
0
    def initialised(self):
        """
        Initialises bot
        Stores the market id parameters for Order Management
        """
        # dict to track market attributes
        markets_to_trade = self.markets

        for key in markets_to_trade:
            self.inform(markets_to_trade[key])

            # initialise public and private market IDs
            if markets_to_trade[key].private_market:
                self._private_market_id = key
            else:
                self._public_market_id = key

        # track public market price tick
        self._price_tick = Market(self._public_market_id).price_tick
Ejemplo n.º 14
0
    def _sell_notes(self):
        """
        Determines if current cash level is below arbitrary threshold,
        if it yes, sells notes at a small loss
        :return:
        """
        # stop if initialising OR if have enough cash
        if len(self._asset_units.keys()) == 0 or \
                self._cash_available > MIN_CASH_THRESHOLD:
            return

        # find the note key
        note_key = ""
        for asset in self._asset_units:
            if asset.lower() == "note":
                note_key = asset

        # check if have notes available to short
        if self._asset_units[note_key] > self._short_units_allowed[note_key]:
            self.inform(f"Cash avail: {self._cash_available}")
            self.inform(f"Selling notes+++++++++++++++++++++++++++")

            # create note sell orders for some price to obtain quick cash
            market = Market(self._market_ids[note_key])
            price_tick = market.price_tick
            new_order = Order.create_new()
            new_order.price = NOTE_SELLING_PRICE - \
                              (NOTE_SELLING_PRICE % price_tick)
            new_order.market = market
            new_order.units = 1
            new_order.order_side = OrderSide.SELL
            new_order.order_type = OrderType.LIMIT

            new_order.ref = "Order need_cash - SM"

            self._waiting = True
            self._order_id += 1
            self._num_orders_sent += 1
            self.send_order(new_order)
Ejemplo n.º 15
0
    def _create_new_order(self, market: int, price: int, units: int,
                          order_side: OrderSide, order_type: OrderType,
                          ref: str):
        """
        :param market: market ID for the order
        :param price: determined price
        :param units: # of units to be submitted, fixed to 1
        :param order_side: buy or sell
        :param order_type: limit or market, fixed to limit
        :param ref: customer string of format "Order: {self._sent_order_count} - SM"
        :return:
        """
        new_order = Order.create_new()
        new_order.market = Market(market)
        new_order.price = price
        new_order.units = units
        new_order.order_side = order_side
        new_order.order_type = order_type
        new_order.ref = ref

        self.send_order(new_order)
        self._waiting_for_server = True
        self._sent_order_count += 1