Example #1
0
File: nb.py Project: yamen/vectorbt
def buy_in_cash_nb(run_cash, run_shares, order_price, order_cash, order_fees,
                   order_fixed_fees, order_slippage):
    """Buy shares for `order_cash` cash.

    Returns an updated cash and shares balance, and `vectorbt.portfolio.enums.FilledOrder`."""
    # Get offered cash
    offer_cash = min(run_cash, order_cash)

    # Get effective cash by subtracting costs
    if is_close_or_less_nb(offer_cash, order_fixed_fees):
        # Can't cover
        return run_cash, run_shares, None
    effect_cash = (offer_cash - order_fixed_fees) * (1 - order_fees)

    # Get price adjusted with slippage
    adj_price = order_price * (1 + order_slippage)

    # Get final size for that cash
    final_size = effect_cash / adj_price

    # Get paid fees
    fees_paid = offer_cash - effect_cash

    # Update current cash and shares
    run_shares += final_size
    if is_close_or_less_nb(run_cash, order_cash):
        run_cash = 0.  # numerical stability
    else:
        run_cash -= offer_cash
    return run_cash, run_shares, FilledOrder(final_size, adj_price, fees_paid,
                                             OrderSide.Buy)
Example #2
0
File: nb.py Project: yamen/vectorbt
def sell_in_shares_nb(run_cash, run_shares, order_price, order_size,
                      order_fees, order_fixed_fees, order_slippage):
    """Sell `order_size` shares.

    Returns an updated cash and shares balance, and `vectorbt.portfolio.enums.FilledOrder`."""

    # Get price adjusted with slippage
    adj_price = order_price * (1 - order_slippage)

    # Compute acquired cash
    final_size = min(run_shares, order_size)
    acq_cash = final_size * adj_price

    # Get final cash by subtracting costs
    final_cash = acq_cash * (1 - order_fees)
    if is_close_or_less_nb(run_cash + final_cash, order_fixed_fees):
        # Can't cover
        return run_cash, run_shares, None
    final_cash -= order_fixed_fees

    # Update fees
    fees_paid = acq_cash - final_cash

    # Update current cash and shares
    run_cash += final_size * adj_price - fees_paid
    if is_close_or_less_nb(run_shares, order_size):
        run_shares = 0.  # numerical stability
    else:
        run_shares -= final_size
    return run_cash, run_shares, FilledOrder(final_size, adj_price, fees_paid,
                                             OrderSide.Sell)
Example #3
0
def sell_nb(run_cash, run_shares, order):
    """Perform a Sell.

    Returns an updated cash and shares balance, the number of shares sold,
    the price adjusted with slippage, and fees paid."""

    # Compute acquired cash
    adj_price = order.price * (1 - order.slippage)
    adj_size = min(run_shares, abs(order.size))
    cash = adj_size * adj_price

    # Minus costs
    adj_cash = cash * (1 - order.fees)
    if is_close_or_less_nb(adj_cash, order.fixed_fees):
        # Can't cover
        return run_cash, run_shares, None
    adj_cash -= order.fixed_fees

    # Update fees
    fees_paid = cash - adj_cash

    # Update current cash and shares
    run_cash += adj_size * adj_price - fees_paid
    if is_close_or_less_nb(run_shares, abs(order.size)):
        run_shares = 0.  # numerical stability
    else:
        run_shares -= adj_size
    return run_cash, run_shares, FilledOrder(adj_size, adj_price, fees_paid,
                                             OrderSide.Sell)
