Example #1
0
def execute_sell_order(order: 'Order', base_wallet: 'Wallet',
                       quote_wallet: 'Wallet', current_price: float,
                       options: 'ExchangeOptions', clock: 'Clock') -> 'Trade':
    if order.type == TradeType.LIMIT and order.price > current_price:
        return None

    filled = order.remaining.contain(order.exchange_pair)

    commission = options.commission * filled
    quantity = filled - commission

    if commission.size < Decimal(10)**-quantity.instrument.precision:
        order.cancel("COMMISSION IS LESS THAN PRECISION.")
        return None

    # Transfer Funds from Quote Wallet to Base Wallet
    transfer = Wallet.transfer(source=quote_wallet,
                               target=base_wallet,
                               quantity=quantity,
                               commission=commission,
                               exchange_pair=order.exchange_pair,
                               reason="SELL")

    trade = Trade(order_id=order.id,
                  step=clock.step,
                  exchange_pair=order.exchange_pair,
                  side=TradeSide.SELL,
                  trade_type=order.type,
                  quantity=transfer.quantity,
                  price=transfer.price,
                  commission=transfer.commission)

    return trade
    def adjust_trade(self, trade: Trade) -> Trade:
        price_slippage = np.random.uniform(0, self.max_slippage_percent / 100)

        initial_price = trade.price

        if trade.type == TradeType.MARKET:
            if trade.side == TradeSide.BUY:
                trade.price = max(initial_price * (1 + price_slippage), 1e-3)
            else:
                trade.price = max(initial_price * (1 - price_slippage), 1e-3)
        else:
            if trade.side == TradeSide.BUY:
                trade.price = max(initial_price * (1 + price_slippage), 1e-3)

                if trade.price > initial_price:
                    trade.size *= min(initial_price / trade.price, 1)
            else:
                trade.price = max(initial_price * (1 - price_slippage), 1e-3)

                if trade.price < initial_price:
                    trade.size *= min(trade.price / initial_price, 1)

        return trade
Example #3
0
def execute_buy_order(order: 'Order', base_wallet: 'Wallet',
                      quote_wallet: 'Wallet', current_price: float,
                      options: 'ExchangeOptions', exchange_id: str,
                      clock: 'Clock') -> 'Trade':
    price = contain_price(current_price, options)

    if order.type == TradeType.LIMIT and order.price < current_price:
        return None

    commission = Quantity(order.pair.base, order.size * options.commission,
                          order.path_id)
    size = contain_size(order.size - commission.size, options)

    if order.type == TradeType.MARKET:
        scale = order.price / price
        size = contain_size(scale * order.size - commission.size, options)

    base_wallet -= commission.reason("COMMISSION FOR BUY")

    try:
        quantity = Quantity(order.pair.base, size, order.path_id)
        base_wallet -= quantity.reason("REMOVE FROM LOCKED TO FILL ORDER")
    except InsufficientFunds:
        balance = base_wallet.locked[order.path_id]
        quantity = Quantity(order.pair.base, balance.size, order.path_id)
        base_wallet -= quantity.reason(
            "REMOVE FROM LOCKED TO FILL ORDER (INSUFFICIENT FUNDS)")

    quote_size = (order.price / price) * (size / price)

    filled_quantity = Quantity(order.pair.quote, quote_size, order.path_id)
    quote_wallet += filled_quantity.reason("BOUGHT @ {} {}".format(
        price, order.pair))

    trade = Trade(order_id=order.id,
                  exchange_id=exchange_id,
                  step=clock.step,
                  pair=order.pair,
                  side=TradeSide.BUY,
                  trade_type=order.type,
                  quantity=quantity,
                  price=price,
                  commission=commission)

    return trade
Example #4
0
def execute_buy_order(order: 'Order',
                      base_wallet: 'Wallet',
                      quote_wallet: 'Wallet',
                      current_price: float,
                      options: 'ExchangeOptions',
                      exchange_id: str,
                      clock: 'Clock') -> 'Trade':
    price = contain_price(current_price, options)

    if order.type == TradeType.LIMIT and order.price < current_price:
        return None

    commission = Quantity(order.pair.base, order.size * options.commission, order.path_id)
    size = contain_size(order.size - commission.size, options)

    if order.type == TradeType.MARKET:
        scale = order.price / price
        size = contain_size(scale * order.size - commission.size, options)

    base_wallet -= commission

    try:
        quantity = Quantity(order.pair.base, size, order.path_id)
        base_wallet -= quantity
    except InsufficientFunds:
        balance = base_wallet.locked[order.path_id]
        quantity = Quantity(order.pair.base, balance.size, order.path_id)
        base_wallet -= quantity

    quote_size = (order.price / price) * (size / price)
    quote_wallet += Quantity(order.pair.quote, quote_size, order.path_id)

    trade = Trade(order_id=order.id,
                  exchange_id=exchange_id,
                  step=clock.step,
                  pair=order.pair,
                  side=TradeSide.BUY,
                  trade_type=order.type,
                  quantity=quantity,
                  price=price,
                  commission=commission)

    return trade
Example #5
0
def execute_buy_order(order: 'Order', base_wallet: 'Wallet',
                      quote_wallet: 'Wallet', current_price: float,
                      options: 'ExchangeOptions', clock: 'Clock') -> 'Trade':
    if order.type == TradeType.LIMIT and order.price < current_price:
        return None

    filled = order.remaining.contain(order.exchange_pair)

    if order.type == TradeType.MARKET:
        scale = order.price / max(current_price, order.price)
        filled = scale * filled

    commission = options.commission * filled
    quantity = filled - commission

    if commission.size < Decimal(10)**-quantity.instrument.precision:
        order.cancel("COMMISSION IS LESS THAN PRECISION.")
        return None

    transfer = Wallet.transfer(source=base_wallet,
                               target=quote_wallet,
                               quantity=quantity,
                               commission=commission,
                               exchange_pair=order.exchange_pair,
                               reason="BUY")

    trade = Trade(order_id=order.id,
                  step=clock.step,
                  exchange_pair=order.exchange_pair,
                  side=TradeSide.BUY,
                  trade_type=order.type,
                  quantity=transfer.quantity,
                  price=transfer.price,
                  commission=transfer.commission)

    return trade