avatarAlexzap

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

20150

Abstract

_">get_historical_data</span>(<span class="hljs-params">symbol, start_date</span>): api_key = <span class="hljs-string">'your_api_key'</span> api_url = <span class="hljs-string">f'https://api.twelvedata.com/time_series?symbol=<span class="hljs-subst">{symbol}</span>&interval=1day&outputsize=5000&apikey=<span class="hljs-subst">{api_key}</span>'</span> raw_df = requests.get(api_url).json() df = pd.DataFrame(raw_df[<span class="hljs-string">'values'</span>]).iloc[::-<span class="hljs-number">1</span>].set_index(<span class="hljs-string">'datetime'</span>).astype(<span class="hljs-built_in">float</span>) df = df[df.index >= start_date] df.index = pd.to_datetime(df.index) <span class="hljs-keyword">return</span> df

aapl = get_historical_data(<span class="hljs-string">'NVDA'</span>, <span class="hljs-string">'2023-01-03'</span>) aapl.tail()</pre></div><figure id="6e4f"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*AP4fBcG2oCE9t_cj6R9Ovg.jpeg"><figcaption></figcaption></figure><ul><li>Plotting the NVDA stock price data</li></ul><div id="4a33"><pre>plt.plot(aapl.index, aapl[<span class="hljs-string">'close'</span>]) plt.xlabel(<span class="hljs-string">'Date'</span>) plt.ylabel(<span class="hljs-string">'Closing Prices'</span>) plt.title(<span class="hljs-string">'Stock Prices'</span>) plt.show()</pre></div><figure id="114a"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*8v7aMX2I-Wz6uovs7e9syg.jpeg"><figcaption>1Y NVDA stock price data</figcaption></figure><ul><li>Plotting SMA20 vs stock price</li></ul><div id="b006"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">sma</span>(<span class="hljs-params">data, window</span>): sma = data.rolling(window = window).mean() <span class="hljs-keyword">return</span> sma

aapl[<span class="hljs-string">'sma_20'</span>] = sma(aapl[<span class="hljs-string">'close'</span>], <span class="hljs-number">20</span>) aapl.tail(<span class="hljs-number">3</span>)

aapl[<span class="hljs-string">'close'</span>].plot(label = <span class="hljs-string">'CLOSE'</span>, alpha = <span class="hljs-number">0.6</span>) aapl[<span class="hljs-string">'sma_20'</span>].plot(label = <span class="hljs-string">'SMA 20'</span>, linewidth = <span class="hljs-number">2</span>) plt.xlabel(<span class="hljs-string">'Date'</span>) plt.ylabel(<span class="hljs-string">'Closing Prices'</span>) plt.legend(loc = <span class="hljs-string">'upper left'</span>) plt.show()</pre></div><figure id="1a2f"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*HONQCHNufaWr2N7rSl233w.jpeg"><figcaption>NVDA stock price vs SMA20</figcaption></figure><ul><li>As we can see, SMA helps level price action by filtering out the noise from random price fluctuations.</li><li>SMA values below the current price indicate support levels, as shown above.</li><li>Plotting BB20 vs stock price</li></ul><div id="21ac"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">bb</span>(<span class="hljs-params">data, sma, window</span>): std = data.rolling(window = window).std() upper_bb = sma + std * <span class="hljs-number">2</span> lower_bb = sma - std * <span class="hljs-number">2</span> <span class="hljs-keyword">return</span> upper_bb, lower_bb

aapl[<span class="hljs-string">'upper_bb'</span>], aapl[<span class="hljs-string">'lower_bb'</span>] = bb(aapl[<span class="hljs-string">'close'</span>], aapl[<span class="hljs-string">'sma_20'</span>], <span class="hljs-number">20</span>) aapl.tail()

aapl[<span class="hljs-string">'close'</span>].plot(label = <span class="hljs-string">'CLOSE PRICES'</span>, color = <span class="hljs-string">'skyblue'</span>) aapl[<span class="hljs-string">'upper_bb'</span>].plot(label = <span class="hljs-string">'UPPER BB 20'</span>, linestyle = <span class="hljs-string">'--'</span>, linewidth = <span class="hljs-number">1</span>, color = <span class="hljs-string">'black'</span>) aapl[<span class="hljs-string">'sma_20'</span>].plot(label = <span class="hljs-string">'MIDDLE BB 20'</span>, linestyle = <span class="hljs-string">'--'</span>, linewidth = <span class="hljs-number">1.2</span>, color = <span class="hljs-string">'grey'</span>) aapl[<span class="hljs-string">'lower_bb'</span>].plot(label = <span class="hljs-string">'LOWER BB 20'</span>, linestyle = <span class="hljs-string">'--'</span>, linewidth = <span class="hljs-number">1</span>, color = <span class="hljs-string">'black'</span>) plt.legend(loc = <span class="hljs-string">'upper left'</span>) plt.title(<span class="hljs-string">'BOLLINGER BANDS'</span>) plt.show()</pre></div><figure id="74ca"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*BGdiFtqU95jzQWbPsoaQ0w.jpeg"><figcaption>NVDA Bollinger Bands vs Stock Price</figcaption></figure><ul><li>BB help determine whether prices are high or low on a relative basis. They are used in pairs, both upper and lower bands and in conjunction with SMA.</li><li><a href="https://www.schwab.com/learn/story/bollinger-bands-what-they-are-and-how-to-use-them">Bollinger Bands</a> can also indicate the end of a strong trend. Strong trends, especially those developing after a breakout of a trading range, will result in an expansion in volatility that will cause the bands to initially move apart.</li><li>Calculating and plotting the NVDA BB strategy trading signals</li></ul><div id="0da1"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">implement_bb_strategy</span>(<span class="hljs-params">data, lower_bb, upper_bb</span>): buy_price = [] sell_price = [] bb_signal = [] signal = <span class="hljs-number">0</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data)):
    <span class="hljs-keyword">if</span> data[i-<span class="hljs-number">1</span>] &gt; lower_bb[i-<span class="hljs-number">1</span>] <span class="hljs-keyword">and</span> data[i] &lt; lower_bb[i]:
        <span class="hljs-keyword">if</span> signal != <span class="hljs-number">1</span>:
            buy_price.append(data[i])
            sell_price.append(np.nan)
            signal = <span class="hljs-number">1</span>
            bb_signal.append(signal)
        <span class="hljs-keyword">else</span>:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            bb_signal.append(<span class="hljs-number">0</span>)
    <span class="hljs-keyword">elif</span> data[i-<span class="hljs-number">1</span>] &lt; upper_bb[i-<span class="hljs-number">1</span>] <span class="hljs-keyword">and</span> data[i] &gt; upper_bb[i]:
        <span class="hljs-keyword">if</span> signal != -<span class="hljs-number">1</span>:
            buy_price.append(np.nan)
            sell_price.append(data[i])
            signal = -<span class="hljs-number">1</span>
            bb_signal.append(signal)
        <span class="hljs-keyword">else</span>:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            bb_signal.append(<span class="hljs-number">0</span>)
    <span class="hljs-keyword">else</span>:
        buy_price.append(np.nan)
        sell_price.append(np.nan)
        bb_signal.append(<span class="hljs-number">0</span>)
        
<span class="hljs-keyword">return</span> buy_price, sell_price, bb_signal

buy_price, sell_price, bb_signal = implement_bb_strategy(aapl[<span class="hljs-string">'close'</span>], aapl[<span class="hljs-string">'lower_bb'</span>], aapl[<span class="hljs-string">'upper_bb'</span>])

