def stochrsi(data, period): """ StochRSI. Formula: SRSI = ((RSIt - RSI LOW) / (RSI HIGH - LOW RSI)) * 100 """ rsi = relative_strength_index(data, period)[period:] stochrsi = map(lambda idx: 100 * ((rsi[idx] - np.min(rsi[idx+1-period:idx+1])) / (np.max(rsi[idx+1-period:idx+1]) - np.min(rsi[idx+1-period:idx+1]))), range(period-1, len(rsi))) stochrsi = fill_for_noncomputable_vals(data, stochrsi) return stochrsi
def analyze(signal): """ Analyze data """ close_prices = list(signal) rsi = relative_strength_index(close_prices, RSI_PERIOD) Trader.logger.debug("RSI: %.2lf" % rsi[-1]) buy_now = False sell_now = False if rsi[-2] <= RSI_OVERSOLD_PERCENTAGE and rsi[-1] > rsi[-2]: buy_now = True if rsi[-1] >= RSI_OVERBOUGHT_PERCENTAGE: sell_now = True return DictMap({'buy_now': buy_now, 'sell_now': sell_now})
ma30 = pd.DataFrame(closep).rolling(14).mean().values.tolist() ma30 = [v[0] for v in ma30] ma60 = pd.DataFrame(closep).rolling(30).mean().values.tolist() ma60 = [v[0] for v in ma60] nine_period_high = pd.rolling_max(pd.DataFrame(highp), window=ROLLING / 2) nine_period_low = pd.rolling_min(pd.DataFrame(lowp), window=ROLLING / 2) ichimoku = (nine_period_high + nine_period_low) / 2 ichimoku = ichimoku.replace([np.inf, -np.inf], np.nan) ichimoku = ichimoku.fillna(0.).values.tolist() macd_indie = moving_average_convergence(pd.DataFrame(closep)) wpr = williams_percent_r(closep) rsi = relative_strength_index(closep, ROLLING / 2) volatility1 = pd.DataFrame(closep).rolling(ROLLING).std().values #.tolist() volatility2 = pd.DataFrame(closep).rolling(ROLLING).var().values #.tolist() volatility = volatility1 / volatility2 volatility = [v[0] for v in volatility] rolling_skewness = pd.DataFrame(closep).rolling(ROLLING).skew().values rolling_kurtosis = pd.DataFrame(closep).rolling(ROLLING).kurt().values X, Y = [], [] for i in range(WINDOW, len(data_original) - 1, STEP): try: o = openp[i:i + WINDOW] h = highp[i:i + WINDOW]
ma30 = pd.DataFrame(closep).rolling(14).mean().values.tolist() ma30 = [v[0] for v in ma30] ma60 = pd.DataFrame(closep).rolling(30).mean().values.tolist() ma60 = [v[0] for v in ma60] nine_period_high = pd.rolling_max(pd.DataFrame(highp), window= ROLLING / 2) nine_period_low = pd.rolling_min(pd.DataFrame(lowp), window= ROLLING / 2) ichimoku = (nine_period_high + nine_period_low) /2 ichimoku = ichimoku.replace([np.inf, -np.inf], np.nan) ichimoku = ichimoku.fillna(0.).values.tolist() macd_indie = moving_average_convergence(pd.DataFrame(closep)) wpr = williams_percent_r(closep) rsi = relative_strength_index(closep, ROLLING / 2) volatility1 = pd.DataFrame(closep).rolling(ROLLING).std().values#.tolist() volatility2 = pd.DataFrame(closep).rolling(ROLLING).var().values#.tolist() volatility = volatility1 / volatility2 volatility = [v[0] for v in volatility] rolling_skewness = pd.DataFrame(closep).rolling(ROLLING).skew().values rolling_kurtosis = pd.DataFrame(closep).rolling(ROLLING).kurt().values X, Y = [], [] for i in range(WINDOW, len(data_original)-1, STEP): try: o = openp[i:i+WINDOW]
def compute_relative_strength_index(df): df['rsi'] = relative_strength_index(df.close, 14)
def test_relative_strength_index_invalid_period(self): period = 128 with self.assertRaises(Exception) as cm: relative_strength_index.relative_strength_index(self.data, period) expected = "Error: data_len < period" self.assertEqual(str(cm.exception), expected)
def test_relative_strength_index_period_10(self): period = 10 rsi = relative_strength_index.relative_strength_index( self.data, period) np.testing.assert_array_equal(rsi, self.rsi_period_10_expected)
def _get_ta_features(high, low, close, volume, desc): """ Returns a dict containing the technical analysis indicators calculated on the given high, low, close and volumes. """ ta = {} # Set numpy to ignore division error and invalid values (since not all features are complete) old_settings = np.seterr(divide='ignore', invalid='ignore') record_count = len(close) # Determine relative moving averages for _short, _long in desc['rsma']: if record_count < _short or record_count < _long: logging.error( "get_ta_features: not enough records for rsma (short={}, long={}, records={})" .format(_short, _long, record_count)) continue ta['rsma_{}_{}'.format(_short, _long)] = relative_sma(close, _short, _long) for _short, _long in desc['rema']: if record_count < _short or record_count < _long: logging.error( "get_ta_features: not enough records for rema (short={}, long={}, records={})" .format(_short, _long, record_count)) continue ta['rema_{}_{}'.format(_short, _long)] = relative_ema(close, _short, _long) # MACD Indicator if 'macd' in desc: for _short, _long in desc['macd']: if record_count < _short or record_count < _long: logging.error( "get_ta_features: not enough records for rema (short={}, long={}, records={})" .format(_short, _long, record_count)) continue ta['macd_{}_{}'.format( _short, _long)] = moving_average_convergence_divergence( close, _short, _long) # Aroon Indicator if 'ao' in desc: for _period in desc['ao']: if record_count < _period: logging.error( "get_ta_features: not enough records for ao (period={}, records={})" .format(_period, record_count)) continue ta['ao_{}'.format(_period)] = aroon_oscillator(close, _period) # Average Directional Movement Index (ADX) if 'adx' in desc: for _period in desc['adx']: if record_count < _period: logging.error( "get_ta_features: not enough records for adx (period={}, records={})" .format(_period, record_count)) continue ta['adx_{}'.format(_period)] = average_directional_index( close, high, low, _period) # Difference between Positive Directional Index(DI+) and Negative Directional Index(DI-) if 'wd' in desc: for _period in desc['wd']: if record_count < _period: logging.error( "get_ta_features: not enough records for wd (period={}, records={})" .format(_period, record_count)) continue ta['wd_{}'.format(_period)] = \ positive_directional_index(close, high, low, _period) \ - negative_directional_index(close, high, low, _period) # Percentage Price Oscillator if 'ppo' in desc: for _short, _long in desc['ppo']: if record_count < _short or record_count < _long: logging.error( "get_ta_features: not enough records for ppo (short={}, long={}, records={})" .format(_short, _long, record_count)) continue ta['ppo_{}_{}'.format(_short, _long)] = price_oscillator( close, _short, _long) # Relative Strength Index if 'rsi' in desc: for _period in desc['rsi']: if record_count < _period: logging.error( "get_ta_features: not enough records for rsi (period={}, records={})" .format(_period, record_count)) continue ta['rsi_{}'.format(_period)] = relative_strength_index( close, _period) # Money Flow Index if 'mfi' in desc: for _period in desc['mfi']: if record_count < _period: logging.error( "get_ta_features: not enough records for mfi (period={}, records={})" .format(_period, record_count)) continue ta['mfi_{}'.format(_period)] = money_flow_index( close, high, low, volume, _period) # True Strength Index if 'tsi' in desc and len(close) >= 40: if record_count < 40: logging.error( "get_ta_features: not enough records for tsi (period={}, records={})" .format(40, record_count)) else: ta['tsi'] = true_strength_index(close) if 'boll' in desc: for _period in desc['stoch']: if record_count < _period: logging.error( "get_ta_features: not enough records for boll (period={}, records={})" .format(_period, record_count)) continue ta['boll_{}'.format(_period)] = percent_b(close, _period) # Stochastic Oscillator if 'stoch' in desc: for _period in desc['stoch']: if record_count < _period: logging.error( "get_ta_features: not enough records for stoch (period={}, records={})" .format(_period, record_count)) continue ta['stoch_{}'.format(_period)] = percent_k(close, _period) # ta.py['stoch'] = percent_k(high, low, close, 14) # Chande Momentum Oscillator ## Not available in ta.py if 'cmo' in desc: for _period in desc['cmo']: if record_count < _period: logging.error( "get_ta_features: not enough records for cmo (period={}, records={})" .format(_period, record_count)) continue ta['cmo_{}'.format(_period)] = chande_momentum_oscillator( close, _period) # Average True Range Percentage if 'atrp' in desc: for _period in desc['atrp']: if record_count < _period: logging.error( "get_ta_features: not enough records for atrp (period={}, records={})" .format(_period, record_count)) continue ta['atrp_{}'.format(_period)] = average_true_range_percent( close, _period) # Percentage Volume Oscillator if 'pvo' in desc: for _short, _long in desc['pvo']: if record_count < _short or record_count < _long: logging.error( "get_ta_features: not enough records for pvo (short={}, long={}, records={})" .format(_short, _long, record_count)) continue ta['pvo_{}_{}'.format(_short, _long)] = volume_oscillator( volume, _short, _long) # Force Index if 'fi' in desc: fi = force_index(close, volume) for _period in desc['fi']: if record_count < _period: logging.error( "get_ta_features: not enough records for atrp (period={}, records={})" .format(_period, record_count)) continue ta['fi_{}'.format(_period)] = exponential_moving_average( fi, _period) # Accumulation Distribution Line if 'adi' in desc: ta['adi'] = accumulation_distribution(close, high, low, volume) # On Balance Volume if 'obv' in desc: ta['obv'] = on_balance_volume(close, volume) # Restore numpy error settings np.seterr(**old_settings) return ta
high = dataset_train.iloc[:, 2].values low = dataset_train.iloc[:, 3].values close = read_float_with_comma(dataset_train.iloc[:, 4].values) volume = read_float_with_comma(dataset_train.iloc[:, 5].values) from pyti.simple_moving_average import simple_moving_average sma = simple_moving_average(close, period) from pyti.weighted_moving_average import weighted_moving_average wma = weighted_moving_average(close, period) from pyti.momentum import momentum mome = momentum(close, period) from pyti.relative_strength_index import relative_strength_index rsi = relative_strength_index(close, period) from pyti.moving_average_convergence_divergence import moving_average_convergence_divergence macd = moving_average_convergence_divergence(close, short_period=1, long_period=10) from pyti.commodity_channel_index import commodity_channel_index cci = commodity_channel_index(close, high_data=high, low_data=low, period=period) from pyti.williams_percent_r import williams_percent_r willr = williams_percent_r(close)
def convert(str): period = 10 dataset_train = pd.read_csv(str) x = dataset_train.iloc[:, 4].values try: open = dataset_train.iloc[:, 1].values except Exception: open = read_float_with_comma(dataset_train.iloc[:, 1].values) try: high = dataset_train.iloc[:, 2].values except Exception: high = read_float_with_comma(dataset_train.iloc[:, 2].values) try: low = dataset_train.iloc[:, 3].values except Exception: low = read_float_with_comma(dataset_train.iloc[:, 3].values) try: close = dataset_train.iloc[:, 4].values except Exception: close = read_float_with_comma(dataset_train.iloc[:, 4].values) try: volume = dataset_train.iloc[:, 5].values except Exception: volume = read_float_with_comma(dataset_train.iloc[:, 5].values) from pyti.simple_moving_average import simple_moving_average sma = simple_moving_average(close, period) from pyti.weighted_moving_average import weighted_moving_average wma = weighted_moving_average(close, period) from pyti.momentum import momentum mome = momentum(close, period) from pyti.relative_strength_index import relative_strength_index rsi = relative_strength_index(close, period) from pyti.moving_average_convergence_divergence import moving_average_convergence_divergence macd = moving_average_convergence_divergence(close, short_period=1, long_period=10) from pyti.commodity_channel_index import commodity_channel_index cci = commodity_channel_index(close, high_data=high, low_data=low, period=period) from pyti.williams_percent_r import williams_percent_r willr = williams_percent_r(close) from pyti.accumulation_distribution import accumulation_distribution acd = accumulation_distribution(close_data=close, low_data=low, high_data=high, volume=volume) X = [] Y = [] for _ in range(10, len(open)): tmp = [] tmp.append(sma[_]) tmp.append(wma[_]) tmp.append(mome[_]) tmp.append(rsi[_]) tmp.append(macd[_]) tmp.append(cci[_]) tmp.append(willr[_]) X.append(tmp) Y.append([close[_]]) X, Y = np.array(X), np.array(Y) return X, Y
def get_features_for_predict(cls, dfs, code, start_dt="2016-01-01"): ################## stock_fin_feat ################## # stock_finデータを読み込み stock_fin = dfs["stock_fin"].copy() # 特定の銘柄コードのデータに絞る fin_data = stock_fin[stock_fin["Local Code"] == code].copy() # 業界データと結合 stock_list = dfs["stock_list"].copy() fin_list = stock_list[[ "Local Code", "33 Sector(name)", "17 Sector(name)", "IssuedShareEquityQuote IssuedShare" ]].copy() fin_data = pd.merge(fin_data, fin_list, how="left", on="Local Code") # 日付列をpd.Timestamp型に変換してindexに設定 fin_data["datetime"] = pd.to_datetime(fin_data["base_date"]) fin_data.set_index("datetime", inplace=True) # fin_dataのnp.float64のデータのみを取得 fin_data = fin_data.select_dtypes(include=["float64"]) # 企業 ## 営業利益率 fin_data["Rate_Operating_Margin"] = fin_data[ "Result_FinancialStatement OperatingIncome"] / fin_data[ "Result_FinancialStatement NetSales"] * 100 ## 経常利益率 fin_data["Rate_Ordinary_Margin"] = fin_data[ "Result_FinancialStatement OrdinaryIncome"] / fin_data[ "Result_FinancialStatement NetSales"] * 100 ## 純利益率 fin_data["Rate_Ordinary_Margin"] = fin_data[ "Result_FinancialStatement NetIncome"] / fin_data[ "Result_FinancialStatement NetSales"] * 100 ## 売上成長率 fin_data["Rate_Grow_NetSales"] = fin_data[ "Result_FinancialStatement NetSales"].pct_change(4) ## 営業利益成長率 fin_data["Rate_Grow_Operating"] = fin_data[ "Result_FinancialStatement OperatingIncome"].pct_change(4) ## 経常利益成長率 fin_data["Rate_Grow_Ordinary"] = fin_data[ "Result_FinancialStatement OrdinaryIncome"].pct_change(4) ## 純利益成長率 fin_data["Rate_Grow_NetIncome"] = fin_data[ "Result_FinancialStatement NetIncome"].pct_change(4) ## ROE fin_data["ROE"] = fin_data[ "Result_FinancialStatement NetIncome"] / fin_data[ "Result_FinancialStatement NetAssets"] * 100 ## ROA fin_data["ROA"] = fin_data[ "Result_FinancialStatement NetIncome"] / fin_data[ "Result_FinancialStatement TotalAssets"] * 100 ## EPS fin_data["EPS"] = fin_data[ "Result_FinancialStatement NetIncome"] / fin_data[ "IssuedShareEquityQuote IssuedShare"] * 100 ## BPS fin_data["BPS"] = fin_data[ "Result_FinancialStatement TotalAssets"] / fin_data[ "IssuedShareEquityQuote IssuedShare"] ## ROE成長率 fin_data["Rate_Grow_ROE"] = fin_data["ROE"].pct_change(4) ## ROA成長率 fin_data["Rate_Grow_ROA"] = fin_data["ROA"].pct_change(4) ## 負債比率 fin_data["Result_FinancialStatement Liability"] = fin_data[ "Result_FinancialStatement TotalAssets"] - fin_data[ "Result_FinancialStatement NetAssets"] fin_data["Rate Liability"] = fin_data[ "Result_FinancialStatement Liability"] / fin_data[ "Result_FinancialStatement NetAssets"] * 100 ## 来季結果と今期予測の差異 fin_forecast = fin_data[[ "Forecast_FinancialStatement NetSales", "Forecast_FinancialStatement OperatingIncome", "Forecast_FinancialStatement OrdinaryIncome", "Forecast_FinancialStatement NetIncome" ]].diff(4) fin_data["Diff Forecast Result NetSales"] = fin_forecast[ "Forecast_FinancialStatement NetSales"] / fin_data[ "Result_FinancialStatement NetSales"] * 100 fin_data["Diff Forecast Result OperatingIncome"] = fin_forecast[ "Forecast_FinancialStatement OperatingIncome"] / fin_data[ "Result_FinancialStatement OperatingIncome"] * 100 fin_data["Diff Forecast Result OrdinaryIncome"] = fin_forecast[ "Forecast_FinancialStatement OrdinaryIncome"] / fin_data[ "Result_FinancialStatement OrdinaryIncome"] * 100 fin_data["Diff Forecast Result NetIncome"] = fin_forecast[ "Forecast_FinancialStatement NetIncome"] / fin_data[ "Result_FinancialStatement NetIncome"] * 100 # 欠損値処理 fin_feats = fin_data.fillna(0) ################## stock_price_feat ################## # stock_priceデータを読み込む price = dfs["stock_price"].copy() # 特定の銘柄コードのデータに絞る price_data = price[price["Local Code"] == code].copy() # 日付列をpd.Timestamp型に変換してindexに設定 price_data["datetime"] = pd.to_datetime( price_data["EndOfDayQuote Date"]) price_data.set_index("datetime", inplace=True) # 終値, ボリューム feats = price_data[[ "EndOfDayQuote ExchangeOfficialClose", "EndOfDayQuote Volume" ]].copy() # 終値の20営業日リターン feats["return_1month"] = feats[ "EndOfDayQuote ExchangeOfficialClose"].pct_change(20) # 終値と20営業日の単純移動平均線の乖離 feats[ "MA_gap_1month"] = feats["EndOfDayQuote ExchangeOfficialClose"] / ( feats["EndOfDayQuote ExchangeOfficialClose"].rolling( 20).mean()) # 終値と20営業日の単純移動平均線の乖離 feats["EMA_gap_1month"] = feats[ "EndOfDayQuote ExchangeOfficialClose"] / ( feats["EndOfDayQuote ExchangeOfficialClose"].ewm( span=20).mean()) # 過去20営業日の平均売買金額 feats["Volume_mean_1month"] = feats["EndOfDayQuote Volume"].rolling( window=20).mean() # RSI feats["rsi"] = relative_strength_index( feats["EndOfDayQuote ExchangeOfficialClose"], period=20) # テクニカル指標 # ラグファクター # トレンドライン、サポートライン、レジスタンスライン # おおまかな手順の3つ目 # 欠損値処理 feats = feats.fillna(0) # 財務データの特徴量とマーケットデータの特徴量のインデックスを合わせる feats = feats.loc[feats.index.isin(fin_feats.index)] fin_feats = fin_feats.loc[fin_feats.index.isin(feats.index)] # データを結合 feats = pd.concat([feats, fin_feats], axis=1).dropna() ################## stock_fin&price_feat ################## ## 時価総額 feats["Market Capitalization"] = feats[ "IssuedShareEquityQuote IssuedShare"] * feats[ "EndOfDayQuote ExchangeOfficialClose"] ## PER feats["PER"] = feats["EndOfDayQuote ExchangeOfficialClose"] / feats[ "EPS"] ## PBR feats["PBR"] = feats["EndOfDayQuote ExchangeOfficialClose"] / feats[ "BPS"] # 元データのカラムを削除 feats = feats.drop(["EndOfDayQuote ExchangeOfficialClose"], axis=1) # 不要な特徴を削除 drop_col = [ "Result_FinancialStatement FiscalYear", "Result_Dividend FiscalYear", "Result_FinancialStatement TotalAssets", "Result_FinancialStatement NetAssets", "Result_FinancialStatement Liability", "Forecast_Dividend FiscalYear", "Result_FinancialStatement CashFlowsFromFinancingActivities", "Result_FinancialStatement CashFlowsFromInvestingActivities", "Result_FinancialStatement CashFlowsFromOperatingActivities", "Forecast_FinancialStatement FiscalYear" ] feats = feats.drop(drop_col, axis=1) # 欠損値処理を行います。 feats = feats.replace([np.inf, -np.inf], 0) # 銘柄コードを設定 feats["code"] = code return feats