def change_dl_path(self, new_path="", silent=False, message=message): """ Changes the img_path for new wallpaper downloads """ if not new_path: refresh(message) new_path = input(f""" {colors['green']}Enter the complete img_path to the new location. This is case sensivite. "Pics" and "pics" are different e.g. /home/user/Pictures\n Current img_path is: {pictures}\n{colors['normal']} {colors['red']}x{colors['normal']} : {colors['blue']}main settings{colors['normal']} {colors['red']}q{colors['normal']}: {colors['blue']} Quit{colors['normal']} >>> """) if new_path == "x": self.main_settings() return elif new_path == "q" or new_path == "Q": clear() return elif not os.path.exists(new_path): error = "ERROR: The img_path you entered does not exist." message = f"{colors['red_error']}{error}{colors['normal']}\n" else: config.set("settings", "download_dir", str(new_path)) Settings().save_settings() message = "Path changed successfully" print(message) self.change_dl_path()
def max_dl_choice(self, d_limit="", silent=False, message=message): """ Allows the user to select a max number of wallpaper download attemts """ if not silent: refresh(message) d_limit = input(f"""{colors['green']} Enter the maximum number of wallpaper to attemt to download The number cannot exceed 100. Current value is {d_limit} {colors['normal']}\n {colors['red']}x{colors['normal']}: {colors['blue']} main menu{colors['normal']} {colors['red']}q{colors['normal']}: {colors['blue']} Quit{colors['normal']} >>> """) try: max_dl = int(d_limit) if max_dl > 100: message = f"{colors['green']}Please enter a value (1 - 100){colors['normal']}\n" print(message) else: config.set("settings", "download_limit", str(max_dl)) self.save_settings() except TypeError: max_dl = str(d_limit) if max_dl == "x" or max_dl == "X": self.main_settings() return else: error = "You did not enter a number" message = f"{colors['red_error']}{error}{colors['normal']}\n" refresh(message) self.max_dl_choice()
def rsi(symbol, period=default_period, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the relative strength indexe for the given symbol, saves this data in a .csv file, and returns this data The RSI is a leading momentum indicator. Parameters: symbol : str period : int, optional refresh : bool, optional start_date : date, optional end_date : date, optional Returns: dataframe A dataframe containing the relative strength index for the given symbol """ if not utils.refresh(utils.get_file_path( config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if ("RSI" + str(period)) not in df.columns: delta = df["Close"].diff() up, down = delta.copy(), delta.copy() up[up < 0], down[down > 0] = 0, 0 # df["RSI" + str(period)] = 100 - (100 / (1 + up.rolling(period).mean() / down.abs().rolling(period).mean())) # sma rsi df["RSI" + str(period)] = 100 - ( 100 / (1 + up.ewm(span=period, min_periods=period).mean() / down.abs().ewm(span=period, min_periods=period).mean()) ) # ema rsi utils.debug(df["RSI" + str(period)]) df.to_csv( utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol)) return df["RSI" + str(period)]
def ema(symbol, period, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the exponential moving agerage for the given symbol, saves this data in a .csv file, and returns this data The EMA is a lagging trend indicator. Parameters: symbol : str period : int refresh : bool, optional start_date : date, optional end_date : date, optional Returns: dataframe A dataframe containing the exponential moving agerage for the given symbol """ if not utils.refresh(utils.get_file_path( config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if ("EMA" + str(period)) not in df.columns: df["EMA" + str(period)] = df["Close"].ewm(span=period, min_periods=period, adjust=False).mean() utils.debug(df["EMA" + str(period)]) df.to_csv( utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol)) return df["EMA" + str(period)]
def make_grid_image(grab_area): img = np.zeros(get_hw(grab_area)) for i in tqdm(range(50)): refresh(grab_area) time.sleep(0.5) ss = grab_screen(grab_area) gray = cv2.cvtColor(ss, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 150, 255, 0) img += 255 - thresh img = np.clip(img, 0, 255) cv2.imwrite('grid.png', 255 - img)
def main(): mkdir_if_not_exists(IMAGE_DIR) empty_dir(IMAGE_DIR) grab_area = read_grab_area() crop_areas = find_crop_areas() for _ in tqdm(range(2 ** 11)): ss = grab_screen(grab_area) draw_crop_areas(ss, crop_areas) for img in crop_images(ss, crop_areas): save_path = os.path.join(IMAGE_DIR, generate_uuid() + '.png') cv2.imwrite(save_path, img) refresh(grab_area) time.sleep(1)
def plot_macd(symbol, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the macd for the given symbol, saves this data in a .csv file, and plots this data The MACD is a lagging trend indicator. Parameters: symbol : str period : int or list of int, optional Must contain 3 values. First value is signal line, second is fast line, third is slow line.\ refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A figure and axes containing the macd for the given symbol """ if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if len(period) != 3: raise ValueError("MACD requires 3 periods") if len(df) < period[-1]: raise ta.InsufficientDataException("Not enough data to compute a period length of " + str(period)) fig, ax = plt.subplots(2, figsize=config.figsize) ax[0].plot(df.index, df["Close"], label="Price") utils.prettify_ax(ax[0], title=symbol + "Price", start_date=start_date, end_date=end_date) macd_column_name = "MACD" + str(period[1]) + "-" + str(period[2]) signal_column_name = "MACD" + str(period[0]) if macd_column_name not in df.columns or signal_column_name not in df.columns: df = df.join(macd(symbol, period, refresh=False, start_date=start_date, end_date=end_date)) # if len(df) > period[0] and len(df) > period[1] and len(df) > period[2]: # to prevent AttributeError when the column is all None ax[1].plot(df.index, df[macd_column_name], label="MACD") ax[1].plot(df.index, df[signal_column_name], label="Signal") ax[1].plot(df.index, (df[macd_column_name] - df[signal_column_name]), label="Histogram") # Can't overlay a histogram with line plots so the histogram has to also be a line plot # ax[1].bar(df.index, np.histogram(np.isfinite(df[signal_column_name] - df[macd_column_name])), normed=True, alpha=config.alpha) # ValueError: incompatible sizes: argument 'height' must be length 3876 or scalar utils.prettify_ax(ax[1], title=symbol + "MACD", center=True, start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig(utils.get_file_path(config.ta_graphs_path, get_signal_name(period) + graph_filename, symbol=symbol)) utils.debug(fig) return fig, ax
def macd(symbol, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the exponential moving agerage for the given symbol, saves this data in a .csv file, and returns this data The EMA is a lagging trend indicator. Parameters: symbol : str period : int\ refresh : bool, optional start_date : date, optional end_date : date, optional Returns: dataframe A dataframe containing the exponential moving agerage for the given symbol """ if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if len(period) != 3: raise ValueError("MACD requires 3 periods") macd_column_name = "MACD" + str(period[1]) + "-" + str(period[2]) signal_column_name = "MACD" + str(period[0]) if macd_column_name not in df.columns or signal_column_name not in df.columns: if macd_column_name not in df.columns: ''' # Intermediate steps, can uncomment this part if I want to keep the steps slow_column_name = "EMA" + str(period[1]) if slow_column_name not in df.columns: df[slow_column_name] = df["Close"].ewm(span=period[1], min_periods=period[1], adjust=False).mean() fast_column_name = "EMA" + str(period[2]) if fast_column_name not in df.columns: df[fast_column_name] = df["Close"].ewm(span=period[2], min_periods=period[2], adjust=False).mean() df[macd_column_name] = df[slow_column_name] - df[fast_column_name] ''' df[macd_column_name] = df["Close"].ewm(span=period[1], min_periods=period[1], adjust=False).mean() - df["Close"].ewm(span=period[2], min_periods=period[2], adjust=False).mean() utils.debug(df[macd_column_name]) if signal_column_name not in df.columns: df[signal_column_name] = df[macd_column_name].ewm(span=period[0], min_periods=period[0], adjust=False).mean() utils.debug(df[signal_column_name]) df.to_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol)) return df[[macd_column_name, signal_column_name]]
def get_beta(symbol_a, symbol_b, start_date=config.start_date, end_date=config.end_date): """Returns the beta of symbol_a to symbol_b Parameters: symbol_a : str symbol_b : str start_date : date, optional end_date : date, optional Returns: float The beta of symbol_a to symbol_b """ if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol_a), refresh=False): prices.download_data_from_yahoo(symbol_a, start_date=start_date, end_date=end_date) df_a = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol_a), index_col="Date", parse_dates=["Date"])[start_date:end_date] a = df_a["Close"].add(df_a["Dividends"].cumsum()).pct_change()[1:] if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol_b), refresh=False): prices.download_data_from_yahoo(symbol_b, start_date=start_date, end_date=end_date) df_b = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol_b), index_col="Date", parse_dates=["Date"])[start_date:end_date] b = df_b["Close"].add(df_b["Dividends"].cumsum()).pct_change()[1:] # rolling beta # df["Beta"] = pd.rolling_cov(df_b["Close"].add(df_a["Dividends"].cumsum()), df_b["Close"].add(df_b["Dividends"].cumsum()), window=window) / pd.rolling_var(df_b["Close"].add(df_b["Dividends"].cumsum()), window=window) beta = np.cov(a, b)[0][1] / np.var( b) # Alternately, np.var(b) -> np.cov(a, b)[1][1] return beta
def get_performance(symbol, start_date=config.start_date, end_date=config.end_date): """Returns the overall performance of the given symbol Parameters: symbol : str start_date : date, optional end_date : date, optional Returns: float The overall performance of the given symbol """ if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=False): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] return df["Close"].add(df["Dividends"].cumsum())[-1] / df["Close"][0]
def get_annualized_performance(symbol, start_date=config.start_date, end_date=config.end_date): """Returns the annualized performance of the given symbol Parameters: symbol : str start_date : date, optional end_date : date, optional Returns: float The annualized performance of the given symbol """ if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=False): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] # Not sure about this formula, seems weird. Formula normally has a -1 at the end # return (1 + (df["Close"].add(df["Dividends"].cumsum())[-1] / df["Close"][0])) ** (365 / (df.index[-1] - df.index[0]).days) # exponent equivalent to (252 / len(df.index)) return (df["Close"].add(df["Dividends"].cumsum())[-1] / df["Close"][0]) / (len(df.index) / 252) + 1
def get_sharpe_ratio(symbol, start_date=config.start_date, end_date=config.end_date): """Returns the sharpe ratio of the given symbol Parameters: symbol : str start_date : date, optional end_date : date, optional Returns: float The sharpe ratio of the given symbol """ if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=False): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] # return (df["Close"].add(df["Dividends"].cumsum()) / df["Close"].add(df["Dividends"].cumsum()).shift(1)).mean() / ((df["Close"].add(df["Dividends"].cumsum()) / df["Close"].add(df["Dividends"].cumsum()).shift(1)).std() * np.sqrt(252)) return df["Close"].add( df["Dividends"].cumsum()).pct_change().mean() / df["Close"].add( df["Dividends"].cumsum()).pct_change().std() * np.sqrt(252)
def get_num_conseq_increase_decrease(symbol, refresh=False, start_date=config.start_date, end_date=config.end_date): if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] return { "ConseqIncrease": ((df["Close"].diff() > 0) & (df["Close"].diff().shift(1) > 0)).sum(), "ConseqDecrease": ((df["Close"].diff() < 0) & (df["Close"].diff().shift(1) < 0)).sum(), "Reversal": ((df["Close"].diff() < 0) & (df["Close"].diff().shift(1) > 0)).sum() + ((df["Close"].diff() > 0) & (df["Close"].diff().shift(1) < 0)).sum() }
def get_cgar(symbol, start_date=config.start_date, end_date=config.end_date): """Returns the compound annual growth rate of the given symbol Parameters: symbol : str start_date : date, optional end_date : date, optional Returns: float The compound annual growth rate of the given symbol """ if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=False): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] # Formula normally has a -1 at the end return (df["Close"].add(df["Dividends"].cumsum())[-1] / df["Close"][0])**(1 / ((df.index[-1] - df.index[0]).days) / 252)
def get_price_on_date(self, symbol, date, time="Close"): """Gets the price of the given symbol on the given date Parameters: symbol : str date : datetime time : str Which column to use to determine price. Valid times are "Open" and "Close" Returns: float The price of the given symbol on the given date """ start_time = timer() if symbol in self.price_files: df = self.price_files[symbol] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=False): prices.download_data_from_yahoo(symbol, start_date=self.start_date, end_date=self.end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[self.start_date:self.end_date] self.price_files[symbol] = df price = df.loc[date][time] if date in df.index else self.get_price_on_date(symbol, utils.add_business_days(date, -1), time=time) self.times[get_price_time] = self.times[get_price_time] + timer() - start_time return price
def get_dividends(self, symbol, date): """Adds dividends to the portfolio for the given symbol on the given date Parameters: symbol : str date : datetime Returns: float The dividends added """ start_time = timer() if symbol in self.price_files: df = self.price_files[symbol] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=False): prices.download_data_from_yahoo(symbol, start_date=self.start_date, end_date=self.end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[self.start_date:self.end_date] self.price_files[symbol] = df dividend = self.portfolio[symbol] * df.loc[date]["Dividends"] if date in df.index and "Dividends" in df.columns else 0 if dividend != 0: self.cash += dividend self.total_dividends += dividend self.log.loc[date][actions_column_name] = self.log.loc[date][actions_column_name] + "Dividend: {} {} Shares totaling {:.2f} ".format(symbol, self.portfolio[symbol], dividend) # TODO: move this into update_winners_losers self.cost_basis[symbol] -= df.loc[date]["Dividends"] self.times[get_dividend_time] = self.times[get_dividend_time] + timer() - start_time return dividend
def generate_signals(symbol=default_symbols, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): short_vol_symbol = symbol[0] long_vol_symbol = symbol[1] volforecast(period=period, refresh=refresh, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=short_vol_symbol), refresh=refresh): short_vol = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=short_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=short_vol_symbol), refresh=refresh): prices.download_data_from_yahoo(short_vol_symbol, start_date=start_date, end_date=end_date) short_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=short_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=long_vol_symbol), refresh=refresh): long_vol = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=long_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=long_vol_symbol), refresh=refresh): prices.download_data_from_yahoo(long_vol_symbol, start_date=start_date, end_date=end_date) long_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=long_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] signal_column_name = get_signal_name() if signal_column_name not in short_vol.columns or signal_column_name not in long_vol.columns: short_vol_conditions = [ ((df[signal_column_name].shift(1) > 0) & (df[signal_column_name] < 0)), # near term volatility crossed below expected volatility, short VIX ((df[signal_column_name].shift(1) < 0) & (df[signal_column_name] > 0)), # near term volatility crossed above expected volatility, long VIX False, False ] long_vol_conditions = [ ((df[signal_column_name].shift(1) < 0) & (df[signal_column_name] > 0)), # near term volatility crossed above expected volatility, long VIX ((df[signal_column_name].shift(1) > 0) & (df[signal_column_name] < 0)), # near term volatility crossed below expected volatility, short VIX False, False ] short_vol[signal_column_name] = np.select(short_vol_conditions, ta.signals, default=ta.default_signal) long_vol[signal_column_name] = np.select(long_vol_conditions, ta.signals, default=ta.default_signal) utils.debug(short_vol[signal_column_name]) utils.debug(long_vol[signal_column_name]) short_vol.to_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=short_vol_symbol)) long_vol.to_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=long_vol_symbol)) return short_vol[signal_column_name], long_vol[signal_column_name]
def main(): # 初始化数据库和数据表 ProxiesDataBase.InitDB() # 刷新数据库,添加新数据 utils.refresh() # 获取一个代理使用 proxies = utils.get() print(proxies) # 查询数据库多少条数据 conn = sqlite3.connect(config.DBName) cu = conn.cursor() print( cu.execute("""SELECT * FROM {};""".format( config.TabelName)).fetchall().__len__()) cu.close() conn.close()
def main_menu(self, message=message): refresh(message) choice = input(f"""{colors['green']} Welcome to Redpaper. This is a TUI used to control the underlying Redpaper program. Select an option:\n{colors['normal']} {colors['red']} 1 {colors['normal']}: {colors['blue']} Download wallpapers {colors['normal']} \n {colors['red']} 2 {colors['normal']}: {colors['blue']} Next wallpaper{colors['normal']}\n {colors['red']} 3 {colors['normal']}: {colors['blue']} Previous wallpaper{colors['normal']}\n {colors['red']} 4 {colors['normal']}: {colors['blue']} Settings{colors['normal']}\n {colors['red']} 5 {colors['normal']}: {colors['blue']} Help {colors['normal']}\n {colors['red']} x {colors['normal']}: {colors['blue']} exit {colors['normal']}\n >>> """) if choice == "1": refresh(message) Fetch().wall_dl() elif choice == "2": message = f"{colors['green']} Changed wallpaper {colors['normal']}\n" refresh(message) img_path = WallSet().sequetial(0) WallSet().set_wallpaper(img_path) self.main_menu() elif choice == "3": message = f"{colors['green']} Changed wallpaper {colors['normal']}\n" refresh(message) img_path = WallSet().sequetial(1) WallSet().set_wallpaper(img_path) self.main_menu() elif choice == "4": message = "" Settings().main_settings() elif choice == "5": # TODO: create a help page message = "HELP\n" refresh(message) print(f""" {colors['green']}You can check the wiki for help: https://github.com/keystroke3/redpaper/wiki{colors['normal']}""" ) self.main_menu() elif choice == "x" or choice == "X": clear() else: Home().main_menu()
def volforecast(period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): # if start_date < datetime.date(2018, 3, 1): # raise ta.InsufficientDataException("UVXY and SVXY had their leveraged changes on Feb 27 2018, data before than will not apply now") # if start_date < datetime.date(2011, 11, 1): # raise ta.InsufficientDataException("UVXY and SVXY inception on Oct 7 2011") # if start_date < datetime.date(2009, 10, 1): # raise ta.InsufficientDataException("VIX3M inception on Sept 18 2009, VIX6M inception on Jan 3 2008") if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=""), refresh=refresh): df = pd.DataFrame() # don't refresh any volatility indices, yahoo doesn't work for them if implied_vol_symbol in config.broken_symbols or not utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=implied_vol_symbol), refresh=refresh): iv = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=implied_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: prices.download_data_from_yahoo(implied_vol_symbol, start_date=start_date, end_date=end_date) iv = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=implied_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.prices_data_path, table_filename, symbol=historical_vol_symbol), refresh=refresh): hv = pd.read_csv(utils.get_file_path(config.prices_data_path, table_filename, symbol=historical_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: prices.download_data_from_yahoo(historical_vol_symbol, start_date=start_date, end_date=end_date) hv = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=historical_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] hv = pd.DataFrame({"Close": np.log(hv["Close"] / hv["Close"].shift(1)).rolling(period[0]).std() * 100 * np.sqrt(252)}) ''' voldiff = pd.DataFrame({"VolForecast": (hv["Close"] - iv["Close"]).rolling(period[1]).mean(), "ImpliedVolatility": iv["Close"], "HistoricalVolatility": hv["Close"]}) ''' # this get_signal_name() column name doesn't incorporate period[0] and period[1] if get_signal_name() not in df.columns: df[get_signal_name()] = (hv["Close"] - iv["Close"]).rolling(period[1]).mean() if implied_vol_symbol + "SMA" + str(period[1]) not in df.columns: df[implied_vol_symbol + "SMA" + str(period[1])] = iv["Close"] if "HistoricalVolatility" + "SMA" + str(period[0]) not in df.columns: df["HistoricalVolatility" + "SMA" + str(period[0])] = hv["Close"] df.to_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol="")) return df[get_signal_name()]
def get_vals_import(self, label, *args): keys = [] result = tk.StringVar() for entry in args: if entry['state'] != 'disabled': keys.append(entry.get()) status, strg = utils.import_dict(keys) result.set(strg) label.config(textvariable=result) label.pack() self.root.update_idletasks() # restart app 1 second after success if status: time.sleep(1) debug("Import success") utils.refresh()
def change_subs(self, subs_list="", silent=False): """ Allows the user to select a max number of wallpaper download attemts """ if not silent: refresh(message) subs_list = input(f"""{colors['green']} Enter the subreddits you want seperated by space or comma e.g. wallpaper wallpapers or wallpaper,wallpapers {colors['normal']}\n {colors['red']}x{colors['normal']}: {colors['blue']} main menu{colors['normal']} {colors['red']}q{colors['normal']}: {colors['blue']} Quit{colors['normal']} >>> """) if subs_list.lower() == "x": self.main_settings() return elif subs_list.lower() == "q": clear() config.set("settings", "subreddits", str(parse_subs(subs_list))) self.save_settings()
def get_all_sp500_sub_sectors(): """Returns a list of valid sub sectors in the SP500 Returns: list of str A list of valid sub sectors in the SP500 """ if utils.refresh(sp500_symbols_table_path): download_sp500() df = pd.read_csv(sp500_full_table_path, usecols=[sub_sector_column_name]) return sorted(df[sub_sector_column_name].unique())
def main_settings(self): refresh(message) choice = input(f"""{colors['green']} Welcome to redpaper settings menu. Choose an option:\n{colors['normal']} {colors['red']} 1 {colors['normal']}: {colors['blue']} Change download location{colors['normal']} \n {colors['red']} 2 {colors['normal']}: {colors['blue']} Change the download limit{colors['normal']}\n {colors['red']} 3 {colors['normal']}: {colors['blue']} Change the source subreddits{colors['normal']}\n {colors['red']} r {colors['normal']}: {colors['blue']} Reset to default {colors['normal']}\n {colors['red']} q {colors['normal']}: {colors['blue']} Quit {colors['normal']}\n >>> """) if choice == "1": self.change_dl_path() if choice == "2": self.max_dl_choice() if choice == "3": self.change_subs() elif choice == "r" or choice == "R": self.restore_default() self.main_settings() elif choice == "q" or choice == "Q": clear()
def restore_default(self, message=message): refresh(message) choice = input(f"""{colors['green']} This section allows you to reset all the settings to default. Note that this cannot be undone. \n{colors['normal']} You sure you want to continue?\n {colors['green']} 1: Yes {colors['normal']} \n {colors['red']} 2: No {colors['normal']}\n >>> """) if choice == "2": self.main_settings() return elif choice == "1": config.set("settings", "download_dir", join(HOME, "Pictures", "Redpaper")) config.set("settings", "download_limit", "5") config.set("settings", "subreddits", "wallpaper+wallpapers") self.save_settings() else: error = "ERROR: Choice was not understood" message = f"{colors['red_error']}{error}{colors['normal']}\n" self.restore_default() return
def plot_percentage_gains(symbol, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots a graph of the percentage gains for the given symbol Parameters: symbol : str refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A subplot containing the percentage gains for the given symbol """ if isinstance(symbol, str): symbol = [symbol] symbol.sort() fig, ax = plt.subplots(figsize=config.figsize) for s in symbol: if utils.refresh(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=s), refresh=refresh): download_data_from_yahoo(s, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=s), index_col="Date", parse_dates=["Date"])[start_date:end_date] ax.plot(df.index, df["Close"] / df["Close"][0], label=s + "Price") utils.prettify_ax(ax, title="".join(str(s) for s in symbol) + "Price", start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.prices_graphs_path, price_graph_filename, symbol=",".join(str(s) for s in symbol))) utils.debug(fig) return fig, ax
def get_average_price(symbol, columns=["Open", "High", "Low", "Close"], refresh=False, start_date=config.start_date, end_date=config.end_date): """Creates a list of the average price by date for the given symbol, adds the data to the existing corresponding .csv file, and returns this data If no valid columns are provided in method, the data will be all nulls Parameters: symbol : str columns: list of str The columns to use. The list of expected columns are ["Open", "High", "Low", "Close"], but fewer columns may be valid as well refresh : bool, optional start_date : date, optional end_date : date, optional Returns: dataframe A dataframe containing average price by date for the given symbol """ if utils.refresh(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=symbol), refresh=refresh): download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] if avg_name not in df.columns: df[avg_name] = 0 count = sum(c in df.columns for c in columns) for c in columns: if c in df.columns: df[avg_name] = df[avg_name].add(df[c]) df[avg_name] = df[ avg_name] / count # Will leave null values if no methods were valid utils.debug(df[avg_name]) df.to_csv( utils.get_file_path(config.prices_data_path, price_table_filename, symbol=symbol)) return df[avg_name]
def plot_volforecast(symbol=default_symbols, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): short_vol_symbol = symbol[0] long_vol_symbol = symbol[1] if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: volforecast(period=period, refresh=refresh, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.prices_data_path, table_filename, symbol=short_vol_symbol), refresh=refresh): short_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, table_filename, symbol=short_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: prices.download_data_from_yahoo(short_vol_symbol, start_date=start_date, end_date=end_date) short_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=short_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.prices_data_path, table_filename, symbol=long_vol_symbol), refresh=refresh): long_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, table_filename, symbol=long_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: prices.download_data_from_yahoo(long_vol_symbol, start_date=start_date, end_date=end_date) long_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=long_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] fig, ax = plt.subplots(3, figsize=config.figsize) ax[0].plot(df.index, df[get_signal_name()], label=get_signal_name()) ax[1].plot(df.index, short_vol["Close"], label=short_vol_symbol) ax[2].plot(df.index, long_vol["Close"], label=long_vol_symbol) utils.prettify_ax(ax[0], title=get_signal_name(), center=True, start_date=start_date, end_date=end_date) utils.prettify_ax(ax[1], title=short_vol_symbol, start_date=start_date, end_date=end_date) utils.prettify_ax(ax[2], title=long_vol_symbol, start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig(utils.get_file_path(config.ta_graphs_path, graph_filename, symbol=get_signal_name())) utils.debug(fig) return fig, ax
def get_index(refresh=False): """Returns the symbol of the index as define in config Parameters: refresh : bool, optional Recreate the data file, regardless of whether or not it already exists Returns: str The symbol of the index as define in config """ if utils.refresh(index_table_path, refresh): download_index() utils.debug(config.index) return config.index
def get_sp500(refresh=False): """Returns a list of symbols contained in the SP500 Parameters: refresh : bool, optional Returns: list of str A list of symbols contained in the SP500 """ if utils.refresh(sp500_symbols_table_path, refresh=refresh): download_sp500() df = pd.read_csv(sp500_symbols_table_path) df = df[~df[symbol_column_name].isin(config.broken_symbols)] utils.debug(df[symbol_column_name]) return sorted(df[symbol_column_name].tolist())