Esempio n. 1
0
def test_hedge():
    enter_price = Decimal('989')
    target_price = Decimal('-1012')
    prior_pos = Position(pos=Decimal('0.07'),
                         price=Decimal('1020'),
                         side=Side.BID)

    #hedge over other side
    hedge_pos = hedge_position(prior_pos, target_price, enter_price)

    print("---------------- hedge over other side")
    print("prior " + str(prior_pos))
    print("hedge " + str(hedge_pos))
    print("fin " + str(prior_pos + hedge_pos))

    #hedge over same side
    hedge_pos = hedge_position(prior_pos, target_price, Decimal('-1011'))
    print("---------------- hedge over same side")
    print("prior " + str(prior_pos))
    print("hedge " + str(hedge_pos))
    print("fin " + str(prior_pos + hedge_pos))

    #from reality
    prior_pos = Position(pos=Decimal('0.07'),
                         price=Decimal('1131.2700'),
                         side=Side.ASK)
    hedge_pos = hedge_position(prior_pos, Decimal('-1159.2805'),
                               Decimal('1161.4102'))
    print("---------------- real situation")
    print("prior " + str(prior_pos))
    print("hedge " + str(hedge_pos))
    print("fin " + str(prior_pos + hedge_pos))


#test_hedge()
Esempio n. 2
0
def exit_price_test_func(book, pandl, broker):
    config = MMParams({
        "min_levels": "5",
        "liq_behind_exit": "0.02",
        "liq_behind_entry": {"BID": "0.41", "ASK": "0.41"},
        "order_sizes": {"BID": "0.07", "ASK": "0.07"},
        "min_profit": "0.01",
        "min_order_size": "0.01",
        "buried_volume": "1",
        "taker_exit_profit": "0.1",
        "price_tolerance": "0.0005"
    })
    start_position = Position(pandl.position(), pandl.balance())
    print("before " + str(start_position))
    exit_order = remove_exit_price_strategy(book, start_position, config)
    pandl.execution(exit_order.side(), exit_order.abs_position(), exit_order.price())
    broker.request(0, exit_order.side(), exit_order.price(), exit_order.abs_position())
    keys = broker.om.by_oid.keys()
    tmp = ''
    for x in keys:
        tmp = x

    broker.om.on_ack(Ack(tmp, 1, start_position.abs_position(), start_position.abs_position()))
    print_book_and_orders(book, broker)
    print("after " + str(exit_order))
    assert pandl.closed_pnl > 0
    return exit_order
Esempio n. 3
0
    def execution(self, tx: Exec):
        exec_pos = Position(pos=tx.delta, price=tx.price, side=tx.side)
        if tx.delta > 0:
            self.pos += exec_pos + exec_pos.fee_pos(tx.fee)

        if self.pos.position() == 0:
            self.closed_pnl += self.pos.balance
            self.pos = Position(0, 0)
            self.zero_position_time = time.time()
Esempio n. 4
0
 def __init__(self, fee):
     self.method = BipolarContainer('NONE', 'NONE')
     self.pos = Position(0, 0)
     self.nbbo = BipolarContainer(0, 0)
     self.closed_pnl = Decimal('0')
     self.clean_closed_pnl = Decimal('0')
     self.exit_price = Decimal('0')
     self.fee = Decimal(fee)
     self.ema = EMAHolder(5 * 60)
     self.zero_position_time = time.time()
Esempio n. 5
0
def test_pos():
    bid = Position(pos=Decimal('1'), price=100, side=Side.ASK) + Position(pos=Decimal('0.1'), price=101, side=Side.BID)
    assert bid.position() == Decimal('-0.9')
    assert bid.side() == Side.ASK

    bid = Position(pos=Decimal('1'), price=100, side=Side.BID) + Position(pos=Decimal('0.1'), price=101, side=Side.ASK)
    assert bid.position() == Decimal('0.9')
    assert bid.side() == Side.BID

    print(bid)
Esempio n. 6
0
    def take_pnl(self):
        if self.pos.position() == 0:
            return Decimal('0')
        exit_side = Side.opposite_side(self.position())
        take_price = self.nbbo.side(Side.side(self.position()))
        take_order = Position(pos=self.pos.abs_position(),
                              price=take_price,
                              side=exit_side)
        take_pos = self.pos + take_order + take_order.fee_pos(self.fee)

        return take_pos.balance
