Skip to main content

Swing Trading Strategy Augmented by Python and the Yahoo API

Swing Trading is a strategy that aims to capitalize on short- to medium-term price movements in financial markets. Unlike day trading, which requires constant attention to minute-by-minute price changes, swing trading allows for holding positions for several days or weeks. Traders seek to Capitalize on numerous trades, of favorable Stocks, with repetitive Trading. One of the most crucial aspects of Swing Trading is determining an optimal target price for entries and exits. Without a clear strategy for setting these targets, traders risk entering trades at suboptimal points, reducing their overall profitability. This is synonymous with Mean Reversion ideology to exploit and profit from price movements. Standard Deviation as a Mean Reversion Tool for Swing Trading is a logical and optimal calculation method.

Many traders rely on technical indicators such as moving averages, relative strength index (RSI), and Bollinger Bands. However, one of the most underutilized yet powerful tools is Standard Deviation (StDev). Standard Deviation, commonly used in statistics, can provide significant insight into price volatility and mean reversion—both key components of a successful Swing Trading strategy.

Let's understand Mean Reversion, as used in this writing. Mean reversion is the tendency of an asset's price to move back toward its average over time. Standard Deviation measures the dispersion of price movements around this mean, making it a valuable metric for identifying when prices have deviated significantly from their norm. By using Standard Deviation in conjunction with Python and the Yahoo Finance API, traders can create a robust system for setting trade entry and exit points based on statistical probabilities rather than guesswork.

My strategy assumes that price deviations beyond a certain threshold will likely revert toward their mean, or a percentage there-of. If a stock's price drops significantly below its historical mean (e.g., 1.5-2 standard deviations), it could present a buy opportunity. Conversely, if the price rises well above its mean, it could signal a potential sell opportunity. Execution of either will prompt the polar opposite and/or a Dollar Cost Average (DCA), when a purchase has occurred. A buy has a target sell and a related target purchase, if a drop occurs in price. A sell deletes any related DCA and creates a target buy or re-entry at a reduced price.

Below is a Python script that leverages Standard Deviation to set related target prices for swing trades, with fail-safes in place for instances when data retrieval fails.

Function for Implementation, on My Master Program

Needed Imports then the Function (Not the entire Program):
import yfinance as yf
import pandas as pd
import numpy as np
import time
import datetime
from google_sheet_codes import standard_deviation_factor, retries, success, max_retries, delay, sleep, mDly

def standard_deviation_related(etrade_transaction, price_of_shares, ticker):
    standard_deviation = None
    seeking = None
    stdv_related_target_price = None
    stdv_related_exit_price = None

    while retries < max_retries and not success:
        try:
            stock = yf.Ticker(ticker)

            if etrade_transaction == "Buy":
                data = stock.history(period='3mo')
                if data.empty:
                    print("3mo data is empty. Trying 90d period.")
                    data = stock.history(period='90d')
            elif etrade_transaction == "Sell":
                data = stock.history(period='1mo')
                if data.empty:
                    print("1mo data is empty. Trying 30d period.")
                    data = stock.history(period='30d')

            if data is None or data.empty:
                raise ValueError(f"Failed to retrieve data for {ticker}. Please check the ticker or the period.")

            close_prices = data['Close']

            if close_prices.isnull().values.any():
                raise ValueError(f"Data contains null values for {ticker}. Unable to compute standard deviation.")

            standard_deviation = round(float(np.std(close_prices)), 2)
            if not standard_deviation or np.isnan(standard_deviation):
                standard_deviation = float(input('\nEnter StDev manually:'))

            print(f'Std Dev for {ticker}: {standard_deviation}')
            seeking = round(float(standard_deviation * standard_deviation_factor), 2)

            if etrade_transaction == "Buy":
                stdv_related_target_price = price_of_shares - seeking
                stdv_related_exit_price = round(float(stdv_related_target_price + (seeking * 1.02)), 2)
            elif etrade_transaction == "Sell":
                magnifyer = 1 + round(float((standard_deviation / price_of_shares)), 3)
                magnifyer = min(1.075, magnifyer)
                stdv_related_target_price = round(float(price_of_shares - seeking), 2)
                stdv_related_exit_price = round(float(stdv_related_target_price + (seeking * magnifyer)), 2)

            time.sleep(delay)
            success = True
            retries = 0
            return stdv_related_target_price, stdv_related_exit_price

        except (ValueError, TypeError) as e:
            print(f"\nError: {e}\nInvalid input for standard deviation.")
            retries += 1
            if retries < max_retries:
                wait_time = min(mDly, (sleep * retries))
                print(f"\nRetry {retries}/{max_retries}. Sleeping {wait_time} seconds before retrying.")
                time.sleep(wait_time)

    if not success:
        print("Failed to retrieve data after max retries. Manual entry required.")
        try:
            standard_deviation = float(input('Enter Standard Deviation manually: '))
            seeking = round(float(standard_deviation * standard_deviation_factor), 2)
            
            if etrade_transaction == "Buy":
                stdv_related_target_price = price_of_shares - seeking
                stdv_related_exit_price = round(float(stdv_related_target_price + seeking), 2)
            elif etrade_transaction == "Sell":
                magnifyer = 1 + round(float((standard_deviation / price_of_shares)), 3)
                magnifyer = min(1.075, magnifyer)
                stdv_related_target_price = round(float(price_of_shares - seeking), 2)
                stdv_related_exit_price = round(float(stdv_related_target_price + (seeking * magnifyer)), 2)

            time.sleep(delay)
            return stdv_related_target_price, stdv_related_exit_price

        except ValueError:
            print("Manual entry failed. Please check your inputs.")
            return None, None

