Are you a Beginner in Trading? Build your First Trading strategy with Python

Lucero Emperatriz
Geek Culture
Published in
6 min readMar 30, 2022

If you are new to the world of Trading, surely you have ever wondered when it is convenient for you to buy or, what indicators should you pay attention to when entering the market?
With Python and Plotly you can build your first interactive trading strategy so that analyzing your actions is not a nightmare!

Import Python libraries

To start we will import the pandas library and the Plotly libraries for visualization.

#1 Import pandas
import pandas as pd
import numpy as np
from pandas_datareader import data as pdr
import datetime as dt
from datetime import date, timedelta
#2 For Plotly
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import plotly.express as px
import plotly.io as pio
pio.templates
import yfinance as yf

In addition, we will need to connect to the Yahoo Finance API with yfinance, which provides a wide range of data on crypto and other financial instruments in real time.

Load financial data

To obtain data on the stock of our interest, we will ask to enter the trading ticker symbol and we will save it in the variable stock (you can consult some symbols here). Then, we will need to specify the date range to analyze in datatime format (“year-month-day”) to finally collect the data in a dataframe.

yf.pdr_override()#1 Asking for stock symbol
stock = input ("Enter a stock ticker symbol: ")
print(stock)
#2 Set date
start = dt.datetime(2021,1,1)
now=dt.datetime.now()
df = pdr.get_data_yahoo(stock, start, now)
df.round(2)

The output obtained contains the stock price variables and the volume traded per day. For this example we will use the data for the symbol “TQQQ”, starting from 1–1–2021 to the current date.

Output of price variables for “TQQQ” stock

Define Strategy: Trading Moving Averages

To identify historical patterns we will use the Simple Moving Average (SME) which will calculate the average price of a stock over “x” consecutive days. According to the Capital investment platform, it is common to use 10 days for short-term trends (“SMA 10”) and 80 days for the long term (“SMA 80”), for which we will use these periods. This strategy is known as Crossover Strategy, which has as general principles:

  1. If the price is above the SMA line: The trend is bullish, that is, it is convenient to buy the value.
  2. If the price is below the SMA line: The trend is bearish, it is convenient to sell the value.

So, we use the function rolling() to calculate the SMA of the adjusted closing price “Adj. Close”, where the window size is the range of days to average. Let’s see the code!

df = pd.DataFrame()sma10 ='sma10'
sma80 ='sma80'
df[sma10]= df.iloc[:,4].rolling(window=10).mean()
df[sma80]= df.iloc[:,4].rolling(window=80).mean()
df.round(2)

Because the SMA calculates the average of previous values counted from the current period, the first rows of our dataset contain null values “Nan” since there are no values to average with.

Candlestick chart with historical prices
We will use the Candlestick Chart to display the information, it is made up of 2 elements: the wicks and the real body.

  • The wicks: They are the extreme points showing the variables “High” and “Low”, the highest and lowest price negotiated for a period
  • The real body: is the wide part of a candle, where the upper and lower corners of the body show the opening price “Open” and the closing price “Close” of the stock. If the closing price of the day is lower than the opening price, the candle will be shown in red, since the result is unfavorable.
Candlestick structure. Adapted from: Warrior Trading

We add the data to the figure with the attribute go.candlestick and the SMA lines with go.Scatter. To customize the design you can add more properties that Ploty offers in its documentation here or you can use one Plotly template.

#1 Adding data to Candlestick
fig = go.Figure(data=[go.Candlestick(x=df.index, name = 'Price',
open=df['Open'], high=df['High'],
low=df['Low'], close=df['Close']),
go.Scatter(x=data1.index, y=data1.sma10, name='SMA 10'),
go.Scatter(x=data1.index, y=data1.sma80,name='SMA 80')])
#2 Add template and custom layout
for template in ["plotly_dark"]:

fig.layout.font.family = 'Balto'
fig.update_layout(template=template,
title="Historical Price and SME of '"+str(stock)+"' index")


#Legend format
fig.update_layout(legend=dict(bgcolor="#2b2929",borderwidth=0.5))

