├── .gitignore ├── BERT Sentiment Analysis ├── README.md ├── test.py └── training.ipynb ├── Financely.pptx ├── Financely ├── Financely │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── settings.cpython-38.pyc │ │ ├── urls.cpython-38.pyc │ │ └── wsgi.cpython-38.pyc │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── basic_app │ ├── FA.py │ ├── ProphetTrend.py │ ├── TA.py │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── decorators.py │ ├── forms.py │ ├── get_news.py │ ├── get_stock_info.py │ ├── models.py │ ├── sectorPerformance.py │ ├── sentiment_analysis.py │ ├── stock_data.py │ ├── templatetags │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-37.pyc │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── __init__.cpython-39.pyc │ │ │ ├── poll_extras.cpython-37.pyc │ │ │ ├── poll_extras.cpython-38.pyc │ │ │ └── poll_extras.cpython-39.pyc │ │ └── poll_extras.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── db.sqlite3 ├── manage.py ├── static │ ├── images │ │ ├── favicon.ico │ │ └── favicon1.png │ └── js │ │ └── stock.js └── templates │ └── basic_app │ ├── base.html │ ├── dashboard.html │ ├── index.html │ ├── login.html │ ├── portfolio.html │ ├── price_prediction.html │ ├── profile.html │ ├── register.html │ ├── statisticsAdmin.html │ └── stock.html ├── LICENSE ├── README.md ├── Tech and Fin analysis ├── Dataset.py ├── FA.py ├── ProphetTrend.py ├── TA.py └── sectorPerformance.py ├── assets ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png └── logo.png └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | Financely/basic_app/__pycache__/ 2 | Financely/basic_app/migrations/ 3 | Financely/basic_app/bert_sentiment_analysis.pt 4 | -------------------------------------------------------------------------------- /BERT Sentiment Analysis/README.md: -------------------------------------------------------------------------------- 1 | Model Download Link - https://drive.google.com/file/d/1vGN0481ovU6mQZkgKO2lLAGMKnXVbufi/view?usp=sharing -------------------------------------------------------------------------------- /BERT Sentiment Analysis/test.py: -------------------------------------------------------------------------------- 1 | from transformers import BertModel, BertTokenizer 2 | import torch 3 | from torch import nn 4 | 5 | RANDOM_SEED = 42 6 | torch.manual_seed(RANDOM_SEED) 7 | 8 | class_names = ['negative', 'neutral', 'positive'] 9 | PRE_TRAINED_MODEL_NAME = 'bert-base-cased' 10 | tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) 11 | 12 | class SentimentClassifier(nn.Module): 13 | def __init__(self, n_classes): 14 | super(SentimentClassifier, self).__init__() 15 | self.bert = BertModel.from_pretrained(PRE_TRAINED_MODEL_NAME) 16 | self.drop = nn.Dropout(p=0.3) 17 | self.out = nn.Linear(self.bert.config.hidden_size, n_classes) 18 | 19 | def forward(self, input_ids, attention_mask): 20 | output = self.bert( 21 | input_ids=input_ids, 22 | attention_mask=attention_mask 23 | ) 24 | pooled_output = output[1] 25 | output = self.drop(pooled_output) 26 | return self.out(output) 27 | 28 | model = SentimentClassifier(len(class_names)) 29 | 30 | model.load_state_dict(torch.load("bert_sentiment_analysis.pt", map_location=torch.device('cpu'))) 31 | 32 | 33 | def predict_sentiment(sample_text): 34 | encoded_review = tokenizer.encode_plus( 35 | sample_text, 36 | max_length=512, 37 | add_special_tokens=True, 38 | return_token_type_ids=False, 39 | pad_to_max_length=True, 40 | return_attention_mask=True, 41 | return_tensors='pt', 42 | ) 43 | 44 | input_ids = encoded_review['input_ids'] 45 | attention_mask = encoded_review['attention_mask'] 46 | 47 | output = model(input_ids, attention_mask) 48 | _, prediction = torch.max(output, dim=1) 49 | 50 | print(f'Review text: {sample_text}') 51 | print(f'Sentiment : {class_names[prediction]}') 52 | 53 | predict_sentiment("Kill me please") -------------------------------------------------------------------------------- /Financely.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely.pptx -------------------------------------------------------------------------------- /Financely/Financely/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/Financely/__init__.py -------------------------------------------------------------------------------- /Financely/Financely/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/Financely/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /Financely/Financely/__pycache__/settings.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/Financely/__pycache__/settings.cpython-38.pyc -------------------------------------------------------------------------------- /Financely/Financely/__pycache__/urls.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/Financely/__pycache__/urls.cpython-38.pyc -------------------------------------------------------------------------------- /Financely/Financely/__pycache__/wsgi.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/Financely/__pycache__/wsgi.cpython-38.pyc -------------------------------------------------------------------------------- /Financely/Financely/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for Financely project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Financely.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Financely/Financely/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for Financely project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.2.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.2/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | import os 15 | 16 | os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" 17 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 18 | BASE_DIR = Path(__file__).resolve().parent.parent 19 | TEMPLATE_DIR = os.path.join(BASE_DIR, "templates") 20 | STATIC_DIR = os.path.join(BASE_DIR, "static") 21 | 22 | # Quick-start development settings - unsuitable for production 23 | # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ 24 | 25 | # SECURITY WARNING: keep the secret key used in production secret! 26 | SECRET_KEY = 'django-insecure-v&g3s&y$lnzs(ph^2*o*n+nh(1=bc0bmq^6xnn^0-w)d*o(jz)' 27 | 28 | # SECURITY WARNING: don't run with debug turned on in production! 29 | DEBUG = True 30 | 31 | ALLOWED_HOSTS = [] 32 | 33 | 34 | # Application definition 35 | 36 | INSTALLED_APPS = [ 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 'basic_app', 44 | ] 45 | 46 | MIDDLEWARE = [ 47 | 'django.middleware.security.SecurityMiddleware', 48 | 'django.contrib.sessions.middleware.SessionMiddleware', 49 | 'django.middleware.common.CommonMiddleware', 50 | 'django.middleware.csrf.CsrfViewMiddleware', 51 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 52 | 'django.contrib.messages.middleware.MessageMiddleware', 53 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 54 | ] 55 | 56 | ROOT_URLCONF = 'Financely.urls' 57 | 58 | TEMPLATES = [ 59 | { 60 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 61 | 'DIRS': [TEMPLATE_DIR,], 62 | 'APP_DIRS': True, 63 | 'OPTIONS': { 64 | 'context_processors': [ 65 | 'django.template.context_processors.debug', 66 | 'django.template.context_processors.request', 67 | 'django.contrib.auth.context_processors.auth', 68 | 'django.contrib.messages.context_processors.messages', 69 | ], 70 | }, 71 | }, 72 | ] 73 | 74 | WSGI_APPLICATION = 'Financely.wsgi.application' 75 | 76 | 77 | # Database 78 | # https://docs.djangoproject.com/en/3.2/ref/settings/#databases 79 | 80 | DATABASES = { 81 | 'default': { 82 | 'ENGINE': 'django.db.backends.sqlite3', 83 | 'NAME': BASE_DIR / 'db.sqlite3', 84 | } 85 | } 86 | 87 | 88 | # Password validation 89 | # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators 90 | 91 | AUTH_PASSWORD_VALIDATORS = [ 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 103 | }, 104 | ] 105 | 106 | 107 | # Internationalization 108 | # https://docs.djangoproject.com/en/3.2/topics/i18n/ 109 | 110 | LANGUAGE_CODE = 'en-us' 111 | 112 | TIME_ZONE = 'UTC' 113 | 114 | USE_I18N = True 115 | 116 | USE_L10N = True 117 | 118 | USE_TZ = True 119 | 120 | 121 | # Static files (CSS, JavaScript, Images) 122 | # https://docs.djangoproject.com/en/3.2/howto/static-files/ 123 | 124 | STATIC_URL = '/static/' 125 | STATICFILES_DIRS = [STATIC_DIR,] 126 | # Default primary key field type 127 | # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field 128 | 129 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 130 | -------------------------------------------------------------------------------- /Financely/Financely/urls.py: -------------------------------------------------------------------------------- 1 | """Financely URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.2/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path,include 18 | 19 | urlpatterns = [ 20 | path('admin/', admin.site.urls), 21 | path('', include('basic_app.urls')) 22 | ] 23 | -------------------------------------------------------------------------------- /Financely/Financely/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for Financely project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Financely.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Financely/basic_app/FA.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import datetime 3 | import yfinance as yf 4 | 5 | def piotroski(ticker): 6 | bs = yf.Ticker(ticker).balance_sheet 7 | inc = yf.Ticker(ticker).financials 8 | cf = yf.Ticker(ticker).cashflow 9 | longTermDebt = bs.loc['Long Term Debt'][0] 10 | longTermDebtPre = bs.loc['Long Term Debt'][1] 11 | totalAssets = bs.loc['Total Assets'][0] 12 | totalAssetsPre = bs.loc['Total Assets'][1] 13 | totalAssetsPre2 = bs.loc['Total Assets'][2] 14 | currentAssets = bs.loc['Total Current Assets'][0] 15 | currentAssetsPre = bs.loc['Total Current Assets'][1] 16 | currentLiabilities = bs.loc['Total Current Liabilities'][0] 17 | currentLiabilitiesPre = bs.loc['Total Current Liabilities'][1] 18 | revenue = inc.loc['Total Revenue'][0] 19 | revenuePre = inc.loc['Total Revenue'][1] 20 | grossProfit = inc.loc['Gross Profit'][0] 21 | grossProfitPre = inc.loc['Gross Profit'][1] 22 | netIncome = inc.loc['Net Income'][0] 23 | netIncomePre = inc.loc['Net Income'][1] 24 | operatingCashFlow = cf.loc['Total Cash From Operating Activities'][0] 25 | operatingCashFlowPre = cf.loc['Total Cash From Operating Activities'][1] 26 | commonStock = bs.loc['Common Stock'][0] 27 | commonStockPre = bs.loc['Common Stock'][1] 28 | ROAFS = int(netIncome/((totalAssets + totalAssetsPre)/2)>0) 29 | CFOFS = int(operatingCashFlow>0) 30 | ROADFS = int((netIncome/((totalAssets + totalAssetsPre)/2))>(netIncomePre/((totalAssetsPre + totalAssetsPre2)))) 31 | CFOROAFS = int((operatingCashFlow/totalAssets)>(netIncome/((totalAssets + totalAssetsPre)/2))) 32 | LTDFS = int(longTermDebt <= longTermDebtPre) 33 | CRFS = int(currentAssets/currentLiabilities)>(currentAssetsPre/currentLiabilitiesPre) 34 | NSFS = int(commonStock <= commonStockPre) 35 | GMFS = int(grossProfit/revenue>grossProfitPre/revenuePre) 36 | ATOFS = int((revenue/((totalAssets + totalAssetsPre)/2))>(revenuePre/((totalAssetsPre + totalAssetsPre2)))) 37 | return ROAFS + CFOFS + ROADFS + CFOROAFS + LTDFS + CRFS + NSFS + GMFS + ATOFS 38 | # print(piotroski('msft')) -------------------------------------------------------------------------------- /Financely/basic_app/ProphetTrend.py: -------------------------------------------------------------------------------- 1 | from prophet import Prophet 2 | #import pystan 3 | import yfinance as yf 4 | import pandas as pd 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | import base64 8 | from io import BytesIO 9 | 10 | def get_graph(): 11 | buffer = BytesIO() 12 | plt.savefig(buffer,format = "png") 13 | buffer.seek(0) 14 | image_png = buffer.getvalue() 15 | graph = base64.b64encode(image_png) 16 | graph = graph.decode('utf-8') 17 | buffer.close() 18 | return graph 19 | 20 | 21 | def forecast(ticker): 22 | df = yf.Ticker(ticker).history(period='5y', interval = '1d') 23 | df = df[['Close']] 24 | dfx = pd.DataFrame() 25 | dfx['ds'] = pd.to_datetime(df.index) 26 | dfx['y'] = df.Close.values 27 | fbp = Prophet(daily_seasonality = True) 28 | fbp.fit(dfx) 29 | fut = fbp.make_future_dataframe(periods=(365)) 30 | forecast = fbp.predict(fut) 31 | plot = fbp.plot(forecast) 32 | plt.xlabel("Date") 33 | plt.ylabel("Price") 34 | graph = get_graph() 35 | return graph 36 | # plt.show() 37 | # pchange = ((forecast.trend.values[-1] - dfx.y.values[-1])*100)/dfx.y.values[-1] 38 | # if pchange > 0: 39 | # rating = 1 40 | # elif pchange == 0: 41 | # rating = 0 42 | # else: 43 | # rating = -1 44 | # return plot, rating 45 | # plot, rating = forecast('googl') 46 | -------------------------------------------------------------------------------- /Financely/basic_app/TA.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import yfinance as yf 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import talib as ta 6 | plt.style.use('seaborn') 7 | 8 | def sma(ticker): 9 | df = yf.Ticker(ticker).history(period='1y') 10 | # print(df.head()) 11 | df['SMA'] = ta.SMA(df['Close'],20) 12 | df[['SMA']].plot(figsize=(12,12)) 13 | plt.show() 14 | return plt 15 | 16 | def ema(ticker): 17 | df = yf.Ticker(ticker).history(period='1y') 18 | # print(df.head()) 19 | df['EMA'] = ta.EMA(df['Close'],20) 20 | df[['EMA']].plot(figsize=(12,12)) 21 | plt.show() 22 | return plt 23 | 24 | def macd(ticker): 25 | df = yf.Ticker(ticker).history(period='1y') 26 | # print(df.head()) 27 | df['MACD'], df['MACDSIGNAL'], df['MACDHIST'] = ta.MACD(df['Close'],20) 28 | df[['MACD','MACDSIGNAL', 'MACDHIST']].plot(figsize=(12,12)) 29 | plt.show() 30 | return plt 31 | 32 | def rsi(ticker): 33 | df = yf.Ticker(ticker).history(period='1y') 34 | # print(df.head()) 35 | df['RFI'] = ta.RSI(df['Close'],20) 36 | df[['RFI']].plot(figsize=(12,12)) 37 | plt.show() 38 | return plt 39 | 40 | def adx(ticker): 41 | df = yf.Ticker(ticker).history(period='1y') 42 | # print(df.head()) 43 | df['ADX'] = ta.ADX(df['High'], df['Low'], df['Close'],20) 44 | df[['ADX']].plot(figsize=(12,12)) 45 | plt.show() 46 | return plt 47 | 48 | def bband(ticker): 49 | df = yf.Ticker(ticker).history(period='1y') 50 | # print(df.head()) 51 | df['UpBand'], df['MidBand'], df['LowBand'] = ta.BBANDS(df['Close'], timeperiod =20) 52 | df[['UpBand','MidBand','LowBand']].plot(figsize=(12,12)) 53 | plt.show() 54 | return plt 55 | 56 | def obv(ticker): 57 | df = yf.Ticker(ticker).history(period='1y') 58 | # print(df.head()) 59 | df['OBV'] = ta.OBV(df['Close'], df['Volume']) 60 | df[['OBV']].plot(figsize=(12,12)) 61 | plt.show() 62 | return plt 63 | 64 | def pivots(ticker): 65 | df = yf.Ticker(ticker).history(interval='1d').tail(1) 66 | # print(df) 67 | df = df.reset_index(drop=True, inplace=False) 68 | pp = float((df['High'] + df['Low'] + df['Close'])/3) 69 | r1 = float(2*pp - df['Low']) 70 | s1 = float(2*pp - df['High']) 71 | r2 = float(pp + (df['High'] - df['Low'])) 72 | s2 = float(pp - (df['High'] - df['Low'])) 73 | r3 = float(pp + 2*(df['High'] - df['Low'])) 74 | s3 = float(pp - 2*(df['High'] - df['Low'])) 75 | print(pp, r1, r2, r3, s1, s2, s3) 76 | return pp, r1, r2, r3, s1, s2, s3 77 | 78 | sma('msft') 79 | ema('msft') 80 | macd('msft') 81 | rsi('msft') 82 | adx('msft') 83 | bband('msft') 84 | obv('msft') 85 | pivots('hdfcbank.ns') 86 | -------------------------------------------------------------------------------- /Financely/basic_app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/__init__.py -------------------------------------------------------------------------------- /Financely/basic_app/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Client,Portfolio,Stock 3 | # Register your models here. 4 | admin.site.register(Client) 5 | admin.site.register(Portfolio) 6 | admin.site.register(Stock) 7 | -------------------------------------------------------------------------------- /Financely/basic_app/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BasicAppConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'basic_app' 7 | -------------------------------------------------------------------------------- /Financely/basic_app/decorators.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | from django.shortcuts import redirect 3 | 4 | 5 | def unauthenticated_user(view_func): 6 | def wrapper_func(request, *args, **kwargs): 7 | 8 | if request.user.is_authenticated: 9 | return redirect("basic_app:index") 10 | else: 11 | return view_func(request, *args, **kwargs) 12 | 13 | return wrapper_func 14 | 15 | 16 | def allowed_users(allowed_roles=[]): 17 | def decorator(view_func): 18 | def wrapper_func(request, *args, **kwargs): 19 | 20 | group = None 21 | if request.user.groups.exists(): 22 | group = request.user.groups.all()[0].name 23 | 24 | if group in allowed_roles: 25 | return view_func(request, *args, **kwargs) 26 | else: 27 | return HttpResponse('You are not authorized to view this page') 28 | return wrapper_func 29 | return decorator 30 | # 31 | # def search_bar(view_func): 32 | # def wrapper_func(request, *args, **kwargs): 33 | # if request.is_ajax(): 34 | # res = None 35 | # data = request.POST.get('searchData') 36 | # item = getStockInfo(data) 37 | # if len(item)>0 and len(data): 38 | # res = item 39 | # else: 40 | # res = 'No stocks found..' 41 | # 42 | # #print(data) 43 | # return JsonResponse({'data':res}) 44 | # else: 45 | # return view_func(request, *args, **kwargs) 46 | # 47 | # return wrapper_func 48 | 49 | 50 | # def admin_only(view_func): 51 | # def wrapper_function(request, *args, **kwargs): 52 | # group = None 53 | # if request.user.groups.exists(): 54 | # group = request.user.groups.all()[0].name 55 | # 56 | # if group == 'Client': 57 | # return redirect('user-page') 58 | # 59 | # if group == 'Admin': 60 | # return view_func(request, *args, **kwargs) 61 | # 62 | # return wrapper_function 63 | -------------------------------------------------------------------------------- /Financely/basic_app/forms.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.forms import UserCreationForm 2 | from django import forms 3 | from django.forms import ModelForm 4 | from django.contrib.auth.models import User 5 | from .models import Stock 6 | 7 | 8 | 9 | class CreateUserForm(UserCreationForm): 10 | class Meta: 11 | model = User 12 | fields = ['username','password1','password2'] 13 | 14 | # class updateQuantityForm(forms.ModelForm): 15 | # class Meta: 16 | # model = Stock 17 | # fields = ['quantity'] 18 | -------------------------------------------------------------------------------- /Financely/basic_app/get_news.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import random 3 | from basic_app.sentiment_analysis import predict_sentiment 4 | def getNews(key): 5 | r = requests.get(f"https://newsapi.org/v2/everything?q={key}&pageSize=12&apiKey=9b23adeb6a634a0ba1f62e76dcbc54de") 6 | res = r.json() 7 | news = {} 8 | 9 | if res['status'] == 'ok': 10 | articles = res['articles'] 11 | random_news=random.sample(articles, 12) 12 | for i in range(12): 13 | #random_news[i]['sentiment'] = predict_sentiment([random_news[i]['description'][:100]])[0] 14 | news[i]=random_news[i] 15 | 16 | 17 | return news 18 | 19 | def getNewsWithSentiment(key): 20 | r = requests.get(f"https://newsapi.org/v2/everything?q={key}&pageSize=12&apiKey=9b23adeb6a634a0ba1f62e76dcbc54de") 21 | res = r.json() 22 | news = {} 23 | 24 | if res['status'] == 'ok': 25 | articles = res['articles'] 26 | random_news=random.sample(articles, 12) 27 | for i in range(12): 28 | random_news[i]['sentiment'] = predict_sentiment([random_news[i]['description'][:100]])[0] 29 | news[i]=random_news[i] 30 | 31 | 32 | return news 33 | 34 | # print(getNews()) 35 | -------------------------------------------------------------------------------- /Financely/basic_app/get_stock_info.py: -------------------------------------------------------------------------------- 1 | import urllib.request, json 2 | 3 | def getStockInfo(var): 4 | var = var.replace(' ','') 5 | url = "https://finance.yahoo.com/_finance_doubledown/api/resource/searchassist;searchTerm={}?device=console&returnMeta=true".format(var) 6 | response = urllib.request.urlopen(url) 7 | data = json.loads(response.read()) 8 | return data['data']['items'] 9 | -------------------------------------------------------------------------------- /Financely/basic_app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | # Create your models here. 4 | 5 | class Client(models.Model): 6 | user = models.OneToOneField(User,null=True,blank= True,on_delete=models.CASCADE) 7 | name = models.CharField(max_length=100, null=True) 8 | # def __str__(self): 9 | # return self.name 10 | 11 | class Portfolio(models.Model): 12 | client = models.OneToOneField(Client,on_delete=models.CASCADE,blank=True,null=True) 13 | 14 | # def __str__(self): 15 | # return self.client.name + "'s Portfolio" 16 | 17 | class Stock(models.Model): 18 | id = models.BigAutoField(primary_key=True) 19 | parent_portfolio = models.ForeignKey(Portfolio,related_name="stocks",on_delete=models.CASCADE,null=True,blank=True) 20 | stock_symbol = models.CharField(max_length=100,null=True) 21 | stock_price = models.CharField(max_length=100,null=True,blank=True) 22 | stock_sector_performance = models.CharField(max_length=100,null=True,blank=True) 23 | stock_name = models.CharField(max_length=100,null=True) 24 | quantity = models.IntegerField(default=0,null=True,blank=True) 25 | date_added = models.DateTimeField(auto_now_add=True) 26 | 27 | # def __str__(self): 28 | # return self.stock_name 29 | -------------------------------------------------------------------------------- /Financely/basic_app/sectorPerformance.py: -------------------------------------------------------------------------------- 1 | import yfinance as yf 2 | import pandas as pd 3 | import numpy as np 4 | from urllib.request import urlopen 5 | import json 6 | def sectorPerformance(ticker): 7 | sec = yf.Ticker(ticker).info['sector'] 8 | # print(sec) 9 | rating = 0 10 | response = urlopen("https://financialmodelingprep.com/api/v3/stock/sectors-performance?apikey=d55bd9a8a60f1a0d29e6673e4a46cd3e") 11 | data = json.loads(response.read().decode("utf-8")) 12 | for x in data['sectorPerformance']: 13 | if x['sector'] == sec: 14 | rating = float(x['changesPercentage'][:-1]) 15 | break 16 | if rating>0: 17 | return "Positive" 18 | elif rating<0: 19 | return "Negative" 20 | else: 21 | return "Neutral" 22 | 23 | 24 | #print(sectorPerformance('aapl')) 25 | -------------------------------------------------------------------------------- /Financely/basic_app/sentiment_analysis.py: -------------------------------------------------------------------------------- 1 | from transformers import BertModel, BertTokenizer 2 | import torch 3 | from torch import nn 4 | 5 | RANDOM_SEED = 42 6 | torch.manual_seed(RANDOM_SEED) 7 | 8 | class_names = ['negative', 'neutral', 'positive'] 9 | PRE_TRAINED_MODEL_NAME = 'bert-base-cased' 10 | tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) 11 | 12 | class SentimentClassifier(nn.Module): 13 | def __init__(self, n_classes): 14 | super(SentimentClassifier, self).__init__() 15 | self.bert = BertModel.from_pretrained(PRE_TRAINED_MODEL_NAME) 16 | self.drop = nn.Dropout(p=0.3) 17 | self.out = nn.Linear(self.bert.config.hidden_size, n_classes) 18 | 19 | def forward(self, input_ids, attention_mask): 20 | output = self.bert( 21 | input_ids=input_ids, 22 | attention_mask=attention_mask 23 | ) 24 | pooled_output = output[1] 25 | output = self.drop(pooled_output) 26 | return self.out(output) 27 | 28 | model = SentimentClassifier(len(class_names)) 29 | 30 | model.load_state_dict(torch.load("basic_app/bert_sentiment_analysis.pt", map_location=torch.device('cpu'))) 31 | 32 | 33 | def predict_sentiment(sample_texts): 34 | sentiment = [] 35 | for sample_text in sample_texts: 36 | encoded_review = tokenizer.encode_plus( 37 | sample_text, 38 | max_length=512, 39 | add_special_tokens=True, 40 | return_token_type_ids=False, 41 | pad_to_max_length=True, 42 | return_attention_mask=True, 43 | return_tensors='pt', 44 | ) 45 | 46 | input_ids = encoded_review['input_ids'] 47 | attention_mask = encoded_review['attention_mask'] 48 | 49 | output = model(input_ids, attention_mask) 50 | _, prediction = torch.max(output, dim=1) 51 | 52 | # print(f'Review text: {sample_text}') 53 | # print(f'Sentiment : {class_names[prediction]}') 54 | sentiment.append(class_names[prediction]) 55 | 56 | return sentiment 57 | 58 | # i = predict_sentiment(["he is in a better place","I always lie"]) 59 | # print(i) 60 | # if i<0: 61 | # print("negative") 62 | # elif i>0: 63 | # print("positive") 64 | # else: 65 | # print("neutral") 66 | -------------------------------------------------------------------------------- /Financely/basic_app/stock_data.py: -------------------------------------------------------------------------------- 1 | import yfinance as yf 2 | from datetime import datetime 3 | import pandas as pd 4 | 5 | 6 | def candlestick_data(ticker): 7 | #now = datetime.now() 8 | aapl = yf.Ticker(ticker) 9 | now = datetime.now().date().strftime('%Y-%m-%d') 10 | # data = aapl.history(end=now,period='1mo', interval='1d') 11 | # newdata= data.to_dict() 12 | # print(newdata)'%Y-%m-%d' 13 | old = aapl.history(start="2001-05-21", end=now) 14 | 15 | old = old.reset_index() 16 | for i in ['Open', 'High', 'Close', 'Low']: 17 | 18 | old[i] = old[i].astype('float64') 19 | 20 | cols = old.columns 21 | 22 | cols =cols[:5].values 23 | data = [] 24 | for i,val in old.iterrows(): 25 | d = {} 26 | for c in cols: 27 | d[c] = val[c] 28 | 29 | data.append(d) 30 | 31 | for i in range(len(data)): 32 | timestampStr = data[i]['Date'].date().strftime("%d-%b-%Y") 33 | data[i]['Date'] = timestampStr 34 | 35 | 36 | return(data) 37 | #print(old) 38 | # return data 39 | # final_data = {} 40 | # if(len(passover['Open']) > 0): 41 | # 42 | # open_last = list(passover['Open'].keys())[-1] 43 | # high_last = list(passover['High'].keys())[-1] 44 | # 45 | # low_last = list(passover['Low'].keys())[-1] 46 | # 47 | # close_last = list(passover['Close'].keys())[-1] 48 | # 49 | # final_data = { 50 | # "Open":passover['Open'][open_last], 51 | # "High":passover['High'][high_last], 52 | # "Low":passover['Low'][low_last], 53 | # "Close":passover['Close'][close_last], 54 | # 55 | # } 56 | # 57 | # 58 | # 59 | # return passover['Open'].keys() 60 | 61 | #print(get_data("aapl")) 62 | 63 | def get_data(ticker): 64 | #now = datetime.now() 65 | aapl = yf.Ticker(ticker) 66 | data = aapl.info 67 | return data 68 | 69 | def get_name(ticker): 70 | symbol = yf.Ticker(ticker) 71 | data = symbol.info 72 | print(data) 73 | return(data['shortName']) 74 | 75 | def get_price(ticker): 76 | symbol = yf.Ticker(ticker) 77 | # df =symbol.history(interval='5m') 78 | data = symbol.info 79 | price = symbol.history(interval='5m').iloc[-1].Close 80 | # print(df) 81 | return([price, data['currency']]) 82 | 83 | 84 | 85 | # for a in get_data("aapl"): 86 | # print(a.shortName) 87 | -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__init__.py -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__pycache__/poll_extras.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__pycache__/poll_extras.cpython-37.pyc -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__pycache__/poll_extras.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__pycache__/poll_extras.cpython-38.pyc -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/__pycache__/poll_extras.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/basic_app/templatetags/__pycache__/poll_extras.cpython-39.pyc -------------------------------------------------------------------------------- /Financely/basic_app/templatetags/poll_extras.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter(name='has_group') 6 | def has_group(user, group_name): 7 | return user.groups.filter(name=group_name).exists() 8 | 9 | # @register.filter(name ='get_item') 10 | # def get_item(dictionary, key): 11 | # return d[str(key)] 12 | -------------------------------------------------------------------------------- /Financely/basic_app/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Financely/basic_app/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from basic_app import views 3 | 4 | app_name = 'basic_app' 5 | urlpatterns = [ 6 | path('', views.dashboard,name="dashboard"), 7 | path('home/', views.index, name='index'), 8 | path('profile/',views.profile, name ='profile'), 9 | path('portfolio/', views.portfolio, name='portfolio'), 10 | path('home/', views.stock, name = "stock"), 11 | 12 | path('home//price_prediction', views.price_prediction,name="prediction"), 13 | path('login/', views.loginPage,name="login"), 14 | path('logout/',views.logoutUser,name="logout"), 15 | path('register/',views.registerPage,name="register"), 16 | path('stats/',views.statisticsAdmin,name = "stats"), 17 | path('home//add', views.addToPortfolio, name = "addToPortfolio"), 18 | path('portfolio//remove',views.removeFromPortfolio,name="removeFromPortfolio"), 19 | path('portfolio//quantityAdd', views.quantityAdd, name = "quantityAdd"), 20 | path('portfolio//quantitySub', views.quantitySub, name = "quantitySub") 21 | 22 | ] 23 | -------------------------------------------------------------------------------- /Financely/basic_app/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render,redirect 2 | from .models import Portfolio,Client,Stock 3 | from .forms import CreateUserForm 4 | from .sectorPerformance import sectorPerformance 5 | from .decorators import unauthenticated_user,allowed_users 6 | from basic_app.stock_data import candlestick_data,get_data,get_name,get_price 7 | from basic_app.FA import piotroski 8 | # Create your views here. 9 | from django.http import HttpResponse 10 | from django.contrib.auth.forms import UserCreationForm 11 | from django.contrib.auth import authenticate,login,logout 12 | from django.contrib import messages 13 | from django.contrib.auth.models import User,Group 14 | from django.contrib.auth.decorators import login_required 15 | from basic_app.get_news import getNews,getNewsWithSentiment 16 | from basic_app.get_stock_info import getStockInfo 17 | from django.http import JsonResponse 18 | from json import dumps,loads 19 | from basic_app.ProphetTrend import forecast 20 | 21 | def dashboard(request): 22 | return render(request,"basic_app/dashboard.html") 23 | 24 | 25 | 26 | @login_required(login_url='basic_app:login') 27 | @allowed_users(allowed_roles=['Client']) 28 | def index(request): 29 | if request.is_ajax(): 30 | res = None 31 | data = request.POST.get('searchData') 32 | item = getStockInfo(data) 33 | if len(item)>0 and len(data): 34 | res = item 35 | else: 36 | res = 'No stocks found..' 37 | 38 | #print(data) 39 | 40 | return JsonResponse({'data':res}) 41 | 42 | user = request.user 43 | client = Client.objects.get(user=user) 44 | portfolio = Portfolio.objects.get(client=client) 45 | stocks = portfolio.stocks.all() 46 | #print(stocks) 47 | #print(stocks) 48 | news = getNews("business") 49 | #print(news) 50 | context = {'stocks':stocks,'news':news,'page_title':"Home"} 51 | 52 | return render(request,"basic_app/index.html",context) 53 | 54 | @login_required(login_url='basic_app:login') 55 | @allowed_users(allowed_roles=['Client']) 56 | def profile(request): 57 | client = request.user 58 | return render(request,"basic_app/profile.html",{'client':client,'page_title':"User Profile"}) 59 | 60 | @login_required(login_url='basic_app:login') 61 | @allowed_users(allowed_roles=['Client']) 62 | def portfolio(request): 63 | user = request.user 64 | client = Client.objects.get(user=user) 65 | portfolio = Portfolio.objects.get(client=client) 66 | stocks = portfolio.stocks.all() 67 | # Sentiment = {} 68 | # for s in stocks: 69 | # sentiment = 0; 70 | # for i in range(12): 71 | # news = getNewsWithSentiment(s.stock_symbol) 72 | # if news[i]['sentiment'] == 'positive': 73 | # sentiment+=1 74 | # elif news[i]['sentiment'] == 'negative': 75 | # sentiment-=1 76 | # 77 | # if sentiment >0: 78 | # s.stock_sentiment = "Positive" 79 | # elif sentiment<0: 80 | # s.stock_sentiment = "Negative" 81 | # else: 82 | # s.stock_sentiment = "Neutral" 83 | # 84 | SP = {} 85 | for s in stocks: 86 | if(not s.stock_sector_performance): 87 | s.stock_sector_performance = sectorPerformance(s.stock_symbol) 88 | if(not s.stock_price): 89 | price = get_price(s.stock_symbol) 90 | s.stock_price = str(round(price[0],2))+ " " + price[1] 91 | s.save() 92 | 93 | context = {'stocks':stocks,'page_title':"Your Portfolio"} 94 | return render(request,"basic_app/portfolio.html",context) 95 | 96 | @login_required(login_url='basic_app:login') 97 | def stock(request,symbol): 98 | data = candlestick_data(symbol) 99 | item = getStockInfo(symbol) 100 | info = get_data(symbol) 101 | piotroski_score = piotroski(symbol) 102 | news = getNewsWithSentiment(info['shortName']) 103 | print(news) 104 | sentiment_news_chart = {'positive':0,'negative':0,'neutral':0} 105 | for i in range(12): 106 | if news[i]['sentiment'] == 'positive': 107 | sentiment_news_chart['positive']+=1 108 | elif news[i]['sentiment'] == 'negative': 109 | sentiment_news_chart['negative']+=1 110 | else: 111 | sentiment_news_chart['neutral']+=1 112 | print(sentiment_news_chart) 113 | recommendation = False 114 | overall_sentiment = sentiment_news_chart['positive']-sentiment_news_chart["negative"] 115 | if piotroski_score>5 and overall_sentiment>0: 116 | recommendation = True 117 | 118 | print(recommendation) 119 | context ={'data':dumps(data),'item':dumps(item),'info':info,'piotroski_score':piotroski_score,'sentiment_data':dumps(sentiment_news_chart),'page_title':symbol+" Info",'recommendation':recommendation} 120 | if request.is_ajax(): 121 | run = False 122 | res = None 123 | data = request.POST.get('myData') 124 | action = request.POST.get('action') 125 | name = request.POST.get('name') 126 | print(data) 127 | print(name) 128 | user = request.user 129 | print(user) 130 | client = Client.objects.get(user=user) 131 | portfolio = Portfolio.objects.get(client=client) 132 | stocks = portfolio.stocks.all() 133 | for stock in stocks: 134 | if data == stock.stock_symbol: 135 | stock.quantity+=1 136 | stock.save() 137 | run = True 138 | 139 | if run != True: 140 | new_stock = Stock.objects.create(parent_portfolio = portfolio,stock_symbol=data,stock_name=name) 141 | new_stock.quantity = 1; 142 | new_stock.save() 143 | #print(stock) 144 | return JsonResponse({}) 145 | 146 | 147 | 148 | # print('Action:',action) 149 | # print('symbol:',stock_key) 150 | 151 | 152 | # customer = request.user.customer 153 | # product = Product.objects.get(id=productId) 154 | # order, created = Order.objects.get_or_create(customer=customer, complete=False) 155 | # 156 | # orderItem, created = OrderItem.objects.get_or_create(order=order, product=product) 157 | # 158 | # if action == 'add': 159 | # orderItem.quantity = (orderItem.quantity + 1) 160 | # elif action == 'remove': 161 | # orderItem.quantity = (orderItem.quantity - 1) 162 | # 163 | # orderItem.save() 164 | # 165 | # if orderItem.quantity <= 0: 166 | # orderItem.delete() 167 | 168 | 169 | #data['symbol'] = symbol 170 | return render(request,"basic_app/stock.html",context) 171 | 172 | @unauthenticated_user 173 | def loginPage(request): 174 | if request.method == "POST": 175 | username = request.POST.get('username') 176 | password = request.POST.get('password') 177 | 178 | user = authenticate(request,username =username, password=password) 179 | 180 | if user is not None: 181 | login(request,user) 182 | if(user.groups.all()[0].name == 'Admin'): 183 | return redirect("basic_app:stats") 184 | else: 185 | return redirect("basic_app:index") 186 | else: 187 | messages.info(request,"Incorrect username or password") 188 | return redirect("basic_app:login") 189 | 190 | 191 | return render(request,"basic_app/login.html",{'page_title':"Login"}) 192 | 193 | @login_required(login_url='basic_app:login') 194 | def logoutUser(request): 195 | logout(request) 196 | return redirect("basic_app:login") 197 | 198 | @unauthenticated_user 199 | def registerPage(request): 200 | form = CreateUserForm() 201 | if request.method == "POST": 202 | form = CreateUserForm(request.POST) 203 | if form.is_valid(): 204 | user = form.save() 205 | group = Group.objects.get(name='Client') 206 | user.groups.add(group) 207 | client = Client.objects.create(user=user) 208 | portfolio = Portfolio.objects.create(client=client) 209 | return redirect('basic_app:login') 210 | 211 | context = {'form':form,'page_title':"Register"} 212 | return render(request,"basic_app/register.html",context) 213 | 214 | @login_required(login_url='basic_app:login') 215 | @allowed_users(allowed_roles=['Admin']) 216 | def statisticsAdmin(request): 217 | return render(request,"basic_app/statisticsAdmin.html") 218 | 219 | def price_prediction(request,symbol): 220 | price_prediction = forecast(symbol) 221 | return render(request,"basic_app/price_prediction.html",{'price_prediction':price_prediction,'page_title':"Price Prediction"}) 222 | 223 | def addToPortfolio(request,symbol): 224 | user = request.user 225 | run =False 226 | print(user) 227 | client = Client.objects.get(user=user) 228 | portfolio = Portfolio.objects.get(client=client) 229 | stocks = portfolio.stocks.all() 230 | for stock in stocks: 231 | if symbol == stock.stock_symbol: 232 | stock.quantity+=1 233 | stock.save() 234 | run = True 235 | 236 | name = get_name(symbol) 237 | if run != True: 238 | new_stock = Stock.objects.create(parent_portfolio = portfolio,stock_symbol=symbol,stock_name=name) 239 | new_stock.quantity = 1; 240 | new_stock.save() 241 | #print(stock) 242 | return redirect('basic_app:portfolio') 243 | 244 | 245 | def removeFromPortfolio(request,symbol): 246 | user = request.user 247 | print(user) 248 | client = Client.objects.get(user=user) 249 | portfolio = Portfolio.objects.get(client=client) 250 | stocks = portfolio.stocks.all() 251 | for stock in stocks: 252 | if symbol == stock.stock_symbol: 253 | stock.delete() 254 | 255 | return redirect("basic_app:portfolio") 256 | 257 | 258 | def quantityAdd(request,symbol): 259 | user = request.user 260 | print(user) 261 | client = Client.objects.get(user=user) 262 | portfolio = Portfolio.objects.get(client=client) 263 | stocks = portfolio.stocks.all() 264 | for stock in stocks: 265 | if symbol == stock.stock_symbol: 266 | stock.quantity+=1 267 | stock.save() 268 | return redirect("basic_app:portfolio") 269 | 270 | def quantitySub(request,symbol): 271 | user = request.user 272 | print(user) 273 | client = Client.objects.get(user=user) 274 | portfolio = Portfolio.objects.get(client=client) 275 | stocks = portfolio.stocks.all() 276 | for stock in stocks: 277 | if symbol == stock.stock_symbol: 278 | stock.quantity-=1 279 | 280 | if stock.quantity == 0: 281 | stock.delete() 282 | else: 283 | stock.save() 284 | 285 | return redirect("basic_app:portfolio") 286 | 287 | 288 | 289 | # def search_results(request): 290 | # if request.is_ajax(): 291 | # data = request.POST.get('searchData') 292 | # return JsonResponse({'data':data}) 293 | # return JsonResponse({}) 294 | 295 | 296 | 297 | # Underdog Stocks(already listed) 298 | # Indian Stocks (you cant go wrong)(fundamentally strong indian companies) 299 | # Upcoming IPOs 300 | # Price Prediction 301 | # Patience 302 | # Company risk 303 | # Most Popular (Stocks,Brokers) 304 | # Information Section(keep learning) 305 | -------------------------------------------------------------------------------- /Financely/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/db.sqlite3 -------------------------------------------------------------------------------- /Financely/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Financely.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Financely/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/static/images/favicon.ico -------------------------------------------------------------------------------- /Financely/static/images/favicon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/Financely/static/images/favicon1.png -------------------------------------------------------------------------------- /Financely/static/js/stock.js: -------------------------------------------------------------------------------- 1 | //console.log("add to portfolio") 2 | var updateBtns = document.getElementsByClassName("update-portfolio"); 3 | 4 | 5 | updateBtns[0].addEventListener("click",function(){ 6 | var stock_key = this.dataset.symbol; 7 | var action = this.dataset.action; 8 | var name = this.dataset.name; 9 | console.log(stock_key + " " + action) 10 | console.log(name) 11 | $.ajax({ 12 | type: 'POST', 13 | url: '', 14 | data: { 15 | 'myData': stock_key, 16 | 'action': action, 17 | 'name': name, 18 | 'csrfmiddlewaretoken': csrftoken 19 | }, 20 | success: console.log('success'), 21 | error: console.log('failure') 22 | }); 23 | 24 | }) 25 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/base.html: -------------------------------------------------------------------------------- 1 | 2 | {% load static %} 3 | {% load poll_extras %} 4 | 5 | 6 | 7 | 8 | 9 | {{page_title}} 10 | 11 | 12 | 13 | 14 | 35 | 36 | 110 | 111 | 200 |
201 |
202 |
203 | {% block content %} 204 | 205 | {% endblock %} 206 |
207 | 208 | 209 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/dashboard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

