def api_disconnect(request):
    # context = {}
    # print('Updating values before disconnecting')
    # update_values(request)

    # Resetting all email alerts to False
    reset_email_alerts()

    # Resetting the alarms
    saved_alarms_stocks = StockData.objects.filter(stock_alarm=True)
    for stock in saved_alarms_stocks:
        reset_alarms(stock)

    print('Stopping the IB API...')
    ib_api_wrapper(request,action=STOP_API )
    sleep(2)

    print('Stopping Yahoo scrapers...')
    indices_scrapers(stop=True)

    return 
Esempio n. 2
0
def home(request, table_index=1):
    user = authenticate(username='******', password='******')
    if user is not None:
        login(request, user)

    context = {}
    context['table_index'] = table_index
    ib_api_connected = api_connection_status()
    context['ib_api_connected'] = ib_api_connected
    request.session['table_index'] = table_index

    try:
        context['email_enabled'] = EmailSupport.objects.all().first().enabled
        print(f'EM: {context["email_enabled"]}')
    except:
        email_support = EmailSupport()
        email_support.enabled = False
        email_support.save()

    stock_ref = StockData.objects.all().last()

    # Check if there are any stocks in the DB
    if stock_ref:
        last_update = stock_ref.stock_date
    else:
        last_update = False

    # Checking current sample_ period
    try:
        sample_period = stock_ref.sample_period_14
    except:
        sample_period = None

    context['sample_period_14'] = sample_period

    current_running_threads = threading.active_count()
    print(
        f"ACTIVE THREADS: ***************{current_running_threads}****************"
    )

    stocks = StockData.objects.filter(table_index=table_index)
    context['stocks'] = stocks

    # VALUES UPDATES
    #########################

    #TODO: Replace this update with current database data query.
    # Updating indexes data every time homepage rendered

    # indexes_update_done, indexes_info = indexes_updates(request)

    # if indexes_update_done:
    #     print('Finished updating indexes')
    #     context.update(indexes_info)
    # else:
    #     messages.error(request, 'Failed updating indexes.')
    #     logger.error('Failed updating indexes.')
    #     print('Failed updating indexes.')

    # Stock data will be updated at API connect
    if request.method == 'POST':
        if 'connect_ib_api' in request.POST:

            api_connect(request)

            stocks = StockData.objects.filter(table_index=table_index)
            context['stocks'] = stocks

            ib_api_connected = api_connection_status()
            context['ib_api_connected'] = ib_api_connected

            # Start scraping for indices data
            indices_scrapers()

            return render(request, 'kadima/home.html', context)

        elif 'update_now' in request.POST:
            update_values(request)

        elif 'disconnect_ib_api' in request.POST:
            # print('Stopping the IB API...')
            # ib_api_wrapper(request,action=STOP_API )
            # sleep(2)
            api_disconnect(request)
            context['ib_api_connected'] = api_connection_status()
            return render(request, 'kadima/home.html', context)

        elif 'sort_gap' in request.POST:
            print('>> Gap Sorting <<')
            request.session['sort_by'] = 'gap_1'
            context['sort_by'] = request.session['sort_by']

        elif 'sort_week1' in request.POST:
            print('>> Week1 Sorting <<')
            request.session['sort_by'] = 'week_1'
            context['sort_by'] = request.session['sort_by']

        elif 'sort_week3' in request.POST:
            print('>> Week3 Sorting <<')
            request.session['sort_by'] = 'week_3'
            context['sort_by'] = request.session['sort_by']

        elif 'add_stock' in request.POST:

            stocks_to_add = request.POST.get('stock').split(',')

            # Checking list of current stocks in the DB
            old_stocks = StockData.objects.all()
            old_stocks_list = []
            for stock in old_stocks:
                old_stocks_list.append(stock.id)

            for stock in stocks_to_add:

                stock = stock.strip()

                print(f'Adding stock: {stock}')
                context['stock'] = stock
                try:
                    stock_df = fin_data.get_data_yahoo(stock,
                                                       start=MAX_PAST,
                                                       end=TODAY)
                except Exception as e:
                    messages.error(request, 'Stock does not exists')
                    # return render(request, 'kadima/home.html', context)
                    continue

                stock_data = StockData()

                stock_data.table_index = table_index

                # stock_data.stock_date = stock_df.index[-1]
                stock_data.stock_displayed_date = date_obj_to_date(
                    pd.Timestamp("today"), date_format='slash')

                stock_data.ticker = stock.upper()
                stock_data.stock_price = float("%0.2f" %
                                               stock_df['Close'].iloc[-1])

                stock_data.week_1, stock_data.week_1_min, stock_data.week_1_max = week_values(
                    stock_df, 90)
                stock_data.week_2, stock_data.week_2_min, stock_data.week_2_max = week_values(
                    stock_df, 10)
                stock_data.week_3, stock_data.week_3_min, stock_data.week_3_max = week_values(
                    stock_df, 15)
                stock_data.week_5, stock_data.week_5_min, stock_data.week_5_max = week_values(
                    stock_df, 25)

                stock_data.week_1_color = week_color(stock_data.week_1,
                                                     week3=True)
                stock_data.week_2_color = week_color(stock_data.week_2)
                stock_data.week_3_color = week_color(stock_data.week_3,
                                                     week3=True)
                stock_data.week_5_color = week_color(stock_data.week_5)

                prev_close = round(stock_df.loc[stock_df.index[-2]]['Close'],
                                   2)
                todays_open = round(stock_df.loc[stock_df.index[-1]]['Open'],
                                    2)
                stock_data.prev_close = prev_close
                stock_data.todays_open = todays_open

                gap_1, gap_1_color = gap_1_check(prev_close, todays_open)
                stock_data.gap_1 = gap_1
                stock_data.gap_1_color = gap_1_color

                # Earning dates
                try:
                    try:
                        earnings = yf.Ticker(stock).calendar[0][0]
                    except:
                        try:
                            earnings = yf.Ticker(stock).calendar['Value'][0]
                        except:
                            print(f'No earnings found for {stock}')

                    year = earnings.year
                    month = earnings.month
                    day = earnings.day
                    earnings_date = str(f'{day}/{month}/{year}')

                    earnings_ts = time.mktime(
                        datetime.datetime.strptime(earnings_date,
                                                   "%d/%m/%Y").timetuple())
                    today_ts = datetime.datetime.timestamp(TODAY)
                    earnings_dt = datetime.datetime.fromtimestamp(earnings_ts)
                    today_dt = datetime.datetime.fromtimestamp(today_ts)

                    if (earnings_dt - today_dt).days <= 7 and (
                            earnings_dt - today_dt).days >= 0:
                        stock_data.earnings_warning = "blink-bg"
                        stock_data.earnings_call_displayed = earnings_date
                    elif (earnings_dt - today_dt).days < 0:
                        stock_data.earnings_warning = "PAST"
                        stock_data.earnings_call_displayed = None
                    else:
                        stock_data.earnings_warning = ""
                        stock_data.earnings_call_displayed = earnings_date

                except Exception as e:
                    messages.error(
                        request,
                        'Stock does not have an earnings call date defined.')
                    print(
                        f'Stock {stock} does not have an earnings call date defined.'
                    )
                    earnings = None

                tan_deviation_angle = math.tan(
                    math.radians(settings.DEVIATION_ANGLE))

                # Stock Trend - 30 days sample
                a_stock_30, a_macd_30, a_mfi_30, rsi, week1, week2, week3 = trends(
                    stock, 30)

                # a_stock_30 = stock_regression(stock, 30)
                stock_data.stock_trend_30 = round(a_stock_30, 2)

                # MACD trend
                # a_macd_30 = trend_calculator(stock, 'MACD', period=30)
                stock_data.macd_trend_30 = round(a_macd_30, 2)

                if np.abs(a_macd_30) > tan_deviation_angle:

                    if (a_stock_30 > 0
                            and a_macd_30 < 0) or (a_stock_30 < 0
                                                   and a_macd_30 > 0):
                        stock_data.macd_30_clash = True
                        stock_data.macd_30_color = 'red'
                    elif (a_stock_30 < 0
                          and a_macd_30 < 0) or (a_stock_30 > 0
                                                 and a_macd_30 > 0):
                        stock_data.macd_30_clash = False
                        stock_data.macd_30_color = 'green'

                else:
                    stock_data.macd_30_clash = False
                    stock_data.macd_30_color = 'green'

                # MFI trend
                # a_mfi_30 = trend_calculator(stock, 'MFI', period=30)
                stock_data.money_flow_trend_30 = round(a_mfi_30, 2)

                if np.abs(a_mfi_30) > tan_deviation_angle:

                    if (a_stock_30 > 0 and a_mfi_30 < 0) or (a_stock_30 < 0
                                                             and a_mfi_30 > 0):
                        stock_data.mfi_30_clash = True
                        stock_data.mfi_30_color = 'red'
                    elif (a_stock_30 < 0
                          and a_mfi_30 < 0) or (a_stock_30 > 0
                                                and a_mfi_30 > 0):
                        stock_data.mfi_30_clash = False
                        stock_data.mfi_30_color = 'green'
                else:
                    stock_data.mfi_30_clash = False
                    stock_data.mfi_30_color = 'green'

                # Stock Trend - 14 days sample
                a_stock_14, a_macd_14, a_mfi_14, rsi_14, week1, week2, week3 = trends(
                    stock, 14)  # rsi_14 is just for unpacking. it's not user.

                # a_stock_14 = stock_regression(stock, 14)
                stock_data.stock_trend_14 = round(a_stock_14, 2)

                # MACD trend
                # a_macd_14 = trend_calculator(stock, 'MACD', period=14)
                stock_data.macd_trend_14 = round(a_macd_14, 2)

                if np.abs(a_macd_14) > tan_deviation_angle:

                    if (a_stock_14 > 0
                            and a_macd_14 < 0) or (a_stock_14 < 0
                                                   and a_macd_14 > 0):
                        stock_data.macd_14_clash = True
                        stock_data.macd_14_color = 'red'
                    elif (a_stock_14 < 0
                          and a_macd_14 < 0) or (a_stock_14 > 0
                                                 and a_macd_14 > 0):
                        stock_data.macd_14_clash = False
                        stock_data.macd_14_color = 'green'

                else:
                    stock_data.macd_14_clash = False
                    stock_data.macd_14_color = 'green'

                # MFI trend
                # a_mfi_14 = trend_calculator(stock, 'MFI', period=14)
                stock_data.money_flow_trend_14 = round(a_mfi_14, 2)

                if np.abs(a_mfi_30) > tan_deviation_angle:

                    if (a_stock_14 > 0 and a_mfi_14 < 0) or (a_stock_14 < 0
                                                             and a_mfi_14 > 0):
                        stock_data.mfi_14_clash = True
                        stock_data.mfi_14_color = 'red'
                    elif (a_stock_14 < 0
                          and a_mfi_14 < 0) or (a_stock_14 > 0
                                                and a_mfi_14 > 0):
                        stock_data.mfi_14_clash = False
                        stock_data.mfi_14_color = 'green'
                else:
                    stock_data.mfi_14_clash = False
                    stock_data.mfi_14_color = 'green'

                # RSI
                # rsi = last_rsi(stock, period=30)
                stock_data.rsi = rsi
                if rsi > 0 and rsi <= 30:
                    stock_data.rsi_color = 'red'
                elif rsi > 30 and rsi <= 65:
                    stock_data.rsi_color = 'orange'
                elif rsi > 65 and rsi <= 100:
                    stock_data.rsi_color = 'green'
                else:
                    stock_data.rsi_color = ''

                try:
                    stock_data.save()
                except Exception as e:
                    print(f'ERROR Adding Stock. Reason: {e}')
                    messages.error(
                        request,
                        f'Stock {stock} was not added. Already in the list.')
                    return render(request, 'kadima/home.html', context)

            new_stocks = StockData.objects.filter(
                table_index=table_index).order_by('week_3')
            context['stocks'] = new_stocks

            ## Updating the streaming IB API data with added stock
            new_stocks_api = StockData.objects.all()
            new_stocks_list = dict()
            for stock in new_stocks_api:
                new_stocks_list[stock.id] = stock.ticker

            if api_connection_status():
                ib_api_wrapper(request,
                               old_stocks_list,
                               new_stocks_list,
                               action=UPADATE_STOCKS)

            return render(request, 'kadima/home.html', context)

        ## Enable email support
        elif 'email_enable' in request.POST:
            print('>> Enable Email <<')
            try:
                email_enable = EmailSupport.objects.all().first()
                if email_enable.enabled:
                    email_enable.enabled = False
                    context['email_enabled'] = False
                    email_enable.save()

                    # Resetting all email alerts to False
                    reset_email_alerts()

                else:
                    email_enable.enabled = True
                    context['email_enabled'] = True
                    email_enable.save()
            except:
                email_enable = EmailSupport()
                email_enable.enabled = True
                context['email_enabled'] = True
                email_enable.save()

        # Update sample period for MACD and MFI calculations
        elif 'sample_period' in request.POST:
            print('>> Sampling <<')
            stocks = StockData.objects.all()
            for stock in stocks:
                if request.POST['sample_period'] == '14':
                    stock.sample_period_14 = True
                    stock.save()
                    context['sample_period_14'] = True

                else:
                    stock.sample_period_14 = False
                    stock.save()
                    context['sample_period_14'] = False

        # Stock Delete
        elif 'delete_stock' in request.POST:
            print('>> Deleting <<')
            old_stocks = StockData.objects.all()
            old_stocks_list = []
            for stock in old_stocks:
                old_stocks_list.append(stock.id)

            # Deleting a stock from DB
            delete_stock = StockData.objects.filter(
                pk=request.POST["delete_stock"])
            delete_stock.delete()
            new_stocks = StockData.objects.filter(
                table_index=table_index).order_by('week_3')
            context['stocks'] = new_stocks

            ## Updating the streaming IB API data with deleted stock
            new_stocks_api = StockData.objects.all()
            new_stocks_list = dict()
            for stock in new_stocks_api:
                new_stocks_list[stock.id] = stock.ticker

            if api_connection_status():
                ib_api_wrapper(request,
                               old_stocks_list,
                               new_stocks_list,
                               action=UPADATE_STOCKS)
            # ib_api_wrapper(request,old_stocks_list=old_stocks_list, updated_stock_list=new_stocks_list, action=UPADATE_STOCKS)

            return render(request, 'kadima/home.html', context)

        # Save stock to history
        elif 'save_stock' in request.POST:
            print('>> Saving <<')
            stock_id = request.POST['save_stock']
            stock_data = StockData.objects.get(id=stock_id)
            stock_data.saved_to_history = True
            stock_data.save()

            history_stock = HistoryStock.objects.create(
                table_index=table_index,
                ticker=stock_data.ticker,
                stock_price=stock_data.stock_price,
                week_1=stock_data.week_1,
                week_1_color=stock_data.week_1_color,
                week_2=stock_data.week_2,
                week_2_color=stock_data.week_2_color,
                week_3=stock_data.week_3,
                week_3_color=stock_data.week_3_color,
                week_5=stock_data.week_5,
                week_5_color=stock_data.week_5_color,
                gap_1=stock_data.gap_1,
                gap_1_color=stock_data.gap_1_color,
                earnings_call_displayed=stock_data.earnings_call_displayed)

            messages.success(
                request,
                f"Stock was saved. You can review it's data on the History page."
            )

            stocks = StockData.objects.filter(
                table_index=table_index).order_by('week_3')
            context['stocks'] = stocks
            return render(request, 'kadima/home.html', context)

        elif 'alarm_stock' in request.POST:
            print('>> Alarm Stock <<')
            stock_id = request.POST['alarm_stock']
            stock_data = StockData.objects.get(id=stock_id)
            stock_data.stock_alarm = True
            stock_data.stock_load_price = stock_data.stock_current_price
            stock_data.save()
            messages.info(
                request,
                f"Stock {stock_data.ticker} was added to alarm page. You can trigger value alarms on the Alarms page."
            )

            stocks = StockData.objects.filter(
                table_index=table_index).order_by('week_3')
            context['stocks'] = stocks
            return render(request, 'kadima/home.html', context)

        else:
            stocks = StockData.objects.filter(
                table_index=table_index).order_by('week_3')
            context['stocks'] = stocks

            return render(request, 'kadima/home.html', context)

    else:
        stocks = StockData.objects.filter(
            table_index=table_index).order_by('week_3')
        context['stocks'] = stocks
        return render(request, 'kadima/home.html', context)

    return render(request, 'kadima/home.html', context)