aapl[<span class="hljs-string">'close'</span>].plot(label = <span class="hljs-string">'CLOSE PRICES'</span>, alpha = <span class="hljs-number">0.3</span>) aapl[<span class="hljs-string">'upper_bb'</span>].plot(label = <span class="hljs-string">'UPPER BB'</span>, linestyle = <span class="hljs-string">'--'</span>, linewidth = <span class="hljs-number">1</span>, color = <span class="hljs-string">'black'</span>) aapl[<span class="hljs-string">'sma_20'</span>].plot(label = <span class="hljs-string">'MIDDLE BB'</span>, linestyle = <span class="hljs-string">'--'</span>, linewidth = <span class="hljs-number">1.2</span>, color = <span class="hljs-string">'grey'</span>) aapl[<span class="hljs-string">'lower_bb'</span>].plot(label = <span class="hljs-string">'LOWER BB'</span>, linestyle = <span class="hljs-string">'--'</span>, linewidth = <span class="hljs-number">1</span>, color = <span class="hljs-string">'black'</span>) plt.scatter(aapl.index, buy_price, marker = <span class="hljs-string">'^'</span>, color = <span class="hljs-string">'green'</span>, label = <span class="hljs-string">'BUY'</span>, s = <span class="hljs-number">200</span>) plt.scatter(aapl.index, sell_price, marker = <span class="hljs-string">'v'</span>, color = <span class="hljs-string">'red'</span>, label = <span class="hljs-string">'SELL'</span>, s = <span class="hljs-number">200</span>) plt.title(<span class="hljs-string">'BB STRATEGY TRADING SIGNALS'</span>) plt.legend(loc = <span class="hljs-string">'upper left'</span>) plt.show()</pre></div><figure id="8aaa"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*9fYT44XI7WgaWlVK9cNLkw.jpeg"><figcaption>NVDA BB strategy trading signals</figcaption></figure><ul><li>Calculating and plotting the NVDA BB strategy daily returns</li></ul><div id="1bcd"><pre>position = [] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(bb_signal)): <span class="hljs-keyword">if</span> bb_signal[i] > <span class="hljs-number">1</span>: position.append(<span class="hljs-number">0</span>) <span class="hljs-keyword">else</span>: position.append(<span class="hljs-number">1</span>)

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(aapl[<span class="hljs-string">'close'</span>])): <span class="hljs-keyword">if</span> bb_signal[i] == <span class="hljs-number">1</span>: position[i] = <span class="hljs-number">1</span> <span class="hljs-keyword">elif</span> bb_signal[i] == -<span class="hljs-number">1</span>: position[i] = <span class="hljs-number">0</span> <span class="hljs-keyword">else</span>: position[i] = position[i-<span class="hljs-number">1</span>]

upper_bb = aapl[<span class="hljs-string">'upper_bb'</span>] lower_bb = aapl[<span class="hljs-string">'lower_bb'</span>] close_price = aapl[<span class="hljs-string">'close'</span>] bb_signal = pd.DataFrame(bb_signal).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'bb_signal'</span>}).set_index(aapl.index) position = pd.DataFrame(position).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'bb_position'</span>}).set_index(aapl.index)

frames = [close_price, upper_bb, lower_bb, bb_signal, position] strategy = pd.concat(frames, join = <span class="hljs-string">'inner'</span>, axis = <span class="hljs-number">1</span>)

<span class="hljs-comment">#strategy.tail(10)</span>

rets = aapl.close.pct_change().dropna() strat_rets = strategy.bb_position[<span class="hljs-number">1</span>:]*rets

plt.title(<span class="hljs-string">'Daily Returns'</span>) rets.plot(color = <span class="hljs-string">'blue'</span>, alpha = <span class="hljs-number">0.3</span>, linewidth = <span class="hljs-number">7</span>) strat_rets.plot(color = <span class="hljs-string">'r'</span>, linewidth = <span class="hljs-number">1</span>) plt.show()</pre></div><figure id="7ca1"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*ZFNLE4wHpJwkiYsmMy8NJA.jpeg"><figcaption>NVDA BB strategy daily returns</figcaption></figure><ul><li>Calculating and plotting the Keltner Channel (<a href="https://github.com/Nikhil-Adithyan/Algorithmic-Trading-with-Python/blob/main/Volatility/Keltner_Channel.py">KC20</a>)</li></ul><div id="98f4"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_kc</span>(<span class="hljs-params">high, low, close, kc_lookback, multiplier, atr_lookback</span>): tr1 = pd.DataFrame(high - low) tr2 = pd.DataFrame(<span class="hljs-built_in">abs</span>(high - close.shift())) tr3 = pd.DataFrame(<span class="hljs-built_in">abs</span>(low - close.shift())) frames = [tr1, tr2, tr3] tr = pd.concat(frames, axis = <span class="hljs-number">1</span>, join = <span class="hljs-string">'inner'</span>).<span class="hljs-built_in">max</span>(axis = <span class="hljs-number">1</span>) atr = tr.ewm(alpha = <span class="hljs-number">1</span>/atr_lookback).mean()

kc_middle = close.ewm(kc_lookback).mean()
kc_upper = close.ewm(kc_lookback).mean() + multiplier * atr
kc_lower = close.ewm(kc_lookback).mean() - multiplier * atr

<span class="hljs-keyword">return</span> kc_middle, kc_upper, kc_lower

aapl = aapl.iloc[:,:<span class="hljs-number">4</span>] aapl[<span class="hljs-string">'kc_middle'</span>], aapl[<span class="hljs-string">'kc_upper'</span>], aapl[<span class="hljs-string">'kc_lower'</span>] = get_kc(aapl[<span class="hljs-string">'high'</span>], aapl[<span class="hljs-string">'low'</span>], aapl[<span class="hljs-string">'close'</span>], <span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">10</span>) <span class="hljs-comment">#aapl.tail()</span>

<span class="hljs-comment"># KELTNER CHANNEL PLOT</span>

plt.plot(aapl[<span class="hljs-string">'close'</span>], linewidth = <span class="hljs-number">2</span>, label = <span class="hljs-string">'NVDA'</span>) plt.plot(aapl[<span class="hljs-string">'kc_upper'</span>], linewidth = <span class="hljs-number">2</span>, color = <span class="hljs-string">'orange'</span>, linestyle = <span class="hljs-string">'--'</span>, label = <span class="hljs-string">'KC UPPER 20'</span>) plt.plot(aapl[<span class="hljs-string">'kc_middle'</span>], linewidth = <span class="hljs-number">1.5</span>, color = <span class="hljs-string">'grey'</span>, label = <span class="hljs-string">'KC MIDDLE 20'</span>) plt.plot(aapl[<span class="hljs-string">'kc_lower'</span>], linewidth = <span class="hljs-number">2</span>, color = <span class="hljs-string">'orange'</span>, linestyle = <span class="hljs-string">'--'</span>, label = <span class="hljs-string">'KC LOWER 20'</span>) plt.legend(loc = <span class="hljs-string">'lower right'</span>, fontsize = <span class="hljs-number">15</span>) plt.title(<span class="hljs-string">'KELTNER CHANNEL 20'</span>) plt.show()</pre></div><figure id="997c"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*oUEVYFw4F-e5rsGOkD16Xw.jpeg"><figcaption>NVDA Keltner Channel 20 vs stock price</figcaption></figure><ul><li>Performing <a href="https://github.com/Nikhil-Adithyan/Algorithmic-Trading-with-Python/blob/main/Volatility/Bollinger_Bands.py">backtesting</a> of the BB trading strategy by investing $10k</li></ul><div id="5b95"><pre><span class="hljs-keyword">import</span> math

aapl_ret = pd.DataFrame(np.diff(aapl[<span class="hljs-string">'close'</span>])).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'returns'</span>}) tsi_strategy_ret = []

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(aapl_ret)): returns = aapl_ret[<span class="hljs-string">'returns'</span>][i]*strategy[<span class="hljs-string">'bb_position'</span>][i] tsi_strategy_ret.append(returns)

