Programming Chunks

Explore Python And Data Science with me!!

Home » Long term investment- Decision make approaches using python

Long term investment- Decision make approaches using python

So, there are basically two approches.

Market Growth Approach

This approach focuses on broader market trends and economic indicators. It’s ideal for a passive investment strategy where you aim to track or slightly outperform the market.

Financial Parameters Approach

This approach uses detailed financial metrics of individual companies to evaluate their financial health, profitability, and long-term growth potential. It’s ideal for an active investment strategy where you focus on finding undervalued companies with strong financials.

Key Metrics:

  • Total Equity: Indicates the company’s net worth.
  • Total Liabilities: Helps assess the company’s debt and financial obligations.
  • Net Income: Reflects the profitability of the company.
  • Total Revenue: Shows the company’s sales performance.
  • Gross Profit: Indicates profitability after accounting for the cost of goods sold.
  • Operating Income: Reflects the company’s earnings from operations.

For a Portfolio-Based Strategy: If you are building a diversified portfolio and want to assess the market as a whole, the market growth approach might be more suitable.For Stock Picking: If you aim to pick individual stocks with strong potential, using financial parameters will give you more precise insights.

I have used an algorithm with hybrid approach. Let me explain what I have implemented. So….

First of all see this picture:

It says amazon is at hold. Lets cross check this. I picked this article from nasdaq. It says the same so it is correct right?

So what is that hybrid strategy?

import requests
import numpy as np
import yfinance as yf
from datetime import datetime, timedelta

API_KEY = 'your_finnhub_api_key'

def fetch_financial_data_finnhub(ticker):
    base_url = 'https://finnhub.io/api/v1'

    # Fetch financials reported data
    financials_url = f'{base_url}/stock/financials-reported?symbol={ticker}&token={API_KEY}'
    financials_response = requests.get(financials_url)
    financials_data = financials_response.json()

    # Initialize variables for financial metrics
    total_equity = None
    total_liabilities = None
    net_income = None
    total_revenue = None
    gross_profit = None
    operating_income = None

    # Extract the most recent financial report data
    if 'data' in financials_data and financials_data['data']:
        report = financials_data['data'][0]['report']  # Get the report from the first item in data
        
        # Parse the balance sheet (bs)
        if 'bs' in report:
            for item in report['bs']:
                concept = item.get('concept')
                value = item.get('value')
                if concept == 'us-gaap_StockholdersEquity':
                    total_equity = value
                elif concept == 'us-gaap_Liabilities':
                    total_liabilities = value
        
        # Parse the income statement (ic)
        if 'ic' in report:
            for item in report['ic']:
                concept = item.get('concept')
                value = item.get('value')
                if concept == 'us-gaap_NetIncomeLoss':
                    net_income = value
                elif concept == 'us-gaap_SalesRevenueNet':
                    total_revenue = value
                elif concept == 'us-gaap_GrossProfit':
                    gross_profit = value
                elif concept == 'us-gaap_OperatingIncomeLoss':
                    operating_income = value
             
    financial_data = {
        'total_equity': total_equity,
        'total_liabilities': total_liabilities,
        'net_income': net_income,
        'total_revenue': total_revenue,
        'gross_profit': gross_profit,
        'operating_income': operating_income
    }
    
    return financial_data


def calculate_financial_ratios(financial_data):
    debt_to_equity = None
    roe = None
    gross_margin = None
    
    if financial_data['total_equity'] is not None and financial_data['total_equity'] != 0:
        debt_to_equity = financial_data['total_liabilities'] / financial_data['total_equity'] if financial_data['total_liabilities'] is not None else None
        roe = financial_data['net_income'] / financial_data['total_equity'] if financial_data['net_income'] is not None else None
    
    if financial_data['total_revenue'] is not None and financial_data['total_revenue'] != 0:
        gross_margin = financial_data['gross_profit'] / financial_data['total_revenue'] if financial_data['gross_profit'] is not None else None

    return {
        'debt_to_equity': debt_to_equity,
        'roe': roe,
        'gross_margin': gross_margin
    }


def get_market_growth(symbol='SPY', start_year=2010, end_year=2024):
    start_timestamp = int(datetime(start_year, 1, 1).timestamp())
    end_timestamp = int(datetime(end_year, 12, 31).timestamp())
    
    url = f'https://finnhub.io/api/v1/stock/candle?symbol={symbol}&resolution=M&from={start_timestamp}&to={end_timestamp}&token={API_KEY}'
    response = requests.get(url)
    data = response.json()
    
    if 'c' in data:
        prices = data['c']  # Close prices
        years = pd.date_range(start=f'{start_year}-01-01', end=f'{end_year}-12-31', freq='Y').year
        growth_rates = [prices[i+1]/prices[i] for i in range(len(prices)-1)]
        
        return pd.DataFrame({'Year': years[1:], 'Market_Growth': growth_rates})
    else:
        print("Error fetching market data")
        return None