Esempio n. 3
0
def history_all(request):
    user = authenticate(username='******', password='******')
    if user is not None:
        login(request, user)

    context = {}
    # history_stocks = HistoryStock.objects.filter(table_index=table_index)
    history_stocks = HistoryStock.objects.all()

    # Calculate sum of all total profits
    sum_total_profit = 0
    if history_stocks:
        for hs in history_stocks:
            sum_total_profit += hs.total_profit

        context['sum_total_profit'] = sum_total_profit

    context['email_enabled'] = EmailSupport.objects.all().first().enabled
    context['history_stocks'] = history_stocks
    # context['table_index'] = table_index
    # request.session['table_index'] = table_index

    ib_api_connected = api_connection_status()
    context['ib_api_connected'] = ib_api_connected

    if request.method == 'POST':

        if 'connect_ib_api' in request.POST:

            api_connect(request)
            ib_api_connected = api_connection_status()
            context['ib_api_connected'] = ib_api_connected

            # Start scraping for indices data
            indices_scrapers()

            return render(request, 'kadima/history.html', context)

        elif 'disconnect_ib_api' in request.POST:
            api_disconnect(request)
            # context = {}
            ib_api_connected = api_connection_status()
            context['ib_api_connected'] = ib_api_connected
            return render(request, 'kadima/history.html', context)

        elif 'update_stock' in str(request.POST):

            stock_id = request.POST.get('update_stock')

            stock_data = HistoryStock.objects.get(id=stock_id)

            stocks_bought = request.POST.get(f'stocks_bought_{stock_id}')
            purchase_price = request.POST.get(
                f'stock_purchase_price_{stock_id}')

            stocks_sold = request.POST.get(f'stocks_sold_{stock_id}')
            selling_price = request.POST.get(f'selling_price_{stock_id}')

            if stocks_bought:
                stock_data.stocks_bought = float(stocks_bought)

            if purchase_price:
                stock_data.purchase_price = float(purchase_price)

            if stocks_sold:
                stock_data.stocks_sold = float(stocks_sold)

            if selling_price:
                stock_data.selling_price = float(selling_price)

            if stocks_bought and purchase_price and stocks_sold and selling_price:
                stock_data.profit = round(
                    (stock_data.stocks_sold * stock_data.selling_price) -
                    (stock_data.stocks_bought * stock_data.purchase_price), 3)
                stock_data.sold_date = str(datetime.datetime.today())
            elif stock_data.stocks_bought and stock_data.purchase_price and stocks_sold and selling_price:
                stock_data.profit = round(
                    (stock_data.stocks_sold * stock_data.selling_price) -
                    (stock_data.stocks_bought * stock_data.purchase_price), 3)
                stock_data.sold_date = str(datetime.datetime.today())
            elif stock_data.stocks_bought and stock_data.purchase_price and stock_data.stocks_sold and selling_price:
                stock_data.profit = round(
                    (stock_data.stocks_sold * stock_data.selling_price) -
                    (stock_data.stocks_bought * stock_data.purchase_price), 3)
                stock_data.sold_date = str(datetime.datetime.today())
            elif stock_data.stocks_bought and stock_data.purchase_price and stocks_sold and stock_data.selling_price:
                stock_data.profit = round(
                    (stock_data.stocks_sold * stock_data.selling_price) -
                    (stock_data.stocks_bought * stock_data.purchase_price), 3)
                stock_data.sold_date = str(datetime.datetime.today())

            try:
                stock_data.dividends = float(
                    request.POST.get(f'dividends_{stock_id}'))
            except:
                pass

            if stock_data.profit:
                stock_data.total_profit = round(
                    stock_data.profit + stock_data.dividends, 3)

            stock_data.save()

            return redirect(request.META['HTTP_REFERER'])

        ## Enable email support
        elif 'email_enable' in request.POST:
            print('>> Enable Email <<')
            try:
                email_enable = EmailSupport.objects.all().first()
                if email_enable.enabled:
                    email_enable.enabled = False
                    context['email_enabled'] = False
                    email_enable.save()

                    # Resetting all email alerts to False
                    reset_email_alerts()

                else:
                    email_enable.enabled = True
                    context['email_enabled'] = True
                    email_enable.save()
            except:
                email_enable = EmailSupport()
                email_enable.enabled = True
                context['email_enabled'] = True
                email_enable.save()

        elif 'delete_stock' in request.POST:
            stock_id = request.POST['delete_stock']

            # stock_data = StockData.objects.get(id=stock_id)
            # stock_data.saved_to_history = False
            # stock_data.save()
            delete_from_history = HistoryStock.objects.get(id=stock_id)
            delete_from_history.delete()
            # saved_stocks = StockData.objects.filter(saved_to_history=True)
            # history_stocks = HistoryStock.objects.filter(table_index=table_index)
            # context['history_stocks'] = history_stocks
            # return redirect(request.META['HTTP_REFERER'])

            return HttpResponseRedirect(request.path_info)

        # Filter history stocks according to dates range
        elif 'date_picker' in request.POST:

            if request.POST['datetimepicker1']:
                start_date_arr = request.POST['datetimepicker1'].split('-')
                start_year, start_month, start_day = start_date_arr
                start = datetime.datetime(day=int(start_day),
                                          month=int(start_month),
                                          year=int(start_year))
            else:
                messages.error(request,
                               'Please pick a start date for the filter.')
                return redirect(request.META['HTTP_REFERER'])

            if request.POST['datetimepicker2']:
                end_date_arr = request.POST['datetimepicker2'].split('-')
                end_year, end_month, end_day = end_date_arr
                end = datetime.datetime(day=int(end_day),
                                        month=int(end_month),
                                        year=int(end_year))
            else:
                messages.error(request,
                               'Please pick a end date for the filter.')
                return redirect(request.META['HTTP_REFERER'])

            filtered_stocks = HistoryStock.objects.filter(
                time_added__range=[start, end])

            # Calculate sum of all total profits
            sum_total_profit = 0
            if history_stocks:
                for hs in filtered_stocks:
                    sum_total_profit += hs.total_profit

                context['sum_total_profit'] = sum_total_profit

            context['history_stocks'] = filtered_stocks
            # return HttpResponseRedirect(request.path_info)
            # return render(request, 'kadima/history.html', context)
            return render(request, 'kadima/history-all.html', context)

        elif 'reset_filter' in request.POST:
            # history_stocks = StockData.objects.filter(saved_to_history=True)
            # context['history_stocks'] = history_stocks
            # return HttpResponseRedirect(request.path_info)
            # return render(request, 'kadima/history.html', context)
            return redirect(request.META['HTTP_REFERER'])

        elif 'export_table' in request.POST:

            return redirect('export_data')

        else:
            # saved_stocks = StockData.objects.filter(saved_to_history=True)
            # context['history_stocks'] = saved_stocks
            # return render(request, 'kadima/history.html', context)
            return redirect(request.META['HTTP_REFERER'])

    # return render(request, 'kadima/history.html', context)
    return render(request, 'kadima/history-all.html', context)
