VectorBT Pro - Custom Simulator 0 : Main Functions
Importing The Dependencies
import vectorbtpro as vbt
import numpy as np
import pandas as pd
from numba import njit
import talib
import datetime as dt
import time
from collections import namedtuple
import itertools
import math
from vectorbtpro.records.nb import col_map_nb
from vectorbtpro.portfolio import nb as pf_nb, enums as pf_enums
import plotly.io as pio
from numba import njit
Order Records , Order Counts
The
order recordskeep track of the details of each trade executed by a trading strategy.The purpose of order records is to provide traders with a complete record of all trades executed by the strategy, including the entry and exit prices ,order type , order size and other relevant details.
The
order countsare the number of trades executed by a trading strategy over a certain period of time. They can be analysed to gain insights into trading activity and use this information to adjust their approach.
Process Order
The main purpose of using
vbt.pf_nb.process_order_nbin the functions that will be introduced below is that it takes in theorder_recordsandorder_countswithout having to manually construct them after anOrderhas been submitted.
Enter Position
The enter_position will enter either a Buy or Sell position depending on the logic and overall structure of your strategy.
Its primary purpose is to create the Order corresponding to the percentage_risk and the direction that has been specified.
It takes in a multitude of different arguments the main ones being ;
execution_state_
The
execution_statefeature keeps track of the
current position of a trading strategy (long,short, orneutral) at each time step in a trading simulation.
price_area_
The
price_area_feature can be used when constructing an order to help determine the entry and exit points for a trade since its compromised of theopen,high,lowandclosingprices at the point in time the trade was taken.
percent_risk_
The
percent_risk_% will allow us to specify how much to risk on each trade.
direction
This is simply the direction of the trade that one wants to take whether that be
Buy🟩 orSell🟥.
group_ , col_ , bar_
These refer to the group , column and the current bar number of the iteration of the close prices that we are on.
@njit(nogil = True)
def enter_position(execution_state_,
price_area_,
percent_risk_ = 1,
group_ = 0 , column = 0, bar_ = None,
direction = "Buy",
update_value_ = False, order_records_ = None,
order_counts_ = None, log_records_ = None,
log_counts_ = None):
if direction == "Buy":
direction_to_take = vbt.pf_enums.Direction.LongOnly
else:
direction_to_take = vbt.pf_enums.Direction.ShortOnly
Order = pf_nb.order_nb(size = percent_risk_,
size_type = vbt.pf_enums.SizeType.ValuePercent100,
direction = direction_to_take,
price = execution_state_.val_price
)
order_result , new_execution_state = vbt.pf_nb.process_order_nb(
group = group_ ,col = column , i = bar_,
exec_state = execution_state_,
order = Order,
price_area = price_area_,
update_value = update_value_,
order_records = order_records_,
order_counts = order_counts_,
log_records = log_records_,
log_counts = log_counts_)
return order_result, new_execution_state
close_full_position
There are minor differences between each function in the close_full_position the size is specified to be -np.inf (Infinite size) and the direction is determined via the passed execution_state.
If the execution_state.position is >0 (greater than zero) it indicates that we are invested in a a Buy (Long position) and if it is <0 (Less than zero) then we are invested in a Sell (Short Position).
close_partial_pos
The
close_partial_posintends to close the position only partially.This is useful when taking partial profits which is the basis of many algorithmic trading strategies.
The
Sizewhen constructing theOrderis set to be-closing_percentsuch that if50is specified only 50% of that particular position will be closed.
@njit(nogil = True)
def close_partial_pos(execution_state_,
price_area_,
closing_percent = 50,
group_ = 0 , column = 0, bar_ = None,
update_value_ = False, order_records_ = None,
order_counts_ = None, log_records_ = None,
log_counts_ = None):
if execution_state.position > 0 :
direction_to_take = vbt.pf_enums.Direction.LongOnly
else:
direction_to_take = vbt.pf_enums.Direction.ShortOnly
Order = pf_nb.order_nb(size = -closing_percent,
size_type = vbt.pf_enums.SizeType.ValuePercent100,
direction = direction_to_take,
price = execution_state_.val_price
)
order_result , new_execution_state = vbt.pf_nb.process_order_nb(
group = group_ ,col = column , i = bar_,
exec_state = execution_state_,
order = Order,
price_area = price_area_,
update_value = update_value_,
order_records = order_records_,
order_counts = order_counts_,
log_records = log_records_,
log_counts = log_counts_)
return order_result, new_execution_state
Key Points / Summary 💡
The functions streamline the process of creating the
Orderand allow all the trades to be tracked via theorder_recordsandorder_countsThe
Sizecomponent of theOrderis directly linked to the precentage risk that is being taken on the account and thesize_typeensures that the amount on the account that is risked is exactly as what has been specified in the function argument.