# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

"""
This is a python notebook to create a stock screener. The finished product will accept a set of parameters 
and output the stocks that meet those requirements. Currently this scanner follows the "Swing Traders Checklist" @
https://www.swing-trade-stocks.com/swing-traders-checklist.html. The goal is to deploy this with a suite of Azure Functions 
and use it in a suite of other related financial-python projects, such as twitter sentiment and FinViz sentiment analysis, 
using ML-clustering to define levels of support and resistance, and other ideas I might think of at 2am on a Sunday.
"""

import yahoo_fin.stock_info as si
import pandas as pd
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
import talib
import requests
import json
import openpyxl
import psycopg2 as pg
import StockSentiment_FinViz.ipynb


# +

#Get connected 
conn = pg.connect("dbname=StonksGoUp user=postgres host=localhost password=<PASSWORD>")
cur = conn.cursor()

#read in the finnhub.io token
# This will be used until the ML aspect is tested and complete
with open('local_settings.txt') as f:
    json_local = json.load(f)

finn_token = json_local["finn_token"]

#define scanner parameters:
low = float(2.5)
high = float(25.0)
to = int(datetime.strptime(datetime.today().strftime("%d/%m/%Y") + " +0000", "%d/%m/%Y %z").timestamp())
fro = int((datetime.strptime(datetime.today().strftime("%d/%m/%Y") + " +0000", "%d/%m/%Y %z")-relativedelta(days=300)).timestamp())
earnings_period = int((datetime.strptime(datetime.today().strftime("%d/%m/%Y") + " +0000", "%d/%m/%Y %z")+relativedelta(days=5)).timestamp())
capital = 100000
risk = 0.05

get_tickers = """
    SELECT ticker from stockdata
    WHERE ticker IN (SELECT ticker from tickers)
    GROUP BY ticker
                 """
cur.execute(get_tickers, conn)

scanner_list = list([i[0] for i in cur.fetchall()])
print(scanner_list[:20])

# get sentiment table
get_sentiment = """
    SELECT ticker, round(avg(score), 2) as avg_sentiment 
    FROM sentiment 
    WHERE timestamp > current_date - interval '1 week' 
    GROUP BY ticker
    """
df_sentiment = pd.read_sql(get_sentiment, conn)
print(df_sentiment)


# +
# Functions for Technical Analysis

def get_hist(ticker, conn):
    # Get data from web-scraping
#     req = f"https://query1.finance.yahoo.com/v7/finance/download/{ticker}?period1={fro}&period2={to}&interval=1d&events=history"
#     data = pd.read_csv(req)
    
#     data.index = data["Date"].apply(lambda x: pd.Timestamp(x))
#     data.drop("Date", axis=1, inplace=True)
    
    # Get data from database
    get_data = f"""SELECT 
                    ticker
                    ,quotedate as "Date"
                    ,open as "Open"
                    ,high as "High"
                    ,low as "Low"
                    ,close as "Close"
                    ,adjclose as "Adj Close"
                    ,volume as "Volume"
                    FROM stockdata
                    WHERE ticker = '{ticker}'
                    ORDER BY quotedate ASC"""
    data = pd.read_sql(get_data, conn)
    
    return data

def get_indicators(data):
    # Get MACD
    data["macd"], data["macd_signal"], data["macd_hist"] = talib.MACD(data['Close'])
    
    # Get SMA10 and SMA30
    data["sma10"] = talib.SMA(data["Close"], timeperiod=10)
    data["sma30"] = talib.SMA(data["Close"], timeperiod=30)
    
    # Get MA200
    data["sma200"] = talib.SMA(data["Close"], timeperiod=200)
    
    # Get RSI
    data["rsi"] = talib.RSI(data["Close"])
    
    return data