My Thoughts

This script provides an automated approach to Swing Trading by leveraging Standard Deviation as a measure of price volatility over either a 30day or 90day period. Using Python and the Yahoo Finance API, Swing Traders' can dynamically adjust target prices based on statistical probabilities, enhancing their mean reversion strategy.

Disclaimer

This content is for educational purposes only and should not be considered financial or investment advice. I am not a financial professional or a professional programmer. Trading involves risk, and you should conduct your own research before making any investment decisions.

Further Understanding and Implementation of this Python Code.

  • Data Entry of Stock Transactions Trigger this Code.
  • Implement logging to track failed attempts and store results, I use Google Sheets and Python to append new rows or modify the existing entries.
  • Incorporate other volatility measures such as ATR (Average True Range) or Fibonacci Retracements for a more comprehensive Target and probability.

Let me know in the comments if you have suggestions or improvements!

Popular posts from this blog

How to Add Beneficiaries on E*TRADE Without Losing Your Mind

“Because your money should go where you want it, not where the probate court thinks it should, I am sharing this information.” Ah, E*TRADE. The place where your money grows, your trades execute (sometimes), and your hopes for financial freedom flutter like a candlestick chart on a volatile Thursday. But what happens if you kick the bucket before you get that Tesla stock to moon? Simple: you assign a beneficiary. Unfortunately, E*TRADE doesn’t make this as intuitive as you might think. This isn’t a “click here and boom, you’re immortal” situation. But fear not, fellow capitalist. I’ve braved the pixelated jungle so you don’t have to. 🛠️ Step-by-Step: Setting a Beneficiary for Your E*TRADE Brokerage Account (aka “How to ensure your money doesn’t end up in your ex’s lap or your neighbor's GoFundMe”) Log in at etrade.com . (Obvious, yes. But worth saying—this isn’t Webkinz, you need the real site.) At the top, click “Accounts” and select your Brokerage Account . (The on...

NJ's Middle-Class Squeeze: Too Much for Help, Not Enough for Comfort

This is a long post — longer than what I usually write — because what I’m talking about here isn’t a small annoyance or a passing frustration. It’s something that has been building for years, and I’m finally putting it all into words. I’m upset, I’m exhausted, and I’m passionate about what follows, because it affects every working person in this state who’s trying to stay afloat. There’s a growing group in New Jersey — people who work full‑time, sometimes more than one job, who earn too much to qualify for assistance but not enough to absorb the constant increases in living costs. These are the people tightening their budgets, lowering their thermostats, cutting back wherever they can, and still watching their bills rise for reasons that have nothing to do with their own usage or behavior. If you’re part of that group, or you know someone who is, then what follows will probably resonate with you. And if you’re not, then I hope this gives you a clearer picture of what the middle class i...

Understanding Treasury Bond Auctions: The Difference Between High Yield and Interest Rate

Treasury bonds are a popular choice for investors looking for a reliable source of income backed by the U.S. government. However, understanding how these bonds are priced at auction can be confusing, especially when comparing the High Yield and the Interest Rate (Coupon Rate) columns. In this post, I'll break it down using a real-world example.  A Look at a Recent Treasury Bond Auction Here’s an example of a 20-year Treasury bond that was recently auctioned: Security Term CUSIP Reopening Issue Date Maturity Date High Yield Interest Rate 20-Year 912810UF3 Yes 01/31/2025 11/15/2044 4.900% 4.625% What Do These Numbers Mean? CUSIP : This is a unique identifier for the bond. Reopening : Since it says "Yes," this means the bond was originally issued earlier and is now being reoffered. Issue Date : January 31, 2025—this is when the bond will be offi...