예제 #1
0
파일: news.py 프로젝트: bvermeulen/Django
class StockNewsView(View):

    template_name = 'finance/stock_news.html'
    td = TradingData()
    td.setup()
    data_provider_url = td.data_provider_url

    def get(self, request, source, symbol):
        stock_news = self.td.get_stock_news(symbol)
        context = {
            'source': source,
            'symbol': symbol,
            'company': self.td.get_company_name(symbol),
            'stock_news': stock_news,
        }
        return render(request, self.template_name, context)

    def post(self, request, source, symbol):
        view_kwargs = {
            'source': source,
            'symbol': symbol,
        }
        return redirect(reverse('stock_news', kwargs=view_kwargs))
예제 #2
0
파일: quotes.py 프로젝트: bvermeulen/Django
class QuoteView(View):
    stockquote_form = StockQuoteForm
    template_name = 'finance/stock_quotes.html'

    td = TradingData()
    td.setup()
    markets = ['XNAS', 'XNYS', 'XAMS', 'INDEX']
    data_provider_url = td.data_provider_url

    def get(self, request):
        user = request.user
        if user.is_authenticated:
            # add Person class to user
            user.__class__ = Person

        try:
            default_user = Person.objects.get(username='******')

        except Person.DoesNotExist:
            default_user = None

        quote_string = request.session.get('quote_string', '')
        selected_portfolio = request.session.get('selected_portfolio', '')
        markets = request.session.get('markets', self.markets)
        stockdetail = request.session.get('stockdetail', STOCK_DETAILS[0][0])
        form = self.stockquote_form(
            initial={
                'quote_string': quote_string,
                'selected_portfolio': selected_portfolio,
                'markets': markets,
                'stockdetails': stockdetail,
            })
        portfolios = default_user.get_portfolio_names()

        if user.is_authenticated:
            portfolios += user.get_portfolio_names()

        if selected_portfolio:
            try:
                # try if user has selected a portfolio if authenticated
                if user.is_authenticated:
                    symbols = Portfolio.objects.get(
                        user=user,
                        portfolio_name=selected_portfolio).get_stock()
                    stock_info = self.td.get_stock_trade_info(symbols[0:20])
                    stock_info += self.td.get_stock_trade_info(symbols[20:40])

                else:
                    raise Portfolio.DoesNotExist

            except Portfolio.DoesNotExist:
                # try if it is a default portfolio
                try:
                    symbols = Portfolio.objects.get(
                        user=default_user, portfolio_name=selected_portfolio).get_stock()  #pylint: disable=line-too-long
                    stock_info = self.td.get_stock_trade_info(symbols[0:20])
                    stock_info += self.td.get_stock_trade_info(symbols[20:40])

                except Portfolio.DoesNotExist:
                    pass

        else:
            symbols = self.td.parse_stock_quote(quote_string, markets=markets)
            stock_info = self.td.get_stock_trade_info(symbols[0:20])

        stock_info = add_display_tokens(stock_info)
        stock_info = format_and_sort_stocks(stock_info)

        context = {
            'source': source,
            'stock_info': stock_info,
            'form': form,
            'portfolios': sorted(portfolios),
            'data_provider_url': self.data_provider_url,
        }

        return render(request, self.template_name, context)

    def post(self, request):
        user = request.user
        quote_string = request.session.get('quote_string', '')
        selected_portfolio = request.session.get('selected_portfolio', '')
        markets = request.session.get('markets', self.markets)
        stockdetail = request.session.get('stockdetail', STOCK_DETAILS[0][0])

        form = self.stockquote_form(request.POST)
        if form.is_valid():
            form_data = form.cleaned_data
            new_quote_string = form_data.get('quote_string')
            new_selected_portfolio = form_data.get('selected_portfolio')
            markets = form_data.get('markets')
            stockdetail = form_data.get('stockdetails')

            if new_selected_portfolio != selected_portfolio:
                selected_portfolio = new_selected_portfolio
                quote_string = ''

            elif new_quote_string != quote_string:
                quote_string = new_quote_string
                selected_portfolio = ''

            else:
                pass

            request.session['quote_string'] = quote_string
            request.session['selected_portfolio'] = selected_portfolio
            request.session['markets'] = markets
            request.session['stockdetail'] = stockdetail
            logger.info(f'user {user} [ip: {get_client_ip(request)}] looking '
                        f'up: {quote_string} / {selected_portfolio}')

        else:
            pass

        return redirect(reverse('stock_quotes'))
