12-Supertrend-Indicator

Sat 17 May 2025
# Created: 20250103
import pyutil as pyu
pyu.get_local_pyinfo()
'conda env: ml312-2024; pyv: 3.12.7 | packaged by Anaconda, Inc. | (main, Oct  4 2024, 13:27:36) [GCC 11.2.0]'
print(pyu.ps2("requests"))
requests==2.32.3
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Step 1: Download historical data
symbol = "^GSPC"  # S&P 500 as an example
start = "2020-01-01"
end = "2023-12-31"
data = yf.download(symbol, start=start, end=end)

# Step 2: Calculate ATR
def calculate_atr(data, atr_window=10):
    data['High-Low'] = data['High'] - data['Low']
    data['High-Close'] = abs(data['High'] - data['Close'].shift(1))
    data['Low-Close'] = abs(data['Low'] - data['Close'].shift(1))
    data['True Range'] = data[['High-Low', 'High-Close', 'Low-Close']].max(axis=1)
    data['ATR'] = data['True Range'].rolling(window=atr_window).mean()
    return data

# Step 3: Calculate Supertrend
def calculate_supertrend(data, multiplier=3, atr_window=10):
    data = calculate_atr(data, atr_window)

    # Calculate Basic Upper and Lower Bands
    upper_band = ((data['High'] + data['Low']) / 2) + (multiplier * data['ATR'])
    lower_band = ((data['High'] + data['Low']) / 2) - (multiplier * data['ATR'])

    # Assign calculated Series to the DataFrame
    data['Basic Upper Band'] = upper_band
    data['Basic Lower Band'] = lower_band

    data['Supertrend'] = np.nan
    in_uptrend = True  # Initial trend is uptrend

    for i in range(1, len(data)):
        if in_uptrend:
            if data['Close'].iloc[i] < data['Basic Upper Band'].iloc[i]:
                in_uptrend = False
            data.loc[data.index[i], 'Supertrend'] = max(
                data['Basic Lower Band'].iloc[i], 
                data['Supertrend'].iloc[i - 1]
            )
        else:
            if data['Close'].iloc[i] > data['Basic Lower Band'].iloc[i]:
                in_uptrend = True
            data.loc[data.index[i], 'Supertrend'] = min(
                data['Basic Upper Band'].iloc[i], 
                data['Supertrend'].iloc[i - 1]
            )

    return data

# Apply the Supertrend calculation
data = calculate_supertrend(data)

# Step 4: Plot Supertrend
plt.figure(figsize=(14, 7))
plt.plot(data['Close'], label='Close Price', color='blue')
plt.plot(data['Supertrend'], label='Supertrend', color='red', linestyle='--')
plt.fill_between(data.index, data['Supertrend'], data['Close'], 
                 where=data['Close'] >= data['Supertrend'], 
                 color='green', alpha=0.3, label='Uptrend')
plt.fill_between(data.index, data['Supertrend'], data['Close'], 
                 where=data['Close'] < data['Supertrend'], 
                 color='red', alpha=0.3, label='Downtrend')
plt.title(f'Supertrend Indicator for {symbol}')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='best')
plt.grid(True)
plt.show()
[*********************100%***********************]  1 of 1 completed



---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

/tmp/ipykernel_947826/1063826374.py in ?()
     51 
     52     return data
     53 
     54 # Apply the Supertrend calculation
---> 55 data = calculate_supertrend(data)
     56 
     57 # Step 4: Plot Supertrend
     58 plt.figure(figsize=(14, 7))


/tmp/ipykernel_947826/1063826374.py in ?(data, multiplier, atr_window)
     26     upper_band = ((data['High'] + data['Low']) / 2) + (multiplier * data['ATR'])
     27     lower_band = ((data['High'] + data['Low']) / 2) - (multiplier * data['ATR'])
     28 
     29     # Assign calculated Series to the DataFrame
---> 30     data['Basic Upper Band'] = upper_band
     31     data['Basic Lower Band'] = lower_band
     32 
     33     data['Supertrend'] = np.nan


~/miniconda3/envs/ml312-2024/lib/python3.12/site-packages/pandas/core/frame.py in ?(self, key, value)
   4297             self._setitem_frame(key, value)
   4298         elif isinstance(key, (Series, np.ndarray, list, Index)):
   4299             self._setitem_array(key, value)
   4300         elif isinstance(value, DataFrame):
