def apply_macd(df, n_fast, n_slow, n_sign, on_data="close"): """ calculate MACD on specified data type. return df with columns added Parameters: df : pandas dataframe of ohlcv data n_fast : iterable of length 2, specifying the range to vary the n_fast period of macd n_slow : iterable of length 2, specifying the range to vary the n_slow period of macd n_sign : iterable of length 2, specifying the range to vary the n_signal period of macd on_data : str of data to calculate macd indicator on """ ensure_correct_data_calculation_choice(on_data) n_fast_range = range(n_fast[0], n_fast[1]) n_slow_range = range(n_slow[0], n_slow[1]) n_sign_range = range(n_sign[0], n_sign[1]) complete = product(n_fast_range, n_slow_range, n_sign_range) df_new = pd.DataFrame(index=df.index) for combo in complete: # combo is a tuple of (n_fast, n_slow) df_new["MACD: " + str(combo[0]) + "_" + str(combo[1]) + "_" + str(combo[2])] = macd_diff(df[on_data], n_fast=combo[0], n_slow=combo[1], n_sign=combo[2]) df_new.fillna(0, inplace=True) return df_new
def get_ml_feature(self, symbol, prices=None, cutoff=None): if prices: price = prices.get(symbol, 1E10) vix = prices['^VIX'] else: price = self.closes[symbol][cutoff] vix = self.closes['^VIX'][cutoff] if cutoff: close = self.closes[symbol][cutoff - DAYS_IN_A_YEAR:cutoff] high = np.array( self.hists[symbol].get('High')[cutoff - DAYS_IN_A_YEAR:cutoff]) low = np.array( self.hists[symbol].get('Low')[cutoff - DAYS_IN_A_YEAR:cutoff]) else: close = self.closes[symbol][-DAYS_IN_A_YEAR:] high = np.array(self.hists[symbol].get('High')[-DAYS_IN_A_YEAR:]) low = np.array(self.hists[symbol].get('Low')[-DAYS_IN_A_YEAR:]) # Basic stats day_range_change = price / np.max(close[-DATE_RANGE:]) - 1 today_change = price / close[-1] - 1 yesterday_change = close[-1] / close[-2] - 1 day_before_yesterday_change = close[-2] / close[-3] - 1 twenty_day_change = price / close[-20] - 1 year_high_change = price / np.max(close) - 1 year_low_change = price / np.min(close) - 1 all_changes = [ close[t + 1] / close[t] - 1 for t in range(len(close) - 1) if close[t + 1] > 0 and close[t] > 0 ] # Technical indicators close = np.append(close, price) high = np.append(high, price) low = np.append(low, price) pd_close = pd.Series(close) pd_high = pd.Series(high) pd_low = pd.Series(low) rsi = momentum.rsi(pd_close).values[-1] macd_rate = trend.macd_diff(pd_close).values[-1] / price wr = momentum.wr(pd_high, pd_low, pd_close).values[-1] tsi = momentum.tsi(pd_close).values[-1] feature = { 'Today_Change': today_change, 'Yesterday_Change': yesterday_change, 'Day_Before_Yesterday_Change': day_before_yesterday_change, 'Twenty_Day_Change': twenty_day_change, 'Day_Range_Change': day_range_change, 'Year_High_Change': year_high_change, 'Year_Low_Change': year_low_change, 'Change_Average': np.mean(all_changes), 'Change_Variance': np.var(all_changes), 'RSI': rsi, 'MACD_Rate': macd_rate, 'WR': wr, 'TSI': tsi, 'VIX': vix } return feature
def test_macd_diff(self): target = 'MACD_diff' result = macd_diff(close=self._df['Close'], n_slow=12, n_fast=26, n_sign=9, fillna=False) pd.testing.assert_series_equal(self._df[target].tail(), result.tail(), check_names=False)
def MACD(df0): df = df0 df['macd'] = macd(df['close'], n_slow=26, n_fast=12, fillna=False) df['macd_signal'] = macd_signal(df['close'], n_slow=26, n_fast=12, n_sign=9, fillna=False) df['macd_hist'] = macd_diff(df['close'], n_slow=26, n_fast=12, n_sign=9, fillna=False) return df
def apply_macd(self, on_data="close"): self._ensure_data_calculation_choice(on_data) n_fast_range = range(self.macd_fast[0], self.macd_fast[1]) n_slow_range = range(self.macd_slow[0], self.macd_slow[1]) n_sign_range = range(self.macd_sig[0], self.macd_sig[1]) complete = product(n_fast_range, n_slow_range, n_sign_range) self.macd = pd.DataFrame(index=self.data.index) for combo in tqdm(complete, desc="Creating MACD diff for lines"): self.macd[str(combo[0]) + "f_" + str(combo[1]) + "s_" + str(combo[2]) + "sig"] = macd_diff(self.data[on_data], n_fast=combo[0], n_slow=combo[1], n_sign=combo[2]) self.macd.fillna(0, inplace=True) self.indicator = self.macd
def __dataframe(self): """Create an comprehensive list of from data. Args: None Returns: result: dataframe for learning """ # Calculate the percentage and real differences between columns difference = math.Difference(self._ohlcv) num_difference = difference.actual() pct_difference = difference.relative() # Create result to return. result = pd.DataFrame() # Add current value columns result['open'] = self._ohlcv['open'] result['high'] = self._ohlcv['high'] result['low'] = self._ohlcv['low'] result['close'] = self._ohlcv['close'] result['volume'] = self._ohlcv['volume'] # Add columns of differences result['num_diff_open'] = num_difference['open'] result['num_diff_high'] = num_difference['high'] result['num_diff_low'] = num_difference['low'] result['num_diff_close'] = num_difference['close'] result['pct_diff_open'] = pct_difference['open'] result['pct_diff_high'] = pct_difference['high'] result['pct_diff_low'] = pct_difference['low'] result['pct_diff_close'] = pct_difference['close'] result['pct_diff_volume'] = pct_difference['volume'] # Add date related columns # result['day'] = self._dates.day result['weekday'] = self._dates.weekday # result['week'] = self._dates.week result['month'] = self._dates.month result['quarter'] = self._dates.quarter # result['dayofyear'] = self._dates.dayofyear # Moving averages result['ma_open'] = result['open'].rolling( self._globals['ma_window']).mean() result['ma_high'] = result['high'].rolling( self._globals['ma_window']).mean() result['ma_low'] = result['low'].rolling( self._globals['ma_window']).mean() result['ma_close'] = result['close'].rolling( self._globals['ma_window']).mean() result['ma_volume'] = result['volume'].rolling( self._globals['vma_window']).mean() result['ma_volume_long'] = result['volume'].rolling( self._globals['vma_window_long']).mean() result[ 'ma_volume_delta'] = result['ma_volume_long'] - result['ma_volume'] # Standard deviation related result['ma_std_close'] = result['close'].rolling( self._globals['ma_window']).std() result['std_pct_diff_close'] = result['pct_diff_close'].rolling( self._globals['ma_window']).std() result['bollinger_lband'] = volatility.bollinger_lband(result['close']) result['bollinger_hband'] = volatility.bollinger_lband(result['close']) result[ 'bollinger_lband_indicator'] = volatility.bollinger_lband_indicator( result['close']) result[ 'bollinger_hband_indicator'] = volatility.bollinger_hband_indicator( result['close']) # Rolling ranges result['amplitude'] = result['high'] - result['low'] _min = result['low'].rolling(self._globals['week']).min() _max = result['high'].rolling(self._globals['week']).max() result['amplitude_medium'] = abs(_min - _max) _min = result['low'].rolling(2 * self._globals['week']).min() _max = result['high'].rolling(2 * self._globals['week']).max() result['amplitude_long'] = abs(_min - _max) _min = result['volume'].rolling(self._globals['week']).min() _max = result['volume'].rolling(self._globals['week']).max() result['vol_amplitude'] = abs(_min - _max) _min = result['volume'].rolling(2 * self._globals['week']).min() _max = result['volume'].rolling(2 * self._globals['week']).max() result['vol_amplitude_long'] = abs(_min - _max) # Volume metrics result['force_index'] = volume.force_index(result['close'], result['volume']) result['negative_volume_index'] = volume.negative_volume_index( result['close'], result['volume']) result['ease_of_movement'] = volume.ease_of_movement( result['high'], result['low'], result['close'], result['volume']) result['acc_dist_index'] = volume.acc_dist_index( result['high'], result['low'], result['close'], result['volume']) result['on_balance_volume'] = volume.on_balance_volume( result['close'], result['volume']) result['on_balance_volume_mean'] = volume.on_balance_volume( result['close'], result['volume']) result['volume_price_trend'] = volume.volume_price_trend( result['close'], result['volume']) # Calculate the Stochastic values result['k'] = momentum.stoch(result['high'], result['low'], result['close'], n=self._globals['kwindow']) result['d'] = momentum.stoch_signal(result['high'], result['low'], result['close'], n=self._globals['kwindow'], d_n=self._globals['dwindow']) # Calculate the Miscellaneous values result['rsi'] = momentum.rsi(result['close'], n=self._globals['rsiwindow'], fillna=False) miscellaneous = math.Misc(self._ohlcv) result['proc'] = miscellaneous.proc(self._globals['proc_window']) # Calculate ADX result['adx'] = trend.adx(result['high'], result['low'], result['close'], n=self._globals['adx_window']) # Calculate MACD difference result['macd_diff'] = trend.macd_diff( result['close'], n_fast=self._globals['macd_sign'], n_slow=self._globals['macd_slow'], n_sign=self._globals['macd_sign']) # Create series for increasing / decreasing closes (Convert NaNs to 0) _result = np.nan_to_num(result['pct_diff_close'].values) _increasing = (_result >= 0).astype(int) * self._buy _decreasing = (_result < 0).astype(int) * self._sell result['increasing'] = _increasing + _decreasing # Stochastic subtraciton result['k_d'] = pd.Series(result['k'].values - result['d'].values) # Other indicators result['k_i'] = self._stochastic_indicator(result['k'], result['high'], result['low'], result['ma_close']) result['d_i'] = self._stochastic_indicator(result['d'], result['high'], result['low'], result['ma_close']) result['stoch_i'] = self._stochastic_indicator_2( result['k'], result['d'], result['high'], result['low'], result['ma_close']) result['rsi_i'] = self._rsi_indicator(result['rsi'], result['high'], result['low'], result['ma_close']) result['adx_i'] = self._adx_indicator(result['adx']) result['macd_diff_i'] = self._macd_diff_indicator(result['macd_diff']) result['volume_i'] = self._volume_indicator(result['ma_volume'], result['ma_volume_long']) # Create time shifted columns for step in range(1, self._ignore_row_count + 1): # result['t-{}'.format(step)] = result['close'].shift(step) result['tpd-{}'.format(step)] = result['close'].pct_change( periods=step) # result['tad-{}'.format(step)] = result[ # 'close'].diff(periods=step) # Mask increasing with result['increasing_masked'] = _mask(result['increasing'].to_frame(), result['stoch_i'], as_integer=True).values # Get class values for each vector classes = pd.DataFrame(columns=self._shift_steps) for step in self._shift_steps: # Shift each column by the value of its label classes[step] = result[self._label2predict].shift(-step) # Remove all undesirable columns from the dataframe undesired_columns = ['open', 'close', 'high', 'low', 'volume'] for column in undesired_columns: result = result.drop(column, axis=1) # Delete the firsts row of the dataframe as it has NaN values from the # .diff() and .pct_change() operations result = result.iloc[self._ignore_row_count:] classes = classes.iloc[self._ignore_row_count:] # Convert result to float32 to conserve memory result = result.astype(np.float32) # Return return result, classes
def test_macd_diff(self): target = 'MACD_diff' result = macd_diff(**self._params) pd.testing.assert_series_equal(self._df[target].tail(), result.tail(), check_names=False)
def __dataframe(self): """Create an comprehensive list of from data. Args: None Returns: result: dataframe for learning """ # Calculate the percentage and real differences between columns difference = math.Difference(self._ohlcv) num_difference = difference.actual() pct_difference = difference.relative() # Create result to return. result = pd.DataFrame() # Add current value columns # NOTE Close must be first for correct correlation column dropping result['close'] = self._ohlcv['close'] result['open'] = self._ohlcv['open'] result['high'] = self._ohlcv['high'] result['low'] = self._ohlcv['low'] result['volume'] = self._ohlcv['volume'] # Add columns of differences # NOTE Close must be first for correct correlation column dropping result['num_diff_close'] = num_difference['close'] result['pct_diff_close'] = pct_difference['close'] result['num_diff_open'] = num_difference['open'] result['pct_diff_open'] = pct_difference['open'] result['num_diff_high'] = num_difference['high'] result['pct_diff_high'] = pct_difference['high'] result['num_diff_low'] = num_difference['low'] result['pct_diff_low'] = pct_difference['low'] result['pct_diff_volume'] = pct_difference['volume'] # Add date related columns # result['day'] = self._dates.day result['weekday'] = self._dates.weekday # result['week'] = self._dates.week result['month'] = self._dates.month result['quarter'] = self._dates.quarter # result['dayofyear'] = self._dates.dayofyear # Moving averages result['ma_open'] = result['open'].rolling( self._globals['ma_window']).mean() result['ma_high'] = result['high'].rolling( self._globals['ma_window']).mean() result['ma_low'] = result['low'].rolling( self._globals['ma_window']).mean() result['ma_close'] = result['close'].rolling( self._globals['ma_window']).mean() result['ma_volume'] = result['volume'].rolling( self._globals['vma_window']).mean() result['ma_volume_long'] = result['volume'].rolling( self._globals['vma_window_long']).mean() result['ma_volume_delta'] = result[ 'ma_volume_long'] - result['ma_volume'] # Standard deviation related result['ma_std_close'] = result['close'].rolling( self._globals['ma_window']).std() result['std_pct_diff_close'] = result['pct_diff_close'].rolling( self._globals['ma_window']).std() result['bollinger_lband'] = volatility.bollinger_lband(result['close']) result['bollinger_hband'] = volatility.bollinger_lband(result['close']) result['bollinger_lband_indicator'] = volatility.bollinger_lband_indicator(result['close']) result['bollinger_hband_indicator'] = volatility.bollinger_hband_indicator(result['close']) # Rolling ranges result['amplitude'] = result['high'] - result['low'] _min = result['low'].rolling( self._globals['week']).min() _max = result['high'].rolling( self._globals['week']).max() result['amplitude_medium'] = abs(_min - _max) _min = result['low'].rolling( 2 * self._globals['week']).min() _max = result['high'].rolling( 2 * self._globals['week']).max() result['amplitude_long'] = abs(_min - _max) _min = result['volume'].rolling( self._globals['week']).min() _max = result['volume'].rolling( self._globals['week']).max() result['vol_amplitude'] = abs(_min - _max) _min = result['volume'].rolling( 2 * self._globals['week']).min() _max = result['volume'].rolling( 2 * self._globals['week']).max() result['vol_amplitude_long'] = abs(_min - _max) # Volume metrics result['force_index'] = volume.force_index( result['close'], result['volume']) result['negative_volume_index'] = volume.negative_volume_index( result['close'], result['volume']) result['ease_of_movement'] = volume.ease_of_movement( result['high'], result['low'], result['close'], result['volume']) result['acc_dist_index'] = volume.acc_dist_index( result['high'], result['low'], result['close'], result['volume']) result['on_balance_volume'] = volume.on_balance_volume( result['close'], result['volume']) result['on_balance_volume_mean'] = volume.on_balance_volume( result['close'], result['volume']) result['volume_price_trend'] = volume.volume_price_trend( result['close'], result['volume']) # Calculate the Stochastic values result['k'] = momentum.stoch( result['high'], result['low'], result['close'], n=self._globals['kwindow']) result['d'] = momentum.stoch_signal( result['high'], result['low'], result['close'], n=self._globals['kwindow'], d_n=self._globals['dwindow']) # Calculate the Miscellaneous values result['rsi'] = momentum.rsi( result['close'], n=self._globals['rsiwindow'], fillna=False) miscellaneous = math.Misc(self._ohlcv) result['proc'] = miscellaneous.proc(self._globals['proc_window']) # Calculate ADX result['adx'] = trend.adx( result['high'], result['low'], result['close'], n=self._globals['adx_window']) # Calculate MACD difference result['macd_diff'] = trend.macd_diff( result['close'], n_fast=self._globals['macd_sign'], n_slow=self._globals['macd_slow'], n_sign=self._globals['macd_sign']) # Create series for increasing / decreasing closes (Convert NaNs to 0) _result = np.nan_to_num(result['pct_diff_close'].values) _increasing = (_result >= 0).astype(int) * self._buy _decreasing = (_result < 0).astype(int) * self._sell result['increasing'] = _increasing + _decreasing # Stochastic subtraciton result['k_d'] = pd.Series(result['k'].values - result['d'].values) # Other indicators result['k_i'] = self._stochastic_indicator( result['k'], result['high'], result['low'], result['ma_close']) result['d_i'] = self._stochastic_indicator( result['d'], result['high'], result['low'], result['ma_close']) result['stoch_i'] = self._stochastic_indicator_2( result['k'], result['d'], result['high'], result['low'], result['ma_close']) result['rsi_i'] = self._rsi_indicator( result['rsi'], result['high'], result['low'], result['ma_close']) result['adx_i'] = self._adx_indicator(result['adx']) result['macd_diff_i'] = self._macd_diff_indicator(result['macd_diff']) result['volume_i'] = self._volume_indicator( result['ma_volume'], result['ma_volume_long']) # Create time shifted columns for step in range(1, self._ignore_row_count + 1): result['t-{}'.format(step)] = result['close'].shift(step) result['tpd-{}'.format(step)] = result[ 'close'].pct_change(periods=step) result['tad-{}'.format(step)] = result[ 'close'].diff(periods=step) # Mask increasing with result['increasing_masked'] = _mask( result['increasing'].to_frame(), result['stoch_i'], as_integer=True).values # Get class values for each vector classes = pd.DataFrame(columns=self._shift_steps) for step in self._shift_steps: # Shift each column by the value of its label if self._binary is True: # Classes need to be 0 or 1 (One hot encoding) classes[step] = ( result[self._label2predict].shift(-step) > 0).astype(int) else: classes[step] = result[self._label2predict].shift(-step) # classes[step] = result[self._label2predict].shift(-step) # Delete the firsts row of the dataframe as it has NaN values from the # .diff() and .pct_change() operations ignore = max(max(self._shift_steps), self._ignore_row_count) result = result.iloc[ignore:] classes = classes.iloc[ignore:] # Convert result to float32 to conserve memory result = result.astype(np.float32) # Return return result, classes
def get_ml_feature(self, symbol, prices=None, cutoff=None): feature = {} if prices: price = prices.get(symbol, 1E10) vix = prices['^VIX'] else: price = self.closes[symbol][cutoff] vix = self.closes['^VIX'][cutoff] if cutoff: close = self.closes[symbol][cutoff - DAYS_IN_A_YEAR:cutoff] volume = self.volumes[symbol][cutoff - DAYS_IN_A_YEAR:cutoff] else: close = self.closes[symbol][-DAYS_IN_A_YEAR:] volume = self.volumes[symbol][-DAYS_IN_A_YEAR:] close = np.append(close, price) # Log returns feature['Day_1_Return'] = np.log(close[-1] / close[-2]) feature['Day_2_Return'] = np.log(close[-2] / close[-3]) feature['Day_3_Return'] = np.log(close[-3] / close[-4]) feature['Weekly_Return'] = np.log(price / close[-DAYS_IN_A_WEEK]) feature['Monthly_Return'] = np.log(price / close[-DAYS_IN_A_MONTH]) feature['Quarterly_Return'] = np.log(price / close[-DAYS_IN_A_QUARTER]) feature['From_Weekly_High'] = np.log(price / np.max(close[-DAYS_IN_A_WEEK:])) feature['From_Weekly_Low'] = np.log(price / np.min(close[-DAYS_IN_A_WEEK:])) # Technical indicators pd_close = pd.Series(close) feature['RSI'] = momentum.rsi(pd_close).values[-1] feature['MACD_Rate'] = trend.macd_diff(pd_close).values[-1] / price feature['TSI'] = momentum.tsi(pd_close).values[-1] # Markets feature['VIX'] = vix # Other numerical factors # Fit five data points to a second order polynomial feature['Acceleration'] = (2 * close[-5] - 1 * close[-4] - 2 * close[-3] - 1 * close[-2] + 2 * close[-1]) / 14 feature['Momentum'] = (-2 * close[-5] - 1 * close[-4] + 1 * close[-2] + 2 * close[-1]) / 10 quarterly_returns = [ np.log(close[i] / close[i - 1]) for i in range(-DAYS_IN_A_QUARTER, -1) ] monthly_returns = quarterly_returns[-DAYS_IN_A_MONTH:] weekly_returns = quarterly_returns[-DAYS_IN_A_WEEK:] feature['Monthly_Skewness'] = stats.skew(monthly_returns) feature['Monthly_Volatility'] = np.std(monthly_returns) feature['Weekly_Skewness'] = stats.skew(weekly_returns) feature['Weekly_Volatility'] = np.std(weekly_returns) feature['Z_Score'] = ( feature['Day_1_Return'] - np.mean(quarterly_returns)) / np.std(quarterly_returns) feature['Monthly_Avg_Dollar_Volume'] = np.average( np.multiply(close[-DAYS_IN_A_MONTH - 1:-1], volume[-DAYS_IN_A_MONTH:])) / 1E6 return feature
def __dataframe(self): """Create vectors from data. Args: shift_steps: List of steps Returns: result: dataframe for learning """ # Calculate the percentage and real differences between columns difference = math.Difference(self._file_values()) num_difference = difference.actual() pct_difference = difference.relative() # Create result to return. # Make sure it is float16 for efficient computing result = pd.DataFrame(columns=[ 'open', 'high', 'low', 'close', 'volume', 'increasing', 'weekday', 'day', 'dayofyear', 'quarter', 'month', 'num_diff_open', 'num_diff_high', 'num_diff_low', 'num_diff_close', 'pct_diff_open', 'pct_diff_high', 'pct_diff_low', 'pct_diff_close', 'k', 'd', 'rsi', 'adx', 'macd_diff', 'proc', 'ma_open', 'ma_high', 'ma_low', 'ma_close', 'ma_volume', 'ma_volume_long', 'ma_volume_delta']).astype('float16') # Add current value columns result['open'] = self._file_values()['open'] result['high'] = self._file_values()['high'] result['low'] = self._file_values()['low'] result['close'] = self._file_values()['close'] result['volume'] = self._file_values()['volume'] # Add columns of differences result['num_diff_open'] = num_difference['open'] result['num_diff_high'] = num_difference['high'] result['num_diff_low'] = num_difference['low'] result['num_diff_close'] = num_difference['close'] result['pct_diff_open'] = pct_difference['open'] result['pct_diff_high'] = pct_difference['high'] result['pct_diff_low'] = pct_difference['low'] result['pct_diff_close'] = pct_difference['close'] result['pct_diff_volume'] = pct_difference['volume'] # Add date related columns result['day'] = self.dates().day result['weekday'] = self.dates().weekday result['week'] = self.dates().week result['month'] = self.dates().month result['quarter'] = self.dates().quarter result['dayofyear'] = self.dates().dayofyear # Moving averages result['ma_open'] = result['open'].rolling( self._globals['ma_window']).mean() result['ma_high'] = result['high'].rolling( self._globals['ma_window']).mean() result['ma_low'] = result['low'].rolling( self._globals['ma_window']).mean() result['ma_close'] = result['close'].rolling( self._globals['ma_window']).mean() result['ma_volume'] = result['volume'].rolling( self._globals['vma_window']).mean() result['ma_volume_long'] = result['volume'].rolling( self._globals['vma_window_long']).mean() result['ma_volume_delta'] = result[ 'ma_volume_long'] - result['ma_volume'] # Calculate the Stochastic values stochastic = math.Stochastic( self._file_values(), window=self._globals['kwindow']) result['k'] = stochastic.k() result['d'] = stochastic.d(window=self._globals['dwindow']) # Calculate the Miscellaneous values result['rsi'] = momentum.rsi( result['close'], n=self._globals['rsiwindow'], fillna=False) miscellaneous = math.Misc(self._file_values()) result['proc'] = miscellaneous.proc(self._globals['proc_window']) # Calculate ADX result['adx'] = trend.adx( result['high'], result['low'], result['close'], n=self._globals['adx_window']) # Calculate MACD difference result['macd_diff'] = trend.macd_diff( result['close'], n_fast=self._globals['macd_sign'], n_slow=self._globals['macd_slow'], n_sign=self._globals['macd_sign']) # Create series for increasing / decreasing closes (Convert NaNs to 0) _result = np.nan_to_num(result['pct_diff_close'].values) _increasing = (_result >= 0).astype(int) * 1 _decreasing = (_result < 0).astype(int) * 0 result['increasing'] = _increasing + _decreasing # Delete the first row of the dataframe as it has NaN values from the # .diff() and .pct_change() operations result = result.iloc[self._ignore_row_count:] # Return return result
def scan(stock_detail,stock_budget): # scan the macd on the stock stock_macd = {} stock_macd_signal = {} stock_macd_diff = {} stock_sma = {} # get the macd of all the stocks for sym in stock_detail: # perform a macd on the aggregated data stock_macd[sym] = macd( close = stock_detail[sym]['close'].dropna(), ) stock_macd_signal[sym] = macd_signal( close = stock_detail[sym]['close'].dropna(), ) stock_macd_diff[sym] = macd_diff( close = stock_detail[sym]['close'].dropna(), ) # get 200 day sma stock_sma[sym] = sma_indicator( close = stock_detail[sym]['close'].dropna(), n = 200 ) for sym in stock_macd: curr_price = currentClosePrice(sym,'day') print('PRICE: ' + str(curr_price)) print("MACD: "+ str(stock_macd[sym][-1])) print("MACD SIGNAL: " + str(stock_macd_signal[sym][-1])) print("MACD DIFF:" + str(stock_macd_diff[sym][-1])) print("SMA: " + str(stock_sma[sym][-1])+'\n') # Buy Signal if ((stock_macd[sym][-1]<stock_macd_diff[sym][-1] and stock_macd_signal[sym][-1]<stock_macd_diff[sym][-1]) and #check for macd and signal neg ovr hist not(stock_macd_diff[sym][-3]>0 and stock_macd_diff[sym][-2]>0 and stock_macd_diff[sym][-1]>0) and #hist is not going neg (curr_price<stock_macd[sym][-1])): #close price below 200 moving average # check how many share that the budget can afford shares = determineShare(sym, stock_budget[sym]) # so macd looks good, so maybe want to buy? if shares>0 and clock.is_open(): stock_shares[sym] = shares #update the shares about to buy api.submit_order(sym,shares,'buy','market','day') print("Buying Stock {symbol}".format(symbol=sym)) # Sell Signal elif((stock_macd[sym][-1]>stock_macd_diff[sym][-1] and stock_macd_signal[sym][-1]>stock_macd_diff[sym][-1]) and #check for macd and signal pos ovr hist not(stock_macd_diff[sym][-3]<0 and stock_macd_diff[sym][-2]<0 and stock_macd_diff[sym][-1]<0) and #hist is not going pos (curr_price>stock_macd[sym][-1])): #close price above 200 moving average # check if we have any shares of this stock if stock_shares[sym]>0 and clock.is_open(): print(stock_shares[sym]) # sell all the shares api.submit_order(sym,stock_budget[sym],'sell','market','day') stock_shares[sym] = 0 #update the shares dictionary to 0, b/c sold all print("Selling Stock {symbol}".format(symbol=sym))
def __dataframe(self): """Create vectors from data. Args: shift_steps: List of steps Returns: result: dataframe for learning """ # Calculate the percentage and real differences between columns difference = math.Difference(self._file_values()) num_difference = difference.actual() pct_difference = difference.relative() # Create result to return. # Make sure it is float16 for efficient computing result = pd.DataFrame(columns=[ 'open', 'high', 'low', 'close', 'volume', 'increasing', 'weekday', 'day', 'dayofyear', 'quarter', 'month', 'num_diff_open', 'num_diff_high', 'num_diff_low', 'num_diff_close', 'pct_diff_open', 'pct_diff_high', 'pct_diff_low', 'pct_diff_close', 'k', 'd', 'rsi', 'adx', 'macd_diff', 'proc', 'ma_open', 'ma_high', 'ma_low', 'ma_close', 'ma_volume', 'ma_volume_long', 'ma_volume_delta' ]).astype('float16') # Add current value columns result['open'] = self._file_values()['open'] result['high'] = self._file_values()['high'] result['low'] = self._file_values()['low'] result['close'] = self._file_values()['close'] result['volume'] = self._file_values()['volume'] # Add columns of differences result['num_diff_open'] = num_difference['open'] result['num_diff_high'] = num_difference['high'] result['num_diff_low'] = num_difference['low'] result['num_diff_close'] = num_difference['close'] result['pct_diff_open'] = pct_difference['open'] result['pct_diff_high'] = pct_difference['high'] result['pct_diff_low'] = pct_difference['low'] result['pct_diff_close'] = pct_difference['close'] result['pct_diff_volume'] = pct_difference['volume'] # Add date related columns result['day'] = self.dates().day result['weekday'] = self.dates().weekday result['week'] = self.dates().week result['month'] = self.dates().month result['quarter'] = self.dates().quarter result['dayofyear'] = self.dates().dayofyear # Moving averages result['ma_open'] = result['open'].rolling( self._globals['ma_window']).mean() result['ma_high'] = result['high'].rolling( self._globals['ma_window']).mean() result['ma_low'] = result['low'].rolling( self._globals['ma_window']).mean() result['ma_close'] = result['close'].rolling( self._globals['ma_window']).mean() result['ma_volume'] = result['volume'].rolling( self._globals['vma_window']).mean() result['ma_volume_long'] = result['volume'].rolling( self._globals['vma_window_long']).mean() result[ 'ma_volume_delta'] = result['ma_volume_long'] - result['ma_volume'] # Calculate the Stochastic values stochastic = math.Stochastic(self._file_values(), window=self._globals['kwindow']) result['k'] = stochastic.k() result['d'] = stochastic.d(window=self._globals['dwindow']) # Calculate the Miscellaneous values result['rsi'] = momentum.rsi(result['close'], n=self._globals['rsiwindow'], fillna=False) miscellaneous = math.Misc(self._file_values()) result['proc'] = miscellaneous.proc(self._globals['proc_window']) # Calculate ADX result['adx'] = trend.adx(result['high'], result['low'], result['close'], n=self._globals['adx_window']) # Calculate MACD difference result['macd_diff'] = trend.macd_diff( result['close'], n_fast=self._globals['macd_sign'], n_slow=self._globals['macd_slow'], n_sign=self._globals['macd_sign']) # Create series for increasing / decreasing closes (Convert NaNs to 0) _result = np.nan_to_num(result['pct_diff_close'].values) _increasing = (_result >= 0).astype(int) * 1 _decreasing = (_result < 0).astype(int) * 0 result['increasing'] = _increasing + _decreasing # Delete the first row of the dataframe as it has NaN values from the # .diff() and .pct_change() operations result = result.iloc[self._ignore_row_count:] # Return return result