def evaluate_investment(ticker, financial_data, financial_ratios, thresholds):
    decision = {
        'action': 'Hold',
        'reasons': []
    }

    if financial_ratios['debt_to_equity'] is not None and financial_ratios['debt_to_equity'] > thresholds['max_debt_to_equity']:
        decision['reasons'].append(f"High Debt-to-Equity Ratio: {financial_ratios['debt_to_equity']:.2f}")

    if financial_ratios['roe'] is not None and financial_ratios['roe'] < thresholds['min_roe']:
        decision['reasons'].append(f"Low ROE: {financial_ratios['roe']:.2%}")
    
    if financial_ratios['gross_margin'] is not None and financial_ratios['gross_margin'] < thresholds['min_gross_margin']:
        decision['reasons'].append(f"Low Gross Margin: {financial_ratios['gross_margin']:.2%}")
    
    if not decision['reasons']:
        decision['action'] = "Buy"
    elif len(decision['reasons']) > 2:
        decision['action'] = "Sell"
    else:
        decision['action'] = "Hold"

    reasons_str = " ".join(decision['reasons']) if decision['reasons'] else "Meets all criteria."
    decision_string = f"Investment Decision for {ticker}: {decision['action']}. Reasons: {reasons_str}"
    
    return decision_string


def calculate_macd(price_data):
    short_ema = price_data.ewm(span=12, adjust=False).mean()
    long_ema = price_data.ewm(span=26, adjust=False).mean()
    macd = short_ema - long_ema
    signal_line = macd.ewm(span=9, adjust=False).mean()
    return macd, signal_line


def make_short_term_decision(price_data, rsi, macd, signal_line, moving_average):
    # Example decision logic based on RSI, MACD, and moving average
    if rsi > 70 and macd[-1] < signal_line[-1] and price_data[-1] < moving_average:
        return "Sell"
    elif rsi < 30 and macd[-1] > signal_line[-1] and price_data[-1] > moving_average:
        return "Buy"
    else:
        return "Hold"


def analyze_group_of_symbols(symbols):
    results = {}
    market_growth_symbol = 'SPY'
    market_growth = get_market_growth(symbol=market_growth_symbol)

    if market_growth is not None:
        avg_market_growth = market_growth['Market_Growth'].mean()
        print(f"Average Market Growth: {avg_market_growth:.2f}")
    else:
        print("Market growth analysis failed.")
        return
    
    thresholds = {
        'max_debt_to_equity': 2.0,
        'min_roe': 0.15,
        'min_gross_margin': 0.40
    }

    if avg_market_growth < 1.0:
        thresholds['min_roe'] += 0.05
        thresholds['min_gross_margin'] += 0.05
    elif avg_market_growth > 1.1:
        thresholds['min_roe'] -= 0.05
        thresholds['min_gross_margin'] -= 0.05

    for symbol in symbols:
        financial_data = fetch_financial_data_finnhub(symbol)
        financial_ratios = calculate_financial_ratios(financial_data)
        
        long_term_decision = evaluate_investment(symbol, financial_data, financial_ratios, thresholds)

        end_date = datetime.now().strftime('%Y-%m-%d')
        start_date = (datetime.now() - timedelta(days=5*365)).strftime('%Y-%m-%d')
        price_data = yf.download(symbol, start=start_date, end=end_date)['Adj Close']

        macd, signal_line = calculate_macd(price_data)
        moving_average = np.mean(price_data)
        rsi = 75  # Example RSI value
        
        short_term_decision = make_short_term_decision(price_data, rsi, macd, signal_line, moving_average)
        
        results[symbol] = {
            'short_term_decision': short_term_decision,
            'long_term_decision': long_term_decision,
            'price_data': price_data,
            'rsi': rsi,
            'macd': macd,
            'moving_average': moving_average,
            'financial_data': financial_data
        }
    
   

Explanation:

  1. Market Growth Analysis:
    • The function get_market_growth fetches the historical growth rates for the specified index (e.g., S&P 500). I have use SPY stock market index. You use indices essentially to get market insights
    • The average market growth is calculated to provide a broad indication of market conditions.
    • Next we have to adjust the threshold values based on market performance. Thresold values are the benmarking parameters that is used for evaluation
    if avg_market_growth < 1.0:
        thresholds['min_roe'] += 0.05
        thresholds['min_gross_margin'] += 0.05
    elif avg_market_growth > 1.1:
        thresholds['min_roe'] -= 0.05
        thresholds['min_gross_margin'] -= 0.05
  1. Financial Data and Ratios:
    • The get_financials function retrieves financial data for each stock.
    • This is at the financial parameter level accessing indv company performance
    • The calculate_financial_ratios function calculates key ratios like debt-to-equity, ROE, and gross margin.
    • The evaluate_investment function evaluates whether to buy, hold, or sell based on the financial ratios and thresholds provided.
  2. Hybrid Decision Process:
    • The hybrid_decision_process function combines both market growth analysis and financial analysis. It iterates through each stock, performs financial analysis, and then decides based on the financial health of the company and overall market conditions.
  3. Thresholds:
    • You can adjust the thresholds (max_debt_to_equity, min_roe, min_gross_margin) based on your investment criteria. These thresholds determine whether a stock is considered for buying, holding, or selling.

That’s all for this

pallavy.com

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top