Welcome to base

10 |

Click here to, Login

11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'basic_app/base.html' %} 2 | {% load static %} 3 | {% block content %} 4 | 5 |
6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 |

Welcome to Financely

17 |
18 | 19 |
20 |
21 |

An AI based financial adviser and portfolio manager. Financely allows users to look up stock quotes and offers streamlined technical 22 | and financial analysis, news analysis, future price predictions and simple 23 | recommendations to buy, sell or hold stocks. Users can also set up there own 24 | portfolios and receive recommendations to maximise profits.

25 |
26 | 27 | 28 |
29 | 30 |
31 |
32 |
33 |

Your Portfolio

34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | {% for stock in stocks %} 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {% endfor %} 52 | 53 |
Stock SymbolStock NameQuantityDate added
{{stock.stock_symbol}}{{stock.stock_name}}{{stock.quantity}}{{stock.date_added}}
54 | 55 |
56 | Go to Portfolio 57 | 58 |
59 | 60 | 61 |
62 |

63 |
64 |

Trending News

65 |
66 |
67 | 68 | {% for key,value in news.items %} 69 |
70 |
71 | Card image cap 72 |
73 |
{{value.title}}
74 |
Source: {{value.source.name}}
75 |

{{value.description}}

76 | See Article 77 |
78 |
79 | 80 |
81 | 82 | 83 | {% endfor %} 84 | 85 | 86 |
87 | 88 | 89 | {% endblock %} 90 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | < 5 | Login 6 | 7 | 8 | 9 | 10 | 72 | 73 | 74 | 75 |
76 |
77 |
78 |
79 |

