def stat_feat_15(security_symbol, start_date, end_date, thrd=-0.001, interval=None, conn=None): conn = connect_to_db() if conn is None else conn df = download_data_daily(conn, security_symbol, start_date, end_date) features = feature_extraction_fallraise(df) pos_cnt = 0 neg_cnt = 0 pos = 0 neg = 0 expp_list = list() for index, row in features.iterrows(): if row['lr02'] < row['lr01'] < thrd: if row['lr0'] > 0.000: pos_cnt += 1 pos += row['lr0'] elif row['lr0'] < -0.000: neg_cnt += 1 neg += row['lr0'] if interval is not None and pos_cnt + neg_cnt >= interval: exp_p = (pos + neg) / (pos_cnt + neg_cnt) expp_list.append(round(100*exp_p, 2)) pos_cnt = 0 neg_cnt = 0 pos = 0 neg = 0 if interval is None: exp_p = (pos + neg)/(pos_cnt + neg_cnt) print(f"corr: {pos_cnt} with expected return {round(100*pos/pos_cnt, 2)}%, wrong: {neg_cnt} with expected return " f"{round(100*neg/neg_cnt, 2)}%, Strategy Total Expected Return {round(100*exp_p, 2)}%") else: print(expp_list)
def candle_stick(security_symbol, date_key_int, conn=None, df=None): """ plot candle stick chart :param conn: db engine obj :param security_symbol: string :param date_key_int: int :return: """ if df is None: conn = connect_to_db() if conn is None else conn df = download_data_intraday(conn, security_symbol, date_key_int, "1m") df = estimate_vwap_intraday(df) print(f"plotting chart for {security_symbol} on {date_key_int}...") fig = go.Figure(data=[ go.Candlestick(x=df['time_stamp'], open=df['open_price'], high=df['high_price'], low=df['low_price'], close=df['close_price'], name="Candle Stick"), go.Line(x=df['time_stamp'], y=df['vwap'], mode="lines", name="VWAP") ]) fig.update_layout(title=f'Daily Price Visualization For {date_key_int}', yaxis_title=f'{security_symbol} Stock') fig.show()
def dist_feat_15(security_symbol, start_date, end_date, thrd=-0.001, conn=None): conn = connect_to_db() if conn is None else conn df = download_data_daily(conn, security_symbol, start_date, end_date) features = feature_extraction_fallraise(df) features_ss = features.loc[(features['lr01'] < thrd) & (features['lr02'] < features['lr01'])] print(f"Mean: {features_ss['lr0'].mean()}, Sigma: {features_ss['lr0'].std()}") # print(features_ss) features_ss.hist(column='lr0', bins=500) plt.show()
def stat_feat_14(security_symbol, start_date, end_date, thrd=-0.001, interval=None, conn=None): conn = connect_to_db() if conn is None else conn df = download_data_daily(conn, security_symbol, start_date, end_date) features = feature_extraction_fallraise(df) pos_cnt = 0 neg_cnt = 0 pos = 0 neg = 0 expp_list = list() triggers = list() for index, row in features.iterrows(): if row['lr01'] < row['lr0'] < thrd and row['close_price'] < row[ 'vwap_ma_3']: if row['lr5-5'] > 0.000: pos_cnt += 1 pos += row['lr5-5'] ann = { 'x': row['date_key_int'], 'y': row['high_price'], 'text': round(row['lr5-5'], 2) } triggers.append(ann) elif row['lr5-5'] < -0.000: neg_cnt += 1 neg += row['lr5-5'] ann = { 'x': row['date_key_int'], 'y': row['high_price'], 'text': round(row['lr5-5'], 2) } triggers.append(ann) if interval is not None and pos_cnt + neg_cnt >= interval: exp_p = (pos + neg) / (pos_cnt + neg_cnt) expp_list.append(round(100 * exp_p, 2)) pos_cnt = 0 neg_cnt = 0 pos = 0 neg = 0 if interval is None and (pos_cnt + neg_cnt) > 0: exp_p = (pos + neg) / (pos_cnt + neg_cnt) pos_rate = round(100 * pos / pos_cnt, 2) if pos_cnt > 0 else "N/A" neg_rate = round(100 * neg / neg_cnt, 2) if neg_cnt > 0 else "N/A" print( f"corr: {pos_cnt} with expected return {pos_rate}%, wrong: {neg_cnt} with expected return " f"{neg_rate}%, Strategy Total Expected Return {round(100 * exp_p, 2)}%" ) return exp_p, triggers else: print(expp_list) print(features.iloc[-1]['date_key_int']) return expp_list, triggers
def candle_stick_daily(security_symbol, start_date, end_date, conn=None, df=None, annotations=None): """ :param security_symbol: :param start_date: :param end_date: :param conn: :param df: :param annotations: [{'x': date_key_int, 'y': high_price, 'text': 'falling?'}] :return: """ def __update_annotations(fig, anns): if anns is not None: for ann in anns: fig.add_annotation(x=pd.to_datetime(str(ann['x']), format='%Y%m%d'), y=ann['y'], text=ann['text']) fig.update_annotations( dict(xref="x", yref="y", showarrow=True, arrowhead=7, ax=0, ay=-40)) return True if df is None: conn = connect_to_db() if conn is None else conn df = download_data_daily(conn, security_symbol, start_date, end_date) df['date_key'] = df['date_key_int'].apply( lambda x: pd.to_datetime(str(x), format='%Y%m%d')) print(f"plotting chart for {security_symbol} ...") fig = go.Figure(data=[ go.Candlestick(x=df['date_key'], open=df['open_price'], high=df['high_price'], low=df['low_price'], close=df['close_price'], name="Candle Stick") ]) __update_annotations(fig, annotations) fig.update_layout(title=f'Daily Price Visualization', yaxis_title=f'{security_symbol} Stock') fig.show()
def show_all_fallraise(security_symbol, start_date, end_date, f_thd=-0.01, r_thd=0.02, conn=None): conn = connect_to_db() if conn is None else conn df = download_data_daily(conn, security_symbol, start_date, end_date) df = log_return(df) signals = get_falls_raises(df, falls_thd=f_thd, raises_thd=r_thd) signals['raises'].extend(signals['falls']) print(len(signals['raises']), len(signals['falls'])) candle_stick_daily(security_symbol, start_date, end_date, conn, annotations=signals['raises'])
def rank_performances(file_name, start_date, end_date): """ :param file_name: :param start_date: :param end_date: :return: """ # take second element for sort def __take_second(elem): return elem[1] secs = read_sec_list(file_name) conn = connect_to_db() results = list() for sec in secs: df = download_data_daily(conn, sec, start_date, end_date) perf = get_performance_log_return(df) results.append([sec, perf['mean'], perf['std']]) results.sort(key=__take_second) for each in results: print(each)
email_notice.content_type = 'ETL Warning!' email_notice.content = 'Error(s) occurred in ETL. Please see the log file for details.' else: logfile = None msg = email_notice.email_msg(logfile=logfile) email_notice.send_email(msg) if __name__ == '__main__': if os.path.exists('error.log'): os.remove('error.log') # Read stock symbols in symbol_file = 'stock_symbol.csv' symbol_list = pd.read_csv(symbol_file)['symbol'].to_list() # Create postgresql connection and cursor conn = db_util.connect_to_db() if conn is not None: table_list = [{ 'table_name': 'us_stock_daily', 'res': 'D' }, { 'table_name': 'us_stock_1m', 'res': '1' }] for table in table_list: now = int(datetime.datetime.now().timestamp()) init_time = time.time() for i, symbol in enumerate(symbol_list): # prevent requests from exceeding limit (60 queries per minute) if not (i + 1) % 60: sleeptime = init_time + 61 - time.time(
from utils.db_util import connect_to_db from utils.helpers import read_sec_list from utils.visualization import candle_stick from analytics.oscillation_20 import find_oscs if __name__ == '__main__': conn = connect_to_db() securities = read_sec_list("sec_list.csv") negs = 0 poss = 0 osc_lst = dict() for security in securities: oscs, n, p = find_oscs(conn, security, 20200604, 20200605) if len(oscs) != 0: osc_lst[security] = oscs negs += n poss += p conn = None print(f"positive: {poss}; negative: {negs}") print("ready to plot, press anykey to continue:") for security in osc_lst: for date_key_int in osc_lst[security]: input() candle_stick(security, date_key_int, df=osc_lst[security][date_key_int])