Ejemplo n.º 1
0
    def form_valid(self, form):
        exclude = form.cleaned_data["excluded_stocks"]
        n_days = form.cleaned_data["n_days"]
        algo = form.cleaned_data["method"]
        portfolio_cost = form.cleaned_data["portfolio_cost"]
        exclude_price = form.cleaned_data.get("exclude_price", None)
        max_stocks = form.cleaned_data.get("max_stocks", 80)
        stocks = self.stocks()

        if exclude is not None:
            if isinstance(exclude, str):
                exclude = exclude.split(",")
            stocks = set(stocks).difference(exclude)

        if form.cleaned_data["exclude_etfs"]:
            stocks = set(stocks).difference(all_etfs())
            print(f"After excluding ETFs: {len(stocks)} stocks remain")

        self.timeframe = Timeframe(past_n_days=n_days)
        self.results = optimise_portfolio(
            stocks,
            self.timeframe,
            algo=algo,
            max_stocks=max_stocks,
            total_portfolio_value=portfolio_cost,
            exclude_price=exclude_price,
            warning_cb=lambda msg: warning(self.request, msg),
            returns_by=form.cleaned_data.get("returns_by", None),
        )
        return render(self.request, self.template_name,
                      self.get_context_data())
Ejemplo n.º 2
0
def get_dataset(dataset_wanted, request, timeframe=None):
    assert (dataset_wanted in set(["market_sentiment", "eps-per-sector"])
            or dataset_wanted.startswith("kmeans-")
            or dataset_wanted.startswith("financial-metrics-")
            or dataset_wanted.startswith("stock-quotes-"))

    if timeframe is None:
        timeframe = Timeframe(past_n_days=300)

    if dataset_wanted == "market_sentiment":
        df = cached_all_stocks_cip(timeframe)
        return df
    elif dataset_wanted == "kmeans-watchlist":
        _, _, _, _, df = make_kmeans_cluster_dataframe(
            timeframe, 7, user_watchlist(request.user))
        return df
    elif dataset_wanted == "kmeans-etfs":
        _, _, _, _, df = make_kmeans_cluster_dataframe(timeframe, 7,
                                                       all_etfs())
        return df
    elif dataset_wanted.startswith("stock-quotes-"):
        stock = dataset_wanted[len("stock-quotes-"):]
        validate_stock(stock)
        df = company_prices([stock],
                            timeframe=timeframe,
                            fields=all_stock_fundamental_fields,
                            missing_cb=None)
        df['stock_code'] = stock
        return df
    elif dataset_wanted.startswith("kmeans-sector-"):
        sector_id = int(dataset_wanted[14:])
        sector = Sector.objects.get(sector_id=sector_id)
        if sector is None or sector.sector_name is None:
            raise Http404("No stocks associated with sector")
        asx_codes = all_sector_stocks(sector.sector_name)
        _, _, _, _, df = make_kmeans_cluster_dataframe(timeframe, 7, asx_codes)
        return df
    elif dataset_wanted.startswith("financial-metrics-"):
        stock = dataset_wanted[len("financial-metrics-"):]
        validate_stock(stock)
        df = financial_metrics(stock)
        if df is not None:
            # excel doesnt support timezones, so we remove it first
            colnames = [d.strftime("%Y-%m-%d") for d in df.columns]
            df.columns = colnames
            # FALLTHRU
        return df
    elif dataset_wanted == "eps-per-sector":
        df, _ = pe_trends_df(Timeframe(past_n_days=180))
        df = make_pe_trends_eps_df(df, stocks_by_sector())
        df = df.set_index("asx_code", drop=True)
        return df
    else:
        raise ValueError("Unsupported dataset {}".format(dataset_wanted))
Ejemplo n.º 3
0
def show_etfs(request):
    validate_user(request.user)
    matching_codes = all_etfs()
    extra_context = {
        "title": "Exchange Traded funds over past 300 days",
        "sentiment_heatmap_title": "Sentiment for ETFs",
    }
    return show_companies(
        matching_codes,
        request,
        Timeframe(),
        extra_context,
    )
Ejemplo n.º 4
0
 def stocks(self):
     return sorted(all_etfs())
Ejemplo n.º 5
0
def cluster_stocks_view(request, stocks: str):
    """
    ref: https://pythonforfinance.net/2018/02/08/stock-clusters-using-k-means-algorithm-in-python/
    """
    validate_user(request.user)
    timeframe = Timeframe(past_n_days=300)
    if stocks == "watchlist":
        asx_codes = user_watchlist(request.user)
    elif stocks == "etfs":
        asx_codes = all_etfs()
    elif stocks.startswith("sector-"):
        sector_id = int(stocks[7:])
        sector = Sector.objects.get(sector_id=sector_id)
        if sector is None or sector.sector_name is None:
            raise Http404("No stocks associated with sector")
        asx_codes = all_sector_stocks(sector.sector_name)
    else:
        raise Http404("Unknown stock list {}".format(stocks))
    chosen_k = 7  # often a reasonable tradeoff

    def elbow_curve_plot(ld: LazyDictionary):
        distortion, _, _, _, _ = make_kmeans_cluster_dataframe(
            timeframe, chosen_k, asx_codes
        )
        fig = plt.figure(figsize=(15, 5))
        plt.plot(range(2, 20), distortion)
        plt.grid(True)
        plt.title("Elbow curve")
        return fig

    def cluster_plot(ld: LazyDictionary):
        _, _, centroids, idx, data_df = make_kmeans_cluster_dataframe(
            timeframe, chosen_k, asx_codes
        )
        centroids_df = pd.DataFrame.from_records(
            centroids, columns=["return", "volatility"]
        )
        plot = (
            p9.ggplot(
                data_df, p9.aes("return", "volatility", colour="factor(cluster_id)")
            )
            + p9.geom_point(size=3)
            + p9.facet_wrap("~cluster_id", ncol=3, scales="free")
        )
        return user_theme(
            plot,
            x_axis_label="Returns (%)",
            y_axis_label="Volatility (%)",
            figure_size=(15, 15),
            subplots_adjust={"hspace": 0.15, "wspace": 0.15},
        )

    stocks_as_str = "-".join(sorted(asx_codes))
    elbow_curve_uri = cache_plot(
        f"{request.user.username}-cluster-{stocks_as_str}-elbow-curve-plot",
        elbow_curve_plot,
    )
    cluster_uri = cache_plot(
        f"{request.user.username}-cluster-{stocks_as_str}-kmeans-cluster-plot",
        cluster_plot,
    )
    context = {
        "elbow_curve_plot_uri": elbow_curve_uri,
        "k": chosen_k,
        "dataset": stocks,
        "n_stocks": len(asx_codes),
        "cluster_plot_uri": cluster_uri,
        "timeframe": timeframe,
    }
    return render(request, "cluster_stocks.html", context=context)