Login

80 |
81 |
82 | 83 |
84 | {% csrf_token %} 85 |
86 | 87 |
88 | 94 |
95 | 96 | 97 |
98 | 101 |
102 |
103 | {% for message in messages %} 104 |

{{message}}

105 | {% endfor %} 106 |
107 | 110 |
111 |
112 |
113 |
114 | 131 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/portfolio.html: -------------------------------------------------------------------------------- 1 | {% extends 'basic_app/base.html' %} 2 | {% block content %} 3 |
4 |

5 | Manage Portfolio 6 |

7 |
8 |
9 |
10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for stock in stocks %} 23 | 24 | 25 | 26 | 27 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {% endfor %} 39 | 40 | 41 | 42 |
Stock SymbolStock NameQuantityStock PriceSector Performance
{{stock.stock_symbol}}{{stock.stock_name}} 28 | - 29 | {{stock.quantity}} 30 | + 31 | {{stock.stock_price}}{{stock.stock_sector_performance}}Delete
43 | 44 | 45 |
46 | 47 |
48 |
49 |
50 | 51 | 73 | 74 | {% endblock %} 75 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/price_prediction.html: -------------------------------------------------------------------------------- 1 | {% extends "basic_app/base.html" %} 2 | {% block content %} 3 |
4 |