예제 #3
0
class IntraDayView(View):
    template_name = 'finance/stock_intraday.html'

    td = TradingData()
    td.setup()
    data_provider_url = td.data_provider_url

    def get(self, request, source, symbol):
        user = request.user

        if not Stock.objects.filter(symbol_ric=symbol):
            return redirect(reverse('stock_quotes'))

        intraday_trades = self.td.get_stock_intraday_info(symbol)

        if not intraday_trades:
            return redirect(
                reverse(
                    'stock_history',
                    kwargs={'symbol': symbol, 'source': source, 'period': PLOT_PERIODS[0]}
                )
            )

        chart_data = []
        min_price, max_price, max_volume = None, None, None
        date_format = '%d-%m-%Y %H:%M'

        for trade in intraday_trades:
            chart_data.append([
                trade.date.strftime(date_format),
                trade.open, trade.close, trade.low, trade.high,
                trade.volume, ])

            min_price = get_min(trade.low, min_price)
            max_price = get_max(trade.high, max_price)
            max_volume = get_max(trade.volume, max_volume)

        if not min_price or not max_price:
            min_price, max_price = 0, 0

        if not max_volume:
            max_volume = 0

        try:
            initial_open = intraday_trades[1].open
            latest_close = intraday_trades[-2].close
            prc_change = 100 * (float(latest_close) -
                                float(initial_open)) / float(initial_open)

        except IndexError:
            initial_open, latest_close, prc_change = None, None, None

        if initial_open and latest_close and prc_change:
            if abs(float(prc_change)) < 0.01:
                txt_color = 'txt_normal'
                caret = CARET_NO_CHANGE
            elif float(prc_change) < 0:
                txt_color = 'txt_red'
                caret = CARET_DOWN
            else:
                txt_color = 'txt_green'
                caret = CARET_UP

            subcaption = ''.join([Stock.objects.get(symbol_ric=symbol).currency.currency,
                                  f' {float(latest_close):.2f} ({prc_change:.1f}%)',
                                  f' {caret}'])
        else:
            subcaption = ''
            txt_color = 'txt_normal'

        caption = ''.join([Stock.objects.get(symbol_ric=symbol).company,
                           ' (', symbol, ')'])

        schema = json.dumps(self.td.get_schema(date_format))
        chart_data = json.dumps(chart_data)
        time_series = TimeSeries(FusionTable(schema, chart_data))

        time_series.AddAttribute(
            'styleDefinition',
            {'txt_red': {
                'fill': font_red, 'font-weight': font_weight, 'font-size': font_size},
             'txt_green': {
                 'fill': font_green, 'font-weight': font_weight, 'font-size': font_size},
             'txt_normal': {
                 'fill': font_white, 'font-weight': font_weight, 'font-size': font_size},
            })
        time_series.AddAttribute(
            'chart', {'multicanvas': '0', 'theme': chart_theme, 'showlegend': '0',})
        time_series.AddAttribute('caption', {'text': caption, })
        time_series.AddAttribute(
            'subcaption', {'text': subcaption, 'style': {'text': txt_color}, })
        time_series.AddAttribute('navigator', {'enabled': '0'})
        time_series.AddAttribute(
            'extensions', {'customrangeselector': {'enabled': '0'}})
        time_series.AddAttribute(
            'yaxis', [
                {'plot': [
                    {'value': {
                        'open':'open', 'high': 'high', 'low':'low', 'close':'close'},
                     'type':'candlestick'}],
                 'title':'Stock Value',
                 'min': min_price*0.99,
                 'max': max_price*1.01,
                },
                {'plot': [{'value': 'volume', 'type': 'column'}],
                 'title': 'Volume',
                 'max': max_volume * 3,
                },
            ])

        trade_series = FusionCharts('timeseries',
                                    'trades',
                                    width, height,
                                    'chart-container',
                                    'json',
                                    time_series,
                                   )

        context = {'chart_js': trade_series.render(),
                   'data_provider_url': self.data_provider_url,
                   'stock_symbol': symbol,
                   'source': source,
                   'periods': PLOT_PERIODS,
                  }

        logger.info(f'user {user} [ip: {get_client_ip(request)}] is looking '
                    f'intraday trades for {symbol}')
        return render(request, self.template_name, context)

    def post(self, request, source, symbol):
        pass