#Axis format
fig.update_xaxes(tickangle = -90, tickformat = '%b %e',)
fig.update_yaxes(title_standoff = 8, tickfont=dict(size=8))

#Candles style
fig.update_traces(
increasing_line_color="#2df726",
selector=dict(type='candlestick'))
fig.update_traces(
decreasing_line_color="#ff4038",
selector=dict(type='candlestick'))
fig.show()
Candlestick chart for “TQQQ” stock

Create Buy and Sell indicators

To display the buy or sell indicators, we create a function with the empty columns mustBuy and mustSell where the closing price “Adj close” will be stored.
The variable flag will detect the crossing between both trend lines, if it indicates that the “SMA 80” crosses the “SMA 10”, then it is convenient to sell and the value of “Adj close” will be added to the mustBuy column and a null value “np.nan” otherwise. The same thing happens if the pattern indicates that the stock should be sold, and if it is not convenient to buy or sell, the value to be added will be null.

Next, we save the new variables in a new dataframe data1.

#1 Create functiondef buy_sell(data1):
mustBuy = []
mustSell = []
flag = -1 #when crosed both
for i in range(len(data1)):
close=df["Adj Close"][i]
#If short-term line crosses long-term line
if data1[sma10][i] > data1[sma80][i]:
if flag != 1:
pc=close
mustBuy.append(pc)
mustSell.append(np.nan)
flag = 1
else:
pc=close
mustBuy.append(np.nan)
mustSell.append(np.nan)
#If long-term line crosses short-term line
elif data1[sma10][i] < data1[sma80][i]:
if flag != 0:
ps=close
mustBuy.append(np.nan)
mustSell.append(ps)
flag=0
else:
ps=close
mustBuy.append(np.nan)
mustSell.append(np.nan)
else:
mustBuy.append(np.nan)
mustSell.append(np.nan)

return (mustBuy, mustSell, close)
#2 Store buy and sell decition
buy_sell = buy_sell(data1)
data1['Buy_Price'] = buy_sell[0]
data1['Sell_Price'] = buy_sell[1]

For the visualization we will use a line chart this time, in the data we will include the variables mustBuy and mustSell to show the buy or sell flags as markers of the Close Price line. Let’s see the code!

fig2 = go.Figure()# 1 Add trace of Adj Close
fig2.add_trace(go.Scatter(x=data1.index,
y=data1["Adj Close"]))
# 2 Add SMA traces
fig2.add_trace(go.Scatter(x=data1.index, y=data1[sma10],
name='SMA 10'))
fig2.add_trace(go.Scatter(x=data1.index, y=data1[sma80],
name = 'SMA 80'))
# 3 Create markers for BUY OR SELL
fig2.add_trace(go.Scatter(x=data1.index, y=data1["Buy_Price"],
name='Buy', mode = 'markers',
marker =dict(symbol='triangle-up'),
hovertemplate=('BUY on %{x}'))
fig2.add_trace(go.Scatter(x=data1.index, y=data1["Sell_Price"],
name='Sell', mode = 'markers',
marker =dict(symbol='triangle-down'),
hovertemplate=('SELL on %{x}'))
# 4 Custom layout and template
for template in ["plotly_dark"]:

fig2.update_layout(template=template,
title="Trading Strategy for '"+str(stock)+"' index")
fig2.show()

If you want to change the triangle marker you can do so by editing the marker=dict(symbol) attribute with the symbols available here, you can also change the flag’s popup text with hovertemplate.
Take a look at the end result!

Trading strategy with BUY and SELL flags

Interpretation

As we can see, the chart answers the question: When should I enter the market? and, when should I buy or sell?

By enlarging the chart we will be able to notice the crossover of the short-term (SMA 10) and long-term (SMA80) patterns, and how the flag shows BUY when the Close Price is above the crossover and SELL when it is below this.

Enlarged Strategy Chart: the flags are the red and green triangles

So, we have built our first trading strategy. I hope I’ve helped!

--

--

Lucero Emperatriz
Geek Culture

Data lover and geek 🕵| Researcher and editor | Industrial Engineer focused on the continuous improvement of Business, Efficiency and Productivity 🚀