The reason why it returned error 403 is that the code uses the read_csv function to fetch JSON data from the URL, note how the data source differs from your 2nd code and 3rd code. I barely know Pandas and know some Python a little bit, but here is a little bit fix for the code that shows candlesticks, volume bar, and 20 SMA.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import requests
# data
data = requests.get('https://ftx.com/api/markets/BTC-PERP/candles?resolution=3600&start_time=1609462800').json()
# data initialization
df = pd.DataFrame(data['result'])
df.head()
df['time'] = pd.to_datetime(df['time'], unit='ms')
df.set_index('time', inplace=True)
df['20 SMA'] = df.close.rolling(20).mean()
df.tail()
# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
# include candlestick with rangeselector
fig.add_trace(go.Candlestick(x=df['startTime'],
open=df['open'], high=df['high'],
low=df['low'], close=df['close']),
secondary_y=True,)
# include a go.Bar trace for volumes
fig.add_trace(go.Bar(x=df['startTime'], y=df['volume']),
secondary_y=False)
# include a 20 SMA
fig.add_trace(go.Scatter(x=df['startTime'], y=df['20 SMA'], line=dict(color='purple', width=1)))
fig.layout.yaxis2.showgrid=False
fig.show()