Predicted Price Trend

5 | 6 |
7 | 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/profile.html: -------------------------------------------------------------------------------- 1 | {% extends 'basic_app/base.html' %} 2 | {% block content %} 3 |

User Info, name, pwd, profile_picture etc

4 |

To be done later

5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | < 5 | Login 6 | 7 | 8 | 9 | 10 | 73 | 74 | 75 | 76 |
77 |
78 |
79 |
80 |

Register Account

81 |
82 |
83 | 84 |
85 | {% csrf_token %} 86 |
87 | 88 | {{form.username}} 89 |
90 | 96 |
97 | 98 | {{form.password1}} 99 | 100 |
101 |
102 | 103 | {{form.password2}} 104 |
105 | 106 | 109 |
110 |
111 |

{{form.errors}}

112 |

113 | 116 |
117 |
118 |
119 |
120 | 138 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/statisticsAdmin.html: -------------------------------------------------------------------------------- 1 | {% extends 'basic_app/base.html' %} 2 | {% block content %} 3 |

Welcome here are the statistics for you

4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /Financely/templates/basic_app/stock.html: -------------------------------------------------------------------------------- 1 | {% extends 'basic_app/base.html' %} 2 | {% load static %} 3 | {% block content %} 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 |

{{info.shortName}}

15 | {% if recommendation %} 16 |

