Example #1
0
def customer_command(ticker: str = ""):
    """Displays customers of the company [CSIMarket]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dd-customer %s", ticker)

    if not ticker:
        raise Exception("A ticker is required")

    tickers = csimarket_model.get_customers(ticker)

    if not tickers:
        raise Exception("Enter a valid ticker")

    # Debug user output
    if cfg.DEBUG:
        logger.debug(tickers)

    # Output data

    return {
        "title": f"Stocks: [CSIMarket] {ticker} Customers",
        "description": tickers,
    }
Example #2
0
def metals_command():
    """Displays metals futures data [Finviz]"""
    # Debug user input
    if cfg.DEBUG:
        logger.debug("econ-metals")

    # Retrieve data
    d_futures = finviz_model.get_futures()
    df = pd.DataFrame(d_futures["Metals"])

    # Check for argument
    if df.empty:
        raise Exception("No available data found")

    formats = {"last": "${:.2f}", "prevClose": "${:.2f}"}
    for col, value in formats.items():
        df[col] = df[col].map(lambda x: value.format(x))  # pylint: disable=W0640

    # Debug user output
    if cfg.DEBUG:
        logger.debug(df)

    df = df.sort_values(by="ticker", ascending=False)
    df = df.fillna("")
    df.set_index("label", inplace=True)

    df = df[[
        "prevClose",
        "last",
        "change",
    ]]

    df.index.names = [""]
    df = df.rename(columns={
        "prevClose": "PrevClose",
        "last": "Last",
        "change": "Change"
    })

    dindex = len(df.index)
    fig = df2img.plot_dataframe(
        df,
        fig_size=(800, (40 + (40 * dindex))),
        col_width=[6, 3, 3],
        tbl_cells=dict(
            align="left",
            height=35,
        ),
        template="plotly_dark",
        font=dict(
            family="Consolas",
            size=20,
        ),
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )
    imagefile = save_image("econ-metals.png", fig)
    return {
        "title": "Economy: [WSJ] Metals Futures",
        "imagefile": imagefile,
    }
def toplobbying_command(num: int = 10, raw: bool = False):
    """Displays top lobbying firms [quiverquant.com]"""
    # Debug user input
    if cfg.DEBUG:
        logger.debug("gov-toplobbying %s %s", num, raw)

    # Retrieve Data
    df_lobbying = quiverquant_model.get_government_trading(
        "corporate-lobbying")

    if df_lobbying.empty:
        raise Exception("No corporate lobbying found")

    df_lobbying["Amount"] = df_lobbying.Amount.astype(float).fillna(
        0) / 100_000

    lobbying_by_ticker = pd.DataFrame(
        df_lobbying.groupby("Ticker")["Amount"].agg("sum")).sort_values(
            by="Amount", ascending=False)
    fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    lobbying_by_ticker.head(num).plot(kind="bar", ax=ax)
    ax.set_xlabel("Ticker")
    ax.set_ylabel("Total Amount ($100k)")
    ax.set_title(f"Corporate Lobbying Spent since {df_lobbying['Date'].min()}")
    fig.tight_layout()

    plt.savefig("ta_toplobbying.png")
    imagefile = "ta_toplobbying.png"

    imagefile = image_border(imagefile)
    return {
        "title": "Stocks: [quiverquant.com] Top Lobbying Firms",
        "imagefile": imagefile,
    }
Example #4
0
def quote_command(ticker: str = None):
    """Ticker Quote"""

    # Debug
    if cfg.DEBUG:
        logger.debug("quote %s", ticker)

    # Check for argument
    if ticker is None:
        raise Exception("Stock ticker is required")

    df = quote(ticker)
    fig = df2img.plot_dataframe(
        df,
        fig_size=(600, 1500),
        col_width=[2, 3],
        tbl_cells=dict(
            align="left",
            height=35,
        ),
        template="plotly_dark",
        font=dict(
            family="Consolas",
            size=20,
        ),
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )
    imagefile = save_image("quote.png", fig)

    return {
        "title": f"{ticker.upper()} Quote",
        "imagefile": imagefile,
    }
Example #5
0
def usbonds_command():
    """US bonds overview [Wall St. Journal]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("econ-usbonds")

    # Retrieve data
    df = wsj_model.us_bonds()

    # Check for argument
    if df.empty:
        raise Exception("No available data found")

    df["Rate (%)"] = pd.to_numeric(df["Rate (%)"].astype(float))
    df["Yld (%)"] = pd.to_numeric(df["Yld (%)"].astype(float))
    df["Yld Chg (%)"] = pd.to_numeric(df["Yld Chg (%)"].astype(float))

    formats = {
        "Rate (%)": "{:.2f}%",
        "Yld (%)": "{:.2f}%",
        "Yld Chg (%)": "{:.2f}%",
    }
    for col, value in formats.items():
        df[col] = df[col].map(lambda x: value.format(x))  # pylint: disable=W0640

    df = df.fillna("")
    df.set_index(" ", inplace=True)

    df = df.set_axis(
        [
            "Rate",
            "Yld",
            "Yld Chg",
        ],
        axis="columns",
    )

    dindex = len(df.index)
    fig = df2img.plot_dataframe(
        df,
        fig_size=(800, (40 + (40 * dindex))),
        col_width=[8, 3, 3],
        tbl_cells=dict(
            align="left",
            height=35,
        ),
        template="plotly_dark",
        font=dict(
            family="Consolas",
            size=20,
        ),
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )

    imagefile = save_image("econ-usbonds.png", fig)
    return {
        "title": "Economy: [WSJ] US Bonds",
        "imagefile": imagefile,
    }