tsi_strategy_ret_df = pd.DataFrame(tsi_strategy_ret).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'bb_returns'</span>}) investment_value = <span class="hljs-number">10000</span> number_of_stocks = math.floor(investment_value/aapl[<span class="hljs-string">'close'</span>][<span class="hljs-number">0</span>]) tsi_investment_ret = []

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(tsi_strategy_ret_df[<span class="hljs-string">'bb_returns'</span>])): returns = number_of_stocks*tsi_strategy_ret_df[<span class="hljs-string">'bb_returns'</span>][i] tsi_investment_ret.append(returns)

tsi_investment_ret_df = pd.DataFrame(tsi_investment_ret).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'investment_returns'</span>}) total_investment_ret = <span class="hljs-built_in">round</span>(<span class="hljs-built_in">sum</span>(tsi_investment_ret_df[<span class="hljs-string">'investment_returns'</span>]), <span class="hljs-number">2</span>) profit_percentage = math.floor((total_investment_ret/investment_value)*<span class="hljs-number">100</span>) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Profit gained from the BB strategy by investing $10k : {}'</span>.<span class="hljs-built_in">format</span>(total_investment_ret), attrs = [<span class="hljs-string">'bold'</span>])) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Profit percentage of the BB strategy : {}%'</span>.<span class="hljs-built_in">format</span>(profit_percentage), attrs = [<span class="hljs-string">'bold'</span>]))

Profit gained <span class="hljs-keyword">from</span> the BB strategy by investing 10k : <span class="hljs-number">19797.48</span> Profit percentage of the BB strategy : <span class="hljs-number">197</span>%</pre></div><ul><li>Comparing the BB strategy against the <a href="https://github.com/Nikhil-Adithyan/Algorithmic-Trading-with-Python/blob/main/Volatility/Bollinger_Bands.py">SPY ETF benchmark</a> by investing 10k</li></ul><div id="93c7"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_benchmark</span>(<span class="hljs-params">start_date, investment_value</span>): spy = get_historical_data(<span class="hljs-string">'SPY'</span>, start_date)[<span class="hljs-string">'close'</span>] benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'benchmark_returns'</span>})

investment_value = investment_value
number_of_stocks = math.floor(investment_value/spy[-<span class="hljs-number">1</span>])
benchmark_investment_ret = []

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(benchmark[<span class="hljs-string">'benchmark_returns'</span>])):
    returns = number_of_stocks*benchmark[<span class="hljs-string">'benchmark_returns'</span>][i]
    benchmark_investment_ret.append(returns)

benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'investment_returns'</span>})
<span class="hljs-keyword">return</span> benchmark_investment_ret_df

benchmark = get_benchmark(<span class="hljs-string">'2023-01-03'</span>, <span class="hljs-number">10000</span>) investment_value = <span class="hljs-number">10000</span> total_benchmark_investment_ret = <span class="hljs-built_in">round</span>(<span class="hljs-built_in">sum</span>(benchmark[<span class="hljs-string">'investment_returns'</span>]), <span class="hljs-number">2</span>) benchmark_profit_percentage = math.floor((total_benchmark_investment_ret/investment_value)*<span class="hljs-number">100</span>) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Benchmark profit by investing $10k : {}'</span>.<span class="hljs-built_in">format</span>(total_benchmark_investment_ret), attrs = [<span class="hljs-string">'bold'</span>])) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Benchmark P

Options

rofit percentage : {}%'</span>.<span class="hljs-built_in">format</span>(benchmark_profit_percentage), attrs = [<span class="hljs-string">'bold'</span>])) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'BB Strategy profit is {}% higher than the Benchmark Profit'</span>.<span class="hljs-built_in">format</span>(profit_percentage - benchmark_profit_percentage), attrs = [<span class="hljs-string">'bold'</span>]))

Benchmark profit by investing $10k : <span class="hljs-number">2562.91</span> Benchmark Profit percentage : <span class="hljs-number">25</span>% BB Strategy profit <span class="hljs-keyword">is</span> <span class="hljs-number">172</span>% higher than the Benchmark Profit</pre></div><ul><li>Backtesting can provide valuable insights into NVDA historical performance, but it does not guarantee future success. It’s important to combine backtesting with other forms of risk assessment to make well-informed trading decisions.</li><li>Let’s examine the <a href="https://readmedium.com/algorithmic-trading-with-the-aroon-indicator-in-python-3d2277d2f664">Aroon trading strategy</a> that is used to identify <a href="https://www.investopedia.com/terms/a/aroon.asp">trend</a> changes in the price of an asset, as well as the strength of that trend.</li><li>If the Aroon-Up crosses above the Aroon-Down, then a new uptrend may start soon. Conversely, if Aroon-Down crosses above the Aroon-Up, then a new downtrend may start soon. When Aroon-Up reaches 100, a new uptrend may have begun.</li></ul><div id="c4ff"><pre><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd <span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np <span class="hljs-keyword">import</span> requests <span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt <span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> floor <span class="hljs-keyword">from</span> termcolor <span class="hljs-keyword">import</span> colored <span class="hljs-keyword">as</span> cl

plt.style.use(<span class="hljs-string">'fivethirtyeight'</span>) plt.rcParams[<span class="hljs-string">'figure.figsize'</span>] = (<span class="hljs-number">20</span>, <span class="hljs-number">10</span>) myticker=<span class="hljs-string">'NVDA'</span> mydate=<span class="hljs-string">'2023-1-1'</span> myamount=<span class="hljs-number">10000</span> mywin=<span class="hljs-number">25</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_historical_data</span>(<span class="hljs-params">symbol, start_date</span>): api_key = <span class="hljs-string">'your_api_key'</span> api_url = <span class="hljs-string">f'https://api.twelvedata.com/time_series?symbol=<span class="hljs-subst">{symbol}</span>&interval=1day&outputsize=5000&apikey=<span class="hljs-subst">{api_key}</span>'</span> raw_df = requests.get(api_url).json() df = pd.DataFrame(raw_df[<span class="hljs-string">'values'</span>]).iloc[::-<span class="hljs-number">1</span>].set_index(<span class="hljs-string">'datetime'</span>).astype(<span class="hljs-built_in">float</span>) df = df[df.index >= start_date] df.index = pd.to_datetime(df.index) <span class="hljs-keyword">return</span> df

tsla = get_historical_data(myticker, mydate)

<span class="hljs-keyword">def</span> <span class="hljs-title function_">get_aroon</span>(<span class="hljs-params">symbol, lookback, start_date</span>): api_key = <span class="hljs-string">'your_api_key'</span> api_url = <span class="hljs-string">f'https://api.twelvedata.com/aroon?symbol=<span class="hljs-subst">{symbol}</span>&interval=1day&time_period=<span class="hljs-subst">{lookback}</span>&outputsize=5000&apikey=<span class="hljs-subst">{api_key}</span>'</span> raw_df = requests.get(api_url).json() df = pd.DataFrame(raw_df[<span class="hljs-string">'values'</span>]).iloc[::-<span class="hljs-number">1</span>].set_index(<span class="hljs-string">'datetime'</span>).astype(<span class="hljs-built_in">float</span>) df = df[df.index >= start_date] df.index = pd.to_datetime(df.index) aroon_up = df[<span class="hljs-string">'aroon_up'</span>] aroon_down = df[<span class="hljs-string">'aroon_down'</span>] <span class="hljs-keyword">return</span> aroon_up, aroon_down

tsla[<span class="hljs-string">'aroon_up'</span>], tsla[<span class="hljs-string">'aroon_down'</span>] = get_aroon(myticker, <span class="hljs-number">25</span>, mydate)

