[Python] Error plotting stock trendlines 'support_slope'

Discussão em 'Python' iniciado por Stack, Setembro 27, 2024.

  1. Stack

    Stack Membro Participativo

    Ive been trying to plot trendlines after theyve been calculated. It seems like the calculations are fine and its giving me the slope and intercept for resistance/support, but at the end i get the error in the terminal 'support_slope'

    Heres some sample output from the terminal,my plotter.py, and then my code. The code is below the output

    Support Slope: 0.0017904146337511123, Support Intercept: 6.270467036397379
    Resistance Slope: 0.0015433163283149968, Resistance Intercept: 6.287617104916379
    Support Slope: 0.0018135332025410028, Support Intercept: 6.270549335972292
    Resistance Slope: 0.0015762954337882838, Resistance Intercept: 6.287418760297718
    Support Levels: [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, np.float64(6.144023780
    900805), np.float64(6.139272016303774), np.float64(6.139236054845795), np.float64(6.119863757404568), np.float64(6.133514713049237), np.float64(6.133697068080789), np.float64(6.1200345
    68688048), np.float64(6.110688954469717), np.float64(6.108510722295112), np.float64(6.137271723388179), np.float64(6.160351804707739), np.float64(6.1813442733810025), np.float64(6.1916
    032959539224), np.float64(6.208925947305385), np.float64(6.232421713945308), np.float64(6.249004195128121), np.float64(6.2638613148808115), np.float64(6.288766828797837), np.float64(6.
    309077362254943), np.float64(6.31954801808132), np.float64(6.3380756247241905), np.float64(6.349634383922647), np.float64(6.355377536278531), np.float64(6.355900011928189), np.float64(
    6.364599208546319), np.float64(6.365795236301613), np.float64(6.360730467321387), np.float64(6.346940148758835), np.float64(6.3329739658960476), np.float64(6.332096599388408), np.float
    64(6.328854356895254), np.float64(6.331209666839308), np.float64(6.336403886964111), np.float64(6.330559710886555), np.float64(6.327838400676507), np.float64(6.323902898043602), np.flo
    at64(6.336588173577053), np.float64(6.330674481859525), np.float64(6.325814536246106), np.float64(6.326863165767089), np.float64(6.336544775507685), np.float64(6.3337464975689635), np.
    float64(6.331847691075078), np.float64(6.329740546356697), np.float64(6.328298764355487), np.float64(6.328005740754699), np.float64(6.329680350609911), np.float64(6.325719089567122), n
    p.float64(6.3243307446886705), np.float64(6.325448927831566), np.float64(6.334578329454965), np.float64(6.33896391203015), np.float64(6.344131278178628), np.float64(6.345356344597908),
    np.float64(6.346462198490341), np.float64(6.343113888450451), np.float64(6.343424216863268), np.float64(6.345341423373968), np.float64(6.346972516801389), np.float64(6.334264118794359
    ), np.float64(6.320089688105729), np.float64(6.312857554024797), np.float64(6.316468722278171), np.float64(6.318770614006674), np.float64(6.293275167243099), np.float64(6.2868357551319
    41), np.float64(6.293672057142271), np.float64(6.295650261238481), np.float64(6.288105008093921), np.float64(6.304956932950881), np.float64(6.290524120516261), np.float64(6.27196138260
    8476), np.float64(6.240503578113983), np.float64(6.259191315422179), np.float64(6.264032931716887), np.float64(6.275802149857954), np.float64(6.29233973650218), np.float64(6.3006824029
    oat64(6.334235373638061), np.float64(6.341579565934726), np.float64(6.340000587817826), np.float64(6.338312257141873), np.float64(6.333532479392294), np.float64(6.332473569280897), np.float64(6.344098126493882), np.float64(6.339507945235541), np.float64(6.333704021994592), np.float64(6.3428688570829435), np.float64(6.342334160177025), np.float64(6.344709729292713), np.float64(6.337728487338099), np.float64(6.338619707086098), np.float64(6.333662929035197), np.float64(6.333684162928985), np.float64(6.333202487126668), np.float64(6.33928656376116), np.float64(6.330249065524638), np.float64(6.334848796670068), np.float64(6.339420206710769), np.float64(6.344802237117225), np.float64(6.346227097003739), np.float64(6.347123646336369), np.float64(6.354121989515852), np.float64(6.353924990190995), np.float64(6.3543024437610685), np.float64(6.353970228525719), np.float64(6.352181076792252), np.float64(6.341243716481276), np.float64(6.336772414427273), np.float64(6.324483795335574), np.float64(6.324418583207052), np.float64(6.3251664107730265), np.float64(6.309703929270188), np.float64(6.3052894397965975), np.float64(6.303937420069597), np.float64(6.303213765410882), np.float64(6.303689961844675), np.float64(6.314676405983143), np.float64(6.31701275659393), np.float64(6.285420637158929), np.float64(6.263110757880048), np.float64(6.27780083067335), np.float64(6.284769799572417), np.float64(6.28812757507824), np.float64(6.298014617933884), np.float64(6.303804648765466), np.float64(6.319345221944853), np.float64(6.326887545481974), np.float64(6.342850838796915), np.float64(6.345421387394117), np.float64(6.351798715882801), np.float64(6.3513087475600045), np.float64(6.349152466841291), np.float64(6.345642719249067), np.float64(6.339129510642452), np.float64(6.33303749352764), np.float64(6.321874547055881), np.float64(6.314012034357801), np.float64(6.309673336064435), np.float64(6.303752394332343), np.float64(6.291300389835199), np.float64(6.2747276885625975), np.float64(6.271091021114691)]
    Trendlines calculated successfully.
    An error occurred: 'support_slope'



    Code for trendline.py

    import pandas as pd
    import numpy as np
    from sklearn.linear_model import LinearRegression

    def fit_trendlines_single(data: np.array):
    """Fit a linear regression to the given data and return the slope and intercept."""
    x = np.arange(len(data)).reshape(-1, 1) # Create an array of indices
    model = LinearRegression().fit(x, data)
    return model.coef_[0], model.intercept_ # Return slope and intercept

    def fit_trendlines_high_low(high: np.array, low: np.array):
    """Fit trendlines to high and low prices."""
    support_slope, support_intercept = fit_trendlines_single(low)
    resist_slope, resist_intercept = fit_trendlines_single(high)

    # Debugging statements
    print(f"Support Slope: {support_slope}, Support Intercept: {support_intercept}")
    print(f"Resistance Slope: {resist_slope}, Resistance Intercept: {resist_intercept}")

    return (support_slope, support_intercept), (resist_slope, resist_intercept)

    def calculate_trendlines(data: pd.DataFrame):
    """Calculate support and resistance trendlines from the given DataFrame."""
    required_columns = ['high', 'low', 'close']
    for col in required_columns:
    if col not in data.columns:
    raise KeyError(f"Column '{col}' is missing from the data.")

    # Take natural log of data
    data['close'] = np.log(data['close'])
    data['high'] = np.log(data['high'].replace(0, np.nan))
    data['low'] = np.log(data['low'].replace(0, np.nan))

    lookback = 30
    support_levels = [np.nan] * len(data)
    resist_levels = [np.nan] * len(data)

    for i in range(lookback - 1, len(data)):
    candles = data.iloc[i - lookback + 1: i + 1]
    try:
    # Fit the trendlines and get slopes and intercepts
    (support_slope, support_intercept), (resist_slope, resist_intercept) = fit_trendlines_high_low(
    candles['high'].values,
    candles['low'].values
    )
    except Exception as e:
    print(f"Error fitting trendlines for index {i}: {e}")
    continue # Skip to the next iteration if there's an error

    # Calculate support and resistance levels
    support_intercept = candles['low'].iloc[-1] - support_slope * (lookback - 1)
    resist_intercept = candles['high'].iloc[-1] - resist_slope * (lookback - 1)

    support_levels = support_slope * (len(data) - 1 - i) + support_intercept
    resist_levels = resist_slope * (len(data) - 1 - i) + resist_intercept

    # Convert back to price level and handle any potential issues
    data['support'] = np.exp(support_levels) # Convert back to price level
    data['resistance'] = np.exp(resist_levels) # Convert back to price level

    # Debugging output for support and resistance levels
    print("Support Levels:", support_levels)
    print("Resistance Levels:", resist_levels)

    return data[['support', 'resistance']]




    Heres my plotter.py code.

    import pandas as pd
    import mplfinance as mpf
    from trendline import calculate_trendlines
    from directional_change import directional_change

    def plot_stock_data(df: pd.DataFrame):
    print("Starting to calculate trendlines...")
    trendlines = calculate_trendlines(df)
    print("Trendlines calculated successfully.")

    # Access support and resistance lines
    support_line = trendlines['support_slope'] # Adjusted to match returned DataFrame
    resist_line = trendlines['resist_slope'] # Adjusted to match returned DataFrame

    # Add support and resistance lines to the main DataFrame
    df['support'] = support_line
    df['resistance'] = resist_line

    # Create addplots for support and resistance lines
    apdict = mpf.make_addplot(df[['support', 'resistance']], panel=0, type='line', color=['g', 'r'])

    # Plot the stock data as a candlestick chart with support and resistance lines
    mpf.plot(df, type='candle', addplot=apdict,
    title='Stock Price with Support and Resistance Levels',
    ylabel='Price',
    volume=False,
    style='yahoo')


    # Example of loading data and plotting
    if __name__ == "__main__":
    try:
    # Load your CSV file into a DataFrame
    df = pd.read_csv('bestdata.csv', parse_dates=['date'], index_col='date')
    print("Data loaded successfully.")

    # Ensure required columns are present
    if not {'open', 'high', 'low', 'close'}.issubset(df.columns):
    raise KeyError("The DataFrame must contain 'open', 'high', 'low', and 'close' columns.")

    # Plot the stock data
    plot_stock_data(df)
    except Exception as e:
    print(f"An error occurred: {e}")



    Ive tried a bunch of things, including adding debugging statements but im pretty lost on this. I appreciate any help given

    Continue reading...

Compartilhe esta Página