-> 4301             self._set_item_frame_value(key, value)
   4302         elif (
   4303             is_list_like(value)
   4304             and not self.columns.is_unique


~/miniconda3/envs/ml312-2024/lib/python3.12/site-packages/pandas/core/frame.py in ?(self, key, value)
   4455 
   4456             return self.isetitem(locs, value)
   4457 
   4458         if len(value.columns) > 1:
-> 4459             raise ValueError(
   4460                 "Cannot set a DataFrame with multiple columns to the single "
   4461                 f"column {key}"
   4462             )


ValueError: Cannot set a DataFrame with multiple columns to the single column Basic Upper Band
# Step 2: Calculate ATR
def calculate_atr(data, atr_window=10):
    data['High-Low'] = data['High'] - data['Low']
    data['High-Close'] = abs(data['High'] - data['Close'].shift(1))
    data['Low-Close'] = abs(data['Low'] - data['Close'].shift(1))
    data['True Range'] = data[['High-Low', 'High-Close', 'Low-Close']].max(axis=1)
    data['ATR'] = data['True Range'].rolling(window=atr_window).mean()
    return data

# Step 3: Calculate Supertrend
def calculate_supertrend(data, multiplier=3, atr_window=10):
    data = calculate_atr(data, atr_window)
    # Ensure correct column assignment with a single series
    data['Basic Upper Band'] = ((data['High'] + data['Low']) / 2) + (multiplier * data['ATR'])
    data['Basic Lower Band'] = ((data['High'] + data['Low']) / 2) - (multiplier * data['ATR'])

    data['Supertrend'] = np.nan
    in_uptrend = True  # Initial trend is uptrend

    for i in range(len(data)):
        if i == 0:
            data.loc[data.index[i], 'Supertrend'] = data.loc[data.index[i], 'Basic Lower Band']
            continue

        if in_uptrend:
            if data.loc[data.index[i], 'Close'] < data.loc[data.index[i], 'Basic Upper Band']:
                in_uptrend = False
            data.loc[data.index[i], 'Supertrend'] = max(
                data.loc[data.index[i], 'Basic Lower Band'], 
                data.loc[data.index[i - 1], 'Supertrend']
            )
        else:
            if data.loc[data.index[i], 'Close'] > data.loc[data.index[i], 'Basic Lower Band']:
                in_uptrend = True
            data.loc[data.index[i], 'Supertrend'] = min(
                data.loc[data.index[i], 'Basic Upper Band'], 
                data.loc[data.index[i - 1], 'Supertrend']
            )

    return data

def show_graph(symbol):

    # Step 1: Download historical data
    start = "2020-01-01"
    end = "2023-12-31"
    data = yf.download(symbol, start=start, end=end)

    # Apply the Supertrend calculation
    data = calculate_supertrend(data)

    # Step 4: Plot Supertrend
    plt.figure(figsize=(14, 7))
    plt.plot(data['Close'], label='Close Price', color='blue')
    plt.plot(data['Supertrend'], label='Supertrend', color='red', linestyle='--')
    plt.fill_between(data.index, data['Supertrend'], data['Close'], 
                     where=data['Close'] >= data['Supertrend'], 
                     color='green', alpha=0.3, label='Uptrend')
    plt.fill_between(data.index, data['Supertrend'], data['Close'], 
                     where=data['Close'] < data['Supertrend'], 
                     color='red', alpha=0.3, label='Downtrend')
    plt.title(f'Supertrend Indicator for {symbol}')
    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.legend(loc='best')
    plt.grid(True)
    plt.show()
show_graph("AMZN")
[*********************100%***********************]  1 of 1 completed



---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

/tmp/ipykernel_947826/73109923.py in ?()
----> 1 show_graph("AMZN")


/tmp/ipykernel_947826/2804851505.py in ?(symbol)
      5     end = "2023-12-31"
      6     data = yf.download(symbol, start=start, end=end)
      7 
      8     # Apply the Supertrend calculation
----> 9     data = calculate_supertrend(data)
     10 
     11     # Step 4: Plot Supertrend
     12     plt.figure(figsize=(14, 7))


/tmp/ipykernel_947826/4282768184.py in ?(data, multiplier, atr_window)
     11 def calculate_supertrend(data, multiplier=3, atr_window=10):
     12     data = calculate_atr(data, atr_window)
     13     # Ensure correct column assignment with a single series
---> 14     data['Basic Upper Band'] = ((data['High'] + data['Low']) / 2) + (multiplier * data['ATR'])
     15     data['Basic Lower Band'] = ((data['High'] + data['Low']) / 2) - (multiplier * data['ATR'])
     16 
     17     data['Supertrend'] = np.nan


~/miniconda3/envs/ml312-2024/lib/python3.12/site-packages/pandas/core/frame.py in ?(self, key, value)
   4297             self._setitem_frame(key, value)
   4298         elif isinstance(key, (Series, np.ndarray, list, Index)):
   4299             self._setitem_array(key, value)
   4300         elif isinstance(value, DataFrame):
-> 4301             self._set_item_frame_value(key, value)
   4302         elif (
   4303             is_list_like(value)
   4304             and not self.columns.is_unique


~/miniconda3/envs/ml312-2024/lib/python3.12/site-packages/pandas/core/frame.py in ?(self, key, value)
   4455 
   4456             return self.isetitem(locs, value)
   4457 
   4458         if len(value.columns) > 1:
-> 4459             raise ValueError(
   4460                 "Cannot set a DataFrame with multiple columns to the single "
   4461                 f"column {key}"
   4462             )


ValueError: Cannot set a DataFrame with multiple columns to the single column Basic Upper Band


Score: 10

Category: stockmarket