Example #6
0
def sec_command(ticker=""):
    """Displays sec filings [Market Watch]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dd-sec %s", ticker)

    if ticker == "":
        raise Exception("A ticker is required")

    df_financials = marketwatch_model.get_sec_filings(ticker)

    if df_financials.empty:
        raise Exception("Enter a valid ticker")

    # Debug user output
    if cfg.DEBUG:
        logger.debug(df_financials.to_string())

    df = df_financials
    df.loc[:, "Link"] = "[Link Source](" + df.loc[:, "Link"].astype(str)
    df.loc[:, "Link"] = df.loc[:, "Link"] + ")"

    # Output data
    return {
        "title": "Stocks: [Market Watch] SEC Filings",
        "description": df.to_string(),
    }
Example #7
0
def currencies_command():
    """Currencies overview [Wall St. Journal]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("econ-currencies")

    # Retrieve data
    df = wsj_model.global_currencies()
    df = pd.DataFrame.from_dict(df)

    # Check for argument
    if df.empty:
        raise Exception("No available data found")

    df["Last"] = pd.to_numeric(df["Last"].astype(float))
    df["Chng"] = pd.to_numeric(df["Chng"].astype(float))
    df["%Chng"] = pd.to_numeric(df["%Chng"].astype(float))

    formats = {"Last": "{:.2f}", "Chng": "{:.2f}", "%Chng": "{:.2f}%"}
    for col, value in formats.items():
        df[col] = df[col].map(lambda x: value.format(x))  # pylint: disable=W0640

    df = df.fillna("")
    df.set_index(" ", inplace=True)

    # Debug user output
    if cfg.DEBUG:
        logger.debug(df.to_string())

    df = df[[
        "Last",
        "Chng",
        "%Chng",
    ]]
    dindex = len(df.index)
    fig = df2img.plot_dataframe(
        df,
        fig_size=(800, (40 + (40 * dindex))),
        col_width=[8, 3, 3],
        tbl_cells=dict(
            align="left",
            height=35,
        ),
        template="plotly_dark",
        font=dict(
            family="Consolas",
            size=20,
        ),
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )
    imagefile = save_image("econ-currencies.png", fig)
    return {
        "title": "Economy: [WSJ] Currencies",
        "imagefile": imagefile,
    }
Example #8
0
def histcont_command(ticker=""):
    """Displays historical quarterly-contracts [quiverquant.com]"""
    # Debug user input
    if cfg.DEBUG:
        logger.debug("gov-histcont %s", ticker)

    if ticker == "":
        raise Exception("A ticker is required")

    # Retrieve Data
    df_contracts = quiverquant_model.get_government_trading(
        "quarter-contracts", ticker=ticker
    )

    if df_contracts.empty:
        logger.debug("No quarterly government contracts found")
        raise Exception("No quarterly government contracts found")

    # Output Data
    amounts = df_contracts.sort_values(by=["Year", "Qtr"])["Amount"].values

    qtr = df_contracts.sort_values(by=["Year", "Qtr"])["Qtr"].values
    year = df_contracts.sort_values(by=["Year", "Qtr"])["Year"].values

    quarter_ticks = [
        f"{quarter[0]}" if quarter[1] == 1 else "" for quarter in zip(year, qtr)
    ]

    fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

    ax.plot(np.arange(0, len(amounts)), amounts / 1000, "-*", lw=2, ms=15)

    ax.set_xlim([-0.5, len(amounts) - 0.5])
    ax.set_xticks(np.arange(0, len(amounts)))
    ax.set_xticklabels(quarter_ticks)
    ax.grid()
    ax.set_title(f"Historical Quarterly Government Contracts for {ticker.upper()}")
    ax.set_xlabel("Date")
    ax.set_ylabel("Amount ($1k)")
    fig.tight_layout()

    plt.savefig("gov_histcont.png")
    imagefile = "gov_histcont.png"

    imagefile = image_border(imagefile)
    return {
        "title": "Stocks: Historical Quarterly Government Contract ",
        "imagefile": imagefile,
    }
def presets_default_command():
    """Displays default presets"""

    # Debug
    if cfg.DEBUG:
        logger.debug("scr-presets")

    description = ""
    for signame, sigdesc in so.d_signals_desc.items():
        description += f"**{signame}:** *{sigdesc}*\n"

    return {
        "title": "Stocks: Screener Default Presets",
        "description": description,
    }