Esempio n. 7
0
def test_hedge_order():
    position = Position(side=Side.BID,
                        price=Decimal('1500'),
                        pos=Decimal('0.01'))
    hedge_pos = hedge_positon_size(position,
                                   Decimal('1500') * Decimal('1.01'),
                                   Decimal('0.01'))
    print(hedge_pos)
    print(position + hedge_pos)
Esempio n. 8
0
 def hedge_workflow(prior_pos: Position, target_price, enter_price):
     # define current state
     pandl.execution(prior_pos.side(), prior_pos.abs_position(),
                     prior_pos.price())
     exit_order = remove_exit_price_strategy(book, prior_pos, None)
     #place exit order
     broker.request(0, exit_order.side(), exit_order.price(),
                    exit_order.abs_position())
     # calc hedge order
     hedge_pos = hedge_position(prior_pos, target_price, enter_price)
     #place hedge order
     broker.request(1, hedge_pos.side(), hedge_pos.price(),
                    hedge_pos.abs_position())
     # exec hedge order
     pandl.execution(hedge_pos.side(), hedge_pos.abs_position(),
                     hedge_pos.price())
     # look at new exit
     exit_order = remove_exit_price_strategy(
         book, Position(pandl.pos(), pandl.balance()), None)
Esempio n. 9
0
def test_exit_price_strategy():
    # remove
    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('900'), side=Side.BID)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('989')
    assert eo.side() == Side.ASK
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0
    #remove
    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('900'), side=Side.BID)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('989')
    assert eo.side() == Side.ASK
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0
    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('1100'), side=Side.ASK)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('1011')
    assert eo.side() == Side.BID
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0
    #quote
    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('1010'), side=Side.BID)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('1011')
    assert eo.side() == Side.ASK
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0
    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('990'), side=Side.ASK)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('989')
    assert eo.side() == Side.BID
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0
    #min profit
    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('1013'), side=Side.BID)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('1013.1427')
    assert eo.side() == Side.ASK
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0

    prior_pos = Position(pos=Decimal('0.07'), price=Decimal('900'), side=Side.ASK)
    eo = simulator_env(exit_price_test_func, prior_pos)
    assert eo.price() == Decimal('899.8572')
    assert eo.side() == Side.BID
    pos = prior_pos + eo
    print("reminder " + str(pos))
    assert pos.balance > 0
Esempio n. 10
0
 def order_event(self, ev):
     try:
         self.order_manager.market_event(ev)
         if type(ev) == ErrorRequest:
             self.event_hub.order_error(str(ev))
             if ev.error_class != ErrorRequest.ORDER_NOT_FOUND:
                 self.rm.set_cancel_all()
         elif type(ev) == Exec and ev.delta > 0:
             if self.pnl.exit_method() == "REMOVE":
                 ev.fee = self.pnl.fee
             self.pnl.execution(ev)
             exec_time = time.strftime("%H:%M:%S", time.localtime())
             order_fee = Position(pos=ev.delta,
                                  price=ev.price,
                                  side=ev.side).fee_pos(ev.fee).balance
             self.execution_sink.append({
                 "time":
                 exec_time,
                 'order_id':
                 ev.order_id,
                 'side':
                 ev.side,
                 'price':
                 str(ev.price),
                 'size':
                 str(ev.delta),
                 'timestamp':
                 int(1000 * time.time()),
                 'method':
                 str(self.pnl.exit_method()),
                 'P&L':
                 str(self.pnl.closed_pnl),
                 'fee':
                 str(order_fee)
             })
             self.on_exec(ev)
     except UnknownOid:
         self.event_hub.order_error('Unknown oid ' + ev.oid)
         self.rm.set_cancel_all()
     except UnknownOrderId:
         self.event_hub.order_error('Unknown order id ' + ev.order_id)
         self.rm.set_cancel_all()
     except ExecHasNoEffect:
         pass
     except NegativeAmountAfterExec:
         self.event_hub.order_error('NegativeAmountAfterExec')
         self.rm.set_cancel_all()
     except UnknownExec:
         self.event_hub.order_error('UnknownExec order_id: ' + str(ev))
         self.rm.set_cancel_all()
Esempio n. 11
0
def test_eneter_hedge(pos: Position):
    print("pos" + str(pos))
    book = gen_book()
    pnl = PNL(Decimal('0.16'))
    pnl.quote_changed(book.quote(Side.BID))
    pnl.quote_changed(book.quote(Side.ASK))
    pnl.pos = pos
    config: AppConfig = load_config('config.json')
    hedge = enter_hedge(pnl, book, pos.side(), config.algo, config.venue)
    print("hedge " + str(hedge[0]) + " method " + hedge[1])
    print("after hedge " + str(hedge[0] + pos))
    #print("after hedge " + str(hedge[0]+pos))
    print('-----------')
    pass