</pre></div><ul><li>Plotting NVDA Close Price vs Aroon 25</li></ul><div id="f8a1"><pre>ax1 = plt.subplot2grid((<span class="hljs-number">11</span>,<span class="hljs-number">1</span>), (<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), rowspan = <span class="hljs-number">5</span>, colspan = <span class="hljs-number">1</span>) ax2 = plt.subplot2grid((<span class="hljs-number">11</span>,<span class="hljs-number">1</span>), (<span class="hljs-number">6</span>,<span class="hljs-number">0</span>), rowspan = <span class="hljs-number">4</span>, colspan = <span class="hljs-number">1</span>) ax1.plot(tsla[<span class="hljs-string">'close'</span>], linewidth = <span class="hljs-number">2.5</span>, color = <span class="hljs-string">'#2196f3'</span>) ax1.set_title(<span class="hljs-string">'NVDA CLOSE PRICES'</span>) ax2.plot(tsla[<span class="hljs-string">'aroon_up'</span>], color = <span class="hljs-string">'#26a69a'</span>, linewidth = <span class="hljs-number">2</span>, label = <span class="hljs-string">'AROON UP'</span>) ax2.plot(tsla[<span class="hljs-string">'aroon_down'</span>], color = <span class="hljs-string">'#ef5350'</span>, linewidth = <span class="hljs-number">2</span>, label = <span class="hljs-string">'AROON DOWN'</span>) ax2.legend() ax2.set_title(<span class="hljs-string">'NVDA AROON 25'</span>) plt.show()</pre></div><figure id="e78d"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*qMpMEuVybxtcnEViv93RZA.jpeg"><figcaption>NVDA Close Price vs Aroon 25</figcaption></figure><ul><li>Implementing the Aroon trading <a href="https://readmedium.com/algorithmic-trading-with-the-aroon-indicator-in-python-3d2277d2f664">strategy</a></li></ul><div id="c3e0"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">implement_aroon_strategy</span>(<span class="hljs-params">prices, up, down</span>): buy_price = [] sell_price = [] aroon_signal = [] signal = <span class="hljs-number">0</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(prices)):
    <span class="hljs-keyword">if</span> up[i] &gt;= <span class="hljs-number">70</span> <span class="hljs-keyword">and</span> down[i] &lt;= <span class="hljs-number">30</span>:
        <span class="hljs-keyword">if</span> signal != <span class="hljs-number">1</span>:
            buy_price.append(prices[i])
            sell_price.append(np.nan)
            signal = <span class="hljs-number">1</span>
            aroon_signal.append(signal)
        <span class="hljs-keyword">else</span>:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            aroon_signal.append(<span class="hljs-number">0</span>)
    <span class="hljs-keyword">elif</span> up[i] &lt;= <span class="hljs-number">30</span> <span class="hljs-keyword">and</span> down[i] &gt;= <span class="hljs-number">70</span>:
        <span class="hljs-keyword">if</span> signal != -<span class="hljs-number">1</span>:
            buy_price.append(np.nan)
            sell_price.append(prices[i])
            signal = -<span class="hljs-number">1</span>
            aroon_signal.append(signal)
        <span class="hljs-keyword">else</span>:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            aroon_signal.append(<span class="hljs-number">0</span>)
    <span class="hljs-keyword">else</span>:
        buy_price.append(np.nan)
        sell_price.append(np.nan)
        aroon_signal.append(<span class="hljs-number">0</span>)
        
<span class="hljs-keyword">return</span> buy_price, sell_price, aroon_signal

buy_price, sell_price, aroon_signal = implement_aroon_strategy(tsla[<span class="hljs-string">'close'</span>], tsla[<span class="hljs-string">'aroon_up'</span>], tsla[<span class="hljs-string">'aroon_down'</span>])</pre></div><ul><li>Plotting the NVDA Aroon trading signals</li></ul><div id="ad3c"><pre>ax1 = plt.subplot2grid((<span class="hljs-number">11</span>,<span class="hljs-number">1</span>), (<span class="hljs-number">0</span>,<span class="hljs-number">0</span>), rowspan = <span class="hljs-number">5</span>, colspan = <span class="hljs-number">1</span>) ax2 = plt.subplot2grid((<span class="hljs-number">11</span>,<span class="hljs-number">1</span>), (<span class="hljs-number">6</span>,<span class="hljs-number">0</span>), rowspan = <span class="hljs-number">4</span>, colspan = <span class="hljs-number">1</span>) ax1.plot(tsla[<span class="hljs-string">'close'</span>], linewidth = <span class="hljs-number">2.5</span>, color = <span class="hljs-string">'#2196f3'</span>) ax1.plot(tsla.index, buy_price, marker = <span class="hljs-string">'^'</span>, color = <span class="hljs-string">'#26a69a'</span>, markersize = <span class="hljs-number">12</span>) ax1.plot(tsla.index, sell_price, marker = <span class="hljs-string">'v'</span>, color = <span class="hljs-string">'#ef5350'</span>, markersize = <span class="hljs-number">12</span>) ax1.set_title(<span class="hljs-string">'NVDA CLOSE PRICES'</span>) ax2.plot(tsla[<span class="hljs-string">'aroon_up'</span>], color = <span class="hljs-string">'#26a69a'</span>, linewidth = <span class="hljs-number">2</span>, label = <span class="hljs-string">'AROON UP'</span>) ax2.plot(tsla[<span class="hljs-string">'aroon_down'</span>], color = <span class="hljs-string">'#ef5350'</span>, linewidth = <span class="hljs-number">2</span>, label = <span class="hljs-string">'AROON DOWN'</span>) ax2.legend() ax2.set_title(<span class="hljs-string">'NVDA AROON 25'</span>) plt.show()</pre></div><figure id="9c50"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*hdCA74p924_LyJiIshYdlQ.jpeg"><figcaption>The NVDA Aroon trading signals</figcaption></figure><ul><li>Performing <a href="https://readmedium.com/algorithmic-trading-with-the-aroon-indicator-in-python-3d2277d2f664">backtesting</a> of these signals by investing $10k</li></ul><div id="d779"><pre>position = [] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(aroon_signal)): <span class="hljs-keyword">if</span> aroon_signal[i] > <span class="hljs-number">1</span>: position.append(<span class="hljs-number">0</span>) <span class="hljs-keyword">else</span>: position.append(<span class="hljs-number">1</span>)

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(tsla[<span class="hljs-string">'close'</span>])): <span class="hljs-keyword">if</span> aroon_signal[i] == <span class="hljs-number">1</span>: position[i] = <span class="hljs-number">1</span> <span class="hljs-keyword">elif</span> aroon_signal[i] == -<span class="hljs-number">1</span>: position[i] = <span class="hljs-number">0</span> <span class="hljs-keyword">else</span>: position[i] = position[i-<span class="hljs-number">1</span>]

aroon_up = tsla[<span class="hljs-string">'aroon_up'</span>] aroon_down = tsla[<span class="hljs-string">'aroon_down'</span>] close_price = tsla[<span class="hljs-string">'close'</span>] aroon_signal = pd.DataFrame(aroon_signal).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'aroon_signal'</span>}).set_index(tsla.index) position = pd.DataFrame(position).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'aroon_position'</span>}).set_index(tsla.index)

frames = [close_price, aroon_up, aroon_down, aroon_signal, position] strategy = pd.concat(frames, join = <span class="hljs-string">'inner'</span>, axis = <span class="hljs-number">1</span>)

tsla_ret = pd.DataFrame(np.diff(tsla[<span class="hljs-string">'close'</span>])).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'returns'</span>}) aroon_strategy_ret = []

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(tsla_ret)): returns = tsla_ret[<span class="hljs-string">'returns'</span>][i]*strategy[<span class="hljs-string">'aroon_position'</span>][i] aroon_strategy_ret.append(returns)