def analyze_chart(indicated_data, df_analyzed):
    #quote_price = indicated_data.loc[:,'Adj Close'].iloc[-1]
    # Check RSI
    if indicated_data.loc[:,'rsi'].iloc[-1] < 35: 
        rsi = "Oversold"
    elif indicated_data.loc[:,'rsi'].iloc[-1] > 65: 
        rsi = "Overbought"
    else: 
        rsi = None

    # Check SMA Trend
    if indicated_data.loc[:,'sma30'].iloc[-1]<indicated_data.loc[:,'sma10'].iloc[-1]:
        trend = "Uptrend"
    elif indicated_data.loc[:,'sma30'].iloc[-1]>indicated_data.loc[:,'sma10'].iloc[-1]:
        trend = "Downtrend"
    else:
        trend = None
    
    # Check 200SMA
    if indicated_data.loc[:,'Open'].iloc[-1]>indicated_data.loc[:,'sma200'].iloc[-1]: 
        above200 = True
    else:
        above200 = None
    
    # Check for Earnings
    try:
        if pd.isnull(si.get_quote_table(ticker)['Earnings Date']):
            earnings_date = None
        elif datetime.strptime(si.get_quote_table(ticker)['Earnings Date'].split(' - ')[0], '%b %d, %Y'):
            earnings_date = datetime.strptime(si.get_quote_table(ticker)['Earnings Date'].split(' - ')[0], '%b %d, %Y')
        else:
            earnings_date = datetime.strptime(si.get_quote_table(ticker)['Earnings Date'], '%b %d, %Y')
    except:
        earnings_date = None
    
    # Check for support or resistance
    req = requests.get(f'https://finnhub.io/api/v1/scan/support-resistance?symbol={ticker}&resolution=D&token={finn_token}')
    supp_res = None
    supp_res_price = float()
    for level in req.json()['levels']:
        if float(level)*0.90 < indicated_data.loc[:,'Open'].iloc[-1] < float(level)*1.10:
            if indicated_data.loc[:,'Open'].iloc[-1] >= float(level):
                supp_res = "support"
                supp_res_price = round(level, 2)
            elif indicated_data.loc[:,'Open'].iloc[-1] <= float(level):
                supp_res = "resistance"
                supp_res_price = round(level, 2)
            else:
                supp_res = "Indeterminant"
                supp_res_price = None
        else:
            pass
    # Check TAZ
    # Check for Pullback
    if indicated_data.loc[:,'Adj Close'].iloc[-1]<= indicated_data.loc[:,'Adj Close'].iloc[-2]<= indicated_data.loc[:,'Adj Close'].iloc[-3]:
        pullback = True
    else: 
        pullback = None
    # Add latest sentiment
    

    df_analyzed = df_analyzed.append({'Ticker' : ticker, 
                          'Open' : round(indicated_data.loc[:,'Open'].iloc[-1]),
                          'Quote' : round(indicated_data.loc[:,'Adj Close'].iloc[-1]),
                          'RSI' : rsi,
                          'Trend' : trend,
                          'Above200' : above200,
                          'Earnings' : earnings_date, 
                          'Supp/Res' : supp_res,
                          'S/R Price' : supp_res_price,
                          'Pullback' : pullback,
                          'Sentiment' : sentiment
                         }, ignore_index=True)
    
    return df_analyzed

def analyze_position(df_analyzed, capital, risk):
    position_risk = capital*risk
    
    df_analyzed['Entry'] = df_analyzed['S/R Price']
    df_analyzed['Stoploss'] = df_analyzed['S/R Price'].astype(float).apply(lambda x: x * float(0.95))  
    df_analyzed['risk_per_share'] = df_analyzed['Entry'] - df_analyzed['Stoploss']
    df_analyzed['position_size'] = round(position_risk/df_analyzed['risk_per_share'])

    return df_analyzed



# +
scanner_list = ['AAL', 'AES', 'AMCR', 'APA', 'BAC']
df_analyzed = pd.DataFrame(columns=['Ticker', 'Open', 'Quote', 'RSI', 'Trend', 'Above200', 'Earnings', 'Supp/Res', 'S/R Price', 'Pullback'])
for ticker in scanner_list:
    print(ticker)
    # Get historical data
    data = get_hist(ticker, conn)
    
    # Add indicator data
    indicated_data = get_indicators(data)
    
    # Analyze stonks:
    df_analyzed = analyze_chart(indicated_data, df_analyzed)
    
    df_analyzed = analyze_position(df_analyzed, capital, risk)

df_analyzed = df_analyzed[df_analyzed['Above200'] == True]
df_analyzed = df_analyzed[df_analyzed['RSI'] != None]
df_analyzed = df_analyzed[df_analyzed['Trend'] != None]
df_analyzed = df_analyzed[df_analyzed['Earnings'] != None]
df_analyzed = df_analyzed[df_analyzed['Supp/Res'] != None]
df_analyzed = df_analyzed[df_analyzed['Pullback'] != None]
print(df_analyzed)
#df_analyzed.to_excel('Output.xlsx', ignore_index=True)

# -








StarcoderdataJupyterScriptsDedupFiltered