We recommend buying this stock

17 | 18 | {% else %} 19 |

We do not recommend buying this stock

20 | {% endif %} 21 | 22 |
23 |
24 | 25 |
26 | Add to Portfolio 27 | 28 | See Price Prediction 29 | 30 | 31 |
32 | 33 | 34 | 35 |
36 | 37 |
38 | 39 |
40 | 41 | 42 | 43 | 44 | 45 |

{{info.longBusinessSummary}}

46 | 47 |
48 |
49 |
50 | 51 |
52 |
53 |
54 |
55 |
56 |

Technical Analysis

57 |
58 |
59 | 60 |
61 | 62 | 63 | 74 | 75 |
76 |
77 | 78 |
79 | 80 |
81 | 82 | 83 |
84 |
85 |
86 | 87 |
88 | 89 | 90 |
91 | 92 |
93 |
94 |
95 |
96 |

Financial Analysis

97 |
98 |

Piotroski Score

99 |

The Piotroski Score is a discrete score between zero and nine that reflects nine criteria used to determine the strength of a firm's financial position. The Piotroski Score is used to determine the best value stocks, with nine being the best and zero being the worst.

100 | More about the Piotroski Score 101 |
102 |
The score for this stock is: {{piotroski_score}}
103 | 104 |
105 |
106 |
107 |
108 | 109 |
110 |
111 |
112 |
113 |
114 |