aroon_strategy_ret_df = pd.DataFrame(aroon_strategy_ret).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'aroon_returns'</span>}) investment_value = myamount number_of_stocks = floor(investment_value/tsla[<span class="hljs-string">'close'</span>][-<span class="hljs-number">1</span>]) aroon_investment_ret = []

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(aroon_strategy_ret_df[<span class="hljs-string">'aroon_returns'</span>])): returns = number_of_stocks*aroon_strategy_ret_df[<span class="hljs-string">'aroon_returns'</span>][i] aroon_investment_ret.append(returns)

aroon_investment_ret_df = pd.DataFrame(aroon_investment_ret).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'investment_returns'</span>}) total_investment_ret = <span class="hljs-built_in">round</span>(<span class="hljs-built_in">sum</span>(aroon_investment_ret_df[<span class="hljs-string">'investment_returns'</span>]), <span class="hljs-number">2</span>) profit_percentage = floor((total_investment_ret/investment_value)*<span class="hljs-number">100</span>) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Profit gained from the Aroon strategy by investing $10k in NVDA: {}'</span>.<span class="hljs-built_in">format</span>(total_investment_ret), attrs = [<span class="hljs-string">'bold'</span>])) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Profit percentage of the Aroon strategy : {}%'</span>.<span class="hljs-built_in">format</span>(profit_percentage), attrs = [<span class="hljs-string">'bold'</span>]))

Profit gained <span class="hljs-keyword">from</span> the Aroon strategy by investing 10k <span class="hljs-keyword">in</span> NVDA: <span class="hljs-number">4856.17</span> Profit percentage of the Aroon strategy : <span class="hljs-number">48</span>%</pre></div><ul><li>Comparing this strategy against the (SPY ETF) <a href="https://readmedium.com/algorithmic-trading-with-the-aroon-indicator-in-python-3d2277d2f664">benchmark profit</a> by investing 10k</li></ul><div id="7d18"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_benchmark</span>(<span class="hljs-params">start_date, investment_value</span>): spy = get_historical_data(<span class="hljs-string">'SPY'</span>, start_date)[<span class="hljs-string">'close'</span>] benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'benchmark_returns'</span>})

investment_value = investment_value
number_of_stocks = floor(investment_value/spy[-<span class="hljs-number">1</span>])
benchmark_investment_ret = []

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(benchmark[<span class="hljs-string">'benchmark_returns'</span>])):
    returns = number_of_stocks*benchmark[<span class="hljs-string">'benchmark_returns'</span>][i]
    benchmark_investment_ret.append(returns)

benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {<span class="hljs-number">0</span>:<span class="hljs-string">'investment_returns'</span>})
<span class="hljs-keyword">return</span> benchmark_investment_ret_df

benchmark = get_benchmark(mydate, myamount)

investment_value = myamount total_benchmark_investment_ret = <span class="hljs-built_in">round</span>(<span class="hljs-built_in">sum</span>(benchmark[<span class="hljs-string">'investment_returns'</span>]), <span class="hljs-number">2</span>) benchmark_profit_percentage = floor((total_benchmark_investment_ret/investment_value)*<span class="hljs-number">100</span>) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Benchmark profit by investing $10k : {}'</span>.<span class="hljs-built_in">format</span>(total_benchmark_investment_ret), attrs = [<span class="hljs-string">'bold'</span>])) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Benchmark Profit percentage : {}%'</span>.<span class="hljs-built_in">format</span>(benchmark_profit_percentage), attrs = [<span class="hljs-string">'bold'</span>])) <span class="hljs-built_in">print</span>(cl(<span class="hljs-string">'Aroon Strategy profit is {}% higher than the Benchmark Profit'</span>.<span class="hljs-built_in">format</span>(profit_percentage - benchmark_profit_percentage), attrs = [<span class="hljs-string">'bold'</span>]))

Benchmark profit by investing $10k : <span class="hljs-number">1819.73</span> Benchmark Profit percentage : <span class="hljs-number">18</span>% Aroon Strategy profit <span class="hljs-keyword">is</span> <span class="hljs-number">30</span>% higher than the Benchmark Profit</pre></div><h2 id="e205">Summary</h2><ul><li>We have performed fundamental/technical analysis of NVIDIA to determine the real value of NVIDIA within 1 year.</li><li>By analyzing NVIDIA’s financials and various types of growth rates, we have attempted to validate the <a href="https://www.macroaxis.com/valuation/NVDA/NVIDIA">NVIDIA’s intrinsic value</a>.</li><li>We have used a set of Python functions to recognize potential entry and exit points for NVIDIA from various indicators.</li><li>This study will help investors to minimize the risk associated with market volatility and company-specific events by looking at <a href="https://investor.nvidia.com/financial-info/quarterly-results/default.aspx">earnings</a>, fundamental and technical indicators, industry peers as well as independent analyst <a href="https://www.macroaxis.com/technical-analysis/NVDA/NVIDIA">opinions</a>.</li></ul><h2 id="6943">References</h2><ul><li><a href="https://readmedium.com/support-your-algorithmic-trading-with-fundamental-data-e81781b10d9d">Support your algorithmic trading with fundamental data</a></li><li><a href="https://pypi.org/project/fmp-python/">fmp-python 0.1.4</a></li><li><a href="https://github.com/ddalgotrader">ddalgotrader</a>/<a href="https://github.com/ddalgotrader/support_trading_fundamental_data">support_trading_fundamental_data</a></li><li><a href="https://benjaq.medium.com/a-simple-guide-how-to-use-the-financial-modeling-prep-api-in-python-b3e03e742fb8">A simple guide how to use the Financial Modeling Prep API in Python</a></li><li><a href="https://readmedium.com/algorithmic-trading-with-the-keltner-channel-in-python-9c272051d43d">Algorithmic Trading with the Keltner Channel in Python</a></li><li><a href="https://github.com/Nikhil-Adithyan">Nikhil-Adithyan</a>/<a href="https://github.com/Nikhil-Adithyan/Algorithmic-Trading-with-Python">Algorithmic-Trading-with-Python</a></li><li><a href="https://readmedium.com/algorithmic-trading-with-the-aroon-indicator-in-python-3d2277d2f664">Algorithmic Trading with Aroon Indicator in Python</a></li><li><a href="https://www.macroaxis.com/investing/NVDA">Nvidia Stock Technical Analysis</a></li></ul></article></body>

An Algo-Trading Sneak Peek at Top AI-Powered Growth Stocks — 1. NVIDIA

Photo by Christian Wiediger on Unsplash
  • The objective of this study is to conduct Fundamental & Technical Analysis (FTA) of top growth stocks. This analysis falls within the realm of algo-trading (aka automated/algorithmic trading) in Python.
  • Let’ kick off with an extensive FTA of NVIDIA to benchmark a company’s performance against its peers.
  • NVIDIA is a leading provider of GPUs and industry-specific AI solutions in automotive & transportation, fintech, healthtech, retail, energy, media & entertainment, telecoms, smart cities, etc.
  • In fact, NVIDIA is the largest graphics processor manufacturer. Various brands use these GPUs on their video cards. NVIDIA graphics processors are available for all types of users, from ultra high-end cards for gamers to simple models for use in a basic home or office computer.
  • As of March 2024 NVIDIA has a market cap of $2.214 Trillion USD. This makes NVIDIA the world’s third most valuable company by market cap according to the data.
  • The latest NVDA financials shatter expectations, with a 22% quarterly and 265% yearly revenue spike to $22.1 billion amid rising AI adoption across industries.
  • The company’s EPS told a similar success story: GAAP EPS at $11.93, up 586% from the previous year, and non-GAAP EPS at $12.96, marking a 288% increase.

Fundamental Analysis using FMP API

  • Getting basic stock financials