Esempio n. 4
0
def home(request, table_index=1):
    user = authenticate(username="******", password="******")
    if user is not None:
        login(request, user)

    context = {}
    context["table_index"] = table_index
    ib_api_connected = api_connection_status()
    context["ib_api_connected"] = ib_api_connected
    request.session["table_index"] = table_index

    try:
        context["email_enabled"] = EmailSupport.objects.all().first().enabled
        print(f'Email Enabled: {context["email_enabled"]}')
    except:
        email_support = EmailSupport()
        email_support.enabled = False
        email_support.save()

    stock_ref = StockData.objects.all().last()

    # Check if there are any stocks in the DB
    if stock_ref:
        last_update = stock_ref.stock_date
    else:
        last_update = False

    # Checking current sample_ period
    try:
        sample_period = stock_ref.sample_period_14
    except:
        sample_period = None

    context["sample_period_14"] = sample_period

    current_running_threads = threading.active_count()
    print(
        f"ACTIVE THREADS: ***************{current_running_threads}****************"
    )

    stocks = StockData.objects.filter(table_index=table_index)
    none_stocks = StockData.objects.filter(
        Q(table_index=table_index)
        & (Q(gap_1=None) | Q(week_1=None) | Q(week_3=None)
           | Q(stock_price=None)))

    if len(none_stocks) > 0:
        missing_data = True
    else:
        missing_data = False

    # default sorting
    try:
        print(f"{request.session['sort_by']=}")
        context["sort_by"] = request.session["sort_by"]
    except:
        request.session["sort_by"] = "ticker"
        context["sort_by"] = request.session["sort_by"]

    context["stocks"] = stocks

    # VALUES UPDATES
    #########################

    # TODO: Replace this update with current database data query.
    # Updating indexes data every time homepage rendered

    # indexes_update_done, indexes_info = indexes_updates(request)

    # if indexes_update_done:
    #     print('Finished updating indexes')
    #     context.update(indexes_info)
    # else:
    #     messages.error(request, 'Failed updating indexes.')
    #     logger.error('Failed updating indexes.')
    #     print('Failed updating indexes.')

    # Stock data will be updated at API connect
    if request.method == "POST":

        if "connect_ib_api" in request.POST:

            api_connect(request)

            stocks = StockData.objects.filter(table_index=table_index)
            context["stocks"] = stocks

            ib_api_connected = api_connection_status()
            context["ib_api_connected"] = ib_api_connected

            # Start scraping for indices data
            indices_scrapers()

            return render(request, "kadima/home.html", context)

        elif "update_now" in request.POST:
            update_values(request)

        elif "disconnect_ib_api" in request.POST:
            # print('Stopping the IB API...')
            # ib_api_wrapper(request,action=STOP_API )
            # sleep(2)
            api_disconnect(request)
            context["ib_api_connected"] = api_connection_status()
            return render(request, "kadima/home.html", context)

        elif "sort_gap" in request.POST:
            print(">> Gap Sorting <<")
            if missing_data:
                messages.error(
                    request,
                    "Table might not sort poperly due to missing stock information. Please remove stocks with None and try again.",
                )
                return redirect(request.META["HTTP_REFERER"])
            else:
                request.session["sort_by"] = "gap_1"
                context["sort_by"] = "gap_1"

        elif "sort_week1" in request.POST:
            print(">> Week1 Sorting <<")
            if missing_data:
                messages.error(
                    request,
                    "Table might not sort poperly due to missing stock information. Please remove stocks with None and try again.",
                )
                return redirect(request.META["HTTP_REFERER"])
            else:
                request.session["sort_by"] = "week_1"
                context["sort_by"] = "week_1"

        elif "sort_week3" in request.POST:
            print(">> Week3 Sorting <<")
            if missing_data:
                messages.error(
                    request,
                    "Table might not sort poperly due to missing stock information. Please remove stocks with None and try again.",
                )
                return redirect(request.META["HTTP_REFERER"])
            else:
                request.session["sort_by"] = "week_3"
                context["sort_by"] = "week_3"

        elif "add_stock" in request.POST:
            try:

                stocks_to_add = request.POST.get("stock").split(",")

                # Checking list of current stocks in the DB
                old_stocks = StockData.objects.all()
                old_stocks_list = []
                for stock in old_stocks:
                    old_stocks_list.append(stock.id)

                for stock in stocks_to_add:

                    stock = stock.strip()

                    print(f"Adding stock: {stock}")
                    logger.info(f"Adding stock: {stock}")
                    context["stock"] = stock
                    try:
                        stock_df = yf.download(stock, period="1mo")
                    except Exception as e:
                        print(f"Failed getting stock. ERROR: {e}")
                        logger.error(f"Failed getting stock. ERROR: {e}")
                        messages.error(request, "Stock does not exists")
                        # return render(request, 'kadima/home.html', context)
                        continue

                    stock_data = StockData()

                    stock_data.table_index = table_index

                    # stock_data.stock_date = stock_df.index[-1]
                    stock_data.stock_displayed_date = date_obj_to_date(
                        pd.Timestamp("today"), date_format="slash")

                    stock_data.ticker = stock.upper()
                    stock_data.stock_price = float("%0.2f" %
                                                   stock_df["Close"].iloc[-1])

                    (
                        stock_data.week_1,
                        stock_data.week_1_min,
                        stock_data.week_1_max,
                    ) = week_values(stock_df, 90)
                    (
                        stock_data.week_2,
                        stock_data.week_2_min,
                        stock_data.week_2_max,
                    ) = week_values(stock_df, 10)
                    (
                        stock_data.week_3,
                        stock_data.week_3_min,
                        stock_data.week_3_max,
                    ) = week_values(stock_df, 15)
                    (
                        stock_data.week_5,
                        stock_data.week_5_min,
                        stock_data.week_5_max,
                    ) = week_values(stock_df, 25)

                    stock_data.week_1_color = week_color(stock_data.week_1,
                                                         week3=True)
                    stock_data.week_2_color = week_color(stock_data.week_2)
                    stock_data.week_3_color = week_color(stock_data.week_3,
                                                         week3=True)
                    stock_data.week_5_color = week_color(stock_data.week_5)

                    prev_close = round(
                        stock_df.loc[stock_df.index[-2]]["Close"], 2)
                    todays_open = round(
                        stock_df.loc[stock_df.index[-1]]["Open"], 2)
                    stock_data.prev_close = prev_close
                    stock_data.todays_open = todays_open

                    gap_1, gap_1_color = gap_1_check(prev_close, todays_open)
                    stock_data.gap_1 = gap_1
                    stock_data.gap_1_color = gap_1_color

                    # Earning dates
                    try:
                        try:
                            earnings = yf.Ticker(stock).calendar[0][0]
                        except:
                            try:
                                earnings = yf.Ticker(
                                    stock).calendar["Value"][0]
                            except:
                                print(f"No earnings found for {stock}")

                        year = earnings.year
                        month = earnings.month
                        day = earnings.day
                        earnings_date = str(f"{day}/{month}/{year}")

                        earnings_ts = time.mktime(
                            datetime.datetime.strptime(earnings_date,
                                                       "%d/%m/%Y").timetuple())
                        today_ts = datetime.datetime.timestamp(TODAY)
                        earnings_dt = datetime.datetime.fromtimestamp(
                            earnings_ts)
                        today_dt = datetime.datetime.fromtimestamp(today_ts)

                        if (earnings_dt - today_dt).days <= 7 and (
                                earnings_dt - today_dt).days >= 0:
                            stock_data.earnings_warning = "blink-bg"
                            stock_data.earnings_call_displayed = earnings_date
                        elif (earnings_dt - today_dt).days < 0:
                            stock_data.earnings_warning = "PAST"
                            stock_data.earnings_call_displayed = None
                        else:
                            stock_data.earnings_warning = ""
                            stock_data.earnings_call_displayed = earnings_date

                    except Exception as e:
                        messages.error(
                            request,
                            "Stock does not have an earnings call date defined.",
                        )
                        print(
                            f"Stock {stock} does not have an earnings call date defined."
                        )
                        earnings = None

                    tan_deviation_angle = math.tan(
                        math.radians(settings.DEVIATION_ANGLE))

                    # Stock Trend - 30 days sample
                    a_stock_30, a_macd_30, a_mfi_30, rsi, week1, week2, week3 = trends(
                        stock, 30)

                    # a_stock_30 = stock_regression(stock, 30)
                    stock_data.stock_trend_30 = round(a_stock_30, 2)

                    # MACD trend
                    # a_macd_30 = trend_calculator(stock, 'MACD', period=30)
                    stock_data.macd_trend_30 = round(a_macd_30, 2)

                    if np.abs(a_macd_30) > tan_deviation_angle:

                        if (a_stock_30 > 0
                                and a_macd_30 < 0) or (a_stock_30 < 0
                                                       and a_macd_30 > 0):
                            stock_data.macd_30_clash = True
                            stock_data.macd_30_color = "red"
                        elif (a_stock_30 < 0
                              and a_macd_30 < 0) or (a_stock_30 > 0
                                                     and a_macd_30 > 0):
                            stock_data.macd_30_clash = False
                            stock_data.macd_30_color = "green"

                    else:
                        stock_data.macd_30_clash = False
                        stock_data.macd_30_color = "green"

                    # MFI trend
                    # a_mfi_30 = trend_calculator(stock, 'MFI', period=30)
                    stock_data.money_flow_trend_30 = round(a_mfi_30, 2)

                    if np.abs(a_mfi_30) > tan_deviation_angle:

                        if (a_stock_30 > 0
                                and a_mfi_30 < 0) or (a_stock_30 < 0
                                                      and a_mfi_30 > 0):
                            stock_data.mfi_30_clash = True
                            stock_data.mfi_30_color = "red"
                        elif (a_stock_30 < 0
                              and a_mfi_30 < 0) or (a_stock_30 > 0
                                                    and a_mfi_30 > 0):
                            stock_data.mfi_30_clash = False
                            stock_data.mfi_30_color = "green"
                    else:
                        stock_data.mfi_30_clash = False
                        stock_data.mfi_30_color = "green"

                    # Stock Trend - 14 days sample
                    (
                        a_stock_14,
                        a_macd_14,
                        a_mfi_14,
                        rsi_14,
                        week1,
                        week2,
                        week3,
                    ) = trends(
                        stock,
                        14)  # rsi_14 is just for unpacking. it's not user.

                    # a_stock_14 = stock_regression(stock, 14)
                    stock_data.stock_trend_14 = round(a_stock_14, 2)

                    # MACD trend
                    # a_macd_14 = trend_calculator(stock, 'MACD', period=14)
                    stock_data.macd_trend_14 = round(a_macd_14, 2)

                    if np.abs(a_macd_14) > tan_deviation_angle:

                        if (a_stock_14 > 0
                                and a_macd_14 < 0) or (a_stock_14 < 0
                                                       and a_macd_14 > 0):
                            stock_data.macd_14_clash = True
                            stock_data.macd_14_color = "red"
                        elif (a_stock_14 < 0
                              and a_macd_14 < 0) or (a_stock_14 > 0
                                                     and a_macd_14 > 0):
                            stock_data.macd_14_clash = False
                            stock_data.macd_14_color = "green"

                    else:
                        stock_data.macd_14_clash = False
                        stock_data.macd_14_color = "green"

                    # MFI trend
                    # a_mfi_14 = trend_calculator(stock, 'MFI', period=14)
                    stock_data.money_flow_trend_14 = round(a_mfi_14, 2)

                    if np.abs(a_mfi_30) > tan_deviation_angle:

                        if (a_stock_14 > 0
                                and a_mfi_14 < 0) or (a_stock_14 < 0
                                                      and a_mfi_14 > 0):
                            stock_data.mfi_14_clash = True
                            stock_data.mfi_14_color = "red"
                        elif (a_stock_14 < 0
                              and a_mfi_14 < 0) or (a_stock_14 > 0
                                                    and a_mfi_14 > 0):
                            stock_data.mfi_14_clash = False
                            stock_data.mfi_14_color = "green"
                    else:
                        stock_data.mfi_14_clash = False
                        stock_data.mfi_14_color = "green"

                    # RSI
                    # rsi = last_rsi(stock, period=30)
                    stock_data.rsi = rsi
                    if rsi > 0 and rsi <= 30:
                        stock_data.rsi_color = "red"
                    elif rsi > 30 and rsi <= 65:
                        stock_data.rsi_color = "orange"
                    elif rsi > 65 and rsi <= 100:
                        stock_data.rsi_color = "green"
                    else:
                        stock_data.rsi_color = ""

                    try:
                        stock_data.save()
                    except Exception as e:
                        print(f"ERROR Adding Stock. Reason: {e}")
                        messages.error(
                            request,
                            f"Stock {stock} was not added. Already in the list.",
                        )
                        return render(request, "kadima/home.html", context)

                new_stocks = StockData.objects.filter(
                    table_index=table_index).order_by("week_3")
                context["stocks"] = new_stocks

                ## Updating the streaming IB API data with added stock
                new_stocks_api = StockData.objects.all()
                new_stocks_list = dict()
                for stock in new_stocks_api:
                    new_stocks_list[stock.id] = stock.ticker

                if api_connection_status():
                    ib_api_wrapper(request,
                                   old_stocks_list,
                                   new_stocks_list,
                                   action=UPADATE_STOCKS)

            except Exception as e:
                print(f"Failed adding stock. ERROR: {e}")
                logger.error(f"Failed adding stock. ERROR: {e}")

            return render(request, "kadima/home.html", context)

        ## Enable email support
        elif "email_enable" in request.POST:
            print(">> Enable Email <<")
            try:
                email_enable = EmailSupport.objects.all().first()
                if email_enable.enabled:
                    email_enable.enabled = False
                    context["email_enabled"] = False
                    email_enable.save()

                    # Resetting all email alerts to False
                    reset_email_alerts()

                else:
                    email_enable.enabled = True
                    context["email_enabled"] = True
                    email_enable.save()
            except:
                email_enable = EmailSupport()
                email_enable.enabled = True
                context["email_enabled"] = True
                email_enable.save()

        # Update sample period for MACD and MFI calculations
        elif "sample_period" in request.POST:
            print(">> Sampling <<")
            stocks = StockData.objects.all()
            for stock in stocks:
                if request.POST["sample_period"] == "14":
                    stock.sample_period_14 = True
                    stock.save()
                    context["sample_period_14"] = True

                else:
                    stock.sample_period_14 = False
                    stock.save()
                    context["sample_period_14"] = False

        # Stock Delete
        elif "delete_stock" in request.POST:
            print(">> Deleting <<")
            old_stocks = StockData.objects.all()
            old_stocks_list = []
            for stock in old_stocks:
                old_stocks_list.append(stock.id)

            # Deleting a stock from DB
            delete_stock = StockData.objects.filter(
                pk=request.POST["delete_stock"])
            delete_stock.delete()
            new_stocks = StockData.objects.filter(
                table_index=table_index).order_by("week_3")
            context["stocks"] = new_stocks

            ## Updating the streaming IB API data with deleted stock
            new_stocks_api = StockData.objects.all()
            new_stocks_list = dict()
            for stock in new_stocks_api:
                new_stocks_list[stock.id] = stock.ticker

            if api_connection_status():
                ib_api_wrapper(request,
                               old_stocks_list,
                               new_stocks_list,
                               action=UPADATE_STOCKS)
            # ib_api_wrapper(request,old_stocks_list=old_stocks_list, updated_stock_list=new_stocks_list, action=UPADATE_STOCKS)

            return render(request, "kadima/home.html", context)

        # Save stock to history
        elif "save_stock" in request.POST:
            print(">> Saving <<")
            stock_id = request.POST["save_stock"]
            stock_data = StockData.objects.get(id=stock_id)
            stock_data.saved_to_history = True
            stock_data.save()

            history_stock = HistoryStock.objects.create(
                table_index=table_index,
                ticker=stock_data.ticker,
                stock_price=stock_data.stock_price,
                week_1=stock_data.week_1,
                week_1_color=stock_data.week_1_color,
                week_2=stock_data.week_2,
                week_2_color=stock_data.week_2_color,
                week_3=stock_data.week_3,
                week_3_color=stock_data.week_3_color,
                week_5=stock_data.week_5,
                week_5_color=stock_data.week_5_color,
                gap_1=stock_data.gap_1,
                gap_1_color=stock_data.gap_1_color,
                earnings_call_displayed=stock_data.earnings_call_displayed,
            )

            messages.success(
                request,
                f"Stock was saved. You can review it's data on the History page.",
            )

            stocks = StockData.objects.filter(
                table_index=table_index).order_by("week_3")
            context["stocks"] = stocks
            return render(request, "kadima/home.html", context)

        elif "alarm_stock" in request.POST:
            print(">> Alarm Stock <<")
            stock_id = request.POST["alarm_stock"]
            stock_data = StockData.objects.get(id=stock_id)
            stock_data.stock_alarm = True
            stock_data.stock_load_price = stock_data.stock_current_price
            stock_data.save()
            messages.info(
                request,
                f"Stock {stock_data.ticker} was added to alarm page. You can trigger value alarms on the Alarms page.",
            )

            stocks = StockData.objects.filter(
                table_index=table_index).order_by("week_3")
            context["stocks"] = stocks
            return render(request, "kadima/home.html", context)

        else:
            stocks = StockData.objects.filter(
                table_index=table_index).order_by("week_3")
            context["stocks"] = stocks

            return render(request, "kadima/home.html", context)

    else:
        stocks = StockData.objects.filter(
            table_index=table_index).order_by("week_3")
        context["stocks"] = stocks
        return render(request, "kadima/home.html", context)

    return render(request, "kadima/home.html", context)