Example #4
0
File: nb.py Project: yamen/vectorbt
def sell_in_cash_nb(run_cash, run_shares, order_price, order_cash, order_fees,
                    order_fixed_fees, order_slippage):
    """Sell shares for `order_cash` cash.

    Returns an updated cash and shares balance, and `vectorbt.portfolio.enums.FilledOrder`."""
    # Get price adjusted with slippage
    adj_price = order_price * (1 - order_slippage)

    # Get value required to complete this order
    req_value = (order_cash + order_fixed_fees) / (1 - order_fees)

    # Translate this to shares
    req_shares = req_value / adj_price

    if is_close_or_less_nb(req_shares, run_shares):
        # Sufficient shares
        final_size = req_shares
        fees_paid = req_value - order_cash

        # Update current cash and shares
        run_cash += order_cash
        run_shares -= req_shares
    else:
        # Insufficient shares, cash will be less than requested
        final_size = run_shares
        acq_cash = final_size * adj_price

        # Get final cash by subtracting costs
        final_cash = acq_cash * (1 - order_fees)
        if is_close_or_less_nb(run_cash + final_cash, order_fixed_fees):
            # Can't cover
            return run_cash, run_shares, None
        final_cash -= order_fixed_fees

        # Update fees
        fees_paid = acq_cash - final_cash

        # Update current cash and shares
        run_cash += final_cash
        run_shares = 0.
    return run_cash, run_shares, FilledOrder(final_size, adj_price, fees_paid,
                                             OrderSide.Sell)
Example #5
0
File: nb.py Project: yamen/vectorbt
def buy_in_shares_nb(run_cash, run_shares, order_price, order_size, order_fees,
                     order_fixed_fees, order_slippage):
    """Buy `order_size` shares.

    Returns an updated cash and shares balance, and `vectorbt.portfolio.enums.FilledOrder`."""

    # Get price adjusted with slippage
    adj_price = order_price * (1 + order_slippage)

    # Get cash required to complete this order
    req_cash = order_size * adj_price
    adj_req_cash = req_cash * (1 + order_fees) + order_fixed_fees

    if is_close_or_less_nb(adj_req_cash, run_cash):
        # Sufficient cash
        final_size = order_size
        fees_paid = adj_req_cash - req_cash

        # Update current cash and shares
        run_cash -= order_size * adj_price + fees_paid
        run_shares += final_size
    else:
        # Insufficient cash, size will be less than requested
        if is_close_or_less_nb(run_cash, order_fixed_fees):
            # Can't cover
            return run_cash, run_shares, None

        # For fees of 10% and 1$ per transaction, you can buy shares for 90$ (effect_cash)
        # to spend 100$ (adj_req_cash) in total
        effect_cash = (run_cash - order_fixed_fees) / (1 + order_fees)

        # Update size and fees
        final_size = effect_cash / adj_price
        fees_paid = run_cash - effect_cash

        # Update current cash and shares
        run_cash = 0.  # numerical stability
        run_shares += final_size

    # Return filled order
    return run_cash, run_shares, FilledOrder(final_size, adj_price, fees_paid,
                                             OrderSide.Buy)
Example #6
0
def buy_nb(run_cash, run_shares, order):
    """Perform a Buy.

    Returns an updated cash and shares balance, the number of shares bought,
    the price adjusted with slippage, and fees paid."""

    # Compute cash required to complete this order
    adj_price = order.price * (1 + order.slippage)
    req_cash = order.size * adj_price
    adj_req_cash = req_cash * (1 + order.fees) + order.fixed_fees

    if is_close_or_less_nb(adj_req_cash, run_cash):
        # Sufficient cash
        adj_size = order.size
        fees_paid = adj_req_cash - req_cash

        # Update current cash and shares
        run_cash -= adj_size * adj_price + fees_paid
        run_shares += adj_size
    else:
        # Insufficient cash, size will be less than requested
        if is_close_or_less_nb(run_cash, order.fixed_fees):
            # Can't cover
            return run_cash, run_shares, None

        # For fees of 10%, you can buy shares for 90.9$ (adj_cash) to spend 100$ (run_cash) in total
        adj_cash = (run_cash - order.fixed_fees) / (1 + order.fees)

        # Update size and feee
        adj_size = adj_cash / adj_price
        fees_paid = run_cash - adj_cash

        # Update current cash and shares
        run_cash = 0.  # numerical stability
        run_shares += adj_size

    # Return filled order
    return run_cash, run_shares, FilledOrder(adj_size, adj_price, fees_paid,
                                             OrderSide.Buy)