from fmp_python.fmp import FMP
fmp = FMP(api_key='your_api_code')
fmp.get_quote('NVDA')
[{'symbol': 'NVDA',
  'name': 'NVIDIA Corporation',
  'price': 893.98,
  'changesPercentage': 1.0661,
  'change': 9.43,
  'dayLow': 850.12,
  'dayHigh': 905.37,
  'yearHigh': 974,
  'yearLow': 253.81,
  'marketCap': 2234950000000,
  'priceAvg50': 708.781,
  'priceAvg200': 514.4562,
  'exchange': 'NASDAQ',
  'volume': 66520583,
  'avgVolume': 51110326,
  'open': 866,
  'previousClose': 884.55,
  'eps': 11.94,
  'pe': 74.87,
  'earningsAnnouncement': '2024-05-22T10:59:00.000+0000',
  'sharesOutstanding': 2500000000,
  'timestamp': 1710878400}]
  • Getting general company’s information for investors
from fmp_api_python.fmp import FMPClient
from FmpConnector import FmpConnector
fmp_api=FmpConnector('your_secret_key')
nvda_info_df=fmp_api.get_company_info(symbol='NVDA', info_type='company_profile')
print(nvda_info_df)
symbol                                                          NVDA
price                                                         893.98
beta                                                           1.725
volAvg                                                      51110326
mktCap                                                 2234950000000
lastDiv                                                         0.16
range                                                   253.81-974.0
changes                                                         9.43
companyName                                       NVIDIA Corporation
currency                                                         USD
cik                                                       0001045810
isin                                                    US67066G1040
cusip                                                      67066G104
exchange                                        NASDAQ Global Select
exchangeShortName                                             NASDAQ
industry                                              Semiconductors
website                                       https://www.nvidia.com
description        NVIDIA Corporation provides graphics, and comp...
ceo                                              Mr. Jen-Hsun  Huang
sector                                                    Technology
country                                                           US
fullTimeEmployees                                              29600
phone                                                   408 486 2000
address                                    2788 San Tomas Expressway
city                                                     Santa Clara
state                                                             CA
zip                                                            95051
dcfDiff                                                    339.96848
dcf                                                       554.011519
image              https://financialmodelingprep.com/image-stock/...
ipoDate                                                   1999-01-22
defaultImage                                                   False
isEtf                                                          False
isActivelyTrading                                               True
isAdr                                                          False
isFund                                                         False
  • Getting the company’s rating score and recommendations
nvda_info_df=fmp_api.get_company_info(symbol='NVDA', info_type='company_rating')
print(nvda_info_df)
symbol                                NVDA
date                            2024-03-19
rating                                  S-
ratingScore                              5
ratingRecommendation            Strong Buy
ratingDetailsDCFScore                    3
ratingDetailsDCFRecommendation     Neutral
ratingDetailsROEScore                    5
ratingDetailsROERecommendation  Strong Buy
ratingDetailsROAScore                    5
ratingDetailsROARecommendation  Strong Buy
ratingDetailsDEScore                     3
ratingDetailsDERecommendation      Neutral
ratingDetailsPEScore                     5
ratingDetailsPERecommendation   Strong Buy
ratingDetailsPBScore                     5
ratingDetailsPBRecommendation   Strong Buy
  • Getting NVDA annual balance statements (5 years)
nvda_info_df=fmp_api.get_financial_data(symbol='NVDA', report_type='balance_statement', period='annual', limit=10)
print(nvda_info_df)
 date symbol reportedCurrency         cik fillingDate  \
0  2024-01-28   NVDA              USD  0001045810  2024-02-21   
1  2023-01-29   NVDA              USD  0001045810  2023-02-24   
2  2022-01-30   NVDA              USD  0001045810  2022-03-18   
3  2021-01-31   NVDA              USD  0001045810  2021-02-26   
4  2020-01-26   NVDA              USD  0001045810  2020-02-20   

          acceptedDate calendarYear period  cashAndCashEquivalents  \
0  2024-02-21 16:36:57         2024     FY              7280000000   
1  2023-02-24 17:23:43         2023     FY              3389000000   
2  2022-03-17 20:33:34         2022     FY              1990000000   
3  2021-02-26 17:03:14         2021     FY               847000000   
4  2020-02-20 16:38:18         2020     FY             10896000000   

   shortTermInvestments  ...  totalStockholdersEquity  totalEquity  \
0           18704000000  ...              42978000000  42978000000   
1            9907000000  ...              22101000000  22101000000   
2           19218000000  ...              26612000000  26612000000   
3           10714000000  ...              16893000000  16893000000   
4               1000000  ...              12204000000  12204000000   

   totalLiabilitiesAndStockholdersEquity  minorityInterest  \
0                            65728000000                 0   
1                            41182000000                 0   
2                            44187000000                 0   
3                            28791000000                 0   
4                            17315000000                 0   

   totalLiabilitiesAndTotalEquity  totalInvestments    totalDebt     netDebt  \
0                     65728000000       20250000000  11056000000  3776000000   
1                     41182000000       10206000000  11855000000  8466000000   
2                     44187000000       19484000000  11687000000  9697000000   
3                     28791000000       10858000000   7597000000  6750000000   
4                     17315000000           1000000   2552000000 -8344000000   

                                                link  \
0  https://www.sec.gov/Archives/edgar/data/104581...   
1  https://www.sec.gov/Archives/edgar/data/104581...   
2  https://www.sec.gov/Archives/edgar/data/104581...   
3  https://www.sec.gov/Archives/edgar/data/104581...   
4  https://www.sec.gov/Archives/edgar/data/104581...   

                                           finalLink  
0  https://www.sec.gov/Archives/edgar/data/104581...  
1  https://www.sec.gov/Archives/edgar/data/104581...  
2  https://www.sec.gov/Archives/edgar/data/104581...  
3  https://www.sec.gov/Archives/edgar/data/104581...  
4  https://www.sec.gov/Archives/edgar/data/104581...  

[5 rows x 54 columns]
  • Plotting the NVDA stock candlesticks vs volume using Plotly
nvda_price_df=fmp_api.get_daily_prices(symbol='NVDA')
fmp_api.draw_chart(nvda_price_df)
Plotly: NVDA daily stock price candlesticks vs volume 2019–2024.
  • Writing the stock price DataFrame to the csv file

Technical Analysis

  • Examining the above NVDA stock price in terms of the basic technical trading indicators such as SMA20, BB20, and KC20. Using the algo-trading algorithm to perform backtesting and benchmarking against SPY ETF.
  • Extracting the 1Y NVDA stock data
import pandas as pd 
import matplotlib.pyplot as plt 
import requests
import math
from termcolor import colored as cl 
import numpy as np

plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20, 10)

# EXTRACTING STOCK DATA

def get_historical_data(symbol, start_date):
    api_key = 'your_api_key'
    api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df.index = pd.to_datetime(df.index)
    return df

aapl = get_historical_data('NVDA', '2023-01-03')
aapl.tail()
  • Plotting the NVDA stock price data
plt.plot(aapl.index, aapl['close'])
plt.xlabel('Date')
plt.ylabel('Closing Prices')
plt.title('Stock Prices')
plt.show()
1Y NVDA stock price data
  • Plotting SMA20 vs stock price
def sma(data, window):
    sma = data.rolling(window = window).mean()
    return sma

aapl['sma_20'] = sma(aapl['close'], 20)
aapl.tail(3)

aapl['close'].plot(label = 'CLOSE', alpha = 0.6)
aapl['sma_20'].plot(label = 'SMA 20', linewidth = 2)
plt.xlabel('Date')
plt.ylabel('Closing Prices')
plt.legend(loc = 'upper left')
plt.show()
NVDA stock price vs SMA20
  • As we can see, SMA helps level price action by filtering out the noise from random price fluctuations.
  • SMA values below the current price indicate support levels, as shown above.
  • Plotting BB20 vs stock price
def bb(data, sma, window):
    std = data.rolling(window = window).std()
    upper_bb = sma + std * 2
    lower_bb = sma - std * 2
    return upper_bb, lower_bb