def history(request, table_index=1):
    context = {}
    saved_stocks = StockData.objects.filter(saved_to_history=True, table_index=table_index)
    context['email_enabled'] = EmailSupport.objects.all().first().enabled
    context['stocks'] = saved_stocks
    context['table_index'] = table_index
    request.session['table_index'] = table_index

    ib_api_connected = api_connection_status()
    context['ib_api_connected'] = ib_api_connected

    date_picker = DateForm()

    if request.method == 'POST':
        if 'connect_ib_api' in request.POST:
            api_connect(request)
            ib_api_connected = api_connection_status()
            context['ib_api_connected'] = ib_api_connected

            # Start scraping for indices data
            indices_scrapers()

            return render(request, 'kadima/history.html', context)
 
        elif 'disconnect_ib_api' in request.POST:
            api_disconnect(request)
            # context = {}
            ib_api_connected = api_connection_status()
            context['ib_api_connected'] = ib_api_connected
            return render(request, 'kadima/history.html', context)
    
        elif 'update_stock' in str(request.POST):

            for k in request.POST.keys():
                if 'update_stock' in k:
                    stock_id = k.split('_')[-1]
                else:
                    print(f'ERROR:failed getting stock ID')
                    logger.error(f'ERROR:failed getting stock ID')

            stock_data = StockData.objects.get(id=stock_id)

            stock_data.stocks_bought = int(request.POST.get(f'stocks_bought_{stock_id}'))
            stock_data.purchase_price = float(request.POST.get(f'stock_purchase_price_{stock_id}'))
            stock_data.stocks_sold = int(request.POST.get(f'stocks_sold_{stock_id}'))
            stock_data.selling_price = float(request.POST.get(f'selling_price_{stock_id}'))

            stock_data.profit = (stock_data.stocks_sold * stock_data.selling_price) - (stock_data.stocks_bought * stock_data.purchase_price)

            try:
                stock_data.dividends = float(request.POST.get(f'dividends_{stock_id}'))
            except:
                pass

            stock_data.total_profit = stock_data.profit + stock_data.dividends
            stock_data.save()

            context['stocks'] = saved_stocks

        ## Enable email support
        elif 'email_enable' in request.POST:
            print('>> Enable Email <<')
            try:
                email_enable = EmailSupport.objects.all().first()
                if email_enable.enabled:
                    email_enable.enabled = False
                    context['email_enabled'] = False
                    email_enable.save()
                    
                    # Resetting all email alerts to False
                    reset_email_alerts()

                else:
                    email_enable.enabled = True
                    context['email_enabled'] = True
                    email_enable.save()
            except:
                email_enable = EmailSupport()
                email_enable.enabled = True
                context['email_enabled'] = True
                email_enable.save()

        elif 'delete_stock' in request.POST:
            stock_id = request.POST['delete_stock']
            stock_data = StockData.objects.get(id=stock_id)
            stock_data.saved_to_history = False 
            stock_data.save()

            saved_stocks = StockData.objects.filter(saved_to_history=True)
            context['stocks'] = saved_stocks

            return HttpResponseRedirect(request.path_info)


        # Filter history stocks according to dates range
        elif 'date_picker' in request.POST:
            start_date = request.POST['datetimepicker1']
            end_date = request.POST['datetimepicker2']

            start = date_obj_to_date(start_date,'dash')
            end = date_obj_to_date(end_date,'dash')

            print(f"START: ***************{start}****************")

            filtered_stocks = StockData.objects.filter(saved_to_history=True, stock_date_range=[start, end])
            context['stocks'] = filtered_stocks

            # return HttpResponseRedirect(request.path_info)
            return render(request, 'kadima/history.html', context)

        else:
            saved_stocks = StockData.objects.filter(saved_to_history=True)
            context['stocks'] = saved_stocks
            
            return render(request, 'kadima/history.html', context)
    
    return render(request, 'kadima/history.html', context)