mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-12 20:31:18 +00:00
Groupme Bot (#1418)
* Added groupme helpers * Began handling of user input * Expanded commands, improved bot * Completed dictionary * Eliminated redundancies * Added more * Added debuggers for server * Fixed bugs * Improved input handling and image sending * Fixed dd-est * Fixed dd commands * Added dps fix * Fixed feargreed * Fixed econ commands * Fixed gov commands * Fixed ta * Added docstrings * Added docstrings * black Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
This commit is contained in:
@@ -12,15 +12,7 @@ from bots.stocks.dark_pool_shorts.psi import psi_command
|
||||
from bots.stocks.dark_pool_shorts.shorted import shorted_command
|
||||
from bots.stocks.dark_pool_shorts.sidtc import sidtc_command
|
||||
from bots.stocks.dark_pool_shorts.spos import spos_command
|
||||
|
||||
pos_choices = {
|
||||
"Short Vol (1M)": "sv",
|
||||
"Short Vol %": "sv_pct",
|
||||
"Net Short Vol (1M)": "nsv",
|
||||
"Net Short Vol ($100M)": "nsv_dollar",
|
||||
"DP Position (1M)": "dpp",
|
||||
"DP Position ($1B)": "dpp_dollar",
|
||||
}
|
||||
from bots.common import commands_dict
|
||||
|
||||
|
||||
class DarkPoolShortsCommands(commands.Cog):
|
||||
@@ -57,7 +49,7 @@ class DarkPoolShortsCommands(commands.Cog):
|
||||
async def pos(
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
sort: str = commands.Param(choices=pos_choices),
|
||||
sort: str = commands.Param(choices=commands_dict.dps_pos_choices),
|
||||
num: int = 10,
|
||||
):
|
||||
"""Dark pool short position [Stockgrid]
|
||||
|
||||
@@ -16,34 +16,7 @@ from bots.economy.softs import softs_command
|
||||
from bots.economy.usbonds import usbonds_command
|
||||
from bots.economy.valuation import valuation_command
|
||||
from bots.helpers import ShowView
|
||||
|
||||
group = [
|
||||
"basic_materials",
|
||||
"capitalization",
|
||||
"communication_services",
|
||||
"consumer_cyclical",
|
||||
"consumer_defensive",
|
||||
"country",
|
||||
"energy",
|
||||
"financial",
|
||||
"healthcare",
|
||||
"industry",
|
||||
"industrials",
|
||||
"real_estate",
|
||||
"sector",
|
||||
"technology",
|
||||
"utilities",
|
||||
]
|
||||
|
||||
fgind = {
|
||||
"Junk Bond Demand": "jbd",
|
||||
"Market Volatility": "mv",
|
||||
"Put and Call Options": "pco",
|
||||
"Market Momentum": "mm",
|
||||
"Stock Price Strength": "sps",
|
||||
"Stock Price Breadth": "spb",
|
||||
"Safe Heaven Demand": "shd",
|
||||
}
|
||||
from bots.common import commands_dict
|
||||
|
||||
|
||||
class EconomyCommands(commands.Cog):
|
||||
@@ -116,7 +89,7 @@ class EconomyCommands(commands.Cog):
|
||||
async def valuation(
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
economy_group: str = commands.Param(choices=group),
|
||||
economy_group: str = commands.Param(choices=commands_dict.econ_group),
|
||||
):
|
||||
"""Valuation of sectors, industry, country [Finviz]
|
||||
|
||||
@@ -132,7 +105,7 @@ class EconomyCommands(commands.Cog):
|
||||
async def performance(
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
economy_group: str = commands.Param(choices=group),
|
||||
economy_group: str = commands.Param(choices=commands_dict.econ_group),
|
||||
):
|
||||
"""Performance of sectors, industry, country [Finviz]
|
||||
|
||||
|
||||
@@ -17,12 +17,7 @@ from bots.stocks.options.unu import unu_command
|
||||
from bots.stocks.options.vol import vol_command
|
||||
from bots.stocks.options.vsurf import vsurf_command
|
||||
from bots.stocks.quote import quote_command
|
||||
|
||||
vsurf_choices = {
|
||||
"Volatility": "IV",
|
||||
"Open Interest": "OI",
|
||||
"Last Price": "LP",
|
||||
}
|
||||
from bots.common import commands_dict
|
||||
|
||||
|
||||
class SlashCommands(commands.Cog):
|
||||
@@ -268,7 +263,7 @@ class SlashCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
ticker: str = commands.Param(autocomplete=ticker_autocomp),
|
||||
z: str = commands.Param(choices=vsurf_choices),
|
||||
z: str = commands.Param(choices=commands_dict.options_vsurf_choices),
|
||||
):
|
||||
"""Display Volatility Surface
|
||||
|
||||
|
||||
@@ -13,108 +13,8 @@ from bots.stocks.screener.presets_custom import presets_custom_command
|
||||
from bots.stocks.screener.presets_default import presets_default_command
|
||||
from bots.stocks.screener.technical import technical_command
|
||||
from bots.stocks.screener.valuation import valuation_command
|
||||
from bots.common import commands_dict
|
||||
|
||||
sort = {
|
||||
"overview": [
|
||||
"Ticker",
|
||||
"Company",
|
||||
"Sector",
|
||||
"Industry",
|
||||
"Country",
|
||||
"Market Cap",
|
||||
"P/E",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"valuation": [
|
||||
"Ticker",
|
||||
"Market Cap",
|
||||
"P/E",
|
||||
"Fwd P/E",
|
||||
"PEG",
|
||||
"P/S",
|
||||
"P/B",
|
||||
"P/C",
|
||||
"P/FCF",
|
||||
"EPS this Y",
|
||||
"EPS next Y",
|
||||
"EPS past 5Y",
|
||||
"EPS next 5Y",
|
||||
"Sales past 5Y",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"financial": [
|
||||
"Ticker",
|
||||
"Market Cap",
|
||||
"Dividend",
|
||||
"ROA",
|
||||
"ROE",
|
||||
"ROI",
|
||||
"Curr R",
|
||||
"Quick R",
|
||||
"LTDebt/Eq",
|
||||
"Debt/Eq",
|
||||
"Gross M",
|
||||
"Oper M",
|
||||
"Profit M",
|
||||
"Earnings",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"ownership": [
|
||||
"Ticker",
|
||||
"Market Cap",
|
||||
"Outstanding",
|
||||
"Float",
|
||||
"Insider Own",
|
||||
"Insider Trans",
|
||||
"Inst Own",
|
||||
"Inst Trans",
|
||||
"Float Short",
|
||||
"Short Ratio",
|
||||
"Avg Volume",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"performance": [
|
||||
"Ticker",
|
||||
"Perf Week",
|
||||
"Perf Month",
|
||||
"Perf Quart",
|
||||
"Perf Half",
|
||||
"Perf Year",
|
||||
"Perf YTD",
|
||||
"Volatility W",
|
||||
"Volatility M",
|
||||
"Recom",
|
||||
"Avg Volume",
|
||||
"Rel Volume",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"technical": [
|
||||
"Ticker",
|
||||
"Beta",
|
||||
"ATR",
|
||||
"SMA20",
|
||||
"SMA50",
|
||||
"SMA200",
|
||||
"52W High",
|
||||
"52W Low",
|
||||
"RSI",
|
||||
"Price",
|
||||
"Change",
|
||||
"from Open",
|
||||
"Gap",
|
||||
"Volume",
|
||||
],
|
||||
}
|
||||
# pylint: disable=R0912
|
||||
|
||||
|
||||
@@ -157,7 +57,7 @@ class ScreenerCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
preset: str = commands.Param(autocomplete=presets_custom_autocomp),
|
||||
sort: str = commands.Param(choices=sort["overview"]),
|
||||
sort: str = commands.Param(choices=commands_dict.screener_sort["overview"]),
|
||||
limit: int = 5,
|
||||
ascend: bool = False,
|
||||
):
|
||||
@@ -179,7 +79,7 @@ class ScreenerCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
preset: str = commands.Param(autocomplete=presets_custom_autocomp),
|
||||
sort: str = commands.Param(choices=sort["valuation"]),
|
||||
sort: str = commands.Param(choices=commands_dict.screener_sort["valuation"]),
|
||||
limit: int = 5,
|
||||
ascend: bool = False,
|
||||
):
|
||||
@@ -201,7 +101,7 @@ class ScreenerCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
preset: str = commands.Param(autocomplete=presets_custom_autocomp),
|
||||
sort: str = commands.Param(choices=sort["financial"]),
|
||||
sort: str = commands.Param(choices=commands_dict.screener_sort["financial"]),
|
||||
limit: int = 5,
|
||||
ascend: bool = False,
|
||||
):
|
||||
@@ -223,7 +123,7 @@ class ScreenerCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
preset: str = commands.Param(autocomplete=presets_custom_autocomp),
|
||||
sort: str = commands.Param(choices=sort["ownership"]),
|
||||
sort: str = commands.Param(choices=commands_dict.screener_sort["ownership"]),
|
||||
limit: int = 5,
|
||||
ascend: bool = False,
|
||||
):
|
||||
@@ -245,7 +145,7 @@ class ScreenerCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
preset: str = commands.Param(autocomplete=presets_custom_autocomp),
|
||||
sort: str = commands.Param(choices=sort["performance"]),
|
||||
sort: str = commands.Param(choices=commands_dict.screener_sort["performance"]),
|
||||
limit: int = 5,
|
||||
ascend: bool = False,
|
||||
):
|
||||
@@ -267,7 +167,7 @@ class ScreenerCommands(commands.Cog):
|
||||
self,
|
||||
inter: disnake.AppCmdInter,
|
||||
preset: str = commands.Param(autocomplete=presets_custom_autocomp),
|
||||
sort: str = commands.Param(choices=sort["technical"]),
|
||||
sort: str = commands.Param(choices=commands_dict.screener_sort["technical"]),
|
||||
limit: int = 5,
|
||||
ascend: bool = False,
|
||||
):
|
||||
|
||||
@@ -29,26 +29,6 @@ from bots.stocks.technical_analysis.view import view_command
|
||||
from bots.stocks.technical_analysis.wma import wma_command
|
||||
from bots.stocks.technical_analysis.zlma import zlma_command
|
||||
|
||||
possible_ma = [
|
||||
"dema",
|
||||
"ema",
|
||||
"fwma",
|
||||
"hma",
|
||||
"linreg",
|
||||
"midpoint",
|
||||
"pwma",
|
||||
"rma",
|
||||
"sinwma",
|
||||
"sma",
|
||||
"swma",
|
||||
"t3",
|
||||
"tema",
|
||||
"trima",
|
||||
"vidya",
|
||||
"wma",
|
||||
"zlma",
|
||||
]
|
||||
|
||||
|
||||
class TechnicalAnalysisCommands(commands.Cog):
|
||||
"""Technical Analysis menu."""
|
||||
|
||||
809
bots/common/commands_dict.py
Normal file
809
bots/common/commands_dict.py
Normal file
@@ -0,0 +1,809 @@
|
||||
import re
|
||||
from typing import List
|
||||
|
||||
import pandas as pd
|
||||
from bots.economy.currencies import currencies_command
|
||||
from bots.economy.energy import energy_command
|
||||
from bots.economy.feargreed import feargreed_command
|
||||
from bots.economy.futures import futures_command
|
||||
from bots.economy.glbonds import glbonds_command
|
||||
from bots.economy.grains import grains_command
|
||||
from bots.economy.indices import indices_command
|
||||
from bots.economy.meats import meats_command
|
||||
from bots.economy.metals import metals_command
|
||||
from bots.economy.overview import overview_command
|
||||
from bots.economy.performance import performance_command
|
||||
from bots.economy.softs import softs_command
|
||||
from bots.economy.usbonds import usbonds_command
|
||||
from bots.economy.valuation import valuation_command
|
||||
from bots.stocks.candle import candle_command
|
||||
from bots.stocks.dark_pool_shorts.dpotc import dpotc_command
|
||||
from bots.stocks.dark_pool_shorts.ftd import ftd_command
|
||||
from bots.stocks.dark_pool_shorts.hsi import hsi_command
|
||||
from bots.stocks.dark_pool_shorts.pos import pos_command
|
||||
from bots.stocks.dark_pool_shorts.psi import psi_command
|
||||
from bots.stocks.dark_pool_shorts.shorted import shorted_command
|
||||
from bots.stocks.dark_pool_shorts.sidtc import sidtc_command
|
||||
from bots.stocks.dark_pool_shorts.spos import spos_command
|
||||
from bots.stocks.disc.ford import ford_command
|
||||
from bots.stocks.due_diligence.analyst import analyst_command
|
||||
from bots.stocks.due_diligence.arktrades import arktrades_command
|
||||
from bots.stocks.due_diligence.customer import customer_command
|
||||
from bots.stocks.due_diligence.est import est_command
|
||||
from bots.stocks.due_diligence.pt import pt_command
|
||||
from bots.stocks.due_diligence.sec import sec_command
|
||||
from bots.stocks.due_diligence.supplier import supplier_command
|
||||
from bots.stocks.government.contracts import contracts_command
|
||||
from bots.stocks.government.gtrades import gtrades_command
|
||||
from bots.stocks.government.histcont import histcont_command
|
||||
from bots.stocks.government.lastcontracts import lastcontracts_command
|
||||
from bots.stocks.government.lasttrades import lasttrades_command
|
||||
from bots.stocks.government.lobbying import lobbying_command
|
||||
from bots.stocks.government.qtrcontracts import qtrcontracts_command
|
||||
from bots.stocks.government.topbuys import topbuys_command
|
||||
from bots.stocks.government.toplobbying import toplobbying_command
|
||||
from bots.stocks.government.topsells import topsells_command
|
||||
from bots.stocks.insider.lins import lins_command
|
||||
from bots.stocks.options.cc_hist import cc_hist_command
|
||||
from bots.stocks.options.hist import hist_command
|
||||
from bots.stocks.options.iv import iv_command
|
||||
from bots.stocks.options.oi import oi_command
|
||||
from bots.stocks.options.opt_chain import chain_command
|
||||
from bots.stocks.options.overview import overview_command as overview_opt_command
|
||||
from bots.stocks.options.unu import unu_command
|
||||
from bots.stocks.options.vol import vol_command
|
||||
from bots.stocks.options.vsurf import vsurf_command
|
||||
from bots.stocks.quote import quote_command
|
||||
from bots.stocks.screener.financial import financial_command
|
||||
from bots.stocks.screener.historical import historical_command
|
||||
from bots.stocks.screener.overview import overview_command as overview_screener_command
|
||||
from bots.stocks.screener.ownership import ownership_command
|
||||
from bots.stocks.screener.performance import (
|
||||
performance_command as performance_screener_command,
|
||||
)
|
||||
from bots.stocks.screener.presets_custom import presets_custom_command
|
||||
from bots.stocks.screener.presets_default import presets_default_command
|
||||
from bots.stocks.screener.technical import technical_command
|
||||
from bots.stocks.screener.valuation import (
|
||||
valuation_command as valuation_screener_command,
|
||||
)
|
||||
from bots.stocks.technical_analysis.ad import ad_command
|
||||
from bots.stocks.technical_analysis.adosc import adosc_command
|
||||
from bots.stocks.technical_analysis.adx import adx_command
|
||||
from bots.stocks.technical_analysis.aroon import aroon_command
|
||||
from bots.stocks.technical_analysis.bbands import bbands_command
|
||||
from bots.stocks.technical_analysis.cci import cci_command
|
||||
from bots.stocks.technical_analysis.donchian import donchian_command
|
||||
from bots.stocks.technical_analysis.ema import ema_command
|
||||
from bots.stocks.technical_analysis.fib import fib_command
|
||||
from bots.stocks.technical_analysis.fisher import fisher_command
|
||||
from bots.stocks.technical_analysis.hma import hma_command
|
||||
from bots.stocks.technical_analysis.kc import kc_command
|
||||
from bots.stocks.technical_analysis.macd import macd_command
|
||||
from bots.stocks.technical_analysis.obv import obv_command
|
||||
from bots.stocks.technical_analysis.recom import recom_command
|
||||
from bots.stocks.technical_analysis.rsi import rsi_command
|
||||
from bots.stocks.technical_analysis.sma import sma_command
|
||||
from bots.stocks.technical_analysis.stoch import stoch_command
|
||||
from bots.stocks.technical_analysis.summary import summary_command
|
||||
from bots.stocks.technical_analysis.view import view_command
|
||||
from bots.stocks.technical_analysis.wma import wma_command
|
||||
from bots.stocks.technical_analysis.zlma import zlma_command
|
||||
|
||||
re_date = re.compile(r"/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/")
|
||||
re_int = re.compile(r"^[1-9]\d*$")
|
||||
re_float = re.compile(r"^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$")
|
||||
re_name = re.compile(r"(?s).*")
|
||||
re_window = re.compile(r"(?s).*")
|
||||
|
||||
gov_type = ["congress", "senate", "house"]
|
||||
|
||||
dps_pos_choices = {
|
||||
"Short Vol (1M)": "sv",
|
||||
"Short Vol %": "sv_pct",
|
||||
"Net Short Vol (1M)": "nsv",
|
||||
"Net Short Vol ($100M)": "nsv_dollar",
|
||||
"DP Position (1M)": "dpp",
|
||||
"DP Position ($1B)": "dpp_dollar",
|
||||
}
|
||||
|
||||
econ_group = [
|
||||
"basic_materials",
|
||||
"capitalization",
|
||||
"communication_services",
|
||||
"consumer_cyclical",
|
||||
"consumer_defensive",
|
||||
"country",
|
||||
"energy",
|
||||
"financial",
|
||||
"healthcare",
|
||||
"industry",
|
||||
"industrials",
|
||||
"real_estate",
|
||||
"sector",
|
||||
"technology",
|
||||
"utilities",
|
||||
]
|
||||
|
||||
econ_fgind = {
|
||||
"Junk Bond Demand": "jbd",
|
||||
"Market Volatility": "mv",
|
||||
"Put and Call Options": "pco",
|
||||
"Market Momentum": "mm",
|
||||
"Stock Price Strength": "sps",
|
||||
"Stock Price Breadth": "spb",
|
||||
"Safe Heaven Demand": "shd",
|
||||
}
|
||||
|
||||
options_vsurf_choices = {
|
||||
"Volatility": "IV",
|
||||
"Open Interest": "OI",
|
||||
"Last Price": "LP",
|
||||
}
|
||||
|
||||
opt_intervals = [1, 5, 15, 30, 60, 1440]
|
||||
|
||||
|
||||
screener_sort = {
|
||||
"overview": [
|
||||
"Ticker",
|
||||
"Company",
|
||||
"Sector",
|
||||
"Industry",
|
||||
"Country",
|
||||
"Market Cap",
|
||||
"P/E",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"valuation": [
|
||||
"Ticker",
|
||||
"Market Cap",
|
||||
"P/E",
|
||||
"Fwd P/E",
|
||||
"PEG",
|
||||
"P/S",
|
||||
"P/B",
|
||||
"P/C",
|
||||
"P/FCF",
|
||||
"EPS this Y",
|
||||
"EPS next Y",
|
||||
"EPS past 5Y",
|
||||
"EPS next 5Y",
|
||||
"Sales past 5Y",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"financial": [
|
||||
"Ticker",
|
||||
"Market Cap",
|
||||
"Dividend",
|
||||
"ROA",
|
||||
"ROE",
|
||||
"ROI",
|
||||
"Curr R",
|
||||
"Quick R",
|
||||
"LTDebt/Eq",
|
||||
"Debt/Eq",
|
||||
"Gross M",
|
||||
"Oper M",
|
||||
"Profit M",
|
||||
"Earnings",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"ownership": [
|
||||
"Ticker",
|
||||
"Market Cap",
|
||||
"Outstanding",
|
||||
"Float",
|
||||
"Insider Own",
|
||||
"Insider Trans",
|
||||
"Inst Own",
|
||||
"Inst Trans",
|
||||
"Float Short",
|
||||
"Short Ratio",
|
||||
"Avg Volume",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"performance": [
|
||||
"Ticker",
|
||||
"Perf Week",
|
||||
"Perf Month",
|
||||
"Perf Quart",
|
||||
"Perf Half",
|
||||
"Perf Year",
|
||||
"Perf YTD",
|
||||
"Volatility W",
|
||||
"Volatility M",
|
||||
"Recom",
|
||||
"Avg Volume",
|
||||
"Rel Volume",
|
||||
"Price",
|
||||
"Change",
|
||||
"Volume",
|
||||
],
|
||||
"technical": [
|
||||
"Ticker",
|
||||
"Beta",
|
||||
"ATR",
|
||||
"SMA20",
|
||||
"SMA50",
|
||||
"SMA200",
|
||||
"52W High",
|
||||
"52W Low",
|
||||
"RSI",
|
||||
"Price",
|
||||
"Change",
|
||||
"from Open",
|
||||
"Gap",
|
||||
"Volume",
|
||||
],
|
||||
}
|
||||
|
||||
presets = [
|
||||
"potential_reversals",
|
||||
"golden_cross_penny",
|
||||
"rosenwald_gtfo",
|
||||
"golden_cross",
|
||||
"bull_runs_over_10pct",
|
||||
"recent_growth_and_support",
|
||||
"heavy_inst_ins",
|
||||
"short_squeeze_scan",
|
||||
"under_15dol_stocks",
|
||||
"top_performers_healthcare",
|
||||
"oversold_under_3dol",
|
||||
"value_stocks",
|
||||
"cheap_dividend",
|
||||
"death_cross",
|
||||
"top_performers_tech",
|
||||
"unusual_volume",
|
||||
"cheap_oversold",
|
||||
"undervalue",
|
||||
"high_vol_and_low_debt",
|
||||
"simplistic_momentum_scanner_under_7dol",
|
||||
"5pct_above_low",
|
||||
"growth_stocks",
|
||||
"cheap_bottom_dividend",
|
||||
"analyst_strong_buy",
|
||||
"oversold",
|
||||
"rosenwald",
|
||||
"weak_support_and_top_performers",
|
||||
"channel_up_and_low_debt_and_sma_50and200",
|
||||
"template",
|
||||
"modified_neff",
|
||||
"buffett_like",
|
||||
"oversold_under_5dol",
|
||||
"sexy_year",
|
||||
"news_scanner",
|
||||
"top_performers_all",
|
||||
"stocks_strong_support_levels",
|
||||
"continued_momentum_scan",
|
||||
"modified_dreman",
|
||||
"break_out_stocks",
|
||||
]
|
||||
signals = [
|
||||
"top_gainers",
|
||||
"top_losers",
|
||||
"new_high",
|
||||
"new_low",
|
||||
"most_volatile",
|
||||
"most_active",
|
||||
"unusual_volume",
|
||||
"overbought",
|
||||
"oversold",
|
||||
"downgrades",
|
||||
"upgrades",
|
||||
"earnings_before",
|
||||
"earnings_after",
|
||||
"recent_insider_buying",
|
||||
"recent_insider_selling",
|
||||
"major_news",
|
||||
"horizontal_sr",
|
||||
"tl_resistance",
|
||||
"tl_support",
|
||||
"wedge_up",
|
||||
"wedge_down",
|
||||
"wedge",
|
||||
"triangle_ascending",
|
||||
"triangle_descending",
|
||||
"channel_up",
|
||||
"channel_down",
|
||||
"channel",
|
||||
"double_top",
|
||||
"double_bottom",
|
||||
"multiple_top",
|
||||
"multiple_bottom",
|
||||
"head_shoulders",
|
||||
"head_shoulders_inverse",
|
||||
]
|
||||
|
||||
possible_ma = [
|
||||
"dema",
|
||||
"ema",
|
||||
"fwma",
|
||||
"hma",
|
||||
"linreg",
|
||||
"midpoint",
|
||||
"pwma",
|
||||
"rma",
|
||||
"sinwma",
|
||||
"sma",
|
||||
"swma",
|
||||
"t3",
|
||||
"tema",
|
||||
"trima",
|
||||
"vidya",
|
||||
"wma",
|
||||
"zlma",
|
||||
]
|
||||
|
||||
|
||||
def get_tickers() -> List[str]:
|
||||
col_list = ["Name"]
|
||||
df = pd.read_csv("files/tickers.csv", usecols=col_list)
|
||||
df = df["Name"]
|
||||
return df.tolist()
|
||||
|
||||
|
||||
tickers = get_tickers()
|
||||
|
||||
commands = {
|
||||
"dd-analyst": {
|
||||
"function": analyst_command,
|
||||
"required": {"ticker": tickers},
|
||||
},
|
||||
"dd-pt": {
|
||||
"function": pt_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"raw": [True, False], "start": re_date},
|
||||
},
|
||||
"dd-est": {"function": est_command, "required": {"ticker": tickers}},
|
||||
"dd-sec": {"function": sec_command, "required": {"ticker": tickers}},
|
||||
"dd-supplier": {
|
||||
"function": supplier_command,
|
||||
"required": {"ticker": tickers},
|
||||
},
|
||||
"dd-customer": {
|
||||
"function": customer_command,
|
||||
"required": {"ticker": tickers},
|
||||
},
|
||||
"dd-arktrades": {
|
||||
"function": arktrades_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
},
|
||||
"optional": {"num": re_int},
|
||||
},
|
||||
"dps-shorted": {"function": shorted_command, "optional": re_int},
|
||||
"dps-hsi": {"function": hsi_command, "optional": {"num": re_int}},
|
||||
"dps-pos": {
|
||||
"function": pos_command,
|
||||
"required": {"sort": dps_pos_choices.values()},
|
||||
"optional": {"num": re_int},
|
||||
},
|
||||
"dps-sidtc": {
|
||||
"function": sidtc_command,
|
||||
"required": {"sort": ["float", "dtc", "si"]},
|
||||
"optional": {"num": re_int},
|
||||
},
|
||||
"dps-ftd": {
|
||||
"function": ftd_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"start": re_date, "end": re_date},
|
||||
},
|
||||
"dps-dpotc": {
|
||||
"function": dpotc_command,
|
||||
"required": {"ticker": tickers},
|
||||
},
|
||||
"dps-spos": {"function": spos_command, "required": {"ticker": tickers}},
|
||||
"dps-psi": {"function": psi_command, "required": {"ticker": tickers}},
|
||||
"econ-feargreed": {
|
||||
"function": feargreed_command,
|
||||
},
|
||||
"econ-overview": {
|
||||
"function": overview_command,
|
||||
},
|
||||
"econ-indices": {
|
||||
"function": indices_command,
|
||||
},
|
||||
"econ-futures": {
|
||||
"function": futures_command,
|
||||
},
|
||||
"econ-usbonds": {
|
||||
"function": usbonds_command,
|
||||
},
|
||||
"econ-glbonds": {
|
||||
"function": glbonds_command,
|
||||
},
|
||||
"econ-energy": {
|
||||
"function": energy_command,
|
||||
},
|
||||
"econ-metals": {
|
||||
"function": metals_command,
|
||||
},
|
||||
"econ-meats": {
|
||||
"function": meats_command,
|
||||
},
|
||||
"econ-grains": {
|
||||
"function": grains_command,
|
||||
},
|
||||
"econ-softs": {
|
||||
"function": softs_command,
|
||||
},
|
||||
"econ-currencies": {
|
||||
"function": currencies_command,
|
||||
},
|
||||
"econ-valuation": {
|
||||
"function": valuation_command,
|
||||
"required": {"economy_group": econ_group},
|
||||
},
|
||||
"econ-performance": {
|
||||
"function": performance_command,
|
||||
"required": {"economy_group": econ_group},
|
||||
},
|
||||
"gov-lasttrades": {
|
||||
"function": lasttrades_command,
|
||||
"required": {"gov_type": gov_type},
|
||||
"optional": {"past_days": re_int, "representative": re_name},
|
||||
},
|
||||
"gov-topbuys": {
|
||||
"function": topbuys_command,
|
||||
"required": {"gov_type": gov_type},
|
||||
"optional": {
|
||||
"past_transactions_months": re_int,
|
||||
"num": re_int,
|
||||
"raw": [True, False],
|
||||
},
|
||||
},
|
||||
"gov-topsells": {
|
||||
"function": topsells_command,
|
||||
"required": {"gov_type": gov_type},
|
||||
"optional": {
|
||||
"past_transactions_months": re_int,
|
||||
"num": re_int,
|
||||
"raw": [True, False],
|
||||
},
|
||||
},
|
||||
"gov-lastcontracts": {
|
||||
"function": lastcontracts_command,
|
||||
"optional": {"past_transactions_days": re_int, "num": re_int},
|
||||
},
|
||||
"gov-qtrcontracts": {
|
||||
"function": qtrcontracts_command,
|
||||
"required": {"analysis": ["total", "upmom", "downmom"]},
|
||||
"optional": {
|
||||
"num": re_int,
|
||||
},
|
||||
},
|
||||
"gov-toplobbying": {
|
||||
"function": toplobbying_command,
|
||||
"optional": {"num": re_int, "raw": [True, False]},
|
||||
},
|
||||
"gov-gtrades": {
|
||||
"function": gtrades_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"gov_type": gov_type,
|
||||
},
|
||||
"optional": {"past_transactions_months": re_int, "raw": [True, False]},
|
||||
},
|
||||
"gov-contracts": {
|
||||
"function": contracts_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"past_transaction_days": re_int,
|
||||
"raw": [True, False],
|
||||
},
|
||||
},
|
||||
"gov-histcont": {"function": histcont_command, "required": {"ticker": tickers}},
|
||||
"gov-lobbying": {
|
||||
"function": lobbying_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"num": re_int,
|
||||
},
|
||||
},
|
||||
"opt-chain": {
|
||||
"function": chain_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"expiry": re_date,
|
||||
"opt_type": ["Calls", "Puts"],
|
||||
},
|
||||
"optional": {"min_sp": re_float, "max_sp": re_float},
|
||||
},
|
||||
"opt-oi": {
|
||||
"function": oi_command,
|
||||
"required": {"ticker": tickers, "expiry": re_date},
|
||||
"optional": {"min_sp": re_float, "max_sp": re_float},
|
||||
},
|
||||
"opt-iv": {
|
||||
"function": iv_command,
|
||||
"required": {"ticker": tickers},
|
||||
},
|
||||
"q": {"function": quote_command, "required": {"ticker": tickers}},
|
||||
"disc-ford": {
|
||||
"function": ford_command,
|
||||
},
|
||||
"opt-unu": {
|
||||
"function": unu_command,
|
||||
},
|
||||
"ins-last": {
|
||||
"function": lins_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"num": re_int},
|
||||
},
|
||||
"cc": {
|
||||
"function": candle_command,
|
||||
"required": {"ticker": tickers, "interval": opt_intervals},
|
||||
"optional": {"past_days": re_int, "start": re_date, "end": re_date},
|
||||
},
|
||||
"opt-overview": {
|
||||
"function": overview_opt_command,
|
||||
"required": {"ticker": tickers, "expiry": re_date},
|
||||
"optional": {
|
||||
"min_sp": re_float,
|
||||
"max_sp": re_float,
|
||||
},
|
||||
},
|
||||
"opt-vol": {
|
||||
"function": vol_command,
|
||||
"required": {"ticker": tickers, "expiry": re_date},
|
||||
},
|
||||
"opt-vsurf": {
|
||||
"function": vsurf_command,
|
||||
"required": {"ticker": tickers, "z": options_vsurf_choices.values()},
|
||||
},
|
||||
"opt-hist": {
|
||||
"function": hist_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"expiry": re_date,
|
||||
"strike": re_float,
|
||||
"opt_type": ["Calls", "Puts"],
|
||||
"greek": ["iv", "gamma", "delta", "theta", "rho", "vega"],
|
||||
},
|
||||
},
|
||||
"opt-cc-hist": {
|
||||
"function": cc_hist_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"expiry": re_date,
|
||||
"strike": re_float,
|
||||
"opt_type": ["Calls", "Puts"],
|
||||
},
|
||||
},
|
||||
"scr-presets_default": {
|
||||
"function": presets_default_command,
|
||||
},
|
||||
"scr-presets_custom": {
|
||||
"function": presets_custom_command,
|
||||
},
|
||||
"scr-historical": {
|
||||
"function": historical_command,
|
||||
"required": {"signal": signals},
|
||||
"optional": {"start": re_date},
|
||||
},
|
||||
"scr-overview": {
|
||||
"function": overview_screener_command,
|
||||
"required": {"preset": presets, "sort": screener_sort["overview"]},
|
||||
"optional": {"limit": re_int, "ascend": [True, False]},
|
||||
},
|
||||
"scr-valuation": {
|
||||
"function": valuation_screener_command,
|
||||
"required": {"preset": presets, "sort": screener_sort["valuation"]},
|
||||
"optional": {"limit": re_int, "ascend": [True, False]},
|
||||
},
|
||||
"scr-financial": {
|
||||
"function": financial_command,
|
||||
"required": {"preset": presets, "sort": screener_sort["financial"]},
|
||||
"optional": {"limit": re_int, "ascend": [True, False]},
|
||||
},
|
||||
"scr-ownership": {
|
||||
"function": ownership_command,
|
||||
"required": {"preset": presets, "sort": screener_sort["ownership"]},
|
||||
"optional": {"limit": re_int, "ascend": [True, False]},
|
||||
},
|
||||
"scr-performance": {
|
||||
"function": performance_screener_command,
|
||||
"required": {"preset": presets, "sort": screener_sort["performance"]},
|
||||
"optional": {"limit": re_int, "ascend": [True, False]},
|
||||
},
|
||||
"scr-technical": {
|
||||
"function": technical_command,
|
||||
"required": {"preset": presets, "sort": screener_sort["technical"]},
|
||||
"optional": {"limit": re_int, "ascend": [True, False]},
|
||||
},
|
||||
"ta-ema": {
|
||||
"function": ema_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"window": re_window,
|
||||
"offset": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-sma": {
|
||||
"function": sma_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"window": re_window,
|
||||
"offset": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-wma": {
|
||||
"function": wma_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"window": re_window,
|
||||
"offset": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-hma": {
|
||||
"function": hma_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"window": re_window,
|
||||
"offset": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-zlma": {
|
||||
"function": zlma_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"window": re_window,
|
||||
"offset": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-cci": {
|
||||
"function": cci_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"length": re_int,
|
||||
"scalar": re_float,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-macd": {
|
||||
"function": macd_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"length": re_int,
|
||||
"scalar": re_float,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-rsi": {
|
||||
"function": rsi_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"length": re_int,
|
||||
"scalar": re_float,
|
||||
"drift": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-stoch": {
|
||||
"function": stoch_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"fast_k": re_int,
|
||||
"slow_k": re_int,
|
||||
"slow_d": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-fisher": {
|
||||
"function": fisher_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"length": re_int, "start": re_date, "end": re_date},
|
||||
},
|
||||
"ta-cg": {
|
||||
"function": fisher_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"length": re_int, "start": re_date, "end": re_date},
|
||||
},
|
||||
"ta-adx": {
|
||||
"function": adx_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"length": re_int,
|
||||
"scalar": re_int,
|
||||
"drift": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-aroon": {
|
||||
"function": aroon_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"length": re_int,
|
||||
"scalar": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-bbands": {
|
||||
"function": bbands_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"mamode": ["ema", "sma", "wma", "hma", "zlma"],
|
||||
},
|
||||
"optional": {"length": re_int, "std": re_int, "start": re_date, "end": re_date},
|
||||
},
|
||||
"ta-donchian": {
|
||||
"function": donchian_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {
|
||||
"upper_length": re_int,
|
||||
"lower_length": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-kc": {
|
||||
"function": kc_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
"mamode": ["ema", "sma", "wma", "hma", "zlma"],
|
||||
},
|
||||
"optional": {
|
||||
"length": re_int,
|
||||
"scalar": re_int,
|
||||
"offset": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-ad": {
|
||||
"function": ad_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"is_open": ["True", "False"], "start": re_date, "end": re_date},
|
||||
},
|
||||
"ta-adosc": {
|
||||
"function": adosc_command,
|
||||
"required": {
|
||||
"ticker": tickers,
|
||||
},
|
||||
"optional": {
|
||||
"is_open": ["True", "False"],
|
||||
"fast": re_int,
|
||||
"slow": re_int,
|
||||
"start": re_date,
|
||||
"end": re_date,
|
||||
},
|
||||
},
|
||||
"ta-obv": {
|
||||
"function": obv_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"start": re_date, "end": re_date},
|
||||
},
|
||||
"ta-fib": {
|
||||
"function": fib_command,
|
||||
"required": {"ticker": tickers},
|
||||
"optional": {"start": re_date, "end": re_date},
|
||||
},
|
||||
"ta-view": {"function": view_command, "required": {"ticker": tickers}},
|
||||
"ta-summary": {"function": summary_command, "required": {"ticker": tickers}},
|
||||
"ta-recom": {"function": recom_command, "required": {"ticker": tickers}},
|
||||
}
|
||||
@@ -35,6 +35,7 @@ def indices_command():
|
||||
|
||||
df = df[
|
||||
[
|
||||
" ",
|
||||
"Price",
|
||||
"Chg",
|
||||
"%Chg",
|
||||
|
||||
@@ -30,6 +30,7 @@ def overview_command():
|
||||
|
||||
df = df[
|
||||
[
|
||||
" ",
|
||||
"Price",
|
||||
"Chg",
|
||||
"%Chg",
|
||||
|
||||
75
bots/groupme/groupme_helpers.py
Normal file
75
bots/groupme/groupme_helpers.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""Groupme"""
|
||||
__docformat__ = "numpy"
|
||||
|
||||
from typing import Optional
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import urllib.request as urllib
|
||||
|
||||
import requests
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
base = "https://api.groupme.com/v3"
|
||||
TOKEN = os.getenv("GROUPME_TOKEN")
|
||||
end = f"?token={TOKEN}"
|
||||
|
||||
group_to_bot = {
|
||||
os.getenv("TEST_GROUP_ID"): os.getenv("TEST_GROUP_BOT"),
|
||||
os.getenv("MAIN_GROUP_ID"): os.getenv("MAIN_GROUP_BOT"),
|
||||
}
|
||||
|
||||
|
||||
def shorten_message(message: Optional[str]) -> Optional[str]:
|
||||
# TODO: make the cutoff algorithm better
|
||||
if message is None:
|
||||
return message
|
||||
if len(message) > 990:
|
||||
return f"{message[:990]}..."
|
||||
return message
|
||||
|
||||
|
||||
def upload_image(image: str, local: bool) -> requests.Response:
|
||||
url = "https://image.groupme.com/pictures"
|
||||
headers = {
|
||||
"Content-Type": "image/jpeg",
|
||||
"X-Access-Token": os.getenv("X_ACCESS_TOKEN"),
|
||||
}
|
||||
if local:
|
||||
path_string = pathlib.Path(__file__).parent.parent.resolve()
|
||||
path = os.path.join(path_string, image)
|
||||
return requests.post(url, data=open(path, "rb").read(), headers=headers)
|
||||
with urllib.urlopen(image) as data:
|
||||
return requests.post(url, data=io.BytesIO(data.read()), headers=headers)
|
||||
|
||||
|
||||
def send_message(message: str, group_id: str) -> requests.Response:
|
||||
mid = "/bots/post"
|
||||
bot_id = group_to_bot[group_id]
|
||||
cleaned = shorten_message(message)
|
||||
return requests.post(url=f"{base+mid}?bot_id={bot_id}&text={cleaned}")
|
||||
|
||||
|
||||
def send_image(
|
||||
image: str, group_id: str, text: str = None, local: bool = False
|
||||
) -> requests.Response:
|
||||
if "http" in image:
|
||||
response = upload_image(image, False)
|
||||
else:
|
||||
response = upload_image(image, True)
|
||||
response_json = response.json()
|
||||
image_url = response_json["payload"]["picture_url"]
|
||||
mid = "/bots/post"
|
||||
bot_id = group_to_bot[group_id]
|
||||
text = shorten_message(text)
|
||||
data = {
|
||||
"bot_id": bot_id,
|
||||
"text": text,
|
||||
"attachments": [{"type": "image", "url": image_url}],
|
||||
}
|
||||
if "http" not in image:
|
||||
os.remove(image)
|
||||
return requests.post(base + mid + end, data=json.dumps(data))
|
||||
139
bots/groupme/run_groupme.py
Normal file
139
bots/groupme/run_groupme.py
Normal file
@@ -0,0 +1,139 @@
|
||||
import json
|
||||
from typing import List, Pattern, Dict, Any, Set, Union
|
||||
|
||||
from bots.common.commands_dict import commands
|
||||
from bots.groupme.groupme_helpers import send_message
|
||||
from bots.helpers import ShowView
|
||||
|
||||
|
||||
def get_syntax(selected: Dict[str, Any], cmd: str) -> str:
|
||||
"""Returns the syntax for a given command
|
||||
|
||||
Parameters
|
||||
----------
|
||||
selected : Dict[str, Any]
|
||||
The command object
|
||||
cmd : str
|
||||
The command that was attempted
|
||||
|
||||
Returns
|
||||
---------
|
||||
syntax : str
|
||||
The syntax for the given command
|
||||
"""
|
||||
|
||||
syntax = f"{cmd}/"
|
||||
syntax += "/".join(selected.get("required", []))
|
||||
return syntax
|
||||
|
||||
|
||||
def get_arguments(selected: Dict[str, Any], req_name: str, group_id: str) -> None:
|
||||
"""Returns the arguments for a given command
|
||||
|
||||
Parameters
|
||||
----------
|
||||
selected : Dict[str, Any]
|
||||
The command object
|
||||
req_name : str
|
||||
The name of the requirement
|
||||
group_id : str
|
||||
The groupme chat id
|
||||
"""
|
||||
|
||||
if req_name == "ticker":
|
||||
send_message("Please give a listed ticker", group_id)
|
||||
elif req_name == "past_transactions_days":
|
||||
send_message("Please give the number of days as an integer", group_id)
|
||||
elif req_name == "raw":
|
||||
send_message("Please type true or false", group_id)
|
||||
else:
|
||||
select = [str(x) for x in selected["required"].get(req_name, [])]
|
||||
selections = ", ".join(select)
|
||||
if len(selections) < 990:
|
||||
selections = f"{selections[:990]}"
|
||||
send_message(f"Options: {selections}", group_id)
|
||||
|
||||
|
||||
def send_options(name: str, items: Union[List[Any], Set[Any]], group_id: str) -> None:
|
||||
"""Sends the options for a user
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name : str
|
||||
The name of the section
|
||||
items : List[str]
|
||||
The items the user can select from
|
||||
group_id : str
|
||||
The groupme chat id
|
||||
"""
|
||||
message = name
|
||||
clean = list(items)
|
||||
clean.sort()
|
||||
message += ", ".join(list(clean))
|
||||
send_message(message, group_id)
|
||||
|
||||
|
||||
def handle_groupme(request) -> bool:
|
||||
"""Handles groupme bot inputs
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : Request
|
||||
The request object provided by FASTAPI
|
||||
|
||||
Returns
|
||||
----------
|
||||
success : bool
|
||||
Whether the response was sent successfully
|
||||
"""
|
||||
|
||||
req = json.loads(request.decode("utf-8"))
|
||||
text = req.get("text").strip().lower()
|
||||
group_id = req.get("group_id").strip()
|
||||
|
||||
if text[0] == "!":
|
||||
cmd = text[1:]
|
||||
full_cmd = cmd.split("/")
|
||||
group = full_cmd[0].split("-")[0]
|
||||
parents = {x.split("-")[0] for x in commands}
|
||||
if group in parents:
|
||||
if full_cmd[0] in commands:
|
||||
selected = commands[full_cmd[0]]
|
||||
if len(full_cmd) != len(selected.get("required", [])) + 1:
|
||||
syntax = get_syntax(selected, full_cmd[0])
|
||||
send_message(f"Required syntax: {syntax}", group_id)
|
||||
return False
|
||||
other_args = {}
|
||||
for i, val in enumerate(full_cmd[1:]):
|
||||
req_name = list(selected.get("required", {}).keys())[i]
|
||||
required = selected.get("required", [])[req_name]
|
||||
if isinstance(required, List) and required != [True, False]:
|
||||
required = [str(x) for x in required]
|
||||
if isinstance(val, str) and req_name in ["ticker"]:
|
||||
val = val.upper()
|
||||
elif isinstance(val, str) and req_name == "raw":
|
||||
val = bool(val)
|
||||
if (isinstance(required, List) and val not in required) or (
|
||||
isinstance(required, Pattern) and not required.match(val)
|
||||
):
|
||||
syntax = get_syntax(selected, full_cmd[0])
|
||||
send_message(
|
||||
f"{syntax}\nInvalid argument for: {req_name}", group_id
|
||||
)
|
||||
get_arguments(selected, req_name, group_id)
|
||||
return False
|
||||
other_args[req_name] = val
|
||||
func = selected["function"]
|
||||
ShowView().groupme(func, group_id, cmd, **other_args)
|
||||
return True
|
||||
else:
|
||||
show_cmds = []
|
||||
for command in commands:
|
||||
if group == command[: len(group)]:
|
||||
show_cmds.append(command)
|
||||
send_options("Valid commands: ", show_cmds, group_id)
|
||||
return False
|
||||
else:
|
||||
send_options("Valid categories: ", parents, group_id)
|
||||
return False
|
||||
return False
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
from typing import List
|
||||
import uuid
|
||||
|
||||
import df2img
|
||||
@@ -9,6 +10,7 @@ from numpy.core.fromnumeric import transpose
|
||||
from PIL import Image
|
||||
|
||||
import bots.config_discordbot as cfg
|
||||
from bots.groupme.groupme_helpers import send_image, send_message
|
||||
|
||||
presets_custom = [
|
||||
"potential_reversals",
|
||||
@@ -201,7 +203,9 @@ def image_border(file, **kwargs):
|
||||
if "fig" in kwargs:
|
||||
fig = kwargs["fig"]
|
||||
fig.write_image(imagefile)
|
||||
img = Image.open(file)
|
||||
img = Image.open(imagefile)
|
||||
else:
|
||||
img = Image.open(file)
|
||||
im_bg = Image.open(cfg.IMG_BG)
|
||||
h = img.height + 240
|
||||
w = img.width + 520
|
||||
@@ -218,7 +222,6 @@ def image_border(file, **kwargs):
|
||||
image = Image.open(file)
|
||||
image = autocrop_image(image, 0)
|
||||
image.save(imagefile, "PNG", quality=100)
|
||||
os.remove(file)
|
||||
return imagefile
|
||||
|
||||
|
||||
@@ -269,3 +272,22 @@ class ShowView:
|
||||
)
|
||||
|
||||
await inter.send(embed=embed, delete_after=30.0)
|
||||
|
||||
def groupme(self, func, group_id, name, *args, **kwargs):
|
||||
data = func(*args, **kwargs)
|
||||
if "imagefile" in data:
|
||||
send_image(data["imagefile"], group_id, data.get("description", ""), True)
|
||||
elif "embeds_img" in data:
|
||||
send_image(
|
||||
data["embeds_img"][0], group_id, data.get("description", ""), True
|
||||
)
|
||||
elif "description" in data:
|
||||
title = data.get("title", "")
|
||||
# TODO: Allow navigation through pages
|
||||
description = data.get("description")
|
||||
if isinstance(description, List):
|
||||
clean_desc = description[0].replace("Page ", "")
|
||||
else:
|
||||
clean_desc = description.replace("Page ", "")
|
||||
message = f"{title}\n{clean_desc}"
|
||||
send_message(message, group_id)
|
||||
|
||||
@@ -8,17 +8,26 @@ import config_discordbot as cfg
|
||||
import disnake
|
||||
from config_discordbot import logger
|
||||
from disnake.ext import commands
|
||||
from fastapi import FastAPI
|
||||
from fastapi import FastAPI, Request
|
||||
|
||||
from bots.groupme.run_groupme import handle_groupme
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
# For next update
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": str(gst_bot.user)}
|
||||
|
||||
|
||||
@app.post("/")
|
||||
async def write_root(request: Request):
|
||||
# TODO: Make this work for more bots
|
||||
req_info = await request.body()
|
||||
value = handle_groupme(req_info)
|
||||
return {"Worked": value}
|
||||
|
||||
|
||||
activity = disnake.Activity(
|
||||
type=disnake.ActivityType.watching,
|
||||
name="Gamestonk Terminal: https://github.com/GamestonkTerminal/GamestonkTerminal",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import pandas as pd
|
||||
from matplotlib import pyplot as plt
|
||||
from typing import Union
|
||||
|
||||
import bots.config_discordbot as cfg
|
||||
from matplotlib import pyplot as plt
|
||||
import pandas as pd
|
||||
from bots.config_discordbot import logger
|
||||
import bots.config_discordbot as cfg
|
||||
from bots.helpers import image_border
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal.helper_funcs import plot_autoscale
|
||||
@@ -10,9 +11,10 @@ from gamestonk_terminal.stocks.government import quiverquant_model
|
||||
|
||||
|
||||
def contracts_command(
|
||||
ticker: str = "", past_transaction_days: int = 10, raw: bool = False
|
||||
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)
|
||||
@@ -24,7 +26,10 @@ def contracts_command(
|
||||
df_contracts = quiverquant_model.get_government_trading("contracts", ticker)
|
||||
|
||||
if df_contracts.empty:
|
||||
raise Exception("No government contracts found")
|
||||
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
|
||||
|
||||
@@ -115,7 +115,7 @@ def financial_command(preset="template", sort="", limit: int = 5, ascend: bool =
|
||||
)
|
||||
)
|
||||
reports.append(f"{description}")
|
||||
|
||||
print(df_screen)
|
||||
return {
|
||||
"view": Menu,
|
||||
"title": title,
|
||||
|
||||
@@ -87,7 +87,7 @@ def display_candle(
|
||||
candle_chart_kwargs["figratio"] = (10, 7)
|
||||
candle_chart_kwargs["figscale"] = 1.10
|
||||
candle_chart_kwargs["figsize"] = plot_autoscale()
|
||||
fig, _ = mpf.plot(data, **candle_chart_kwargs)
|
||||
fig, ax = mpf.plot(data, **candle_chart_kwargs)
|
||||
fig.suptitle(
|
||||
f"{from_symbol}/{to_symbol}",
|
||||
x=0.055,
|
||||
@@ -95,6 +95,7 @@ def display_candle(
|
||||
horizontalalignment="left",
|
||||
)
|
||||
theme.visualize_output(force_tight_layout=False)
|
||||
ax[0].legend()
|
||||
else:
|
||||
if len(external_axes) != 1:
|
||||
logger.error("Expected list of 1 axis items.")
|
||||
|
||||
BIN
gamestonk_terminal/stocks/.stocks_controller.py.swp
vendored
BIN
gamestonk_terminal/stocks/.stocks_controller.py.swp
vendored
Binary file not shown.
Reference in New Issue
Block a user