Example #10
0
def feargreed_command(indicator=""):
    """CNN Fear and Greed Index [CNN]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("econ-futures")

    # Check for argument
    possible_indicators = ("", "jbd", "mv", "pco", "mm", "sps", "spb", "shd")

    if indicator not in possible_indicators:
        raise Exception(
            f"Select a valid indicator from {', '.join(possible_indicators)}"  # nosec
        )

    # Retrieve data
    fig = plt.figure(figsize=[1, 1], dpi=10)

    report, _ = cnn_model.get_feargreed_report(indicator, fig)
    cnn_view.fear_and_greed_index(indicator=indicator, export="png")
    plt.close("all")

    # Output data
    now = datetime.datetime.now()
    image_path = os.path.join(
        cfg.GST_PATH,
        "exports",
        "economy",
        f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
    )

    i = 0
    while not os.path.exists(image_path) and i < 10:
        now -= datetime.timedelta(seconds=1)
        image_path = os.path.join(
            cfg.GST_PATH,
            "exports",
            "economy",
            f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
        )
        i += 1

    return {
        "title": "Economy: [CNN] Fear Geed Index",
        "imagefile": image_path,
        "description": report,
    }
Example #11
0
def contracts_command(
    ticker: str = "", past_transaction_days: Union[int, str] = 10, raw: bool = False
):
    """Displays contracts associated with tickers [quiverquant.com]"""
    past_transaction_days = int(past_transaction_days)
    # Debug user input
    if cfg.DEBUG:
        logger.debug("gov-contracts %s %s %s", ticker, past_transaction_days, raw)

    if ticker == "":
        raise Exception("A ticker is required")

    # Retrieve Data
    df_contracts = quiverquant_model.get_government_trading("contracts", ticker)

    if df_contracts.empty:
        return {
            "title": f"Stocks: [quiverquant.com] Contracts by {ticker}",
            "description": f"{ticker} does not have any contracts",
        }

    # Output Data
    df_contracts["Date"] = pd.to_datetime(df_contracts["Date"]).dt.date

    df_contracts = df_contracts[
        df_contracts["Date"].isin(df_contracts["Date"].unique()[:past_transaction_days])
    ]

    df_contracts.drop_duplicates(inplace=True)

    fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

    df_contracts.groupby("Date").sum().div(1000).plot(kind="bar", rot=0, ax=ax)
    ax.set_ylabel("Amount ($1k)")
    ax.set_title(f"Sum of latest government contracts to {ticker}")
    fig.tight_layout()

    plt.savefig("gov_contracts.png")
    imagefile = "gov_contracts.png"

    imagefile = image_border(imagefile)
    return {
        "title": f"Stocks: [quiverquant.com] Contracts by {ticker}",
        "imagefile": imagefile,
    }
Example #12
0
def analyst_command(ticker=""):
    """Displays analyst recommendations [Finviz]"""

    # Debug
    if cfg.DEBUG:
        logger.debug("dd-analyst %s", ticker)

    # Check for argument
    if not ticker:
        raise Exception("Stock ticker is required")

    df = finviz_model.get_analyst_data(ticker)
    df = df.replace(np.nan, 0)
    df.index.names = ["Date"]
    df = df.rename(
        columns={
            "category": "Category",
            "analyst": "Analyst",
            "rating": "Rating",
            "target": "Target",
            "target_from": "Target From",
            "target_to": "Target To",
        })

    dindex = len(df.index)
    fig = df2img.plot_dataframe(
        df,
        fig_size=(1500, (40 + (40 * dindex))),
        col_width=[5, 5, 8, 14, 5, 5, 5],
        tbl_cells=dict(height=35, ),
        font=dict(
            family="Consolas",
            size=20,
        ),
        template="plotly_dark",
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )
    imagefile = save_image("dd-analyst.png", fig)

    return {
        "title": f"Stocks: [Finviz] Analyst Recommendations {ticker.upper()}",
        "imagefile": imagefile,
    }
Example #13
0
def summary_command(ticker=""):
    """Displays text of a given stocks ta summary [FinBrain API]"""

    # Debug
    if cfg.DEBUG:
        logger.debug("ta-summary %s", ticker)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    report = finbrain_model.get_technical_summary_report(ticker)
    if report:
        report = "```" + report.replace(". ", ".\n") + "```"

    return {
        "title": "Stocks: [FinBrain API] Summary",
        "description": report,
    }
Example #14
0
def iv_command(ticker: str = None):
    """Options IV"""

    # Debug
    if cfg.DEBUG:
        logger.debug("opt-iv %s", ticker)

    # Check for argument
    if ticker is None:
        raise Exception("Stock ticker is required")

    df = barchart_model.get_options_info(ticker)
    df = df.fillna("")
    df = df.set_axis(
        [
            " ",
            "",
        ],
        axis="columns",
    )
    df.set_index(" ", inplace=True)
    fig = df2img.plot_dataframe(
        df,
        fig_size=(600, 1500),
        col_width=[3, 3],
        tbl_cells=dict(
            align="left",
            height=35,
        ),
        template="plotly_dark",
        font=dict(
            family="Consolas",
            size=20,
        ),
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )
    imagefile = save_image("opt-iv.png", fig)

    return {
        "title": f"{ticker.upper()} Options: IV",
        "imagefile": imagefile,
    }
Example #15
0
def ford_command():
    """Display Orders by Fidelity Customers. [Source: Fidelity]"""

    # Debug
    if cfg.DEBUG:
        logger.debug("disc-ford")
    order_header, df_orders = fidelity_model.get_orders()

    df_orders = df_orders.head(n=30).iloc[:, :-1]
    df_orders = df_orders.applymap(str)

    font_color = (["white"] * 2 + [[
        "#ad0000" if boolv else "#0d5700"
        for boolv in df_orders["Price Change"].str.contains("-")
    ]] + [["white"] * 3])

    df_orders.set_index("Symbol", inplace=True)
    df_orders = df_orders.apply(lambda x: x.str.slice(0, 20))

    dindex = len(df_orders.index)
    fig = df2img.plot_dataframe(
        df_orders,
        fig_size=(1500, (40 + (40 * dindex))),
        col_width=[1, 3, 2.2, 3, 2, 2],
        tbl_cells=dict(
            align=["left", "center", "left", "left", "center"],
            font=dict(color=font_color),
            height=35,
        ),
        template="plotly_dark",
        font=dict(
            family="Consolas",
            size=20,
        ),
        paper_bgcolor="rgba(0, 0, 0, 0)",
    )
    imagefile = save_image("disc-ford.png", fig)

    return {
        "title": "Fidelity Customer Orders",
        "imagefile": imagefile,
    }
Example #16
0
def recom_command(ticker=""):
    """Displays text of a given stocks recommendation based on ta [Tradingview API]"""

    # Debug
    if cfg.DEBUG:
        logger.debug("ta-recom %s", ticker)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    recom = tradingview_model.get_tradingview_recommendation(
        ticker, "america", "", "")

    recom = recom[["BUY", "NEUTRAL", "SELL", "RECOMMENDATION"]]

    report = "```" + recom.to_string() + "```"

    return {
        "title": "Stocks: [Tradingview API] Recommendation based on TA",
        "description": report,
    }
def presets_custom_command():
    """Displays every custom preset"""

    # Debug
    if cfg.DEBUG:
        logger.debug("scr-presets")

    description = ""
    for preset in so.presets:
        with open(
                so.presets_path + preset + ".ini",
                encoding="utf8",
        ) as f:
            preset_line = ""
            for line in f:
                if line.strip() == "[General]":
                    break
                preset_line += line.strip()
        description += f"**{preset}:** *{preset_line.split('Description: ')[1].replace('#', '')}*\n"

    return {
        "title": "Stocks: Screener Custom Presets",
        "description": description,
    }
Example #18
0
def view_command(ticker=""):
    """Displays image from Finviz [Finviz]"""

    # Debug
    if cfg.DEBUG:
        logger.debug("ta-view %s", ticker)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    image_data = finviz_model.get_finviz_image(ticker)
    dataBytesIO = io.BytesIO(image_data)
    im = Image.open(dataBytesIO)
    im = im.resize((800, 340), Image.ANTIALIAS)
    imagefile = "ta_view.png"

    im.save(imagefile, "PNG", quality=100)
    imagefile = image_border(imagefile)

    return {
        "title": f"Stocks: [Finviz] Trendlines & Data {ticker}",
        "imagefile": imagefile,
    }
Example #19
0
def sma_command(ticker="", window="", offset="", start="", end=""):
    """Displays chart with simple moving average [Yahoo Finance]"""

    # Debug
    if cfg.DEBUG:
        logger.debug(
            "ta-sma %s %s %s %s %s",
            ticker,
            window,
            offset,
            start,
            end,
        )

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    if start == "":
        start = datetime.now() - timedelta(days=365)
    else:
        start = datetime.strptime(start, cfg.DATE_FORMAT)

    if end == "":
        end = datetime.now()
    else:
        end = datetime.strptime(end, cfg.DATE_FORMAT)

    l_legend = [ticker]

    if window == "":
        window = [20, 50]
    else:
        window_temp = list()
        for wind in window.split(","):
            try:
                window_temp.append(float(wind))
            except Exception as e:
                raise Exception("Window needs to be a float") from e
        window = window_temp

    ticker = ticker.upper()
    stock = helpers.load(ticker, start)
    if stock.empty:
        raise Exception("Stock ticker is invalid")

    # Retrieve Data
    price_df = pd.DataFrame(stock["Adj Close"].values,
                            columns=["Price"],
                            index=stock.index)
    i = 1
    for win in window:
        sma_data = overlap_model.sma(values=stock["Adj Close"],
                                     length=win,
                                     offset=offset)
        price_df = price_df.join(sma_data)
        l_legend.append(f"SMA {win}")
        i += 1

    # Output Data
    start = start.strftime("%Y-%m-%d")
    end = end.strftime("%Y-%m-%d")
    price_df = price_df.loc[(price_df.index >= start) & (price_df.index < end)]

    fig = go.Figure()
    fig.add_trace(
        go.Scatter(
            name=f"{ticker}",
            x=price_df.index,
            y=price_df["Price"],
            line=dict(color="#fdc708", width=2),
            opacity=1,
        ), )
    for i in range(1, price_df.shape[1]):
        trace_name = price_df.columns[i].replace("_", " ")
        fig.add_trace(
            go.Scatter(
                name=trace_name,
                x=price_df.index,
                y=price_df.iloc[:, i],
                opacity=1,
            ), )
    fig.update_layout(
        margin=dict(l=0, r=0, t=50, b=20),
        template=cfg.PLT_TA_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"{ticker} SMA",
        title_x=0.5,
        yaxis_title="Stock Price ($)",
        xaxis_title="Time",
        yaxis=dict(fixedrange=False, ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
        ),
        dragmode="pan",
        legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),
    )
    config = dict({"scrollZoom": True})
    imagefile = "ta_sma.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/sma_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/sma_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )

    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": f"Stocks: Simple-Moving-Average {ticker}",
        "description": plt_link,
        "imagefile": imagefile,
    }
Example #20
0
def chain_command(
    ticker: str = None,
    expiry: str = None,
    opt_type: str = None,
    min_sp: float = None,
    max_sp: float = None,
):
    """Show calls/puts for given ticker and expiration"""

    # Debug
    if cfg.DEBUG:
        logger.debug("opt-chain %s %s %s %s %s", ticker, expiry, opt_type,
                     min_sp, max_sp)

    # Check for argument
    if not ticker:
        raise Exception("Stock ticker is required")

    dates = yfinance_model.option_expirations(ticker)

    if not dates:
        raise Exception("Stock ticker is invalid")

    options = yfinance_model.get_option_chain(ticker, str(expiry))
    calls_df = options.calls.fillna(0)
    puts_df = options.puts.fillna(0)

    column_map = {
        "openInterest": "oi",
        "volume": "vol",
        "impliedVolatility": "iv"
    }
    columns = [
        "strike",
        "bid",
        "ask",
        "volume",
        "openInterest",
        "impliedVolatility",
    ]

    if opt_type == "Calls":
        df = calls_df[columns].rename(columns=column_map)
    if opt_type == "Puts":
        df = puts_df[columns].rename(columns=column_map)

    min_strike = np.percentile(df["strike"], 1)
    max_strike = np.percentile(df["strike"], 100)

    if min_sp:
        min_strike = min_sp
    if max_sp:
        max_strike = max_sp
        if min_sp > max_sp:  # type: ignore
            min_sp, max_sp = max_strike, min_strike

    df = df[df["strike"] >= min_strike]
    df = df[df["strike"] <= max_strike]

    df["iv"] = pd.to_numeric(df["iv"].astype(float))

    formats = {"iv": "{:.2f}"}
    for col, f in formats.items():
        df[col] = df[col].map(lambda x: f.format(x))  # pylint: disable=W0640
    df.set_index("strike", inplace=True)

    title = (
        f"Stocks: {opt_type} Option Chain for {ticker.upper()} on {expiry} [yfinance]"
    )

    embeds: list = []
    # Output
    i, i2, end = 0, 0, 20
    df_pg = []
    embeds_img = []
    dindex = len(df.index)
    while i < dindex:
        df_pg = df.iloc[i:end]
        df_pg.append(df_pg)
        fig = df2img.plot_dataframe(
            df_pg,
            fig_size=(1000, (40 + (40 * 20))),
            col_width=[3, 3, 3, 3],
            tbl_cells=dict(height=35, ),
            font=dict(
                family="Consolas",
                size=20,
            ),
            template="plotly_dark",
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        imagefile = save_image(f"opt-chain{i}.png", fig)

        uploaded_image = gst_imgur.upload_image(imagefile, title="something")
        image_link = uploaded_image.link
        embeds_img.append(f"{image_link}", )
        embeds.append(disnake.Embed(
            title=title,
            colour=cfg.COLOR,
        ), )
        i2 += 1
        i += 20
        end += 20
        os.remove(imagefile)

    # Author/Footer
    for i in range(0, i2):
        embeds[i].set_author(
            name=cfg.AUTHOR_NAME,
            url=cfg.AUTHOR_URL,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embeds[i].set_footer(
            text=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

    i = 0
    for i in range(0, i2):
        embeds[i].set_image(url=embeds_img[i])

        i += 1
    embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
    choices = [
        disnake.SelectOption(label="Home", value="0", emoji="🟢"),
    ]

    return {
        "view": Menu,
        "title": title,
        "embed": embeds,
        "choices": choices,
        "embeds_img": embeds_img,
    }
Example #21
0
def vol_command(
    ticker: str = None,
    expiry: str = "",
    min_sp: float = None,
    max_sp: float = None,
):
    """Options VOL"""

    # Debug
    if cfg.DEBUG:
        logger.debug("opt-vol %s %s %s %s", ticker, expiry, min_sp, max_sp)

    # Check for argument
    if ticker is None:
        raise Exception("Stock ticker is required")

    dates = yfinance_model.option_expirations(ticker)

    if not dates:
        raise Exception("Stock ticker is invalid")

    options = yfinance_model.get_option_chain(ticker, expiry)
    current_price = yfinance_model.get_price(ticker)

    if min_sp is None:
        min_strike = 0.75 * current_price
    else:
        min_strike = min_sp

    if max_sp is None:
        max_strike = 1.25 * current_price
    else:
        max_strike = max_sp

    calls = options.calls
    puts = options.puts
    call_v = calls.set_index("strike")["volume"] / 1000
    put_v = puts.set_index("strike")["volume"] / 1000

    df_opt = pd.merge(put_v, call_v, left_index=True, right_index=True)
    dmax = df_opt.values.max()

    fig = go.Figure()
    fig.add_trace(
        go.Scatter(
            x=call_v.index,
            y=call_v.values,
            name="Calls",
            mode="lines+markers",
            line=dict(color="green", width=3),
        ))
    fig.add_trace(
        go.Scatter(
            x=put_v.index,
            y=put_v.values,
            name="Puts",
            mode="lines+markers",
            line=dict(color="red", width=3),
        ))
    fig.add_trace(
        go.Scatter(
            x=[current_price, current_price],
            y=[0, dmax],
            mode="lines",
            line=dict(color="gold", width=2),
            name="Current Price",
        ))
    fig.update_xaxes(
        range=[min_strike, max_strike],
        constrain="domain",
    )
    fig.update_layout(
        margin=dict(l=0, r=0, t=60, b=20),
        template=cfg.PLT_SCAT_STYLE_TEMPLATE,
        title=f"Volume for {ticker.upper()} expiring {expiry}",
        title_x=0.5,
        legend_title="",
        xaxis_title="Strike",
        yaxis_title="Volume (1k)",
        xaxis=dict(rangeslider=dict(visible=False), ),
        legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),
        dragmode="pan",
    )
    config = dict({"scrollZoom": True})
    imagefile = "opt_vol.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/vol_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/vol_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )

    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": f"Volume for {ticker.upper()} expiring {expiry}",
        "description": plt_link,
        "imagefile": imagefile,
    }
Example #22
0
def spos_command(ticker: str = ""):
    """Net short vs position [Stockgrid]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dps-spos %s", ticker)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    ticker = ticker.upper()

    stock = yf.download(ticker, progress=False)
    if stock.empty:
        raise Exception("Stock ticker is invalid")

    # Retrieve data
    df = stockgrid_model.get_net_short_position(ticker)

    # Debug user output
    if cfg.DEBUG:
        logger.debug(df.to_string())

    # Output data
    title = f"Stocks: [Stockgrid] Net Short vs Position {ticker}"

    fig = make_subplots(shared_xaxes=True, specs=[[{"secondary_y": True}]])

    fig.add_trace(
        go.Scatter(
            name="Position ($)",
            x=df["dates"].values,
            y=df["dollar_dp_position"] * 1_000,
            line=dict(color="#fdc708", width=2),
            opacity=1,
            showlegend=False,
        ),
        secondary_y=True,
    )
    fig.add_trace(
        go.Bar(
            name="Net Short Vol. ($)",
            x=df["dates"],
            y=df["dollar_net_volume"],
            opacity=1,
            showlegend=False,
        ),
        secondary_y=False,
    )
    # Set y-axes titles
    fig.update_xaxes(dtick="M1", tickformat="%b %d\n%Y")
    fig.update_yaxes(title_text="<b>Position</b> ($)", secondary_y=True)
    fig.update_traces(hovertemplate="%{y:.2s}")
    fig.update_layout(
        margin=dict(l=0, r=10, t=40, b=20),
        template=cfg.PLT_TA_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"Net Short Vol. vs Position for {ticker}",
        title_x=0.5,
        yaxis_title="<b>Net Short Vol.</b> ($)",
        yaxis=dict(
            side="left",
            showgrid=False,
            fixedrange=False,
            layer="above traces",
            titlefont=dict(color="#d81aea"),
            tickfont=dict(color="#d81aea"),
            nticks=10,
        ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
            fixedrange=False,
        ),
        xaxis2=dict(
            rangeslider=dict(visible=False),
            type="date",
            fixedrange=False,
        ),
        dragmode="pan",
        legend=dict(orientation="h",
                    yanchor="bottom",
                    y=1.02,
                    xanchor="right",
                    x=1),
        yaxis2=dict(
            side="right",
            position=0.15,
            fixedrange=False,
            titlefont=dict(color="#fdc708"),
            tickfont=dict(color="#fdc708"),
            nticks=10,
        ),
        hovermode="x unified",
    )
    config = dict({"scrollZoom": True})
    imagefile = "dps_spos.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/spos_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/spos_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )

    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": title,
        "description": plt_link,
        "imagefile": imagefile,
    }
