3 minute read

My Python skill is pretty shallow. I hope this mini project can help me deepen my understanding.

Set up a new project

Create a new project directory and activate venv to install packages locally

mkdir buy-sell-signals
cd code buy-sell-signals

python3 -m venv .venv
source .venv/bin/activate

Use SMA 5 and SMA 10

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt


def get_nasdaq_data():
    nasdaq = yf.Ticker("^IXIC")
    nasdaq_data = nasdaq.history(period="3mo", interval="1d")
    nasdaq_data.to_csv("nasdaq.csv")
    return nasdaq_data


def calculate_sma(data, period):
    sma = data["Close"].rolling(window=period).mean()
    return sma


def generate_signals(data):
    data["5_SMA"] = calculate_sma(data, 5)
    data["10_SMA"] = calculate_sma(data, 10)

    data["Signal"] = None
    for i in range(len(data)):
        if data["5_SMA"][i] > data["10_SMA"][i]:
            data["Signal"][i] = 'Buy'
        else:
            data["Signal"][i] = 'Sell'

    return data


def plot_graph(data):
    buy_signals = data[data['Signal'] == 'Buy']
    sell_signals = data[data['Signal'] == 'Sell']

    plt.figure(figsize=(15, 10))
    plt.plot(data.index, data["Close"], label="Nasdaq", alpha=0.5)
    plt.plot(data.index, data["5_SMA"],
             label="5 Day SMA", linestyle="--", alpha=0.7)
    plt.plot(data.index, data["10_SMA"],
             label="10 Day SMA", linestyle="--", alpha=0.7)
    plt.title("Nasdaq Buy/Sell Signals using 5 and 10 Day SMA")
    plt.scatter(buy_signals.index, data.loc[buy_signals.index]
                ['Close'], marker='^', color='g', label='Buy Signal')
    plt.scatter(sell_signals.index, data.loc[sell_signals.index]
                ['Close'], marker='v', color='r', label='Sell Signal')
    plt.xlabel("Date")
    plt.ylabel("Close Price ($)")
    plt.legend()
    plt.show()


def get_latest_signal(data):
    return data["Signal"][-1]


if __name__ == "__main__":
    data = get_nasdaq_data()
    data_with_signals = generate_signals(data)

    latest_signal = get_latest_signal(data_with_signals)
    print(f"Latest Signal: {latest_signal}")
    plot_graph(data_with_signals)

The above code is my attempt to create buy-sell signals using SMA (Simple Moving Average) 5 and SMA 10. My next one is using EMA

EMA Signals

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import yfinance as yf


def get_nasdaq_data():
    nasdaq = yf.Ticker("^IXIC")
    nasdaq_data = nasdaq.history(period="3mo", interval="1d")
    return nasdaq_data


def get_signals(df):
    short_window = 5
    long_window = 15
    alpha = 0.1
    signals = pd.DataFrame(index=df.index)

    signals['ema_signal'] = 0.0
    signals['ema'] = df['Close'].ewm(alpha=alpha, adjust=False).mean()
    signals['ema_positions'] = 0.0
    signals['short_mavg'] = df['Close'].rolling(window=short_window,
                                                min_periods=1,
                                                center=False).mean()
    signals['long_mavg'] = df['Close'].rolling(window=long_window,
                                               min_periods=1,
                                               center=False).mean()
    signals['sma_positions'] = 0.0

    signals['ema_signal'] = np.where(signals['ema'] < df['Close'], 1.0, 0.0)
    signals['ema_positions'] = signals['ema_signal'].diff()
    return signals


def get_figure(df, signals):
    fig = plt.figure(figsize=(12, 10))
    ax1 = fig.add_subplot(111, ylabel='Price in $')

    df.loc['2018-01-01':, 'Close'].plot(ax=ax1,
                                        color='r', lw=2., label='Close Price')
    signals.loc[:, 'ema'].plot(ax=ax1, lw=2.)

    # Plot the buy signals
    ax1.plot(signals.loc[signals.ema_positions == 1.0].index,
             signals.ema[signals.ema_positions == 1.0],
             '^', markersize=10, color='g')

    # Plot the sell signals
    ax1.plot(signals.loc[signals.ema_positions == -1.0].index,
             signals.ema[signals.ema_positions == -1.0],
             'v', markersize=10, color='r')

    plt.legend()
    return fig


df = get_nasdaq_data()
signals = get_signals(df)
chart = get_figure(df, signals)

chart.savefig('signals.png')
print(signals.tail())

# plt.show()

alpha factor

By the way, alpha is a smoothing factor that determines the rate at which the EMA reacts to new price data. It typically ranges between 0 and 1. A smaller alpha value results in a slower reaction to new price data, meaning the EMA will be less sensitive to recent price changes and more influenced by historical prices. Conversely, a larger alpha value will make the EMA react more quickly to new price data, giving more weight to recent price changes.

Import another file

To import another Python file, you can use the import statement followed by the filename without the .py extension. For example, if you have a Python file named other_file.py, you can import it in your current script like this:

import other_file

Once you’ve imported the file, you can access its functions, classes, and variables using the dot notation. For example, if other_file.py contains a function named my_function, you can call it like this:

other_file.my_function()

Keep in mind that the file you want to import should be in the same directory as your current script or in a directory listed in your Python’s sys.path. If the file is in a different directory, you can add that directory to sys.path like this:

import sys
sys.path.append('/path/to/directory')
import other_file

Replace /path/to/directory with the path to the directory containing other_file.py. After adding the directory to sys.path, you can import and use the file as usual

Building and testing Python with Github actions

https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

Send email using sendgrid

Install sendgrid library.

pip install sendgrid

Tags:

Updated:

Comments