aapl['upper_bb'], aapl['lower_bb'] = bb(aapl['close'], aapl['sma_20'], 20)
aapl.tail()

aapl['close'].plot(label = 'CLOSE PRICES', color = 'skyblue')
aapl['upper_bb'].plot(label = 'UPPER BB 20', linestyle = '--', linewidth = 1, color = 'black')
aapl['sma_20'].plot(label = 'MIDDLE BB 20', linestyle = '--', linewidth = 1.2, color = 'grey')
aapl['lower_bb'].plot(label = 'LOWER BB 20', linestyle = '--', linewidth = 1, color = 'black')
plt.legend(loc = 'upper left')
plt.title('BOLLINGER BANDS')
plt.show()
NVDA Bollinger Bands vs Stock Price
  • BB help determine whether prices are high or low on a relative basis. They are used in pairs, both upper and lower bands and in conjunction with SMA.
  • Bollinger Bands can also indicate the end of a strong trend. Strong trends, especially those developing after a breakout of a trading range, will result in an expansion in volatility that will cause the bands to initially move apart.
  • Calculating and plotting the NVDA BB strategy trading signals
def implement_bb_strategy(data, lower_bb, upper_bb):
    buy_price = []
    sell_price = []
    bb_signal = []
    signal = 0
    
    for i in range(len(data)):
        if data[i-1] > lower_bb[i-1] and data[i] < lower_bb[i]:
            if signal != 1:
                buy_price.append(data[i])
                sell_price.append(np.nan)
                signal = 1
                bb_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                bb_signal.append(0)
        elif data[i-1] < upper_bb[i-1] and data[i] > upper_bb[i]:
            if signal != -1:
                buy_price.append(np.nan)
                sell_price.append(data[i])
                signal = -1
                bb_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                bb_signal.append(0)
        else:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            bb_signal.append(0)
            
    return buy_price, sell_price, bb_signal

buy_price, sell_price, bb_signal = implement_bb_strategy(aapl['close'], aapl['lower_bb'], aapl['upper_bb'])

aapl['close'].plot(label = 'CLOSE PRICES', alpha = 0.3)
aapl['upper_bb'].plot(label = 'UPPER BB', linestyle = '--', linewidth = 1, color = 'black')
aapl['sma_20'].plot(label = 'MIDDLE BB', linestyle = '--', linewidth = 1.2, color = 'grey')
aapl['lower_bb'].plot(label = 'LOWER BB', linestyle = '--', linewidth = 1, color = 'black')
plt.scatter(aapl.index, buy_price, marker = '^', color = 'green', label = 'BUY', s = 200)
plt.scatter(aapl.index, sell_price, marker = 'v', color = 'red', label = 'SELL', s = 200)
plt.title('BB STRATEGY TRADING SIGNALS')
plt.legend(loc = 'upper left')
plt.show()
NVDA BB strategy trading signals
  • Calculating and plotting the NVDA BB strategy daily returns
position = []
for i in range(len(bb_signal)):
    if bb_signal[i] > 1:
        position.append(0)
    else:
        position.append(1)
        
for i in range(len(aapl['close'])):
    if bb_signal[i] == 1:
        position[i] = 1
    elif bb_signal[i] == -1:
        position[i] = 0
    else:
        position[i] = position[i-1]
        
upper_bb = aapl['upper_bb']
lower_bb = aapl['lower_bb']
close_price = aapl['close']
bb_signal = pd.DataFrame(bb_signal).rename(columns = {0:'bb_signal'}).set_index(aapl.index)
position = pd.DataFrame(position).rename(columns = {0:'bb_position'}).set_index(aapl.index)

frames = [close_price, upper_bb, lower_bb, bb_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)

#strategy.tail(10)

rets = aapl.close.pct_change().dropna()
strat_rets = strategy.bb_position[1:]*rets

plt.title('Daily Returns')
rets.plot(color = 'blue', alpha = 0.3, linewidth = 7)
strat_rets.plot(color = 'r', linewidth = 1)
plt.show()
NVDA BB strategy daily returns
  • Calculating and plotting the Keltner Channel (KC20)
def get_kc(high, low, close, kc_lookback, multiplier, atr_lookback):
    tr1 = pd.DataFrame(high - low)
    tr2 = pd.DataFrame(abs(high - close.shift()))
    tr3 = pd.DataFrame(abs(low - close.shift()))
    frames = [tr1, tr2, tr3]
    tr = pd.concat(frames, axis = 1, join = 'inner').max(axis = 1)
    atr = tr.ewm(alpha = 1/atr_lookback).mean()
    
    kc_middle = close.ewm(kc_lookback).mean()
    kc_upper = close.ewm(kc_lookback).mean() + multiplier * atr
    kc_lower = close.ewm(kc_lookback).mean() - multiplier * atr
    
    return kc_middle, kc_upper, kc_lower
    
aapl = aapl.iloc[:,:4]
aapl['kc_middle'], aapl['kc_upper'], aapl['kc_lower'] = get_kc(aapl['high'], aapl['low'], aapl['close'], 20, 2, 10)
#aapl.tail()

# KELTNER CHANNEL PLOT

plt.plot(aapl['close'], linewidth = 2, label = 'NVDA')
plt.plot(aapl['kc_upper'], linewidth = 2, color = 'orange', linestyle = '--', label = 'KC UPPER 20')
plt.plot(aapl['kc_middle'], linewidth = 1.5, color = 'grey', label = 'KC MIDDLE 20')
plt.plot(aapl['kc_lower'], linewidth = 2, color = 'orange', linestyle = '--', label = 'KC LOWER 20')
plt.legend(loc = 'lower right', fontsize = 15)
plt.title('KELTNER CHANNEL 20')
plt.show()
NVDA Keltner Channel 20 vs stock price
  • Performing backtesting of the BB trading strategy by investing $10k
import math

aapl_ret = pd.DataFrame(np.diff(aapl['close'])).rename(columns = {0:'returns'})
tsi_strategy_ret = []

for i in range(len(aapl_ret)):
    returns = aapl_ret['returns'][i]*strategy['bb_position'][i]
    tsi_strategy_ret.append(returns)
    
tsi_strategy_ret_df = pd.DataFrame(tsi_strategy_ret).rename(columns = {0:'bb_returns'})
investment_value = 10000
number_of_stocks = math.floor(investment_value/aapl['close'][0])
tsi_investment_ret = []

for i in range(len(tsi_strategy_ret_df['bb_returns'])):
    returns = number_of_stocks*tsi_strategy_ret_df['bb_returns'][i]
    tsi_investment_ret.append(returns)

tsi_investment_ret_df = pd.DataFrame(tsi_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(tsi_investment_ret_df['investment_returns']), 2)
profit_percentage = math.floor((total_investment_ret/investment_value)*100)
print(cl('Profit gained from the BB strategy by investing $10k : {}'.format(total_investment_ret), attrs = ['bold']))
print(cl('Profit percentage of the BB strategy : {}%'.format(profit_percentage), attrs = ['bold']))

Profit gained from the BB strategy by investing $10k : 19797.48
Profit percentage of the BB strategy : 197%
def get_benchmark(start_date, investment_value):
    spy = get_historical_data('SPY', start_date)['close']
    benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})
    
    investment_value = investment_value
    number_of_stocks = math.floor(investment_value/spy[-1])
    benchmark_investment_ret = []
    
    for i in range(len(benchmark['benchmark_returns'])):
        returns = number_of_stocks*benchmark['benchmark_returns'][i]
        benchmark_investment_ret.append(returns)

    benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})
    return benchmark_investment_ret_df