Example #23
0
def fib_command(ticker="", start="", end=""):
    """Displays chart with fibonacci retracement [Yahoo Finance]"""

    # Debug
    if cfg.DEBUG:
        logger.debug(
            "ta-fib %s %s %s",
            ticker,
            start,
            end,
        )

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    if start == "":
        start = datetime.now() - timedelta(days=365)
        f_start = None
    else:
        start = datetime.strptime(start, cfg.DATE_FORMAT)
        f_start = start

    if end == "":
        end = datetime.now()
        f_end = None
    else:
        end = datetime.strptime(end, cfg.DATE_FORMAT)
        f_end = None

    ticker = ticker.upper()
    df_stock = bots.helpers.load(ticker, start)
    if df_stock.empty:
        raise Exception("Stock ticker is invalid")

    # Retrieve Data
    df_stock = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)]

    start = start.strftime("%Y-%m-%d")
    end = end.strftime("%Y-%m-%d")
    (
        df_fib,
        min_date,
        max_date,
        min_pr,
        max_pr,
    ) = custom_indicators_model.calculate_fib_levels(df_stock, 120, f_start, f_end)

    levels = df_fib.Price
    fig, ax = plt.subplots(figsize=(plot_autoscale()), dpi=cfp.PLOT_DPI)

    ax.plot(df_stock["Adj Close"], "b")
    ax.plot([min_date, max_date], [min_pr, max_pr], c="k")

    for i in levels:
        ax.axhline(y=i, c="g", alpha=0.5)

    for i in range(5):
        ax.fill_between(df_stock.index, levels[i], levels[i + 1], alpha=0.6)

    ax.set_ylabel("Price")
    ax.set_title(f"Fibonacci Support for {ticker.upper()}")
    ax.set_xlim(df_stock.index[0], df_stock.index[-1])

    ax1 = ax.twinx()
    ax1.set_ylim(ax.get_ylim())
    ax1.set_yticks(levels)
    ax1.set_yticklabels([0, 0.235, 0.382, 0.5, 0.618, 1])

    plt.gcf().autofmt_xdate()
    fig.tight_layout(pad=1)
    imagefile = "ta_fib.png"
    plt.savefig(imagefile)

    imagefile = image_border(imagefile)

    return {
        "title": f"Stocks: Fibonacci-Retracement-Levels {ticker}",
        "imagefile": imagefile,
    }