Esempio n. 12
0
def simulator_env(func, pos=Position(pos=0, balance=0), book_median=1000):
    pandl = PNL('0.3')
    book = Book()
    book.quote_subscribers.append(pandl)
    broker = Broker(OrderManager())

    pandl.execution(pos.side(), abs(pos.position()), abs(pos.price()))

    for i in range(0, 6):
        book.increment_level(Side.ASK, Decimal(book_median + 10 + randrange()),
                             Decimal(i / 100))
        book.increment_level(Side.BID, Decimal(book_median - 10 - i),
                             Decimal(i / 100))
        book.quote_changed(Side.BID)
        book.quote_changed(Side.ASK)

    return func(book, pandl, broker)
Esempio n. 13
0
 def __init__(self, algo_class, config: AppConfig):
     self.config = config
     self.event_log = ClientEventHandler()
     self.order_manager = OrderManager()
     self.book = Book()
     self.pnl = PNL(config.venue.taker_comission_percent)
     self.pnl.pos = Position(pos=config.venue.start_pos,
                             balance=config.venue.start_balance)
     self.book.quote_subscribers.append(self.pnl)
     self.execution = Broker(self.order_manager)
     self.algo = algo_class(self)
     self.execution_sink = []
     self.snapid = -1
     self.event_hub = EventHub()
     self.event_hub.subscribe(self.book)
     self.event_hub.subscribe(self.algo)
     self.event_hub.subscribe(self.event_log)
     self.event_hub.subscribe(self.order_manager)
     self.rm = RiskManager(self.execution, self.event_hub)
Esempio n. 14
0
def enter_hedge(pnl: PNL, book: Book, side, cfg: HedgeConfig, vc: VenueConfig):
    quote = book.quote(side)
    side = quote.side
    pos = pnl.pos
    order_size = cfg.order_size.side(side)
    theo = (book.quote(Side.BID).price + book.quote(Side.ASK).price) / 2
    if pos.abs_position() < vc.min_order_size:
        # depth or ema
        order_size = adjusted_size(order_size, side, pos.abs_position())
        method, price = depth_ema_price(cfg, order_size, pnl, quote, side, vc)
        return Position(pos=order_size, side=side, price=price), method
    elif Side.opposite(
            pos.side()) == side and pos.abs_position() >= vc.min_order_size:
        # exit order
        # depth or zero
        method, price = depth_ema_price(cfg, order_size, pnl, quote, side, vc)

        add_pos = pos.oppoiste_with_price(price)
        min_margin = pos.opposite_with_margin(vc.tick_size)
        min_margin = bound_pos_to_lower_quote(quote, min_margin, vc.tick_size)

        if (pos + add_pos).balance > 0:
            return add_pos, "QUOTE"
        else:
            return min_margin, "MIN PROFIT"
    elif pos.side(
    ) == side and cfg.max_pos - pos.abs_position() >= vc.min_order_size:
        #depth
        #hedge
        #order_size = adjusted_size(order_size, side, pos.abs_position())
        method, price_depth = depth_ema_price(cfg, order_size, pnl, quote,
                                              side, vc)

        order_size = min(order_size, cfg.max_pos - pos.abs_position())
        depth_pos = Position(pos=order_size, side=side, price=price_depth)
        sign = Side.sign(pos.side())

        target_price = theo - Side.sign(pos.side()) * theo * cfg.hedge_perc
        hedge_pos = hedge_positon_size(pos, Decimal(target_price), order_size)
        hedge_pos = bound_pos_to_lower_quote(quote, hedge_pos, vc.tick_size)
        #return hedge_pos, "HEDGE HEDGE"
        if (side == Side.BID and hedge_pos.price() < depth_pos.price()) \
                or (side == Side.ASK and hedge_pos.price() > depth_pos.price()):
            return hedge_pos, "HEDGE HEDGE"
        else:
            return depth_pos, "HEDGE DEPTH"

    else:
        #zero
        return Position(side=side, pos=0, balance=0), "CANCEL"