예제 #4
0
class PortfolioView(View):

    form_class = PortfolioForm
    template_name = 'finance/stock_portfolio.html'
    td = TradingData()
    td.setup()
    data_provider_url = td.data_provider_url

    def get(self, request):
        currency = request.session.get('currency', 'EUR')
        selected_portfolio = request.session.get('selected_portfolio', '')
        user = request.user
        # add Person class to user
        if user.is_authenticated:
            user.__class__ = Person

        portfolio_name = ''
        stocks = []

        if selected_portfolio:
            try:
                self.portfolio = Portfolio.objects.get(
                    user=user, portfolio_name=selected_portfolio)
                portfolio_name = self.portfolio.portfolio_name
                stocks = self.get_stock_info(GetStock.YES, currency)
                request.session['stock_info'] = json.dumps(
                    stocks, cls=DjangoJSONEncoder)

            except Portfolio.DoesNotExist:
                selected_portfolio = ''

        else:
            pass

        form = self.form_class(user=user,
                               initial={
                                   'symbol': '',
                                   'portfolio_name': portfolio_name,
                                   'portfolios': selected_portfolio,
                                   'currencies': currency
                               })

        totals_values = format_totals_values(
            *self.td.calculate_stocks_value(stocks))
        stocks = add_display_tokens(stocks)
        stocks = format_and_sort_stocks(stocks)
        context = {
            'form': form,
            'stocks': stocks,
            'totals': totals_values,
            'source': source,
            'data_provider_url': self.data_provider_url,
        }
        return render(request, self.template_name, context)

    def post(self, request):
        # TODO add refresh button

        self.request = request
        self.user = self.request.user
        # add Person class to user
        if self.user.is_authenticated:
            self.user.__class__ = Person

        currency = request.session.get('currency', 'EUR')

        form = self.form_class(self.request.POST, user=self.user)
        if form.is_valid():
            form_data = form.cleaned_data
            currency = form_data.get('currencies')
            self.selected_portfolio = form_data.get('portfolios')
            self.portfolio_name = form_data.get('portfolio_name')
            self.new_portfolio = form_data.get('new_portfolio')
            self.symbol = form_data.get('symbol').upper()
            self.btn1_pressed = form_data.get('btn1_pressed')
            self.change_qty_btn_pressed = form_data.get(
                'change_qty_btn_pressed')
            self.delete_symbol_btn_pressed = form_data.get(
                'delete_symbol_btn_pressed')
            self.previous_selected = request.session.get('selected_portfolio')
            previous_currency = request.session.get('currency')

            if (self.previous_selected != self.selected_portfolio
                    or previous_currency != currency):
                get_stock = GetStock.YES

            else:
                get_stock = GetStock.NO

            try:
                self.portfolio = Portfolio.objects.get(
                    user=self.user, portfolio_name=self.selected_portfolio)

            except Portfolio.DoesNotExist:
                self.portfolio = None
                self.selected_portfolio = ''
                self.btn1_pressed = ''
                self.btn2_pressed = ''
                get_stock = GetStock.EMPTY

            if self.new_portfolio:
                get_stock = self.create_new_portfolio()

            elif self.btn1_pressed:
                get_stock = self.rename_or_delete_portfolio_or_add_stock()

            elif self.change_qty_btn_pressed:
                get_stock = self.change_quantity_symbol()

            elif self.delete_symbol_btn_pressed:
                get_stock = self.delete_symbol()

            else:
                pass

            # set portfolio name except if the portfolio has been deleted or
            # does not exist
            try:
                self.portfolio_name = self.portfolio.portfolio_name

            except AttributeError:
                self.portfolio_name = ''

            stocks = self.get_stock_info(get_stock, currency)
            request.session['stock_info'] = json.dumps(stocks,
                                                       cls=DjangoJSONEncoder)
            request.session['selected_portfolio'] = self.selected_portfolio
            request.session['currency'] = currency

            form = self.form_class(user=self.user,
                                   initial={
                                       'portfolio_name': self.portfolio_name,
                                       'portfolios': self.selected_portfolio,
                                       'symbol': self.symbol,
                                       'currencies': currency
                                   })

            logger.info(
                f'user {self.user} [ip: {get_client_ip(self.request)}] '
                f'views {self.selected_portfolio}')

        else:
            form = self.form_class(user=self.user,
                                   initial={
                                       'portfolios': '',
                                       'portfolio_name': '',
                                       'symbol': '',
                                       'currencies': currency
                                   })

            stocks = []

        totals_values = format_totals_values(
            *self.td.calculate_stocks_value(stocks))
        stocks = add_display_tokens(stocks)
        stocks = format_and_sort_stocks(stocks)
        context = {
            'form': form,
            'stocks': stocks,
            'totals': totals_values,
            'source': source,
            'data_provider_url': self.data_provider_url,
        }

        return render(self.request, self.template_name, context)

    def create_new_portfolio(self):
        try:
            self.portfolio = Portfolio.objects.create(
                user=self.user, portfolio_name=self.new_portfolio)
            self.selected_portfolio = self.new_portfolio
            get_stock = GetStock.EMPTY

        except IntegrityError:
            # patch in case initial choice portfolios is None then for some reason
            # choicefield will return the first option. In that case reset all
            if not self.previous_selected:
                self.portfolio = None
                self.selected_portfolio = self.previous_selected
                get_stock = GetStock.EMPTY

            else:
                self.new_portfolio = ''
                get_stock = GetStock.NO

        return get_stock

    def rename_or_delete_portfolio_or_add_stock(self):
        ''' actions when btn1 is pressed '''
        if not self.portfolio:
            logger.warning(f'{self.portfolio}: check existance of portfolio')
            return GetStock.NO

        if not self.portfolio_name:
            return GetStock.NO

        if self.btn1_pressed == 'rename_portfolio':
            get_stock = GetStock.NO
            if self.portfolio_name != self.selected_portfolio:

                try:
                    self.portfolio.portfolio_name = self.portfolio_name
                    self.portfolio.save()
                    self.selected_portfolio = self.portfolio_name

                except IntegrityError:
                    pass
            else:
                pass

        elif self.btn1_pressed == 'delete_portfolio':
            self.portfolio.delete()
            self.portfolio = None
            self.selected_portfolio = ''
            self.portfolio_name = ''
            get_stock = GetStock.EMPTY

        elif self.btn1_pressed == 'add_new_symbol':
            try:
                StockSelection.objects.create(
                    stock=Stock.objects.get(symbol_ric=self.symbol),
                    quantity=0,
                    portfolio=self.portfolio)

                self.symbol = ''
                get_stock = GetStock.YES

            except (Stock.DoesNotExist, IntegrityError, ValueError):
                get_stock = GetStock.NO

        else:
            logger.warning(f'Invalid value btn1_pressed: {self.btn1_pressed}')

        return get_stock

    def change_quantity_symbol(self):
        ''' change quantiy of symbol when change_quantity_btn is pressed '''
        if not self.portfolio:
            logger.warning(f'{self.portfolio}: check existance of portfolio')
            return GetStock.NO

        try:
            symbol, quantity = self.change_qty_btn_pressed.split(',')
            symbol = symbol.strip()
            quantity = quantity.strip()

        except ValueError:
            return GetStock.NO

        portfolio_selected_stock = self.portfolio.stocks.get(
            stock__symbol_ric=symbol)

        if portfolio_selected_stock.stock.currency.currency != 'N/A':
            portfolio_selected_stock.quantity = quantity
            portfolio_selected_stock.save()
            get_stock = GetStock.YES

        else:
            get_stock = GetStock.NO

        return get_stock

    def delete_symbol(self):
        ''' delete symbol from portfolio when delete symbol btn is pressed '''
        if not self.portfolio:
            logger.warning(f'{self.portfolio}: check existance of portfolio')
            return GetStock.NO

        self.portfolio.stocks.get(
            stock__symbol_ric=self.delete_symbol_btn_pressed).delete()

        return GetStock.YES

    def get_stock_info(self, get_stock, currency):
        ''' get stock info depending of get_stock status'''
        stocks = []
        if self.portfolio:

            if get_stock == GetStock.YES:
                stocks = self.td.get_portfolio_stock_info(
                    self.portfolio, currency)

            elif get_stock == GetStock.NO:
                try:
                    stocks = json.loads(self.request.session.get('stock_info'))

                except TypeError:
                    stocks = self.td.get_portfolio_stock_info(
                        self.portfolio, currency)

            elif get_stock == GetStock.EMPTY:
                # stocks is empty list already fullfilled
                pass

            else:
                logger.warning(f'invalid selection for get_stock: {get_stock}')

        else:
            # stocks is empty list already fullfilled
            pass

        return stocks