benchmark = get_benchmark('2023-01-03', 10000)
investment_value = 10000
total_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)
benchmark_profit_percentage = math.floor((total_benchmark_investment_ret/investment_value)*100)
print(cl('Benchmark profit by investing $10k : {}'.format(total_benchmark_investment_ret), attrs = ['bold']))
print(cl('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage), attrs = ['bold']))
print(cl('BB Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage), attrs = ['bold']))

Benchmark profit by investing $10k : 2562.91
Benchmark Profit percentage : 25%
BB Strategy profit is 172% higher than the Benchmark Profit
  • Backtesting can provide valuable insights into NVDA historical performance, but it does not guarantee future success. It’s important to combine backtesting with other forms of risk assessment to make well-informed trading decisions.
  • Let’s examine the Aroon trading strategy that is used to identify trend changes in the price of an asset, as well as the strength of that trend.
  • If the Aroon-Up crosses above the Aroon-Down, then a new uptrend may start soon. Conversely, if Aroon-Down crosses above the Aroon-Up, then a new downtrend may start soon. When Aroon-Up reaches 100, a new uptrend may have begun.
import pandas as pd
import numpy as np
import requests
import matplotlib.pyplot as plt
from math import floor
from termcolor import colored as cl

plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20, 10)
myticker='NVDA'
mydate='2023-1-1'
myamount=10000
mywin=25
def get_historical_data(symbol, start_date):
    api_key = 'your_api_key'
    api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df.index = pd.to_datetime(df.index)
    return df

tsla = get_historical_data(myticker, mydate)

def get_aroon(symbol, lookback, start_date):
    api_key = 'your_api_key'
    api_url = f'https://api.twelvedata.com/aroon?symbol={symbol}&interval=1day&time_period={lookback}&outputsize=5000&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df.index = pd.to_datetime(df.index)
    aroon_up = df['aroon_up']
    aroon_down = df['aroon_down']
    return aroon_up, aroon_down

tsla['aroon_up'], tsla['aroon_down'] = get_aroon(myticker, 25, mydate)

  • Plotting NVDA Close Price vs Aroon 25
ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 4, colspan = 1)
ax1.plot(tsla['close'], linewidth = 2.5, color = '#2196f3')
ax1.set_title('NVDA CLOSE PRICES')
ax2.plot(tsla['aroon_up'], color = '#26a69a', linewidth = 2, label = 'AROON UP')
ax2.plot(tsla['aroon_down'], color = '#ef5350', linewidth = 2, label = 'AROON DOWN')
ax2.legend()
ax2.set_title('NVDA AROON 25')
plt.show()
NVDA Close Price vs Aroon 25
def implement_aroon_strategy(prices, up, down):
    buy_price = []
    sell_price = []
    aroon_signal = []
    signal = 0
    
    for i in range(len(prices)):
        if up[i] >= 70 and down[i] <= 30:
            if signal != 1:
                buy_price.append(prices[i])
                sell_price.append(np.nan)
                signal = 1
                aroon_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                aroon_signal.append(0)
        elif up[i] <= 30 and down[i] >= 70:
            if signal != -1:
                buy_price.append(np.nan)
                sell_price.append(prices[i])
                signal = -1
                aroon_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                aroon_signal.append(0)
        else:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            aroon_signal.append(0)
            
    return buy_price, sell_price, aroon_signal

buy_price, sell_price, aroon_signal = implement_aroon_strategy(tsla['close'], tsla['aroon_up'], tsla['aroon_down'])
  • Plotting the NVDA Aroon trading signals
ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 4, colspan = 1)
ax1.plot(tsla['close'], linewidth = 2.5, color = '#2196f3')
ax1.plot(tsla.index, buy_price, marker = '^', color = '#26a69a', markersize = 12)
ax1.plot(tsla.index, sell_price, marker = 'v', color = '#ef5350', markersize = 12)
ax1.set_title('NVDA CLOSE PRICES')
ax2.plot(tsla['aroon_up'], color = '#26a69a', linewidth = 2, label = 'AROON UP')
ax2.plot(tsla['aroon_down'], color = '#ef5350', linewidth = 2, label = 'AROON DOWN')
ax2.legend()
ax2.set_title('NVDA AROON 25')
plt.show()
The NVDA Aroon trading signals
  • Performing backtesting of these signals by investing $10k
position = []
for i in range(len(aroon_signal)):
    if aroon_signal[i] > 1:
        position.append(0)
    else:
        position.append(1)
        
for i in range(len(tsla['close'])):
    if aroon_signal[i] == 1:
        position[i] = 1
    elif aroon_signal[i] == -1:
        position[i] = 0
    else:
        position[i] = position[i-1]
        
aroon_up = tsla['aroon_up']
aroon_down = tsla['aroon_down']
close_price = tsla['close']
aroon_signal = pd.DataFrame(aroon_signal).rename(columns = {0:'aroon_signal'}).set_index(tsla.index)
position = pd.DataFrame(position).rename(columns = {0:'aroon_position'}).set_index(tsla.index)

frames = [close_price, aroon_up, aroon_down, aroon_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)

tsla_ret = pd.DataFrame(np.diff(tsla['close'])).rename(columns = {0:'returns'})
aroon_strategy_ret = []

for i in range(len(tsla_ret)):
    returns = tsla_ret['returns'][i]*strategy['aroon_position'][i]
    aroon_strategy_ret.append(returns)
    
aroon_strategy_ret_df = pd.DataFrame(aroon_strategy_ret).rename(columns = {0:'aroon_returns'})
investment_value = myamount
number_of_stocks = floor(investment_value/tsla['close'][-1])
aroon_investment_ret = []

for i in range(len(aroon_strategy_ret_df['aroon_returns'])):
    returns = number_of_stocks*aroon_strategy_ret_df['aroon_returns'][i]
    aroon_investment_ret.append(returns)

aroon_investment_ret_df = pd.DataFrame(aroon_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(aroon_investment_ret_df['investment_returns']), 2)
profit_percentage = floor((total_investment_ret/investment_value)*100)
print(cl('Profit gained from the Aroon strategy by investing $10k in NVDA: {}'.format(total_investment_ret), attrs = ['bold']))
print(cl('Profit percentage of the Aroon strategy : {}%'.format(profit_percentage), attrs = ['bold']))

Profit gained from the Aroon strategy by investing $10k in NVDA: 4856.17
Profit percentage of the Aroon strategy : 48%
  • Comparing this strategy against the (SPY ETF) benchmark profit by investing $10k
def get_benchmark(start_date, investment_value):
    spy = get_historical_data('SPY', start_date)['close']
    benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})
    
    investment_value = investment_value
    number_of_stocks = floor(investment_value/spy[-1])
    benchmark_investment_ret = []
    
    for i in range(len(benchmark['benchmark_returns'])):
        returns = number_of_stocks*benchmark['benchmark_returns'][i]
        benchmark_investment_ret.append(returns)

    benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})
    return benchmark_investment_ret_df

benchmark = get_benchmark(mydate, myamount)

investment_value = myamount
total_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)
benchmark_profit_percentage = floor((total_benchmark_investment_ret/investment_value)*100)
print(cl('Benchmark profit by investing $10k : {}'.format(total_benchmark_investment_ret), attrs = ['bold']))
print(cl('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage), attrs = ['bold']))
print(cl('Aroon Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage), attrs = ['bold']))

Benchmark profit by investing $10k : 1819.73
Benchmark Profit percentage : 18%
Aroon Strategy profit is 30% higher than the Benchmark Profit

Summary

  • We have performed fundamental/technical analysis of NVIDIA to determine the real value of NVIDIA within 1 year.
  • By analyzing NVIDIA’s financials and various types of growth rates, we have attempted to validate the NVIDIA’s intrinsic value.
  • We have used a set of Python functions to recognize potential entry and exit points for NVIDIA from various indicators.
  • This study will help investors to minimize the risk associated with market volatility and company-specific events by looking at earnings, fundamental and technical indicators, industry peers as well as independent analyst opinions.

References

AI
Python
Stock Market
Nvidia
Algorithmic Trading
Recommended from ReadMedium