Files
v2realbot/research/basic.ipynb
2024-05-17 14:04:48 +02:00

2.5 MiB
Raw Blame History

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]