fix
This commit is contained in:
125
vbt-snippets.md
125
vbt-snippets.md
@ -31,16 +31,20 @@
|
|||||||
- [CALLBACKS -](#callbacks--)
|
- [CALLBACKS -](#callbacks--)
|
||||||
- [MEMORY](#memory)
|
- [MEMORY](#memory)
|
||||||
- [Portfolio](#portfolio)
|
- [Portfolio](#portfolio)
|
||||||
- [delta format](#delta-format)
|
- [from signals](#from-signals)
|
||||||
- [CALLBACKS](#callbacks)
|
- [CALLBACKS](#callbacks)
|
||||||
- [Staticization](#staticization)
|
- [Access running total return from sim](#access-running-total-return-from-sim)
|
||||||
|
- [Staticization](#staticization)
|
||||||
|
- [Grouping](#grouping)
|
||||||
|
- [Portfolio analysis](#portfolio-analysis)
|
||||||
|
- [Changing year freq for stocks](#changing-year-freq-for-stocks)
|
||||||
- [INDICATORS DEV](#indicators-dev)
|
- [INDICATORS DEV](#indicators-dev)
|
||||||
- [Custom ind](#custom-ind)
|
- [Custom ind](#custom-ind)
|
||||||
- [register custom ind](#register-custom-ind)
|
- [register custom ind](#register-custom-ind)
|
||||||
- [VWAP anchored example](#vwap-anchored-example)
|
- [VWAP anchored example](#vwap-anchored-example)
|
||||||
- [Use ttols indicators](#use-ttols-indicators)
|
- [Use ttols indicators](#use-ttols-indicators)
|
||||||
- [FAV INDICATORS](#fav-indicators)
|
- [FAV INDICATORS](#fav-indicators)
|
||||||
- [GROUPING](#grouping)
|
- [GROUPING](#grouping-1)
|
||||||
- [SPLITTING](#splitting)
|
- [SPLITTING](#splitting)
|
||||||
- [CHARTING](#charting)
|
- [CHARTING](#charting)
|
||||||
- [MULTIACCOUNT](#multiaccount)
|
- [MULTIACCOUNT](#multiaccount)
|
||||||
@ -629,6 +633,7 @@ Usecases:
|
|||||||
# Portfolio
|
# Portfolio
|
||||||
|
|
||||||
group_by=True to put all columns to the same group and cash_sharing=True to share capital among them
|
group_by=True to put all columns to the same group and cash_sharing=True to share capital among them
|
||||||
|
## from signals
|
||||||
|
|
||||||
```python
|
```python
|
||||||
pf = vbt.Portfolio.from_signals(
|
pf = vbt.Portfolio.from_signals(
|
||||||
@ -637,6 +642,8 @@ pf = vbt.Portfolio.from_signals(
|
|||||||
exits=long_exits,
|
exits=long_exits,
|
||||||
short_entries=short_entries_cln,
|
short_entries=short_entries_cln,
|
||||||
short_exits=short_exits,
|
short_exits=short_exits,
|
||||||
|
size=1,
|
||||||
|
size_type=vbt.pf_enums.SizeType.Amount # Value, Percent, TargetAmount
|
||||||
sl_stop=0.3,
|
sl_stop=0.3,
|
||||||
tp_stop = 0.4,
|
tp_stop = 0.4,
|
||||||
delta_format = vbt.pf_enums.DeltaFormat.Percent100, #(Absolute, Percent, Percent100, Target)
|
delta_format = vbt.pf_enums.DeltaFormat.Percent100, #(Absolute, Percent, Percent100, Target)
|
||||||
@ -644,15 +651,11 @@ pf = vbt.Portfolio.from_signals(
|
|||||||
freq="12s") #sl_stop=sl_stop, tp_stop = sl_stop,, tsl_stop
|
freq="12s") #sl_stop=sl_stop, tp_stop = sl_stop,, tsl_stop
|
||||||
```
|
```
|
||||||
|
|
||||||
## delta format
|
[SizeType enums](http://5.161.179.223:8000/vbt-doc/api/portfolio/enums/index.html#vectorbtpro.portfolio.enums.SizeType)
|
||||||
|
|
||||||
```python
|
[DeltaFormat enums](http://5.161.179.223:8000/vbt-doc/api/portfolio/enums/index.html#vectorbtpro.portfolio.enums.DeltaFormat)
|
||||||
vbt.pf_enums.DeltaFormat:
|
|
||||||
Absolute: int = 0
|
[Other PF enums](http://5.161.179.223:8000/vbt-doc/api/portfolio/enums/index.html)
|
||||||
Percent: int = 1
|
|
||||||
Percent100: int = 2
|
|
||||||
Target: int = 3
|
|
||||||
```
|
|
||||||
|
|
||||||
## CALLBACKS
|
## CALLBACKS
|
||||||
|
|
||||||
@ -668,57 +671,100 @@ Importan SignalContact attributes:
|
|||||||
Callback functions:
|
Callback functions:
|
||||||
- signal_func_nb - place/alter entries/exits
|
- signal_func_nb - place/alter entries/exits
|
||||||
- adjust_sl_func_nb - adjust SL at each time stamp
|
- adjust_sl_func_nb - adjust SL at each time stamp
|
||||||
|
- adjust_func_nb - adjust size
|
||||||
|
- post_segment_func_nb
|
||||||
|
|
||||||
|
More on callbacks in [cookbook](http://5.161.179.223:8000/vbt-doc/cookbook/portfolio/index.html#callbacks).
|
||||||
|
|
||||||
For exit dependent entries, the entries can be preprocessed in `signal_func_nb` see [callbacks](http://5.161.179.223:8000/vbt-doc/cookbook/portfolio/index.html#callbacks) in cookbok or [signal function](http://5.161.179.223:8000/vbt-doc/documentation/portfolio/from-signals/index.html#signal-function)in doc
|
For exit dependent entries, the entries can be preprocessed in `signal_func_nb` see [callbacks](http://5.161.179.223:8000/vbt-doc/cookbook/portfolio/index.html#callbacks) in cookbok or [signal function](http://5.161.179.223:8000/vbt-doc/documentation/portfolio/from-signals/index.html#signal-function)in doc
|
||||||
|
|
||||||
```python
|
```python
|
||||||
#@njit
|
@njit
|
||||||
def signal_func_nb(c, entries, exits, short_entries, short_exits, cooldown):
|
def signal_func_nb(c, entries, exits, short_entries, short_exits, cooldown_time, cooldown_bars):
|
||||||
entry = vbt.pf_nb.select_nb(c, entries) #get current value
|
entry = vbt.pf_nb.select_nb(c, entries) #get current value
|
||||||
exit = vbt.pf_nb.select_nb(c, exits)
|
exit = vbt.pf_nb.select_nb(c, exits)
|
||||||
short_entry = vbt.pf_nb.select_nb(c, short_entries)
|
short_entry = vbt.pf_nb.select_nb(c, short_entries)
|
||||||
short_exit = vbt.pf_nb.select_nb(c, short_exits)
|
short_exit = vbt.pf_nb.select_nb(c, short_exits)
|
||||||
if not vbt.pf_nb.in_position_nb(c): # short for c.last_position == 0
|
if not vbt.pf_nb.in_position_nb(c): # short for c.last_position == 0
|
||||||
if vbt.pf_nb.has_orders_nb(c):
|
if vbt.pf_nb.has_orders_nb(c):
|
||||||
if c.last_pos_info[c.col]["pnl"] < 0: #positive pnl on last reade
|
if c.last_pos_info[c.col]["pnl"] < 0: #current index is c.i
|
||||||
last_exit_idx = c.last_pos_info[c.col]["exit_idx"] #exit_idx
|
last_exit_idx = c.last_pos_info[c.col]["exit_idx"] # exit index from last_pos_info named tuple
|
||||||
if c.index[c.i] - c.index[last_exit_idx] < cooldown:
|
if cooldown_time is not None and c.index[c.i] - c.index[last_exit_idx] < cooldown_time:
|
||||||
return False, exit, False, short_exit #disable all entries
|
return False, exit, False, short_exit #disable entry
|
||||||
|
elif cooldown_bars is not None and last_exit_idx + cooldown_bars > c.i:
|
||||||
|
return False, exit, False, short_exit #disable entry
|
||||||
return entry, exit, short_entry, short_exit
|
return entry, exit, short_entry, short_exit
|
||||||
|
|
||||||
"""
|
cooldown_time = vbt.dt.to_ns(vbt.timedelta("1m"))
|
||||||
c.last_pos_info[c.col]
|
cooldown_bars = 3
|
||||||
- is namedtuple {'names': ['id', 'col', 'size', 'entry_order_id', 'entry_idx', 'entry_price', 'entry_fees', 'exit_order_id', 'exit_idx', 'exit_price', 'exit_fees', 'pnl', 'return', 'direction', 'status', 'parent_id']
|
|
||||||
"""
|
|
||||||
|
|
||||||
pf = vbt.Portfolio.from_signals(
|
pf = vbt.Portfolio.from_signals(
|
||||||
close=s12_data.close,
|
close=s12_data.close,
|
||||||
entries=long_entries_cln,
|
entries=long_entries_cln,
|
||||||
exits=long_exits,
|
exits=long_exits,
|
||||||
short_entries=short_entries_cln,
|
short_entries=short_entries_cln,
|
||||||
short_exits=short_exits,
|
short_exits=short_exits,
|
||||||
signal_func_nb=signal_func_nb,
|
signal_func_nb="signal_func_nb.py",
|
||||||
signal_args=(
|
signal_args=(
|
||||||
vbt.Rep("entries"),
|
vbt.Rep("entries"),
|
||||||
vbt.Rep("exits"),
|
vbt.Rep("exits"),
|
||||||
vbt.Rep("short_entries"),
|
vbt.Rep("short_entries"),
|
||||||
vbt.Rep("short_exits"),
|
vbt.Rep("short_exits"),
|
||||||
vbt.dt.to_ns(vbt.timedelta("12s"))*5 # any timedelta, 12s meaning bars - TODO bar count
|
cooldown_time, # cooldown in timedelta in ns after exit
|
||||||
|
cooldown_bars #cooldown in number of bars after exit
|
||||||
),
|
),
|
||||||
sl_stop=0.3,
|
sl_stop=0.3,
|
||||||
tp_stop = 0.4,
|
tp_stop = 0.4,
|
||||||
delta_format = vbt.pf_enums.DeltaFormat.Percent100, #(Absolute, Percent, Percent100, Target)
|
delta_format = vbt.pf_enums.DeltaFormat.Percent100, #(Absolute, Percent, Percent100, Target)
|
||||||
fees=0.0167/100,
|
fees=0.0167/100,
|
||||||
freq="12s",
|
freq="12s",
|
||||||
jitted=False,
|
#staticized=True
|
||||||
statiticized=True) #sl_stop=sl_stop, tp_stop = sl_stop,, tsl_stop
|
#jitted=False
|
||||||
|
) #sl_stop=sl_stop, tp_stop = sl_stop,, tsl_stop
|
||||||
```
|
```
|
||||||
|
|
||||||
Tips:
|
Tips:
|
||||||
- To avoid waiting for the compilation, remove the `@njit` decorator from `signal_func_nb` and pass `jitted=False` to from_signals in order to disable Numba
|
- To avoid waiting for the compilation, remove the `@njit` decorator from `signal_func_nb` and pass `jitted=False` to from_signals in order to disable Numba
|
||||||
|
|
||||||
## Staticization
|
### Access running total return from sim
|
||||||
|
|
||||||
|
create an empty array for cumulative returns and populate it inside the post_segment_func_nb callback. The same array accessed by other callbacks can be used to get the total return at any time step.
|
||||||
|
|
||||||
|
```python
|
||||||
|
@njit
|
||||||
|
def adjust_func_nb(c, cum_return):
|
||||||
|
if c.cash_sharing:
|
||||||
|
total_return = cum_return[c.group] - 1
|
||||||
|
else:
|
||||||
|
total_return = cum_return[c.col] - 1
|
||||||
|
...
|
||||||
|
|
||||||
|
@njit
|
||||||
|
def post_segment_func_nb(c, cum_return):
|
||||||
|
if c.cash_sharing:
|
||||||
|
cum_return[c.group] *= 1 + c.last_return[c.group]
|
||||||
|
else:
|
||||||
|
for col in range(c.from_col, c.to_col):
|
||||||
|
cum_return[col] *= 1 + c.last_return[col]
|
||||||
|
|
||||||
|
cum_return = None
|
||||||
|
def init_cum_return(wrapper):
|
||||||
|
global cum_return
|
||||||
|
if cum_return is None:
|
||||||
|
cum_return = np.full(wrapper.shape_2d[1], 1.0)
|
||||||
|
return cum_return
|
||||||
|
|
||||||
|
pf = vbt.PF.from_signals(
|
||||||
|
...,
|
||||||
|
adjust_func_nb=adjust_func_nb,
|
||||||
|
adjust_args=(vbt.RepFunc(init_cum_return),),
|
||||||
|
post_segment_func_nb=post_segment_func_nb,
|
||||||
|
post_segment_args=(vbt.RepFunc(init_cum_return),),
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Staticization
|
||||||
Callbacks make function uncacheable,
|
Callbacks make function uncacheable,
|
||||||
to overcome that
|
to overcome that
|
||||||
- define the callback in external file `signal_func_nb.py`
|
- define the callback in external file `signal_func_nb.py`
|
||||||
@ -746,6 +792,28 @@ pf = vbt.PF.from_signals(
|
|||||||
staticized=True
|
staticized=True
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Grouping
|
||||||
|
|
||||||
|
Grouping in [signal function](http://5.161.179.223:8000/vbt-doc/documentation/portfolio/from-signals/index.html#signal-function).
|
||||||
|
|
||||||
|
# Portfolio analysis
|
||||||
|
|
||||||
|
```
|
||||||
|
pf.orders.readable
|
||||||
|
pf.entry_trades.readable
|
||||||
|
pf.exit_trades.readable
|
||||||
|
pf.trades.readable
|
||||||
|
pf.positions.readable
|
||||||
|
pf.trade_history
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changing year freq for stocks
|
||||||
|
|
||||||
|
```python
|
||||||
|
vbt.settings.returns.year_freq = pd.Timedelta(hours=6.5) * 252
|
||||||
|
```
|
||||||
|
|
||||||
# INDICATORS DEV
|
# INDICATORS DEV
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -1114,6 +1182,7 @@ vbt.print_cache_stats(vbt.PF)
|
|||||||
|
|
||||||
vbt.flush() #clear cache and collect garbage
|
vbt.flush() #clear cache and collect garbage
|
||||||
vbt.clear_cache(pf) #of specific
|
vbt.clear_cache(pf) #of specific
|
||||||
|
vbt.clear_pycache()
|
||||||
|
|
||||||
|
|
||||||
#TIMING
|
#TIMING
|
||||||
|
|||||||
Reference in New Issue
Block a user