def institutional_list(): """13F list view""" if 'fund' in session and session['fund'] != '': return(redirect('/13F/' + str(session['fund']['cik']))) params = {} try: page = int(request.args.get('page')) except: page = None if page != None: params['page'] = page if 'my_funds_view' in session and session['my_funds_view'] == 'true': if 'funds_ciks' in session: params['ciks'] = ','.join([str(x) for x in session['funds_ciks']]) else: params['ciks'] = default_funds() response = make_api_request('/13F/list/', params) pagination = response.get('_pagination_', {'current': None, 'next': None}) tmplate = generate_institutional_template() html = tmplate.render(institutional=response['_results_']) if request.is_xhr: return jsonify(html=html, pagination=pagination) return render_template('institutional.jinja2', html=html, results=response['_results_'], pagination=pagination)
def econ_list(): """Get a list of most recent economic updates""" if 'series' in session and session['series'] != '': return(redirect('/econ/' + str(session['series']['id']))) params = {} try: page = int(request.args.get('page')) except: page = None if page != None: params['page'] = page if 'most_viewed' in session and session['most_viewed'] == 'true': params['popularity'] = 50 response = make_api_request('/econ/list/', params) pagination = response.get('_pagination_', {'current': None, 'next': None}) html = generate_econ_template() html = html.render(series=response['_results_']) if request.is_xhr: return jsonify(html=html, pagination=pagination) flash("Don't worry, we're gonna bring back the charts shortly", 'info') return render_template('econ.jinja2', html=html, pagination=pagination)
def financials(cik): """ View the financials """ if cik is None and 'ticker' in session and session['ticker'] != {}: return redirect(url_for('financials', cik=session['ticker']['cik'])) if cik is not None: store_cik(cik) if session['ticker'] == {}: flash('Invalid ticker', 'danger') return redirect('/financials/') if cik is None: return render_template('financials.jinja2', cik=None) if app.config['test_data'] == True: if cik != '1288776': return redirect('/financials/1288776/') params = {'ticker': cik, 'length': -5, 'frequency': 12} financials = ['sales', 'ebit', 'adj_ebit', 'ebitda', 'adj_ebitda', 'cfo_minus_capex'] margins = ['gross_profit_margin', 'adj_ebit_margin', 'adj_ebitda_margin', 'adj_pretax_income_margin', 'net_income_margin', 'dividend_yield'] ratios = ['net_debt_to_adj_ebitda', 'debt_to_assets', 'debt_to_equity', 'debt_to_interest_expense', 'return_on_invested_capital'] multiples = ['cev_to_sales', 'cev_to_adj_ebitda', 'price_to_earnings', 'price_to_tangible_book_value'] all_elements = financials + margins + ratios + multiples params['elements'] = ','.join(all_elements) response = make_api_request('/financials/detail/', params) dates = [] valid = [] # get rid of dates with length of 0 for i, date in enumerate(response['_results_']['_dates_']): if 'length' in date and date['length'] != 0: valid.append(i) dates.append(date) results = {'_labels_': response['_results_']['_labels_']} for key, values in response['_results_'].iteritems(): if key not in ['_dates_', '_labels_']: if '_total_' in values: results[key] = [x for i, x in enumerate(values['_total_']) if i in valid] html = generate_financials_template() financials = html.render(elements=financials, results=results) margins = html.render(elements=margins, results=results) ratios = html.render(elements=ratios, results=results) multiples = html.render(elements=multiples, results=results) return render_template('financials.jinja2', detail='true', dates=dates, financials=financials, margins=margins, ratios=ratios, multiples=multiples)
def institutional_search(): """13F Autocomplete""" params = {'term': request.args.get('term'), 'number': 10} response = make_api_request('/13F/search/', params, True) for f in response['_results_']: f['aum'] = format_aum(f['aum']) latest_filing = datetime.strptime(f['latest_filing'], '%Y-%m-%d') latest_filing = datetime.strftime(latest_filing, '%m/%d/%Y') if latest_filing.startswith('0'): latest_filing = latest_filing.replace('0', '', 1) f['latest_filing'] = latest_filing return jsonify(results=response['_results_'])
def filings(cik): """Filings list view""" if cik is None and 'ticker' in session and session['ticker'] != {}: cik = session['ticker']['cik'] if not request.is_xhr: return redirect('/filings/' + str(cik) + '/') if cik is not None: store_cik(cik) if session['ticker'] == {}: # if ticker is invalid flash('Invalid ticker', 'danger') return redirect('/filings/') params = {} try: page = int(request.args.get('page')) except: page = None if page != None: params['page'] = page try: params['forms'] = session['forms'] except: pass try: params['insiders'] = session['insiders'] except: pass try: params['ciks'] = session['ticker']['cik'] except: pass if 'watchlist_view' in session and session['watchlist_view'] == 'true': if 'watchlist_ciks' in session: params['ciks'] = ','.join([str(x) for x in session['watchlist_ciks']]) else: params['ciks'] = default_watchlist() response = make_api_request('/filings/list/', params) pagination = response.get('_pagination_', {'current': None, 'next': None}) html = generate_filings_template() html = html.render(filings=response['_results_']) if request.is_xhr: return jsonify(html=html, pagination=pagination) return render_template('filings.jinja2', html=html, results=response['_results_'], pagination=pagination)
def screen_view(): """Screener, including pre-built & custom screens""" groups = ['formulas', 'margins', 'ratios', 'multiples', 'quotes'] f = make_api_request('/financials/formulas/') formulas = f['_results_'] sorted_formulas = [] for k, v in formulas.iteritems(): if k in groups: sorted_formulas += v sorted_formulas = sorted(sorted_formulas) params = get_params() response = make_api_request('/screen/detail/', params) params = {k: v.split(',') for k, v in params.iteritems()} if 'user_oauth_token' not in session or \ 'access_token' not in session['user_oauth_token']: flash('Login to save screens', 'info') return render_template('screener.jinja2', response=response, params=params, groups=groups, formulas=formulas, sorted_formulas=sorted_formulas)
def insiders(cik): """Get the latest insider filings. If cik is not None then get the latest insider filings for a specific company""" if cik is None and 'ticker' in session and session['ticker'] != {}: cik = session['ticker']['cik'] if not request.is_xhr: return redirect('/insiders/' + str(cik) + '/') if cik is not None: store_cik(cik) if session['ticker'] == {}: flash('Invalid ticker', 'danger') return redirect('/insiders/') params = {} if 'planned' in session: params['planned'] = session['planned'] try: params['ciks'] = session['ticker']['cik'] except: pass if 'watchlist_view' in session and session['watchlist_view'] == 'true': if 'watchlist_ciks' in session: params['ciks'] = ','.join([str(x) for x in session['watchlist_ciks']]) else: params['ciks'] = default_watchlist() try: page = int(request.args.get('page')) except: page = None if page != None: params['page'] = page response = make_api_request('/insiders/list/', params) pagination = response.get('_pagination_', {'current': None, 'next': None}) tmplate = generate_insider_template() html = tmplate.render(insiders=response['_results_'], session=session) if request.is_xhr: return jsonify(html=html, pagination=pagination) flash("Don't worry, we're gonna bring back the charts shortly", 'info') return render_template('insiders.jinja2', html=html, pagination=pagination)
def econ_detail(series): """Get the history of an economic series.""" params = {'reverse': 'true', 'length': -500} series = series.upper() if app.config['test_data'] == True: if series != 'GDP': return redirect('/econ/GDP/') params['series'] = series response = make_api_request('/econ/detail/', params) if '_error_' in response: flash(response['_error_'], 'danger') return redirect(url_for('econ_list')) else: session['series'] = {'id': series, 'name': response['_results_'][series]['name']} flash("Don't worry, we're gonna bring back the charts shortly", 'info') return render_template('econ.jinja2', series=series, results=response['_results_'])
def econ_search(): """Econ Autocomplete""" params = {'term': request.args.get('term'), 'number': 10} response = make_api_request('/econ/search/', params, True) return jsonify(results=response['_results_'])
def institutional_detail(cik): """Compare 2 periods for a 13F filer""" if app.config['test_data'] == True: if cik != 1079114: return redirect('/13F/1079114/') params = {'cik': cik, 'length': -2} response = make_api_request('/13F/detail/', params) periods = sorted([datetime.strptime(x, '%Y-%m-%d') for x in response['_results_'].keys()]) periods = [datetime.strftime(x, '%Y-%m-%d') for x in periods] master = [] current, prior = {}, {} if response['_results_'] == {}: flash('Invalid fund', 'danger') return redirect(url_for('institutional_list')) for item in response['_results_'][periods[-1]]['_holdings_']: current[item['cusip']] = item for item in response['_results_'][periods[0]]['_holdings_']: prior[item['cusip']] = item total_value = 0 previous_total_value = 0 for cusip, v in current.iteritems(): total_value += int(v['value']) tmp = v.copy() tmp['prior_shares'] = 0 tmp['prior_value'] = 0 tmp['action'] = 'New' if cusip in prior: tmp['prior_shares'] = prior[cusip]['shares'] tmp['prior_value'] = prior[cusip]['value'] if v['shares'] > tmp['prior_shares']: tmp['action'] = 'Increased' elif v['shares'] < tmp['prior_shares']: tmp['action'] = 'Decreased' elif v['shares'] == tmp['prior_shares']: tmp['action'] = 'No Change' master.append(tmp) for cusip, v in prior.iteritems(): previous_total_value += int(v['value']) if cusip not in current: tmp = v.copy() tmp['shares'] = 0 tmp['value'] = 0 tmp['prior_shares'] = v['shares'] tmp['prior_value'] = v['value'] tmp['action'] = 'Sold All' master.append(tmp) master = sorted(master, key=lambda k: k['name']) for item in master: item['share_change'] = item['shares'] - item['prior_shares'] try: item['share_change_percent'] = float(float(item['shares']) / float(item['prior_shares']) ) - 1 except ZeroDivisionError: item['share_change_percent'] = 1 item['value_change'] = item['value'] - item['prior_value'] try: item['value_change_percent'] = float(float(item['value']) / float(item['prior_value']) ) - 1 except ZeroDivisionError: item['value_change_percent'] = 1 try: item['percent'] = float(float(item['value']) / float(total_value)) except: item['percent'] = 0 try: item['prior_percent'] = float(float(item['prior_value']) / float(previous_total_value)) except: item['prior_percent'] = 0 try: total_value_change = float(total_value) - float(previous_total_value) except: total_value_change = 0 try: total_value_change_percentage = float(float(total_value) / float(previous_total_value)) - 1 except: total_value_change_percentage = 0 tmplate = institutional_detail_template() html = tmplate.render(institutional=response['_results_'], periods=periods, master=master, total_value=total_value, previous_total_value=previous_total_value, total_value_change=total_value_change, total_value_change_percentage=total_value_change_percentage) session['fund'] = {'cik': cik, 'name': response['_results_'][periods[-1]]['_cover_']['manager']} return render_template('institutional.jinja2', html=html, detail='true')