def execute(stock_name1, stock_name2, start_date, end_date, fetchStocks): stock1 = stockDataRetriever(stock_name1, start_date, end_date).fetchStock(fetchStocks) stock2 = stockDataRetriever(stock_name2, start_date, end_date).fetchStock(fetchStocks) print("Executing: ", stock_name1, stock_name2) # generate df by merging both stocks on date df = pd.merge(stock1[['Date','Close']], stock2[['Date','Close']], on="Date") # generate zscore from pricing ratios ratios = df['Close_x']/df['Close_y'] ratios_mavg = df['Close_x'].rolling(window=60).mean()/df['Close_y'].rolling(window=60).mean() zscore = z_score(ratios) df['zscore'] = zscore # plot_zscore(zscore) # buy stock1 sell stock2 when zscore < -1, buy stock2 sell stock1 when zscore > 1 df['buy'] = np.where(zscore < -1, 1, 0) df['sell'] = np.where(zscore > 1, -1, 0) df['signals'] = df['buy'] + df['sell'] df['positions'] = df['signals'].diff() plot_signals(df, stock_name1, stock_name2) for denom in [10,100,1000]: percent_profit = generate_profit(df,denom) print(percent_profit) print(benchmark().get_SPY_benchmark()) return percent_profit, plt
def cointegration(stock_name1, stock_name2, start_date, end_date, fetchStocks): stock1 = stockDataRetriever(stock_name1, start_date, end_date).fetchStock(fetchStocks) stock2 = stockDataRetriever(stock_name2, start_date, end_date).fetchStock(fetchStocks) score, pvalue, _ = coint(stock1["Close"], stock2["Close"]) return (stock_name1, stock_name2, pvalue)
def execute(): raw_file = stockDataRetriever("wiki/intraday", "none", "none").fetchStock(False) stock_groups = raw_file.groupby(raw_file['Ticker']) # seperate out each stock into groups for name, stock in stock_groups: rsi_df = RSI(name, stock) macd_df = MACD(name, stock) # merge rsi and macd strategies df = pd.merge(rsi_df, macd_df) # scan over 3 periods to find common buy signals for i in range(3,len(df)): if (scan_buy_signal(df['signal_rsi'][i-3:i])) and (scan_buy_signal(df['signal_macd'][i-3:i])): df['positions'][i] = 1 else: df['positions'][i] = 0 # create sell signals sell = np.where((df['signal_rsi'] == -1) | (df['signal_macd'] == -1), -1, 0) df['positions'] += sell # #plot trading signals # ax1 = plt.figure().add_subplot(111, ylabel='Price in $') # df['Close'].plot(ax=ax1, color='r', lw=2.) # ax1.set_title(name + ": RSI_MACD") # plt.xlabel("Time (Minutes)") # ax1.plot(df.loc[df.positions == 1].index, df.Close[df.positions == 1], '^', markersize=10, color='m') # ax1.plot(df.loc[df.positions == -1].index, df.Close[df.positions == -1], 'v', markersize=10, color='k') # plt.show() # for denom in [10,100,1000]: for denom in [100]: profit(df, name, denom)
def build_df(stock_name, start_date, end_date): # get tweet sentiment print("getting tweet sentiment") data = tweetDataRetriever(stock_name).fetch_tweet() data["Date"] = "" sentiment = [] for tweet in data["text"]: sentiment.append(tweet_sentiment(tweet)) data["Sentiment"] = sentiment # convert twitter date format for merge with stock data print("converting dates") date_conv = { 'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', "May": '05', "Jun": '06', "Jul": '07', "Aug": '08', "Sep": '09', "Oct": '10', "Nov": '11', "Dec": '12' } for i, row in data.iterrows(): raw = data["created_at"][i].split() #data["Date"][i] = raw[5] + "-" + date_conv[raw[1]] + "-" + raw[2] data.loc[i, "Date"] = raw[5] + "-" + date_conv[raw[1]] + "-" + raw[2] # drop tweet replies print("dropping replies") for i, row in data.iterrows(): if isinstance(data["in_reply_to_screen_name"][i], str): #print(row, data["in_reply_to_screen_name"][row]) data = data.drop(i) # aggregate tweets on same day print("aggregating tweets") data = data.groupby("Date")[[ "Sentiment", "favorite_count", "retweet_count" ]].apply(lambda x: x.values.tolist()) data = data.to_frame('twitter').reset_index() # merge tweets with stock data print("merging") data_stock = stockDataRetriever(stock_name, start_date, end_date).fetchStock(True) df = data_stock.merge(data, how="left", on='Date') # create average sentiment print("creating average sentiment, other important values") average_sentiment_other_values(df) # create indicators for supervised learning print("creating indicators for learning") df["change"] = df["Close"].diff() df["change"] = df["change"].fillna(0) df["change_int"] = 0 for i, row in df.iterrows(): val = -1 if float(df["change"][i]) > 0: val = 1 df.loc[i, "change_int"] = val df.to_csv("./twitterCSV/" + stock_name[5:] + "_MERGED.csv") return df
def execute(stock_name, start_date, end_date, fetchStocks, share_amount): stock = stockDataRetriever(stock_name, start_date, end_date).fetchStock(fetchStocks) df = pd.DataFrame(index=stock.index) df['Close'] = stock['Close'].copy() df['buy_signal'] = 0 df['sell_signal'] = 0 window = 14 # create frames of roll ups and roll downs delta = stock['Close'].diff() upgains, downloss = delta.copy(), delta.copy() upgains[upgains < 0] = 0 downloss[downloss > 0] = 0 # use moving average to create roll up/down roll_up = upgains.rolling(window=window, min_periods=1, center=False).mean() roll_down = downloss.abs().rolling(window=window, min_periods=1, center=False).mean() # create RSI RS = roll_up / roll_down RSI = 100.0 - (100.0 / (1.0 + RS)) # plot RSI fig = plt.figure() fig.suptitle(stock_name + ": RSI") RSI.plot() df['RSI'] = RSI.copy() # Create df for buy and sell signal df['buy_signal'][window:] = np.where(df['RSI'][window:] < 30, 1.0, 0) df['sell_signal'][window:] = np.where(df['RSI'][window:] > 70, 0, 1.0) # when signal changes from 1 to 0 or 0 to 1 - is a buy or sell df['buy_positions'] = df['buy_signal'].diff() df['sell_positions'] = df['sell_signal'].diff() # merge positions of buying - when RSI crosses 30 and selling - when price crosses 70 df['buy_positions'] = np.where(df['buy_positions'] < 0, 0, df['buy_positions']) df['sell_positions'] = np.where(df['sell_positions'] > 0, 0, df['sell_positions']) df['positions'] = df['buy_positions'] + df['sell_positions'] df['signal'] = createSignals(df['positions'].copy()) ax1 = plt.figure().add_subplot(111, ylabel='Price in $') df[['Close']].plot(ax=ax1, lw=2.) ax1.set_title(stock_name[5:] + ": RSI") ax1.plot(df.loc[df.positions == 1.0].index, df.Close[df.positions == 1.0], '^', markersize=10, color='m') ax1.plot(df.loc[df.positions == -1.0].index, df.Close[df.positions == -1.0], 'v', markersize=10, color='k') #share_amount = 100 initial_capital = float(100000.0) positions = pd.DataFrame(index=df.index).fillna(0.0) positions[stock_name] = share_amount * df['signal'] portfolio = positions.multiply(stock['Adj. Close'], axis=0) pos_diff = positions.diff() portfolio['holdings'] = (positions.multiply(stock['Adj. Close'], axis=0)).sum(axis=1) portfolio['cash'] = initial_capital - (pos_diff.multiply( stock['Adj. Close'], axis=0)).sum(axis=1).cumsum() portfolio['total'] = portfolio['cash'] + portfolio['holdings'] portfolio['returns'] = portfolio['total'].pct_change() # compare against baseline long position baseline_profit = (stock['Adj. Close'].iloc[-1] - stock['Adj. Close'].iloc[0]) * share_amount strategy_profit = portfolio['total'].iloc[-1] - initial_capital print(baseline_profit, strategy_profit) if strategy_profit < baseline_profit: percentage_difference_profit = round( (float(strategy_profit - abs(baseline_profit))) / initial_capital * 100, 2) else: percentage_difference_profit = round( (float(strategy_profit - baseline_profit)) / initial_capital * 100, 2) return percentage_difference_profit, plt
def execute(stock_name, start_date, end_date, fetchStocks, share_amount): stock = stockDataRetriever(stock_name, start_date, end_date).fetchStock(fetchStocks) window = 12 df = pd.DataFrame(index=stock.index) df['low_signal'] = 0.0 df['high_signal'] = 0.0 # Create bands df['middle_band'] = stock['Close'].rolling(window=window, min_periods=1, center=False).mean() df['moving_deviation'] = stock['Close'].rolling(window=window, min_periods=1, center=False).std() df['upper_band'] = df['middle_band'] + df['moving_deviation'] * 2 df['lower_band'] = df['middle_band'] - df['moving_deviation'] * 2 df['closing_price'] = stock['Close'] # Create df for high and low bands signal df['low_signal'][window:] = np.where( df['closing_price'][window:] < df['lower_band'][window:], 1.0, 0) df['high_signal'][window:] = np.where( df['closing_price'][window:] > df['upper_band'][window:], 0, 1.0) # when signal changes from 1 to 0 or 0 to 1 - is a buy or sell df['buy_positions'] = df['low_signal'].diff() df['sell_positions'] = df['high_signal'].diff() # merge positions of buying - when price crosses lower band and selling - when price crosses upper band df['buy_positions'] = np.where(df['buy_positions'] < 0, 0, df['buy_positions']) df['sell_positions'] = np.where(df['sell_positions'] > 0, 0, df['sell_positions']) df['positions'] = df['buy_positions'] + df['sell_positions'] # combine low,high signals to create stock ownership signal df['signal'] = createSignals(df['positions'].copy()) dfplot = df.copy(deep=True) dfplot = dfplot.loc[:600] ax1 = plt.figure().add_subplot(111, ylabel='Price in $') dfplot[['upper_band', 'lower_band', 'middle_band', 'closing_price']].plot(ax=ax1, lw=2.) plt.xlabel("Time (Days)") ax1.set_title(stock_name[5:] + ": Bollinger Bands") ax1.plot(dfplot.loc[dfplot.positions == 1.0].index, dfplot.lower_band[dfplot.positions == 1.0], '^', markersize=10, color='m') ax1.plot(dfplot.loc[dfplot.positions == -1.0].index, dfplot.upper_band[dfplot.positions == -1.0], 'v', markersize=10, color='k') #share_amount = 100 initial_capital = float(10000.0) positions = pd.DataFrame(index=df.index).fillna(0.0) positions[stock_name] = share_amount * df['signal'] portfolio = positions.multiply(stock['Adj. Close'], axis=0) pos_diff = positions.diff() portfolio['holdings'] = (positions.multiply(stock['Adj. Close'], axis=0)).sum(axis=1) portfolio['cash'] = initial_capital - (pos_diff.multiply( stock['Adj. Close'], axis=0)).sum(axis=1).cumsum() portfolio['total'] = portfolio['cash'] + portfolio['holdings'] portfolio['returns'] = portfolio['total'].pct_change() # compare against baseline long position baseline_profit = (stock['Adj. Close'].iloc[-1] - stock['Adj. Close'].iloc[0]) * share_amount strategy_profit = portfolio['total'].iloc[-1] - initial_capital print(baseline_profit, strategy_profit) if strategy_profit < baseline_profit: percentage_difference_profit = round( (float(strategy_profit - abs(baseline_profit))) / initial_capital * 100, 2) else: percentage_difference_profit = round( (float(strategy_profit - baseline_profit)) / initial_capital * 100, 2) return plt, percentage_difference_profit
def execute(stock_name, start_date, end_date, fetchStocks, share_amount): stock = stockDataRetriever(stock_name, start_date, end_date).fetchStock(fetchStocks) # Initialize the short and long windows and buy sell in df short_window = 40 long_window = 100 df = pd.DataFrame(index=stock.index) df['signal'] = 0.0 # Create short and long simple moving average df['short_mavg'] = stock['Close'].rolling(window=short_window, min_periods=1, center=False).mean() df['long_mavg'] = stock['Close'].rolling(window=long_window, min_periods=1, center=False).mean() # Create df df['signal'][short_window:] = np.where( df['short_mavg'][short_window:] > df['long_mavg'][short_window:], 1.0, 0.0) # when signal changes fromn 1 to 0 or 0 to 1 - is a buy or sell df['positions'] = df['signal'].diff() #share_amount = 100 initial_capital = float(10000.0) # create a portfolio that simulates owning and buying stocks positions = pd.DataFrame(index=df.index).fillna(0.0) positions[stock_name] = share_amount * df['signal'] portfolio = positions.multiply(stock['Adj. Close'], axis=0) pos_diff = positions.diff() portfolio['holdings'] = (positions.multiply(stock['Adj. Close'], axis=0)).sum(axis=1) portfolio['cash'] = initial_capital - (pos_diff.multiply( stock['Adj. Close'], axis=0)).sum(axis=1).cumsum() portfolio['total'] = portfolio['cash'] + portfolio['holdings'] portfolio['returns'] = portfolio['total'].pct_change() # compare against baseline long position baseline_profit = (stock['Adj. Close'].iloc[-1] - stock['Adj. Close'].iloc[0]) * share_amount strategy_profit = portfolio['total'].iloc[-1] - initial_capital if strategy_profit < baseline_profit: percentage_difference_profit = round( (float(strategy_profit - abs(baseline_profit))) / initial_capital * 100, 2) else: percentage_difference_profit = round( (float(strategy_profit - baseline_profit)) / initial_capital * 100, 2) print(baseline_profit, strategy_profit) # print out sharpe ratio # sharpe_ratio(portfolio['returns']) fig = plt.figure() fig.suptitle(stock_name + ": SMA") ax1 = fig.add_subplot(111, ylabel='Price in $') dfplot = df.copy(deep=True) dfplot = dfplot.loc[:600] stock.loc[:600]['Close'].plot(ax=ax1, color='r', lw=2.) dfplot[['short_mavg', 'long_mavg']].plot(ax=ax1, lw=2.) plt.xlabel("Time (Days)") #Plot the buy and sell df ax1.plot(dfplot.loc[dfplot.positions == 1.0].index, dfplot.short_mavg[dfplot.positions == 1.0], '^', markersize=10, color='m') ax1.plot(dfplot.loc[dfplot.positions == -1.0].index, dfplot.short_mavg[dfplot.positions == -1.0], 'v', markersize=10, color='k') return plt, percentage_difference_profit
def execute(stock_name, start_date, end_date, fetchStocks, share_amount): stock = stockDataRetriever(stock_name, start_date, end_date).fetchStock(fetchStocks) short_window = 50 long_window = 200 df = pd.DataFrame(index=stock.index) df['signal'] = 0.0 # Create short and long simple moving average df['short_ema'] = stock['Close'].ewm(span=short_window, adjust=False).mean() df['long_ema'] = stock['Close'].ewm(span=long_window, adjust=False).mean() # Create df df['signal'][short_window:] = np.where( df['short_ema'][short_window:] > df['long_ema'][short_window:], 1.0, 0.0) # when signal changes fromn 1 to 0 or 0 to 1 - is a buy or sell df['positions'] = df['signal'].diff() ax1 = plt.figure().add_subplot(111, ylabel='Price in $') stock['Close'].plot(ax=ax1, color='r', lw=2.) df[['short_ema', 'long_ema']].plot(ax=ax1, lw=2.) ax1.set_title(stock_name[5:] + ": EMA") # Plot the buy and sell df ax1.plot(df.loc[df.positions == 1.0].index, df.short_ema[df.positions == 1.0], '^', markersize=10, color='m') ax1.plot(df.loc[df.positions == -1.0].index, df.short_ema[df.positions == -1.0], 'v', markersize=10, color='k') #share_amount = 100 initial_capital = float(100000.0) positions = pd.DataFrame(index=df.index).fillna(0.0) positions[stock_name] = share_amount * df['signal'] portfolio = positions.multiply(stock['Adj. Close'], axis=0) pos_diff = positions.diff() portfolio['holdings'] = (positions.multiply(stock['Adj. Close'], axis=0)).sum(axis=1) portfolio['cash'] = initial_capital - (pos_diff.multiply( stock['Adj. Close'], axis=0)).sum(axis=1).cumsum() portfolio['total'] = portfolio['cash'] + portfolio['holdings'] portfolio['returns'] = portfolio['total'].pct_change() # compare against baseline long position baseline_profit = (stock['Adj. Close'].iloc[-1] - stock['Adj. Close'].iloc[0]) * share_amount strategy_profit = portfolio['total'].iloc[-1] - initial_capital print(baseline_profit, strategy_profit) if strategy_profit < baseline_profit: percentage_difference_profit = round( (float(strategy_profit - abs(baseline_profit))) / initial_capital * 100, 2) else: percentage_difference_profit = round( (float(strategy_profit - baseline_profit)) / initial_capital * 100, 2) return plt, percentage_difference_profit