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)
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)
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)
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 adj_req_cash <= run_cash: # Sufficient cash adj_size = order.size fees_paid = adj_req_cash - req_cash else: # Insufficient cash, size will be less than requested # 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 fees adj_size = adj_cash / adj_price fees_paid = run_cash - adj_cash if adj_size > 0.: # Update current cash and shares run_cash -= adj_size * adj_price + fees_paid run_shares += adj_size return run_cash, run_shares, FilledOrder(adj_size, adj_price, fees_paid, OrderSide.Buy) return run_cash, run_shares, None
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)
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)
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) - order.fixed_fees # Update fees fees_paid = cash - adj_cash if adj_size > 0.: # Update current cash and shares run_cash += adj_size * adj_price - fees_paid run_shares -= adj_size return run_cash, run_shares, FilledOrder(adj_size, adj_price, fees_paid, OrderSide.Sell) return run_cash, run_shares, None