2.5 MiB
2.5 MiB
In [45]:
from v2realbot.tools.loadbatch import load_batch from v2realbot.utils.utils import zoneNY, DATA_DIR import pandas as pd import numpy as np import vectorbtpro as vbt vbt.settings.set_theme("dark") vbt.settings['plotting']['layout']['width'] = 1280 vbt.settings.plotting.auto_rangebreaks = True # Set the option to display with pagination pd.set_option('display.notebook_repr_html', True) pd.set_option('display.max_rows', 10) # Number of rows per page
In [46]:
batch_id = "e44a5075" # res, df = load_batch(batch_id=batch_id, # space_resolution_evenly=False, # indicators_columns=["Rsi14"], # main_session_only=True) # if res < 0: # print("Error" + str(res) + str(df)) # df = df["bars"] # df.info() # df.head() # #df.ptable() # df.to_pickle(DATA_DIR+"/"+f'{batch_id}.pickle')
FILTERING¶
In [47]:
df = pd.read_pickle(DATA_DIR+"/"+f'{batch_id}.pickle') df
Out[47]:
<style scoped="">
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
| Open | High | Low | Close | Volume | Vwap | updated | Rsi14 | |
|---|---|---|---|---|---|---|---|---|
| time | ||||||||
| 2024-03-11 09:30:00-04:00 | 35.3900 | 35.440 | 35.2800 | 35.380 | 473759 | 35.425685 | 2024-03-11 09:30:23.673966885-04:00 | 0.0000 |
| 2024-03-11 09:30:23-04:00 | 35.3900 | 35.490 | 35.3895 | 35.475 | 14119 | 35.447393 | 2024-03-11 09:30:46.228593111-04:00 | 0.0000 |
| 2024-03-11 09:30:46-04:00 | 35.4750 | 35.480 | 35.4200 | 35.460 | 22169 | 35.448066 | 2024-03-11 09:31:09.993794918-04:00 | 0.0000 |
| 2024-03-11 09:31:09-04:00 | 35.4579 | 35.540 | 35.4400 | 35.535 | 29984 | 35.490282 | 2024-03-11 09:31:32.450469017-04:00 | 0.0000 |
| 2024-03-11 09:31:32-04:00 | 35.5350 | 35.595 | 35.5100 | 35.590 | 20348 | 35.560566 | 2024-03-11 09:31:55.688961983-04:00 | 0.0000 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2024-03-13 15:58:19-04:00 | 36.1450 | 36.155 | 36.1300 | 36.145 | 120386 | 36.142679 | 2024-03-13 15:58:42.028856993-04:00 | 59.6001 |
| 2024-03-13 15:58:42-04:00 | 36.1500 | 36.150 | 36.1300 | 36.130 | 139068 | 36.139540 | 2024-03-13 15:59:05.012445927-04:00 | 58.2072 |
| 2024-03-13 15:59:05-04:00 | 36.1300 | 36.140 | 36.0900 | 36.090 | 545827 | 36.118307 | 2024-03-13 15:59:28.043910027-04:00 | 49.7763 |
| 2024-03-13 15:59:28-04:00 | 36.0950 | 36.110 | 36.0500 | 36.080 | 734354 | 36.072968 | 2024-03-13 15:59:51.012413979-04:00 | 37.3871 |
| 2024-03-13 15:59:51-04:00 | 36.0800 | 36.100 | 36.0650 | 36.070 | 321567 | 36.074857 | 2024-03-13 15:59:59.987827063-04:00 | 37.3871 |
2934 rows × 8 columns
In [48]:
#naloadujeme do vbt symbol as column basic_data = vbt.Data.from_data({"BAC": df}, tz_convert=zoneNY) start_date = pd.Timestamp('2024-03-12 09:30', tz=zoneNY) end_date = pd.Timestamp('2024-03-13 16:00', tz=zoneNY) #filter date #basic_data = basic_data.transform(lambda df: df[df.index.date == start_date.date()]) #filter range basic_data = basic_data.transform(lambda df: df[(df.index >= start_date) & (df.index <= end_date)]) #filtered_data = basic_data.transform(lambda df: df[(df.index >= start_date) & (df.index <= end_date)]) # #range filtered_data = data[(data.index >= start_date) & (data.index <= end_date) #df.between_time('09:30', '16:00') #(df.index.time >= pd.Timestamp('09:30').time()) & (df.index.time <= pd.Timestamp('16:00').time())
In [49]:
# basic_data.data["BAC"] rsi14
Out[49]:
time
2024-03-12 09:30:00-04:00 70.6588
2024-03-12 09:30:23-04:00 74.0781
2024-03-12 09:30:47-04:00 76.6184
2024-03-12 09:31:11-04:00 81.0538
2024-03-12 09:31:34-04:00 86.0863
...
2024-03-13 15:58:19-04:00 59.6001
2024-03-13 15:58:42-04:00 58.2072
2024-03-13 15:59:05-04:00 49.7763
2024-03-13 15:59:28-04:00 37.3871
2024-03-13 15:59:51-04:00 37.3871
Name: Rsi14, Length: 1961, dtype: float64
In [50]:
#b = filtered_data.get().iloc[100:200] #b[["Open","High"]] rsi14 = basic_data.data["BAC"]["Rsi14"].rename("Rsi14") #create subploit fig = vbt.make_subplots(rows=2, cols=1, shared_xaxes=True, specs=[[{"secondary_y": True}], [{"secondary_y": False}]]) rsi14.vbt.plot(add_trace_kwargs=dict(row=1, col=1, secondary_y=True),fig=fig) basic_data.data["BAC"].vbt.ohlcv.plot(add_trace_kwargs=dict(row=1, col=1, secondary_y=False), fig=fig)
Out[50]:
FigureWidget({
'data': [{'name': 'Rsi14',
'showlegend': True,
'type': 'scatter',
'uid': '5eb5e6f2-c71f-441c-9c2b-88a379762a9d',
'x': array([datetime.datetime(2024, 3, 12, 9, 30, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 12, 9, 30, 23, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 12, 9, 30, 47, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
...,
datetime.datetime(2024, 3, 13, 15, 59, 5, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 13, 15, 59, 28, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 13, 15, 59, 51, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)],
dtype=object),
'xaxis': 'x',
'y': array([70.6588, 74.0781, 76.6184, ..., 49.7763, 37.3871, 37.3871]),
'yaxis': 'y2'},
{'close': array([35.93 , 35.97 , 35.975, ..., 36.09 , 36.08 , 36.07 ]),
'decreasing': {'fillcolor': '#ee534f', 'line': {'color': '#ee534f'}},
'high': array([35.96 , 35.99 , 35.985, ..., 36.14 , 36.11 , 36.1 ]),
'increasing': {'fillcolor': '#26a69a', 'line': {'color': '#26a69a'}},
'low': array([35.85 , 35.92 , 35.935, ..., 36.09 , 36.05 , 36.065]),
'name': 'OHLC',
'opacity': 0.75,
'open': array([35.9 , 35.925, 35.97 , ..., 36.13 , 36.095, 36.08 ]),
'type': 'candlestick',
'uid': 'e526fc44-8b7e-4948-b4d0-39ae4e7a2b91',
'x': array([datetime.datetime(2024, 3, 12, 9, 30, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 12, 9, 30, 23, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 12, 9, 30, 47, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
...,
datetime.datetime(2024, 3, 13, 15, 59, 5, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 13, 15, 59, 28, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 13, 15, 59, 51, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)],
dtype=object),
'xaxis': 'x',
'yaxis': 'y'},
{'marker': {'color': array(['#26a69a', '#26a69a', '#26a69a', ..., '#ee534f', '#ee534f', '#ee534f'],
dtype=object),
'line': {'width': 0}},
'name': 'Volume',
'opacity': 0.5,
'type': 'bar',
'uid': '213ef8f6-a7f7-46a3-a3b8-f203762289eb',
'x': array([datetime.datetime(2024, 3, 12, 9, 30, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 12, 9, 30, 23, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 12, 9, 30, 47, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
...,
datetime.datetime(2024, 3, 13, 15, 59, 5, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 13, 15, 59, 28, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>),
datetime.datetime(2024, 3, 13, 15, 59, 51, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)],
dtype=object),
'xaxis': 'x2',
'y': array([416236, 25178, 14986, ..., 545827, 734354, 321567]),
'yaxis': 'y3'}],
'layout': {'height': 350,
'legend': {'orientation': 'h',
'traceorder': 'normal',
'x': 1,
'xanchor': 'right',
'y': 1.02,
'yanchor': 'bottom'},
'margin': {'b': 30, 'l': 30, 'r': 30, 't': 30},
'template': '...',
'width': 1280,
'xaxis': {'anchor': 'y',
'domain': [0.0, 0.94],
'matches': 'x2',
'rangeslider': {'visible': False},
'showticklabels': False},
'xaxis2': {'anchor': 'y3', 'domain': [0.0, 0.94]},
'yaxis': {'anchor': 'x', 'domain': [0.575, 1.0]},
'yaxis2': {'anchor': 'x', 'overlaying': 'y', 'side': 'right'},
'yaxis3': {'anchor': 'x2', 'domain': [0.0, 0.425]}}
})
In [51]:
run_rsi = vbt.talib_func("rsi") rsi_new = run_rsi(basic_data.vwap, timeperiod=15) rsi_new = rsi_new.fillna(0) # print(rsi_new) # print(dir(rsi_new)) rsi14 = basic_data.data["BAC"]["Rsi14"] # print(rsi14) #zkombinujeme do stejneho dataframe skrz sloupce (axis1) # combined_df = pd.concat([rsi_new, rsi14], axis=1) # combined_df #create subplot fig = vbt.make_subplots(rows=1, cols=1, shared_xaxes=True) plot_rsi = vbt.talib_plot_func("rsi") plot_rsi(rsi_new, fig=fig) plot_rsi(rsi14, fig=fig) fig.show()
In [52]:
entries = rsi_new.vbt.crossed_below(30) entries
Out[52]:
time
2024-03-12 09:30:00-04:00 False
2024-03-12 09:30:23-04:00 False
2024-03-12 09:30:47-04:00 False
2024-03-12 09:31:11-04:00 False
2024-03-12 09:31:34-04:00 False
...
2024-03-13 15:58:19-04:00 False
2024-03-13 15:58:42-04:00 False
2024-03-13 15:59:05-04:00 False
2024-03-13 15:59:28-04:00 False
2024-03-13 15:59:51-04:00 False
Name: Vwap, Length: 1961, dtype: bool
In [53]:
exits = rsi_new.vbt.crossed_above(70) exits
Out[53]:
time
2024-03-12 09:30:00-04:00 False
2024-03-12 09:30:23-04:00 False
2024-03-12 09:30:47-04:00 False
2024-03-12 09:31:11-04:00 False
2024-03-12 09:31:34-04:00 False
...
2024-03-13 15:58:19-04:00 False
2024-03-13 15:58:42-04:00 False
2024-03-13 15:59:05-04:00 False
2024-03-13 15:59:28-04:00 False
2024-03-13 15:59:51-04:00 False
Name: Vwap, Length: 1961, dtype: bool
In [54]:
def plot_rsi(close, rsi, entries, exits): fig = vbt.make_subplots(rows=2, cols=1, shared_xaxes=True, specs=[[{"secondary_y": True}], [{"secondary_y": False}]]) basic_data.data["BAC"].vbt.ohlcv.plot(add_trace_kwargs=dict(row=1, col=1, secondary_y=True),fig=fig) rsi.vbt.plot(fig=fig, add_trace_kwargs=dict(row=1, col=1, secondary_y=False), trace_kwargs=dict(line=dict(color='grey', width=1.5))) #close.vbt.plot(fig=fig, add_trace_kwargs=dict(row=1, col=1, secondary_y=True)) entries.vbt.signals.plot_as_entries(y=close, fig=fig, add_trace_kwargs=dict(row=1, col=1, secondary_y=True)) exits.vbt.signals.plot_as_exits(y=close, fig=fig, add_trace_kwargs=dict(row=1, col=1, secondary_y=True)) return fig close = basic_data.get("Close") print(entries) plot_rsi(close, rsi_new, entries, exits).show() clean_entries, clean_exits = entries.vbt.signals.clean(exits) plot_rsi(close, rsi_new, clean_entries, clean_exits).show()
time
2024-03-12 09:30:00-04:00 False
2024-03-12 09:30:23-04:00 False
2024-03-12 09:30:47-04:00 False
2024-03-12 09:31:11-04:00 False
2024-03-12 09:31:34-04:00 False
...
2024-03-13 15:58:19-04:00 False
2024-03-13 15:58:42-04:00 False
2024-03-13 15:59:05-04:00 False
2024-03-13 15:59:28-04:00 False
2024-03-13 15:59:51-04:00 False
Name: Vwap, Length: 1961, dtype: bool
In [55]:
clean_entries.vbt.signals.total() clean_exits.vbt.signals.total()
Out[55]:
12
In [56]:
index = basic_data.wrapper.index #minutes from market open market_open_time = pd.to_timedelta('09:30:00') # Calculate the market open datetime for each day market_opens = index.normalize() + market_open_time minutes_from_open = (index - market_opens).total_seconds() / 60 # Ensuring the result is a Series minutes_from_open = pd.Series(minutes_from_open, index=index) #minutes_from_open.values
In [57]:
symbol_wrapper = basic_data.get_symbol_wrapper() @vbt.njit def elapsed_minutes_from_open_nb(time_in_ns): market_opens_in_minute = 570 # 9 hours * 60 minutes + 30 minutes current_minute = vbt.dt_nb.hour_nb(time_in_ns) * 60 + vbt.dt_nb.minute_nb(time_in_ns) #print("current_minutes", current_minutes) # Calculate elapsed minutes since market open at 9:30 AM minutes_from_open = current_minute - market_opens_in_minute print( "elapsed_from_open", minutes_from_open) return minutes_from_open if minutes_from_open >= 0 else 0 @vbt.njit def entry_place_func_nb(c, low, close, time_in_ns, rsi14, window_open, window_close): # if c.from_i == 0: # (1)! # c.out[0] = True # return -1 # print("ted") # print(c.from_i) #exit_i = c.from_i - c.wait # (2)! #exit_price = close[exit_i, c.col] # (3)! #hit_price = exit_price * (1 - th) market_open_minutes = 570 # 9 hours * 60 minutes + 30 minutes for out_i in range(len(c.out)): i = c.from_i + out_i current_minutes = vbt.dt_nb.hour_nb(time_in_ns[i]) * 60 + vbt.dt_nb.minute_nb(time_in_ns[i]) #print("current_minutes", current_minutes) # Calculate elapsed minutes since market open at 9:30 AM elapsed_from_open = current_minutes - market_open_minutes elapsed_from_open = elapsed_from_open if elapsed_from_open >= 0 else 0 #print( "elapsed_from_open", elapsed_from_open) #elapsed_from_open = elapsed_minutes_from_open_nb(time_in_ns) in_window = elapsed_from_open > window_open and elapsed_from_open < window_close #print("in_window", in_window) # if in_window: # print("in window") if in_window and rsi14[i] > 60: # and low[i, c.col] <= hit_price: # and hour == 9: # (4)! return out_i return -1 #whether the date changed # day_changed_nb( # ts1, # ts2 # ) # h_ns(ts1) int @vbt.njit def exit_place_func_nb(c, high, close, time_index, tp, sl): # (5)! entry_i = c.from_i - c.wait entry_price = close[entry_i, c.col] hit_price = entry_price * (1 + tp) stop_price = entry_price * (1 - sl) for out_i in range(len(c.out)): i = c.from_i + out_i last_bar_of_day = vbt.dt_nb.day_changed_nb(time_index[i], time_index[i + 1]) #print(next_day) if last_bar_of_day: #pokud je dalsi next day, tak zavirame posledni print("ted",out_i) return out_i if high[i, c.col] >= hit_price or close[i, c.col] <= stop_price : return out_i return -1 index = basic_data.wrapper.index #minutes from market open market_open_time = pd.to_timedelta('09:30:00') # Calculate the market open datetime for each day market_opens = index.normalize() + market_open_time minutes_from_open = (index - market_opens).total_seconds() / 60 print(minutes_from_open) #index 9:30 az 10:00 time_entry_window = ((index.time >= pd.Timestamp("09:30:00").time())& (index.time <= pd.Timestamp("14:00:00").time())) print(time_entry_window) print(rsi_new) rsi_entries = rsi_new.vbt.crossed_below(64) rsi_entries = rsi_entries < 40 rsi_entries_array = rsi_entries.vbt.to_1d_array() print(rsi_entries_array) entries, exits = vbt.pd_acc.signals.generate_both( # (6)! symbol_wrapper.shape, entry_place_func_nb=entry_place_func_nb, #timeindex to ns to numba entry_place_args=(vbt.Rep("low"), vbt.Rep("close"), vbt.dt.to_ns(basic_data.wrapper.index), vbt.Rep("rsi14"), 0, 380), # (7)! exit_place_func_nb=exit_place_func_nb, exit_place_args=(vbt.Rep("high"), vbt.Rep("close"), vbt.dt.to_ns(basic_data.wrapper.index), 0.001, 0.001), wrapper=symbol_wrapper, broadcast_named_args=dict( # (8)! high=basic_data.get("High"), low=basic_data.get("Low"), close=basic_data.get("Close"), rsi14=basic_data.get("Rsi14"), window_open=10, window_close=60 ), broadcast_kwargs=dict(post_func=np.asarray) # (9)! ) plot_rsi(close, rsi_new, entries, exits).show() # fig = basic_data.plot( # symbol="BAC", # ohlc_trace_kwargs=dict(opacity=0.5), # plot_volume=False # ) # #rsi_entries.vbt.plot(fig=fig) # entries.vbt.signals.plot_as_entries( # y=close, fig=fig) # exits.vbt.signals.plot_as_exits( # y=close, fig=fig) # fig.show() # (10)!
Index([ 0.0, 0.38333333333333336, 0.7833333333333333,
1.1833333333333333, 1.5666666666666667, 2.0,
2.3833333333333333, 2.7666666666666666, 3.15,
3.566666666666667,
...
386.4, 386.78333333333336, 387.1666666666667,
387.55, 387.93333333333334, 388.31666666666666,
388.7, 389.0833333333333, 389.46666666666664,
389.85],
dtype='float64', name='time', length=1961)
[ True True True ... False False False]
time
2024-03-12 09:30:00-04:00 0.000000
2024-03-12 09:30:23-04:00 0.000000
2024-03-12 09:30:47-04:00 0.000000
2024-03-12 09:31:11-04:00 0.000000
2024-03-12 09:31:34-04:00 0.000000
...
2024-03-13 15:58:19-04:00 59.600097
2024-03-13 15:58:42-04:00 58.207248
2024-03-13 15:59:05-04:00 49.776325
2024-03-13 15:59:28-04:00 37.387129
2024-03-13 15:59:51-04:00 38.075336
Name: Vwap, Length: 1961, dtype: float64
[ True True True ... True True True]