Esempio n. 15
0
def remove_exit_price_strategy(book: Book,
                               pos: Position,
                               config: MarketmakerConfig,
                               fee=Decimal(0.3)):
    # pos, last_price = remove_price(book.quote(pos.side()), pos)
    # if pos.balance > 0:
    #     remove_pos = pos.oppoiste_with_price(last_price)
    # print("fee " + str(pos * Decimal('0.3')))
    remove_pos = pos.oppoiste_with_price(book.quote(pos.side()).price)
    remove_pos_wfee = Position(pos=remove_pos.position(),
                               balance=remove_pos.balance +
                               (remove_pos.balance / 100) * fee)
    add_pos = pos.oppoiste_with_price(
        book.quote(Side.opposite(pos.side())).price)
    fee_ = remove_pos * Decimal(fee / 100)
    fin_pos = pos + remove_pos
    if (pos + remove_pos_wfee).balance > 0:
        return remove_pos
    elif (pos + add_pos).balance > 0:
        return add_pos
    else:
        return pos.opposite_with_margin(config.min_profit)
Esempio n. 16
0
 def volume_behind_order(min_pos: Position):
     sign = Side.sign(min_pos.side())
     return sum([
         level.volume() for level in book.quote(min_pos.side())
         if sign * level.price > sign * min_pos.price()
     ])
Esempio n. 17
0
from posmath.position import Position, BID, ASK

print(Position(pos=10, balance=-100))
print(BID(pos=10, balance=100))
print(Position(pos=-10, balance=100))
print(ASK(pos=10, balance=100))
print(BID(pos=10, balance=99) + ASK(pos=10, balance=100))
Esempio n. 18
0
 def nbbo_pnl(self):
     exit_side = Side.opposite_side(self.position())
     nbbo_price = self.nbbo.side(exit_side)
     return (self.pos + Position(pos=self.pos.abs_position(),
                                 price=nbbo_price,
                                 side=exit_side)).balance
Esempio n. 19
0
class PNL:
    def __init__(self, fee):
        self.method = BipolarContainer('NONE', 'NONE')
        self.pos = Position(0, 0)
        self.nbbo = BipolarContainer(0, 0)
        self.closed_pnl = Decimal('0')
        self.clean_closed_pnl = Decimal('0')
        self.exit_price = Decimal('0')
        self.fee = Decimal(fee)
        self.ema = EMAHolder(5 * 60)
        self.zero_position_time = time.time()

    def execution(self, tx: Exec):
        exec_pos = Position(pos=tx.delta, price=tx.price, side=tx.side)
        if tx.delta > 0:
            self.pos += exec_pos + exec_pos.fee_pos(tx.fee)

        if self.pos.position() == 0:
            self.closed_pnl += self.pos.balance
            self.pos = Position(0, 0)
            self.zero_position_time = time.time()
            # self.clean_closed_pnl += self.closed_pnl
            # self.closed_pnl = 0

    def position(self):
        return self.pos.position()

    def abs_position(self):
        return self.pos.abs_position()

    def quote_changed(self, quote):
        self.nbbo.set_side(quote.side, quote.price)
        if self.nbbo.bid() == 0 or self.nbbo.ask() == 0:
            return
        mid_price = (self.nbbo.bid() + self.nbbo.ask()) / 2
        self.ema.add(mid_price)

    def balance(self):
        return self.pos.balance

    def open_pnl(self):
        return self.balance() + self.position() * self.exit_price

    def update_open_pnl(self, exit_price):
        self.exit_price = exit_price

    def nbbo_pnl(self):
        exit_side = Side.opposite_side(self.position())
        nbbo_price = self.nbbo.side(exit_side)
        return (self.pos + Position(pos=self.pos.abs_position(),
                                    price=nbbo_price,
                                    side=exit_side)).balance

    def take_pnl(self):
        if self.pos.position() == 0:
            return Decimal('0')
        exit_side = Side.opposite_side(self.position())
        take_price = self.nbbo.side(Side.side(self.position()))
        take_order = Position(pos=self.pos.abs_position(),
                              price=take_price,
                              side=exit_side)
        take_pos = self.pos + take_order + take_order.fee_pos(self.fee)

        return take_pos.balance

    def position_zero_price(self):
        if self.abs_position() == 0:
            return Decimal('0')
        else:
            return abs(self.balance() / self.abs_position())

    def position_side(self):
        return Side.side(self.position())

    def set_order_method(self, side, method):
        self.method.set_side(side, method)

    def exit_method(self):
        return str(self.method)
Esempio n. 20
0
def calc_target_price(theo: Decimal, pos: Position, hedge_perc: Decimal):
    #exit_side = Side.opposite(pos.side())
    sign = Side.sign(pos.side())
    theo_target = theo - Side.sign(pos.side()) * theo * hedge_perc
    pos_target = pos.price() - sign * theo * hedge_perc
    return theo_target