Example #24
0
def ftd_command(ticker: str = "", start="", end=""):
    """Fails-to-deliver data [SEC]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dps-ftd %s %s %s", ticker, start, end)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    ticker = ticker.upper()

    if start == "":
        start = datetime.now() - timedelta(days=365)
    else:
        start = datetime.strptime(start, cfg.DATE_FORMAT)

    if end == "":
        end = datetime.now()
    else:
        end = datetime.strptime(end, cfg.DATE_FORMAT)

    # Retrieve data
    ftds_data = sec_model.get_fails_to_deliver(ticker, start, end, 0)

    # Debug user output
    if cfg.DEBUG:
        logger.debug(ftds_data.to_string())

    stock = helpers.load(ticker, start)
    stock_ftd = stock[stock.index > start]
    stock_ftd = stock_ftd[stock_ftd.index < end]

    # Output data
    fig = make_subplots(shared_xaxes=True, specs=[[{"secondary_y": True}]])

    fig.add_trace(
        go.Scatter(
            name=ticker,
            x=stock_ftd.index,
            y=stock_ftd["Adj Close"],
            line=dict(color="#fdc708", width=2),
            opacity=1,
            showlegend=False,
        ),
        secondary_y=False,
    )
    fig.add_trace(
        go.Bar(
            name="FTDs",
            x=ftds_data["SETTLEMENT DATE"],
            y=ftds_data["QUANTITY (FAILS)"] / 1000,
            opacity=1,
        ),
        secondary_y=True,
    )
    # Set y-axes titles
    fig.update_yaxes(title_text="<b>Shares</b> [K]", secondary_y=True)
    fig.update_layout(
        margin=dict(l=0, r=20, t=30, b=20),
        template=cfg.PLT_TA_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"{ticker}",
        title_x=0.5,
        yaxis_title="<b>Stock Price</b> ($)",
        yaxis=dict(
            side="right",
            fixedrange=False,
        ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
            fixedrange=False,
        ),
        xaxis2=dict(
            rangeslider=dict(visible=False),
            type="date",
            fixedrange=False,
        ),
        dragmode="pan",
        legend=dict(orientation="h",
                    yanchor="bottom",
                    y=1.02,
                    xanchor="right",
                    x=1),
        yaxis2=dict(
            side="left",
            position=0.15,
            fixedrange=False,
        ),
        hovermode="x unified",
    )
    config = dict({"scrollZoom": True})
    imagefile = "dps_ftd.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/ftds_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/ftds_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )

    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": f"Stocks: [SEC] Failure-to-deliver {ticker}",
        "description": plt_link,
        "imagefile": imagefile,
    }
Example #25
0
def lastcontracts_command(past_transactions_days: int = 2, num: int = 20):
    """Displays last government contracts [quiverquant.com]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("gov lastcontracts %s %s", past_transactions_days, num)

    df_contracts = quiverquant_model.get_government_trading("contracts")

    if df_contracts.empty:
        logger.debug("No government contracts found")
        raise Exception("No government contracts found")

    df_contracts.sort_values("Date", ascending=False)

    df_contracts["Date"] = pd.to_datetime(df_contracts["Date"])
    df_contracts["Date"] = df_contracts["Date"].dt.date

    df_contracts.drop_duplicates(inplace=True)
    df_contracts = df_contracts[df_contracts["Date"].isin(
        df_contracts["Date"].unique()[:past_transactions_days])]

    df_contracts = df_contracts[["Date", "Ticker", "Amount", "Agency"]][:num]
    choices = [
        disnake.SelectOption(label="Overview", value="0", emoji="🟢"),
    ]
    title = "Stocks: [quiverquant.com] Top buy government trading"
    initial_str = "Overview"
    i = 1
    for col_name in df_contracts["Ticker"].values:
        menu = f"\nPage {i}: {col_name}"
        initial_str += f"\nPage {i}: {col_name}"
        choices.append(
            disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), )
        i += 1

    embeds = []
    df_contracts = df_contracts.T
    reports = [f"{initial_str}"]
    embeds.append(
        disnake.Embed(
            title=title,
            description=initial_str,
            colour=cfg.COLOR,
        ).set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        ))
    for column in df_contracts.columns.values:
        description = "```" + df_contracts[column].fillna(
            "").to_string() + "```"
        embeds.append(
            disnake.Embed(
                description=description,
                colour=cfg.COLOR,
            ).set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            ))
        reports.append(f"{description}")

    return {
        "view": Menu,
        "title": title,
        "description": reports,
        "embed": embeds,
        "choices": choices,
    }
