How to calculate slope of moving average accurately for a series of points?

Viewed 1471

What I am trying to do is calculate a simple moving average for a specified period of time for stock prices. I referred to a lot of online resources and all of them recommend using the rolling_mean function to calculate a moving average.

I did the above like this:


def getEODData(symbol):
    api_result = requests.get('http://api.marketstack.com/v1/eod?access_key='+apikey+'&symbols='+symbol+'&limit=2500')
    api_response = api_result.json()
    df=pd.DataFrame.from_dict(api_response['data'])
    df=df.iloc[::-1]
    timeshort=66

    if not df.empty:
        
        df['SMA']=df.iloc[:,3].rolling(window=timeshort).mean() 
        slope_short=((df['SMA'][0]-df['SMA'][timeshort])/timeshort)
        slope_short_deg = math.atan(slope_short) * 180 / math.pi
        print(slope_short_deg)

I did df. iloc[::-1] because the first 66 periods be NaN for rolling_mean calculation so I flipped the data frame so that I can get the moving average values for the latest dates.

This is how it looks after flipping:

open       high        low      close     volume  adj_high  adj_low  ...  adj_volume  split_factor  symbol  exchange                      date          SMA     SMA_long
1791   568.0000   568.0000   552.9200   558.4600    13100.0    568.00   552.92  ...     13100.0           2.0    GOOG      XNAS  2014-03-27T00:00:00+0000          NaN          NaN
1790   561.2000   566.4300   558.6700   559.9900    41100.0    566.43   558.67  ...     41100.0           1.0    GOOG      XNAS  2014-03-28T00:00:00+0000          NaN          NaN
1789   566.8900   567.0000   556.9300   556.9700    10800.0    567.00   556.93  ...     10800.0           1.0    GOOG      XNAS  2014-03-31T00:00:00+0000          NaN          NaN
1788   558.7100   568.4500   558.7100   567.1600     7900.0    568.45   558.71  ...      7900.0           1.0    GOOG      XNAS  2014-04-01T00:00:00+0000          NaN          NaN
1787   565.1060   604.8300   562.1900   567.0000   146700.0    604.83   562.19  ...    146700.0           1.0    GOOG      XNAS  2014-04-02T00:00:00+0000          NaN          NaN
...         ...        ...        ...        ...        ...       ...      ...  ...         ...           ...     ...       ...                       ...          ...          ...
4     2402.7200  2419.7000  2384.5000  2395.1699  1648353.0       NaN      NaN  ...         NaN           1.0    GOOG      XNAS  2021-05-03T00:00:00+0000  2134.197117  1724.360315
3     2369.7400  2379.2600  2311.7000  2354.2500  1686545.0       NaN      NaN  ...         NaN           1.0    GOOG      XNAS  2021-05-04T00:00:00+0000  2141.638632  1728.445849   
2     2368.4199  2382.2000  2351.8850  2356.7400  1090275.0       NaN      NaN  ...         NaN           1.0    GOOG      XNAS  2021-05-05T00:00:00+0000  2149.532571  1732.516758   
1     2350.6399  2382.7100  2342.3381  2381.3501   978908.0       NaN      NaN  ...         NaN           1.0    GOOG      XNAS  2021-05-06T00:00:00+0000  2156.805300  1736.588853   
0     2400.0000  2416.4099  2390.0000  2398.6899  1163600.0       NaN      NaN  ...         NaN           1.0    GOOG      XNAS  2021-05-07T00:00:00+0000  2163.944389  1740.744544   

Now I tried to run for the google stock and it gave the output as 80.47 deg. Then I went to a site called tradingview to verify my result and it was like this:

enter image description here

( settings for this graph -> time period of graph - 1day and moving average period -66)

I drew the red line for the slope for 66 bars and as you can see this is nowhere close to 80 deg.

Then I thought of using np.polyfit() to find the slope like this:

 y=np.array(df['SMA'][-(timeshort):])
 x= range(0, len(y))
 sl, b=np.polyfit(x,y,1)
 sl=math.atan(sl) * 180 / math.pi

But this also gave an output of 79 deg.

What am I doing wrong? How can I get a slope like of the websites?

Any help would be greatly appreciated.

1 Answers

Sorry for the delay, let's see the code snippet below:

>>> import math
>>> slope_short_deg = math.atan(1) * 180 / math.pi
>>> slope_short_deg
45.0
>>> slope_short_deg = math.atan(2) * 180 / math.pi
>>> slope_short_deg
63.43494882292201
>>> slope_short_deg = math.atan(3) * 180 / math.pi
>>> slope_short_deg
71.56505117707799

As you can see, when the input argument of the math.atan() is 1, the degree of the result is 45, so it seems that it considers the x element as 1, and by increasing the input argument, the degree increases.

You can use math.atan2(y, x) and pass x parameter too.

You may say the x parameter is the date of the candles, this is ok, you can see the date size is relative and you can change it by scrolling and the degree of the line in the chart will be changed.

So you can choose an x number and form a condition relative to it according to your strategy.

Related