예제 #5
0
class HistoryView(View):
    template_name = 'finance/stock_history.html'

    td = TradingData()
    td.setup()
    data_provider_url = td.data_provider_url

    def get(self, request, source, symbol, period):
        user = request.user

        if period not in PLOT_PERIODS:
            return redirect(reverse('stock_quotes'))

        elif period == PLOT_PERIODS[-1]:
            period_num = 50

        else:
            period_num = float(period)

        if not Stock.objects.filter(symbol_ric=symbol):
            return redirect(reverse('stock_quotes'))

        history_trades = self.td.get_stock_history_info(symbol, period)
        if history_trades:
            start_period = history_trades[0].date -\
                           datetime.timedelta(days=int(period_num*365))

        chart_data = []
        min_price, max_price, max_volume = None, None, None
        date_format = '%d-%m-%Y'
        for trade in history_trades:
            if trade.date > start_period:
                chart_data.append([
                    trade.date.strftime(date_format),
                    trade.open, trade.close, trade.low, trade.high,
                    trade.volume,])

                min_price = get_min(trade.low, min_price)
                max_price = get_max(trade.high, max_price)
                max_volume = get_max(trade.volume, max_volume)

        if not min_price or not max_price:
            min_price, max_price = 0, 0
            start_date, end_date = '01-01-1900', '01-01-1900'

        else:
            end_date = history_trades[0].date
            start_date = end_date - datetime.timedelta(days=365)
            start_date = start_date.strftime(date_format)
            end_date = end_date.strftime(date_format)

        if not max_volume:
            max_volume = 0

        subcaption = ''
        caption = ''.join([Stock.objects.get(symbol_ric=symbol).company,
                           ' (', symbol, ')'])

        schema = json.dumps(self.td.get_schema(date_format))
        chart_data = json.dumps(chart_data)
        time_series = TimeSeries(FusionTable(schema, chart_data))
        time_series.AddAttribute('chart', {
            'multicanvas': '0', 'theme': chart_theme, 'showlegend': '0',})
        time_series.AddAttribute('caption', {'text': caption, })
        time_series.AddAttribute('subcaption', {'text': subcaption,})
        time_series.AddAttribute('navigator', {'enabled': '1'}, )
        time_series.AddAttribute('extensions', {'customrangeselector': {'enabled': '1'}})
        time_series.AddAttribute('xaxis', {
            'initialinterval': {'from': start_date, 'to': end_date}})
        time_series.AddAttribute('yaxis', [
            {'plot': [{'value':{
                'open':'open', 'high':'high', 'low': 'low', 'close': 'close'},
                       'type': 'candlestick'}],
             'title': 'Stock Value (' + Stock.objects.get(symbol_ric=symbol).
                      currency.currency + ')',
             'min': min_price*0.99,
             'max': max_price*1.01,
            },
            {'plot': [{'value': 'volume', 'type': 'column'}],
             'title': 'Volume',
             'max': max_volume * 3,
            },
        ])

        trade_series = FusionCharts('timeseries',
                                    'trades',
                                    width, height,
                                    'chart-container',
                                    'json',
                                    time_series,
                                   )

        context = {'chart_js': trade_series.render(),
                   'data_provider_url': self.data_provider_url,
                   'stock_symbol': symbol,
                   'source': source,
                   'period': period,
                   'periods': PLOT_PERIODS,
                  }

        logger.info(f'user {user} [ip: {get_client_ip(request)}] is looking '
                    f'historic trades for {symbol}')
        return render(request, self.template_name, context)

    def post(self, request, source, symbol, period):
        pass