Example #26
0
def shorted_command(num: int = 10):
    """Show most shorted stocks [Yahoo Finance]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dps-shorted %s", num)

    # Check for argument
    if num < 0:
        raise Exception("Number has to be above 0")

    # Retrieve data
    df = yahoofinance_model.get_most_shorted().head(num)

    # Debug user output
    if cfg.DEBUG:
        logger.debug(df.to_string())

    # Output data
    title = "Stocks: [Yahoo Finance] Most Shorted"
    df.dropna(how="all", axis=1, inplace=True)
    df = df.replace(float("NaN"), "")
    future_column_name = df["Symbol"]
    df = df.transpose()
    df.columns = future_column_name
    df.drop("Symbol")
    embeds = []
    choices = [
        disnake.SelectOption(label="Overview", value="0", emoji="🟢"),
    ]
    initial_str = "Overview"
    i = 1
    for col_name in df.columns.values:
        menu = f"\nPage {i}: {col_name}"
        initial_str += f"\nPage {i}: {col_name}"
        if i < 19:
            choices.append(
                disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"),
            )
        if i == 20:
            choices.append(
                disnake.SelectOption(label="Max Reached", value=f"{i}", emoji="🟢"),
            )
        i += 1

    reports = [f"{initial_str}"]
    embeds.append(
        disnake.Embed(
            title=title,
            description=initial_str,
            colour=cfg.COLOR,
        ).set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
    )
    for column in df.columns.values:
        description = "```" + df[column].fillna("").to_string() + "```"
        embeds.append(
            disnake.Embed(description=description, colour=cfg.COLOR,).set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
        )
        reports.append(f"{description}")

    return {
        "view": Menu,
        "title": title,
        "description": reports,
        "embed": embeds,
        "choices": choices,
    }
Example #27
0
def obv_command(ticker="", start="", end=""):
    """Displays chart with on balance volume [Yahoo Finance]"""

    # Debug
    if cfg.DEBUG:
        logger.debug(
            "ta-obv %s %s %s",
            ticker,
            start,
            end,
        )

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    if start == "":
        start = datetime.now() - timedelta(days=365)
    else:
        start = datetime.strptime(start, cfg.DATE_FORMAT)

    if end == "":
        end = datetime.now()
    else:
        end = datetime.strptime(end, cfg.DATE_FORMAT)

    ticker = ticker.upper()
    df_stock = helpers.load(ticker, start)
    if df_stock.empty:
        raise Exception("Stock ticker is invalid")

    # Retrieve Data
    df_stock = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)]

    # Output Data
    divisor = 1_000_000
    df_vol = df_stock["Volume"].dropna()
    df_vol = df_vol.values / divisor
    df_ta = volume_model.obv(df_stock)
    df_cal = df_ta.values
    df_cal = df_cal / divisor

    fig = make_subplots(
        rows=3,
        cols=1,
        shared_xaxes=True,
        vertical_spacing=0.06,
        row_width=[0.2, 0.2, 0.2],
    )
    fig.add_trace(
        go.Scatter(
            name=ticker,
            x=df_stock.index,
            y=df_stock["Adj Close"].values,
            line=dict(color="#fdc708", width=2),
            opacity=1,
        ),
        row=1,
        col=1,
    )
    colors = [
        "green" if row.Open < row["Adj Close"] else "red"
        for _, row in df_stock.iterrows()
    ]
    fig.add_trace(
        go.Bar(
            x=df_stock.index,
            y=df_vol,
            name="Volume [M]",
            marker_color=colors,
        ),
        row=2,
        col=1,
    )
    fig.add_trace(
        go.Scatter(
            name="OBC [M]",
            x=df_ta.index,
            y=df_ta.iloc[:, 0].values,
            line=dict(width=2),
            opacity=1,
        ),
        row=3,
        col=1,
    )
    fig.update_layout(
        margin=dict(l=10, r=0, t=40, b=20),
        template=cfg.PLT_TA_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"{ticker} OBV",
        title_x=0.4,
        yaxis_title="Stock Price ($)",
        yaxis2_title="Volume [M]",
        yaxis3_title="OBV [M]",
        yaxis=dict(fixedrange=False, ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
        ),
        dragmode="pan",
        legend=dict(orientation="h",
                    yanchor="bottom",
                    y=1.02,
                    xanchor="right",
                    x=1),
    )
    config = dict({"scrollZoom": True})
    imagefile = "ta_obv.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/obv_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/obv_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )
    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": f"Stocks: On-Balance-Volume {ticker}",
        "description": plt_link,
        "imagefile": imagefile,
    }
Example #28
0
def pos_command(sort="dpp_dollar", num: int = 10):
    """Dark pool short position [Stockgrid]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dps-pos %s %s", sort, num)

    # Check for argument
    possible_sorts = ("sv", "sv_pct", "nsv", "nsv_dollar", "dpp", "dpp_dollar")

    if sort not in possible_sorts:
        raise Exception(f"The possible sorts are: {', '.join(possible_sorts)}")

    if num < 0:
        raise Exception("Number has to be above 0")

    # Retrieve data
    df = stockgrid_model.get_dark_pool_short_positions(sort, False)
    df = df.iloc[:num]

    # Debug user output
    if cfg.DEBUG:
        logger.debug(df.to_string())

    # Output data
    title = "Stocks: [Stockgrid] Dark Pool Short Position"

    dp_date = df["Date"].values[0]
    df = df.drop(columns=["Date"])
    df["Net Short Volume $"] = df["Net Short Volume $"] / 100_000_000
    df["Short Volume"] = df["Short Volume"] / 1_000_000
    df["Net Short Volume"] = df["Net Short Volume"] / 1_000_000
    df["Short Volume %"] = df["Short Volume %"] * 100
    df["Dark Pools Position $"] = df["Dark Pools Position $"] / (1_000_000_000)
    df["Dark Pools Position"] = df["Dark Pools Position"] / 1_000_000
    df.columns = [
        "Ticker",
        "Short Vol. (1M)",
        "Short Vol. %",
        "Net Short Vol. (1M)",
        "Net Short Vol. ($100M)",
        "DP Position (1M)",
        "DP Position ($1B)",
    ]
    future_column_name = df["Ticker"]
    df = df.transpose()
    df.columns = future_column_name
    df.drop("Ticker")
    embeds = []
    choices = [
        disnake.SelectOption(label="Overview", value="0", emoji="🟢"),
    ]
    initial_str = "Overview"
    i = 1
    for col_name in df.columns.values:
        menu = f"\nPage {i}: {col_name}"
        initial_str += f"\nPage {i}: {col_name}"
        if i < 19:
            choices.append(
                disnake.SelectOption(label=menu, value=f"{i}", emoji="🟢"), )
        if i == 20:
            choices.append(
                disnake.SelectOption(label="Max Reached",
                                     value=f"{i}",
                                     emoji="🟢"), )
        i += 1

    reports = [f"{initial_str}"]
    embeds.append(
        disnake.Embed(
            title=title,
            description=initial_str,
            colour=cfg.COLOR,
        ).set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        ))
    for column in df.columns.values:
        description = ("```The following data corresponds to the date: " +
                       dp_date + "\n\n" + df[column].fillna("").to_string() +
                       "```", )
        embeds.append(
            disnake.Embed(
                title=title,
                description=description,
                colour=cfg.COLOR,
            ).set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            ))
        reports.append(f"{description}")

    return {
        "view": Menu,
        "title": title,
        "description": reports,
        "embed": embeds,
        "choices": choices,
    }
