'Identify Range Levels from OHLC chart in Python

I want to identify range levels from OHLC charts in python. Any help on how to achieve this will be really helpful.

2 types of ranges, squeeze and channel type

close within a defined boundary

I some how not sure how this can be applied for entire dataframe of data. Please let me know how to approach this usecase.

Plot function as written is as below:

def plot(symbol, levels, stockdata, tf, linedate):
# Create subplots and mention plot grid size
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, 
            vertical_spacing=0.03, subplot_titles=(symbol + "-" + tf, 'Volume'), 
            row_width=[0.2, 0.7])

# include candlestick with rangeselector
fig.add_trace(go.Candlestick(x=stockdata['Date'],
                open=stockdata['Open'],
                high=stockdata['High'],
                low=stockdata['Low'],
                close=stockdata['Close'],
                name=symbol), row=1, col=1)

# include a go.Bar trace for volumes
fig.add_trace(go.Bar(x=stockdata['Date'], y=stockdata['Volume'], showlegend=False), row=2, col=1)
fig.update_xaxes(rangebreaks=[dict(bounds=["sat", "mon"])])
fig.layout.update(margin=dict(l=50,r=30,b=40,t=40))
fig.layout.yaxis2.showgrid=False
fig.update(layout_xaxis_rangeslider_visible=False)


if linedate != "NA":
    fig.update_layout(
        shapes = [dict(
            x0=linedate, x1=linedate, y0=0, y1=1, xref='x', yref='paper',
            line_width=1)],
    )

# Support Resistance levels
for row in levels:
    fig.add_shape(type="line", x0= row[0], 
                            y0 = row[1],
                            x1 = stockdata.Date.max(),
                            y1 = row[1], fillcolor = 'yellow')
# Current level
fig.add_hline(y=stockdata.iloc[-1]['Close'], line_dash="dot", row=1, col=1, line_color="Red", line_width=1)

# Identify range for last bars
avg_line = stockdata.iloc[-3:].copy()
avg_line['avg_line'] = avg_line['Close'].mean()
fig.add_trace(
    go.Scatter(mode = 'lines',
            x=avg_line['Date'],
        y=avg_line['avg_line'], line={'color':'black', 'width':1}
    ))

fig.update_traces(showlegend=False)
fig.write_image("images/"+symbol + "-" + tf+".png",scale=1,width=1400, height=600)

window shifting for identifying levels

def detect_level_method_2(df):
levels = []
max_list = []
min_list = []
for i in range(5, len(df)-5):
    high_range = df['High'][i-5:i+4]
    current_max = high_range.max()
    if current_max not in max_list:
        max_list = []
    max_list.append(current_max)
    if len(max_list) == 5 and isFarFromLevel(current_max, levels, df):
        levels.append((high_range.idxmax(), current_max))
    
    low_range = df['Low'][i-5:i+5]
    current_min = low_range.min()
    if current_min not in min_list:
        min_list = []
    min_list.append(current_min)
    if len(min_list) == 5 and isFarFromLevel(current_min, levels, df):
        levels.append((low_range.idxmin(), current_min))
return levels


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source