Esempio n. 21
0
def hedge_positon_size(prior_pos, target_price, hedge_size):
    x = (target_price * (prior_pos.abs_position() + hedge_size) -
         prior_pos.price() * prior_pos.abs_position()) / hedge_size
    return Position(price=x, pos=hedge_size, side=prior_pos.side())
Esempio n. 22
0
def bound_pos_to_lower_quote(quote: Level, pos: Position, tick_size):
    lower_quote_price = bound_price_to_lower_quote(quote, pos.price(),
                                                   tick_size)
    return Position(side=pos.side(),
                    price=lower_quote_price,
                    pos=pos.abs_position())
Esempio n. 23
0
    print("pos" + str(pos))
    book = gen_book()
    pnl = PNL(Decimal('0.16'))
    pnl.quote_changed(book.quote(Side.BID))
    pnl.quote_changed(book.quote(Side.ASK))
    pnl.pos = pos
    config: AppConfig = load_config('config.json')
    hedge = enter_hedge(pnl, book, pos.side(), config.algo, config.venue)
    print("hedge " + str(hedge[0]) + " method " + hedge[1])
    print("after hedge " + str(hedge[0] + pos))
    #print("after hedge " + str(hedge[0]+pos))
    print('-----------')
    pass


test_stick_to_quote(Position(pos='0.01', price='1300', side=Side.BID))
test_stick_to_quote(Position(pos='0.01', price='1297', side=Side.BID))

test_stick_to_quote(Position(pos='0.01', price='1300', side=Side.ASK))
test_stick_to_quote(Position(pos='0.01', price='1302', side=Side.ASK))

test_target_price(Position(pos='0.01', price='1300', side=Side.BID))  # good
test_target_price(Position(pos='0.01', price='1300', side=Side.BID))  # good
test_target_price(Position(pos='0.01', price='1500', side=Side.BID))  # perfect

test_target_price(Position(pos='0.01', price='1300', side=Side.ASK))
test_target_price(Position(pos='0.01', price='1500', side=Side.ASK))
test_target_price(Position(pos='0.01', price='1000', side=Side.ASK))

# bought for 1300
# risk - price goes down
Esempio n. 24
0
def hedge_position(prior_pos, target_price, enter_price):
    x = (target_price * prior_pos.position() -
         prior_pos.balance) / (enter_price - target_price)
    return Position(price=enter_price, pos=x)
Esempio n. 25
0
def test_fee():
    def test_case(pos, order):
        fee_pos = order.fee_pos('0.18')
        print("pos " + str(pos))
        print("order " + str(order))
        print("fee " + str(fee_pos))
        wo_fee = pos + order
        w_fee = pos + order + fee_pos
        print("wo_fee " + str(wo_fee))
        print("w_fee " + str(w_fee))
        assert wo_fee.balance >= w_fee.balance, "pos " + str(
            pos) + " order" + str(order)
        assert (abs(fee_pos.balance) < abs(order.balance)) or (order.balance ==0 and fee_pos.balance==0)\
            , "fee " + fee_pos.balance+" order cost " + order.balance

    pos = Position(pos=Decimal('1'), balance=Decimal('1199'), side=Side.BID)
    order = Position(pos=Decimal('1'), balance=Decimal('1200'), side=Side.ASK)
    test_case(order, pos)
    print('---------')
    test_case(pos, order)
    print('---------')
    pos = Position(pos=Decimal('0.01'), balance=Decimal('1199'), side=Side.BID)
    order = Position(pos=Decimal('0.01'),
                     balance=Decimal('1200'),
                     side=Side.ASK)
    test_case(pos, order)
    print('---------')
    pos = Position(pos=Decimal('0.01'), balance=Decimal('12'), side=Side.BID)
    order = Position(pos=Decimal('0.01'), price=Decimal('1201'), side=Side.ASK)
    test_case(order, pos)
    print('---------')
    test_case(pos, order)
    print('---------')
    pos = Position(pos=Decimal('0'), balance=Decimal('0'), side=Side.BID)
    order = Position(pos=Decimal('0.01'), price=Decimal('1201'), side=Side.ASK)
    print("order fee " + str(order.fee_pos(Decimal('0.18')).balance))
    test_case(pos, order)
    print('---------')
    test_case(order, pos)
    assert pos + order == pos + order + order.fee_pos(0)