Example #29
0
def overview_command(preset: str = "template",
                     sort: str = "",
                     limit: int = 5,
                     ascend: bool = False):
    """Displays stocks with overview data such as Sector and Industry [Finviz]"""

    # Check for argument
    if preset == "template" or preset not in so.all_presets:
        raise Exception("Invalid preset selected!")

    # Debug
    if cfg.DEBUG:
        logger.debug("scr-overview %s %s %s %s", preset, sort, limit, ascend)

    # Check for argument
    if limit < 0:
        raise Exception("Number has to be above 0")

    # Output Data
    df_screen = get_screener_data(
        preset,
        "overview",
        limit,
        ascend,
    )

    description = ""
    title = "Stocks: [Finviz] Overview Screener"
    if isinstance(df_screen, pd.DataFrame):
        if df_screen.empty:
            raise Exception("No data found.")

        df_screen = df_screen.dropna(axis="columns", how="all")

        if sort:
            if " ".join(sort) in so.d_cols_to_sort["overview"]:
                df_screen = df_screen.sort_values(
                    by=[" ".join(sort)],
                    ascending=ascend,
                    na_position="last",
                )
            else:
                similar_cmd = difflib.get_close_matches(
                    " ".join(sort),
                    so.d_cols_to_sort["overview"],
                    n=1,
                    cutoff=0.7,
                )
                if similar_cmd:
                    description = f"Replacing '{' '.join(sort)}' by '{similar_cmd[0]}' so table can be sorted.\n\n"
                    df_screen = df_screen.sort_values(
                        by=[similar_cmd[0]],
                        ascending=ascend,
                        na_position="last",
                    )
                else:
                    raise ValueError(
                        f"Wrong sort column provided! Select from: {', '.join(so.d_cols_to_sort['overview'])}"
                    )

        df_screen = df_screen.fillna("")
        future_column_name = df_screen["Ticker"]
        df_screen = df_screen.head(n=limit).transpose()
        df_screen.columns = future_column_name
        df_screen.drop("Ticker")

        embeds = []
        choices = [
            disnake.SelectOption(label="Overview", value="0", emoji="🟢"),
        ]
        initial_str = description + "Overview"
        i = 1
        for column in df_screen.columns.values:
            menu = f"\nPage {i}: {column}"
            initial_str += f"\nPage {i}: {column}"
            if i < 19:
                choices.append(
                    disnake.SelectOption(label=menu,
                                         value=f"{i}",
                                         emoji="🟢"), )
            if i == 20:
                choices.append(
                    disnake.SelectOption(label="Max Reached",
                                         value=f"{i}",
                                         emoji="🟢"), )
            i += 1

        reports = [f"{initial_str}"]
        embeds.append(
            disnake.Embed(
                title=title,
                description=initial_str,
                colour=cfg.COLOR,
            ).set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            ))
        for column in df_screen.columns.values:
            description = f"```{df_screen[column].fillna('')}```"
            embeds.append(
                disnake.Embed(
                    title=title,
                    description=description,
                    colour=cfg.COLOR,
                ).set_author(
                    name=cfg.AUTHOR_NAME,
                    icon_url=cfg.AUTHOR_ICON_URL,
                ))
            reports.append(f"{description}")

    return {
        "view": Menu,
        "title": title,
        "description": reports,
        "embed": embeds,
        "choices": choices,
    }
