Source code for stbt.helpers

#!/usr/bin/env python3
"""Module with Strategy class to all
   backtest related manipulations"""
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator

[docs]def plot_charts(df_ohlc): """Function to plot simple Close/Volume graph Args: df_ohlc (DataFrame): Close and Volume columns are necessary Returns: figure (figure): Matplotlib graph """ if str(type(df_ohlc.index[0])) == "<class 'pandas._libs.tslib.Timestamp'>": pass else: df_ohlc.index = pd.to_datetime(df_ohlc.index) figure = plt.figure() ax1 = plt.subplot2grid((8, 1), (0, 0), rowspan=5, colspan=1) ax1.plot(df_ohlc.index, df_ohlc['Close'], label='Close') plt.xlabel('Date') plt.ylabel('Price') plt.title('Сharts') ax2 = plt.subplot2grid((8, 1), (6, 0), rowspan=2, colspan=1, sharex=ax1) ax2.plot(df_ohlc.index, df_ohlc['Volume'], label='Volume') plt.xticks(rotation=45) ax1.xaxis.set_major_locator(MaxNLocator(5)) plt.ylabel('Volume') return figure
[docs]def resample(df_ohlc, frequency='H'): """Function to change frequency and fill the gaps""" df_ohlc = df_ohlc.resample(frequency).ffill() df_ohlc = df_ohlc.fillna(0) return df_ohlc
[docs]def get_sharpe(df_ohlc): """Function to calculate sharpe ratio""" if isinstance(df_ohlc, pd.DataFrame): return round((np.sqrt(len(df_ohlc)) * df_ohlc.mean() / df_ohlc.std().values).values[0], 2) else: return round((np.sqrt(len(df_ohlc)) * df_ohlc.mean() / df_ohlc.std()), 2)
[docs]def get_max_drawdown(returns): """Assumes returns is a pandas Series""" ret = returns.add(1).cumprod() daily_drawdown = ret.div(ret.cummax()).sub(1) max_drawdown = round(daily_drawdown.min(), 4) end = daily_drawdown.idxmin() start = ret.loc[:end].idxmax() return max_drawdown, start, end
[docs]def get_label_from_dict(settings_dict): """Function to get name from dict""" label = '' if 'delay' in settings_dict.keys(): label += 'd' + str(settings_dict['delay']) if 'commissions_const' in settings_dict.keys(): label += '_' + str(settings_dict['commissions_const'] * 100) + '%' + 'coms' return label
[docs]def initialize_universe(ohlc_df): '''func to create technical data dfs and add them to dict''' # add moex_stocks Universe uni_dict = {} # ohlc_df = pd.read_csv(DATA_DIR + csv_file, index_col='Date') ohlc_df.index = pd.to_datetime(ohlc_df.index) ohlc_df.sort_index(inplace=True) ohlc_df = ohlc_df.loc[~ohlc_df.index.duplicated(keep='first')] # print(ohlc_df.info(max_cols=1000, null_counts=True)) High = [column for column in ohlc_df.columns if 'High' in column] Low = [column for column in ohlc_df.columns if 'Low' in column] Close = [column for column in ohlc_df.columns if 'Close' in column] Open = [column for column in ohlc_df.columns if 'Open' in column] Volume = [column for column in ohlc_df.columns if 'Volume' in column] uni_dict['close'] = ohlc_df[Close].rename(columns=lambda col: col.replace('Close_', '')) uni_dict['volume'] = ohlc_df[Volume].rename(columns=lambda col: col.replace('Volume_', '')) uni_dict['open'] = ohlc_df[Open].rename(columns=lambda col: col.replace('Open_', '')) uni_dict['low'] = ohlc_df[Low].rename(columns=lambda col: col.replace('Low_', '')) uni_dict['high'] = ohlc_df[High].rename(columns=lambda col: col.replace('High_', '')) uni_dict['all'] = ohlc_df return uni_dict
# def prolong(series): # '''func to prolong weight # weights_df = events.rolling(prolong_timeframe).apply(prolong)''' # new_ser = series.copy() # # if new_ser[0] == 0 and new_ser.sum() != 0: # if new_ser.sum() > 0 and new_ser.sum() != len(new_ser): # return 1 # elif new_ser.sum() < 0 and new_ser.sum() != -len(new_ser): # return -1 # else: # return 0
[docs]def prolong(series): '''func to prolong weight weights_df = events.rolling(prolong_timeframe).apply(prolong)''' new_ser = series.copy() # if new_ser[0] == 0 and new_ser.sum() != 0: non_zero = new_ser[new_ser != 0] if not non_zero.empty: if non_zero[-1] > 0 and non_zero.sum() != len(new_ser): return 1 elif non_zero[-1] < 0 and non_zero.sum() != -len(new_ser): return -1 else: return 0 else: return 0
[docs]def unpack_ohlc(ohlc_df): '''Just helper to create dict with all tech vars''' High = [column for column in ohlc_df.columns if 'High' in column] Low = [column for column in ohlc_df.columns if 'Low' in column] Close = [column for column in ohlc_df.columns if 'Close' in column] Open = [column for column in ohlc_df.columns if 'Open' in column] Volume = [column for column in ohlc_df.columns if 'Volume' in column] close = ohlc_df[Close].rename(columns=lambda col: col.replace('Close_', '')) volume = ohlc_df[Volume].rename(columns=lambda col: col.replace('Volume_', '')) opens = ohlc_df[Open].rename(columns=lambda col: col.replace('Open_', '')) low = ohlc_df[Low].rename(columns=lambda col: col.replace('Low_', '')) high = ohlc_df[High].rename(columns=lambda col: col.replace('High_', '')) return volume, opens, high, low, close