News Sentiment

115 |
116 | 117 | 118 | 119 | 120 | 121 |
122 | 123 | 124 | 125 |
126 | 127 | 128 |
129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 473 | 474 | 475 | 476 | 477 | {% endblock %} 478 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Dhruv Garg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Financely 2 | 3 |
logo
4 | Financely is an AI based financial adviser and user portfolio management system. The aim of this project is to help people become financially independent by demystifying trading and the stock market and making them more accessible to people without a formal education in the field. 5 | 6 | # Setting up and running the project 7 | 8 | 1. Fork the repo and clone it 9 | ``` 10 | git clone https://github.com/EnigmAI/Financely.git 11 | cd financely 12 | ``` 13 | 2. Activate your conda or virtual Python environment 14 | 3. To download the required packages run the commands below 15 | ``` 16 | pip install -r requirements.txt 17 | ``` 18 | 4. Download our sentiment analysis model from here and place it inside the directory `Financely/basic_app/` 19 | 20 | 5. After the above setup, run the following commands 21 | ``` 22 | python manage.py migrate 23 | python manage.py makemigrations basic_app 24 | python manage.py migrate 25 | ``` 26 | 6. To start the backend server run the following command 27 | ``` 28 | python manage.py runserver 29 | ``` 30 | 7. Open your browser and navigate to the url below 31 | ``` 32 | http://localhost:8000 33 | ``` 34 | 35 | # Models and Analysis 36 | 37 | 1. Technical Analysis Indicators: 38 | - RSI 39 | - MACD 40 | - EMA 41 | - SMA 42 | - OBV 43 | - Pivot Points 44 | 2. Financial Analysis - Piotroski Score 45 | 3. Price Forecasting - Facebook Prophet Model 46 | 4. Sentiment Analysis - Fine-tuned BERT model 47 | 48 | # Preview 49 | 50 | Project Demo Video Link - https://drive.google.com/file/d/1ehs1m1HP4O2smAXmWmnmH4Y-k36jBmf0/view?usp=sharing 51 | 52 | | ![](assets/1.png) | ![](assets/2.png) | 53 | |:------------------|:------------------| 54 | | ![](assets/3.png) | ![](assets/4.png) | 55 | | ![](assets/5.png) | ![](assets/6.png) | 56 | -------------------------------------------------------------------------------- /Tech and Fin analysis/Dataset.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import yfinance as yf 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import talib as ta 6 | plt.style.use('seaborn') 7 | 8 | def generator(ticker): 9 | df = yf.Ticker(ticker).history(period='max') 10 | df['SMA'] = ta.SMA(df['Close'],20) 11 | df['EMA'] = ta.EMA(df['Close'],20) 12 | df['MACD'], df['MACDSIGNAL'], df['MACDHIST'] = ta.MACD(df['Close'],20) 13 | df['RFI'] = ta.RSI(df['Close'],20) 14 | df['ADX'] = ta.ADX(df['High'], df['Low'], df['Close'],20) 15 | df['UpBand'], df['MidBand'], df['LowBand'] = ta.BBANDS(df['Close'], timeperiod =20) 16 | df['OBV'] = ta.OBV(df['Close'], df['Volume']) 17 | # print(df) 18 | return df 19 | 20 | # generator('msft') -------------------------------------------------------------------------------- /Tech and Fin analysis/FA.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import datetime 3 | import yfinance as yf 4 | 5 | def piotroski(ticker): 6 | bs = yf.Ticker(ticker).balance_sheet 7 | inc = yf.Ticker(ticker).financials 8 | cf = yf.Ticker(ticker).cashflow 9 | longTermDebt = bs.loc['Long Term Debt'][0] 10 | longTermDebtPre = bs.loc['Long Term Debt'][1] 11 | totalAssets = bs.loc['Total Assets'][0] 12 | totalAssetsPre = bs.loc['Total Assets'][1] 13 | totalAssetsPre2 = bs.loc['Total Assets'][2] 14 | currentAssets = bs.loc['Total Current Assets'][0] 15 | currentAssetsPre = bs.loc['Total Current Assets'][1] 16 | currentLiabilities = bs.loc['Total Current Liabilities'][0] 17 | currentLiabilitiesPre = bs.loc['Total Current Liabilities'][1] 18 | revenue = inc.loc['Total Revenue'][0] 19 | revenuePre = inc.loc['Total Revenue'][1] 20 | grossProfit = inc.loc['Gross Profit'][0] 21 | grossProfitPre = inc.loc['Gross Profit'][1] 22 | netIncome = inc.loc['Net Income'][0] 23 | netIncomePre = inc.loc['Net Income'][1] 24 | operatingCashFlow = cf.loc['Total Cash From Operating Activities'][0] 25 | operatingCashFlowPre = cf.loc['Total Cash From Operating Activities'][1] 26 | commonStock = bs.loc['Common Stock'][0] 27 | commonStockPre = bs.loc['Common Stock'][1] 28 | ROAFS = int(netIncome/((totalAssets + totalAssetsPre)/2)>0) 29 | CFOFS = int(operatingCashFlow>0) 30 | ROADFS = int((netIncome/((totalAssets + totalAssetsPre)/2))>(netIncomePre/((totalAssetsPre + totalAssetsPre2)))) 31 | CFOROAFS = int((operatingCashFlow/totalAssets)>(netIncome/((totalAssets + totalAssetsPre)/2))) 32 | LTDFS = int(longTermDebt <= longTermDebtPre) 33 | CRFS = int(currentAssets/currentLiabilities)>(currentAssetsPre/currentLiabilitiesPre) 34 | NSFS = int(commonStock <= commonStockPre) 35 | GMFS = int(grossProfit/revenue>grossProfitPre/revenuePre) 36 | ATOFS = int((revenue/((totalAssets + totalAssetsPre)/2))>(revenuePre/((totalAssetsPre + totalAssetsPre2)))) 37 | return ROAFS + CFOFS + ROADFS + CFOROAFS + LTDFS + CRFS + NSFS + GMFS + ATOFS 38 | print(piotroski('msft')) -------------------------------------------------------------------------------- /Tech and Fin analysis/ProphetTrend.py: -------------------------------------------------------------------------------- 1 | from prophet import Prophet 2 | import yfinance as yf 3 | import pandas as pd 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | 7 | def forecast(ticker): 8 | df = yf.Ticker(ticker).history(period='5y', interval = '1d') 9 | df = df[['Close']] 10 | dfx = pd.DataFrame() 11 | dfx['ds'] = pd.to_datetime(df.index) 12 | dfx['y'] = df.Close.values 13 | fbp = Prophet(daily_seasonality = True) 14 | fbp.fit(dfx) 15 | fut = fbp.make_future_dataframe(periods=(365)) 16 | forecast = fbp.predict(fut) 17 | plot = fbp.plot(forecast) 18 | plt.show() 19 | pchange = ((forecast.trend.values[-1] - dfx.y.values[-1])*100)/dfx.y.values[-1] 20 | if pchange > 0: 21 | rating = 1 22 | elif pchange == 0: 23 | rating = 0 24 | else: 25 | rating = -1 26 | return plot, rating 27 | plot, rating = forecast('googl') -------------------------------------------------------------------------------- /Tech and Fin analysis/TA.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import yfinance as yf 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import talib as ta 6 | plt.style.use('seaborn') 7 | 8 | def sma(ticker): 9 | df = yf.Ticker(ticker).history(period='1y') 10 | # print(df.head()) 11 | df['SMA'] = ta.SMA(df['Close'],20) 12 | df[['SMA']].plot(figsize=(12,12)) 13 | # plt.show() 14 | return plt 15 | 16 | def ema(ticker): 17 | df = yf.Ticker(ticker).history(period='1y') 18 | # print(df.head()) 19 | df['EMA'] = ta.EMA(df['Close'],20) 20 | df[['EMA']].plot(figsize=(12,12)) 21 | # plt.show() 22 | return plt 23 | 24 | def macd(ticker): 25 | df = yf.Ticker(ticker).history(period='1y') 26 | # print(df.head()) 27 | df['MACD'], df['MACDSIGNAL'], df['MACDHIST'] = ta.MACD(df['Close'],20) 28 | df[['MACD','MACDSIGNAL', 'MACDHIST']].plot(figsize=(12,12)) 29 | # plt.show() 30 | return plt 31 | 32 | def rsi(ticker): 33 | df = yf.Ticker(ticker).history(period='1y') 34 | # print(df.head()) 35 | df['RSI'] = ta.RSI(df['Close'],20) 36 | df[['RSI']].plot(figsize=(12,12)) 37 | # plt.show() 38 | return plt 39 | 40 | def adx(ticker): 41 | df = yf.Ticker(ticker).history(period='1y') 42 | # print(df.head()) 43 | df['ADX'] = ta.ADX(df['High'], df['Low'], df['Close'],20) 44 | df[['ADX']].plot(figsize=(12,12)) 45 | # plt.show() 46 | return plt 47 | 48 | def bband(ticker): 49 | df = yf.Ticker(ticker).history(period='1y') 50 | # print(df.head()) 51 | df['UpBand'], df['MidBand'], df['LowBand'] = ta.BBANDS(df['Close'], timeperiod =20) 52 | df[['UpBand','MidBand','LowBand']].plot(figsize=(12,12)) 53 | # plt.show() 54 | return plt 55 | 56 | def obv(ticker): 57 | df = yf.Ticker(ticker).history(period='1y') 58 | # print(df.head()) 59 | df['OBV'] = ta.OBV(df['Close'], df['Volume']) 60 | df[['OBV']].plot(figsize=(12,12)) 61 | # plt.show() 62 | return plt 63 | 64 | def pivots(ticker): 65 | df = yf.Ticker(ticker).history(interval='1d').tail(1) 66 | # print(df) 67 | df = df.reset_index(drop=True, inplace=False) 68 | pp = float((df['High'] + df['Low'] + df['Close'])/3) 69 | r1 = float(2*pp - df['Low']) 70 | s1 = float(2*pp - df['High']) 71 | r2 = float(pp + (df['High'] - df['Low'])) 72 | s2 = float(pp - (df['High'] - df['Low'])) 73 | r3 = float(pp + 2*(df['High'] - df['Low'])) 74 | s3 = float(pp - 2*(df['High'] - df['Low'])) 75 | # print(pp, r1, r2, r3, s1, s2, s3) 76 | return pp, r1, r2, r3, s1, s2, s3 77 | 78 | # sma('msft') 79 | # ema('msft') 80 | # macd('msft') 81 | # rsi('msft') 82 | # adx('msft') 83 | # bband('msft') 84 | # obv('msft') 85 | # pivots('hdfcbank.ns') -------------------------------------------------------------------------------- /Tech and Fin analysis/sectorPerformance.py: -------------------------------------------------------------------------------- 1 | import yfinance as yf 2 | import pandas as pd 3 | import numpy as np 4 | from urllib.request import urlopen 5 | import json 6 | def sectorPerformance(ticker): 7 | sec = yf.Ticker(ticker).info['sector'] 8 | # print(sec) 9 | rating = 0 10 | response = urlopen("https://financialmodelingprep.com/api/v3/stock/sectors-performance?apikey=d55bd9a8a60f1a0d29e6673e4a46cd3e") 11 | data = json.loads(response.read().decode("utf-8")) 12 | for x in data['sectorPerformance']: 13 | if x['sector'] == sec: 14 | rating = float(x['changesPercentage'][:-1]) 15 | break 16 | return rating 17 | print(sectorPerformance('msft')) -------------------------------------------------------------------------------- /assets/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/1.png -------------------------------------------------------------------------------- /assets/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/2.png -------------------------------------------------------------------------------- /assets/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/3.png -------------------------------------------------------------------------------- /assets/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/4.png -------------------------------------------------------------------------------- /assets/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/5.png -------------------------------------------------------------------------------- /assets/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/6.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EnigmAI/Financely/11a0e780a684540c81fb76271aca72e3e45904c9/assets/logo.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | arviz @ file:///home/conda/feedstock_root/build_artifacts/arviz_1618947141331/work 2 | asgiref==3.3.4 3 | certifi==2020.12.5 4 | cftime @ file:///D:/bld/cftime_1621553914127/work 5 | chardet==4.0.0 6 | click==8.0.1 7 | colorama==0.4.4 8 | convertdate @ file:///home/conda/feedstock_root/build_artifacts/convertdate_1615678826465/work 9 | cycler==0.10.0 10 | Cython @ file:///D:/bld/cython_1618445481531/work 11 | Django==3.2.3 12 | ephem @ file:///D:/bld/ephem_1602326724695/work 13 | filelock==3.0.12 14 | hijri-converter @ file:///home/conda/feedstock_root/build_artifacts/hijri-converter_1612531902526/work 15 | holidays @ file:///home/conda/feedstock_root/build_artifacts/holidays_1617373843485/work 16 | huggingface-hub==0.0.8 17 | idna==2.10 18 | joblib==1.0.1 19 | kiwisolver @ file:///D:/bld/kiwisolver_1610099948875/work 20 | korean-lunar-calendar @ file:///home/conda/feedstock_root/build_artifacts/korean_lunar_calendar_1589354365811/work 21 | LunarCalendar==0.0.9 22 | lxml==4.6.3 23 | matplotlib @ file:///D:/bld/matplotlib-suite_1620506206452/work 24 | multitasking==0.0.9 25 | netCDF4 @ file:///D:/bld/netcdf4_1618867945328/work 26 | numpy @ file:///D:/bld/numpy_1621506450533/work 27 | olefile @ file:///home/conda/feedstock_root/build_artifacts/olefile_1602866521163/work 28 | packaging @ file:///home/conda/feedstock_root/build_artifacts/packaging_1612459636436/work 29 | pandas @ file:///D:/bld/pandas_1618263791034/work 30 | Pillow @ file:///D:/bld/pillow_1621288193589/work 31 | prophet @ file:///D:/bld/prophet_1618853394287/work 32 | PyMeeus @ file:///home/conda/feedstock_root/build_artifacts/pymeeus_1615809745702/work 33 | pyparsing==2.4.7 34 | PyQt5==5.12.3 35 | PyQt5-sip==4.19.18 36 | PyQtChart==5.12 37 | PyQtWebEngine==5.12.1 38 | pystan==2.19.1.1 39 | python-dateutil==2.8.1 40 | pytz @ file:///home/conda/feedstock_root/build_artifacts/pytz_1612179539967/work 41 | regex==2021.4.4 42 | requests==2.25.1 43 | sacremoses==0.0.45 44 | scipy @ file:///C:/bld/scipy_1619562091939/work 45 | six @ file:///home/conda/feedstock_root/build_artifacts/six_1620240208055/work 46 | sqlparse==0.4.1 47 | tokenizers==0.10.3 48 | torch==1.8.1+cpu 49 | torchaudio==0.8.1 50 | torchvision==0.9.1+cpu 51 | tornado @ file:///D:/bld/tornado_1610094858390/work 52 | tqdm @ file:///home/conda/feedstock_root/build_artifacts/tqdm_1621890532941/work 53 | transformers==4.6.1 54 | typing-extensions @ file:///home/conda/feedstock_root/build_artifacts/typing_extensions_1602702424206/work 55 | urllib3==1.26.5 56 | wincertstore==0.2 57 | xarray @ file:///home/conda/feedstock_root/build_artifacts/xarray_1621474818012/work 58 | yfinance==0.1.59 59 | --------------------------------------------------------------------------------