Example #30
0
def dpotc_command(ticker: str = ""):
    """Dark pools (ATS) vs OTC data [FINRA]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("dps-dpotc %s", ticker)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    ticker = ticker.upper()

    stock = yf.download(ticker, progress=False)
    if stock.empty:
        raise Exception("Stock ticker is invalid")

    # Retrieve data
    ats, otc = finra_model.getTickerFINRAdata(ticker)

    # Debug user output
    if cfg.DEBUG:
        logger.debug(ats.to_string())
        logger.debug(otc.to_string())

    # Output data
    title = f"Stocks: [FINRA] Dark Pools (ATS) vs OTC {ticker}"

    if ats.empty and otc.empty:
        raise Exception("Stock ticker is invalid")

    fig = make_subplots(
        rows=2,
        cols=1,
        shared_xaxes=True,
        vertical_spacing=0.07,
        row_width=[0.4, 0.6],
        specs=[[{
            "secondary_y": True
        }], [{
            "secondary_y": False
        }]],
    )

    if not ats.empty and not otc.empty:
        fig.add_trace(
            go.Bar(
                x=ats.index,
                y=(ats["totalWeeklyShareQuantity"] +
                   otc["totalWeeklyShareQuantity"]),
                name="ATS",
                opacity=0.8,
            ),
            row=1,
            col=1,
            secondary_y=False,
        )
        fig.add_trace(
            go.Bar(
                x=otc.index,
                y=otc["totalWeeklyShareQuantity"],
                name="OTC",
                opacity=0.8,
                yaxis="y2",
                offset=0.0001,
            ),
            row=1,
            col=1,
        )

    elif not ats.empty:
        fig.add_trace(
            go.Bar(
                x=ats.index,
                y=(ats["totalWeeklyShareQuantity"] +
                   otc["totalWeeklyShareQuantity"]),
                name="ATS",
                opacity=0.8,
            ),
            row=1,
            col=1,
            secondary_y=False,
        )

    elif not otc.empty:
        fig.add_trace(
            go.Bar(
                x=otc.index,
                y=otc["totalWeeklyShareQuantity"],
                name="OTC",
                opacity=0.8,
                yaxis="y2",
                secondary_y=False,
            ),
            row=1,
            col=1,
        )

    if not ats.empty:
        fig.add_trace(
            go.Scatter(
                name="ATS",
                x=ats.index,
                y=ats["totalWeeklyShareQuantity"] /
                ats["totalWeeklyTradeCount"],
                line=dict(color="#fdc708", width=2),
                opacity=1,
                showlegend=False,
                yaxis="y2",
            ),
            row=2,
            col=1,
        )

        if not otc.empty:
            fig.add_trace(
                go.Scatter(
                    name="OTC",
                    x=otc.index,
                    y=otc["totalWeeklyShareQuantity"] /
                    otc["totalWeeklyTradeCount"],
                    line=dict(color="#d81aea", width=2),
                    opacity=1,
                    showlegend=False,
                ),
                row=2,
                col=1,
            )
    else:
        fig.add_trace(
            go.Scatter(
                name="OTC",
                x=otc.index,
                y=otc["totalWeeklyShareQuantity"] /
                otc["totalWeeklyTradeCount"],
                line=dict(color="#d81aea", width=2),
                opacity=1,
                showlegend=False,
            ),
            row=2,
            col=1,
        )

    fig.update_xaxes(showspikes=True, spikesnap="cursor", spikemode="across")
    fig.update_yaxes(showspikes=True, spikethickness=2)
    fig.update_layout(
        margin=dict(l=20, r=0, t=10, b=20),
        template=cfg.PLT_CANDLE_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"Dark Pools (ATS) vs OTC (Non-ATS) Data for {ticker}",
        title_x=0.5,
        yaxis3_title="Shares per Trade",
        yaxis_title="Total Weekly Shares",
        xaxis2_title="Weeks",
        yaxis=dict(
            fixedrange=False,
            side="left",
            nticks=20,
        ),
        yaxis2=dict(
            fixedrange=False,
            showgrid=False,
            overlaying="y",
            anchor="x",
            layer="above traces",
        ),
        yaxis3=dict(
            fixedrange=False,
            nticks=10,
        ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
            showspikes=True,
            nticks=20,
        ),
        legend=dict(orientation="h",
                    yanchor="bottom",
                    y=1.02,
                    xanchor="right",
                    x=1),
        barmode="group",
        bargap=0.5,
        bargroupgap=0,
        dragmode="pan",
        hovermode="x unified",
        spikedistance=1000,
        hoverdistance=100,
    )
    config = dict({"scrollZoom": True})
    imagefile = "dps_dpotc.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/dpotc_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/dpotc_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )

    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": title,
        "description": plt_link,
        "imagefile": imagefile,
    }