def calcMA(self, dates, price): #ma = pd.DataFrame(columns=['timestamp','price','data_sma5','data_sma10','data_sma15','data_sma20','data_sma60']) data_sma5 = np.array(MA(price, 5)) data_sma10 = np.array(MA(price, 10)) data_sma15 = np.array(MA(price, 15)) data_sma20 = np.array(MA(price, 20)) data_sma60 = np.array(MA(price, 60)) """ isExist = 0 for data,date in zip(price,dates): timestamp_ = self.training_window['timestamp'].values if(all(ele in self.training_window.columns.values for ele in ma.columns.values)): isExist = 1 if math.isnan(data) or (date.date() in timestamp_ and all(ele in self.training_window.columns.values for ele in ma.columns.values) and not any(np.isnan(ele) for ele in self.training_window.loc[self.training_window['timestamp'] == date.date()].values[0][1:])): index = index + 1 continue ma = ma.append({'timestamp':date.date(), 'price':price[index], 'data_sma5':data_sma5[index], 'data_sma10':data_sma10[index], 'data_sma15':data_sma15[index], 'data_sma20':data_sma20[index], 'data_sma60':data_sma60[index]},ignore_index=True) index = index + 1 """ ma, isExist = self.createDateFrame( dates, np.column_stack( (data_sma5, data_sma10, data_sma15, data_sma20, data_sma60)), [ 'timestamp', 'data_sma5', 'data_sma10', 'data_sma15', 'data_sma20', 'data_sma60' ]) #print(ma) return ma, isExist
def compute_trading_points(self, stocks, szTimeAxis, n_ahead): assert len( stocks ) == 1, "This strategy allows only a daily candlestick data of one stock." code = next(iter(stocks)) cst = stocks[code].cst # get candlestick data DataTimeAxis = cst['1Day'].index # Moving average maf = MA(cst['1Day']['close'].values, self.nfast) mas = MA(cst['1Day']['close'].values, self.nslow) # skip extra data TimeAxis = DataTimeAxis[n_ahead:] df_ma = pd.DataFrame( { 'ma_fast': maf[n_ahead:], 'ma_slow': mas[n_ahead:] }, index=TimeAxis) #df_ma.plot() #plt.show() start_flag = 0 hold_flag = 0 for ticker in TimeAxis: # skip null value at the beginning if np.isnan(df_ma.at[ticker, 'ma_fast']) or np.isnan( df_ma.at[ticker, 'ma_slow']): continue # skip the days of 'ma_fast'>='ma_slow' at the beginning # those should be the days waiting fo selling, not buying, thus not suitable for a start if (start_flag == 0) and (df_ma.at[ticker, 'ma_fast'] <= df_ma.at[ticker, 'ma_slow']): continue else: start_flag = 1 # start trading if (start_flag == 1): price = cst['1Day'].at[ticker, 'close'] if (hold_flag == 0) and (df_ma.at[ticker, 'ma_fast'] > df_ma.at[ticker, 'ma_slow']): # quantity is the number of shares (unit: boardlot) you buy this time quantity, _, _ = buy(code, price, str(ticker), ratio=1) hold_flag = 1 if (hold_flag == 1) and (df_ma.at[ticker, 'ma_fast'] < df_ma.at[ticker, 'ma_slow']): # sell all the shares bought last time sell(code, price, str(ticker), quantity) hold_flag = 0
def getMA(price): date = 1 ma = [] data_sma5 = np.array(MA(price, 5)) data_sma10 = np.array(MA(price, 10)) data_sma15 = np.array(MA(price, 15)) data_sma20 = np.array(MA(price, 20)) data_sma60 = np.array(MA(price, 60)) for data in price: if (math.isnan(data)): continue ma.append([date, data_sma5[date - 1], data_sma10[date - 1], data_sma15[date - 1], data_sma20[date - 1], data_sma60[date - 1]]) date = date + 1 return ma
def moving_average(data, tp=14): """ :param data: ndarray data for MA :param tp: int time period for MA """ return MA(data, timeperiod=tp)
def handle_data(context, data): long_period = 40 short_period = 20 context.count += 1 if context.count < long_period: return price_history = data.history(context.asset, 'price', long_period, '1d') short_MA = MA(price_history.values, 20) long_MA = MA(price_history.values, 40) if short_MA[-1] < long_MA[-1] and not context.invest: order(context.asset, 10) context.invest = True if short_MA[-1] > long_MA[-1] and context.invest: order(context.asset, -10) context.invest = False record(price=data.current(context.asset, 'price'), promedioMovilCorto=short_MA, promedioMovilLargo=long_MA) lt
def addlineplot(input_df): '''划线,以均线为例子''' source = create_data_source(input_df) MAs = [5, 10, 15, 20] line_color = ['white', 'yellow', 'red', 'green'] for ma_th, ma in enumerate(MAs): legend = 'MA' + str(ma) p.line(x=input_df['date'], y=MA(input_df['close'].as_matrix(), ma, matype=1), legend=legend, line_color=line_color[ma_th], source=create_data_source(input_df))
def handle_single_asset_data(self, context, asset, data): short_ema_value, long_ema_value = self.current_parameter_ trailing_window = data.history(asset, 'price', long_ema_value * 3, '1d') if trailing_window.isnull().values.any(): return short_ema = EMA(trailing_window.values, timeperiod=short_ema_value) long_ema = EMA(trailing_window.values, timeperiod=long_ema_value) vv = data.history(asset, ['high', 'low'], 5, '1d') vv = (vv['high'] - vv['low']).mean() vvv = data.history(asset, ['high', 'low'], 3, '1d') vvv = (vvv['high'] - vvv['low']).mean() * .5 _long = (short_ema[-1] > long_ema[-1]) and (short_ema[-2] >= long_ema[-2]) _short = (short_ema[-1] < long_ema[-1]) and (short_ema[-2] <= long_ema[-2]) pv = data.current(asset, "price") if context.price_highest[asset] < pv: context.price_highest[asset] = pv - vvv trailing_stop = MA(trailing_window.values, timeperiod=3)[-1] < context.price_highest[asset] _short = _short or (context.portfolio_highest[asset] > pv) or trailing_stop pct_per_stock = 1.0 / len(context.assets) cash = context.portfolio.cash * pct_per_stock if _long and cash > pv and context.stock_shares[asset] == 0: number_of_shares = int(cash / pv) order(asset, number_of_shares) context.portfolio_highest[asset] = pv - vv context.stock_shares[asset] = number_of_shares logging.debug('{} buy {} shares at {}'.format( asset, number_of_shares, pv)) elif _short and context.stock_shares[asset] > 0: order_target_percent(asset, 0) number_of_shares = context.stock_shares[asset] context.portfolio_highest[asset] = 0.0 context.price_highest[asset] = 0.0 context.stock_shares[asset] = 0 logging.debug('{} sell {} shares at {}'.format( asset, number_of_shares, pv))
def _calc_indicator(self, OHLCV_input): """ Calculates the EMA technical indicator using a wrapper for the TA-lib Args: :param OHLCV_input: the dataframe with the Open, High, Low, Close and Volume values :type OHLCV_input: pandas DataFrame Returns: DataFrame with the indicators values. """ try: close = OHLCV_input['close'].values[:, 0] except IndexError: close = OHLCV_input['close'].values output = DataFrame(MA(close, self.__timeperiod, self.__matype)) output.columns = ['MA%d' % self.__timeperiod] return output
def ma(candles: np.ndarray, period: int = 30, matype: int = 0, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ MA - (nearly) All Moving Averages of Jesse :param candles: np.ndarray :param period: int - default: 30 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ # Accept normal array too. if len(candles.shape) == 1: source = candles else: candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) if matype <= 8: from talib import MA res = MA(source, timeperiod=period, matype=matype) elif matype == 9: from . import fwma res = fwma(source, period, source_type=source_type, sequential=True) elif matype == 10: from . import hma res = hma(source, period, source_type=source_type, sequential=True) elif matype == 11: from talib import LINEARREG res = LINEARREG(source, period) elif matype == 12: from . import wilders res = wilders(source, period, source_type=source_type, sequential=True) elif matype == 13: from . import sinwma res = sinwma(source, period, source_type=source_type, sequential=True) elif matype == 14: from . import supersmoother res = supersmoother(source, period, source_type=source_type, sequential=True) elif matype == 15: from . import supersmoother_3_pole res = supersmoother_3_pole(source, period, source_type=source_type, sequential=True) elif matype == 16: from . import gauss res = gauss(source, period, source_type=source_type, sequential=True) elif matype == 17: from . import high_pass res = high_pass(source, period, source_type=source_type, sequential=True) elif matype == 18: from . import high_pass_2_pole res = high_pass_2_pole(source, period, source_type=source_type, sequential=True) elif matype == 19: from talib import HT_TRENDLINE res = HT_TRENDLINE(source) elif matype == 20: from . import jma res = jma(source, period, source_type=source_type, sequential=True) elif matype == 21: from . import reflex res = reflex(source, period, source_type=source_type, sequential=True) elif matype == 22: from . import trendflex res = trendflex(source, period, source_type=source_type, sequential=True) elif matype == 23: from . import smma res = smma(source, period, source_type=source_type, sequential=True) elif matype == 24: if len(candles.shape) == 1: raise ValueError("vwma only works with normal candles.") from . import vwma res = vwma(candles, period, source_type=source_type, sequential=True) elif matype == 25: from . import pwma res = pwma(source, period, source_type=source_type, sequential=True) elif matype == 26: from . import swma res = swma(source, period, source_type=source_type, sequential=True) elif matype == 27: from . import alma res = alma(source, period, source_type=source_type, sequential=True) elif matype == 28: from . import hwma res = hwma(source, source_type=source_type, sequential=True) elif matype == 29: from . import vwap if len(candles.shape) == 1: raise ValueError("vwap only works with normal candles.") res = vwap(source, source_type=source_type, sequential=True) elif matype == 30: from . import nma res = nma(source, period, source_type=source_type, sequential=True) elif matype == 31: from . import edcf res = edcf(source, period, source_type=source_type, sequential=True) elif matype == 32: from . import mwdx res = mwdx(source, source_type=source_type, sequential=True) elif matype == 33: from . import maaq res = maaq(source, period, source_type=source_type, sequential=True) elif matype == 34: from . import srwma res = srwma(source, period, source_type=source_type, sequential=True) elif matype == 35: from . import sqwma res = sqwma(source, period, source_type=source_type, sequential=True) elif matype == 36: from . import vpwma res = vpwma(source, period, source_type=source_type, sequential=True) elif matype == 37: from . import cwma res = cwma(source, period, source_type=source_type, sequential=True) elif matype == 38: from . import jsa res = jsa(source, period, source_type=source_type, sequential=True) elif matype == 39: from . import epma res = epma(source, period, source_type=source_type, sequential=True) return res if sequential else res[-1]
def signal_line(series: np.ndarray, period: int = 10, matype: int = 0) -> np.ndarray: return MA(series, timeperiod=period, matype=matype)
# ----------------------Graph plotting----------------------------------- df_plot['Date'] = df_plot['Date'].astype('datetime64[ns]') df_plot['Date'] = df_plot['Date'].map(mdates.date2num) # Candlestick chart with 2 moving average line(10days and 30days) charts_plot, (ax, ax2, ax3) = plt.subplots(nrows=3, ncols=1, figsize=(40, 30), gridspec_kw={ 'height_ratios': [3, 0.5, 1], 'hspace': 0 }) candlestick_ohlc(ax, df_plot.values, width=1, colorup='g', colordown='r') ma_10_plot = MA(df_plot['Close'].values, timeperiod=10, matype=0) ma_30_plot = MA(df_plot['Close'].values, timeperiod=30, matype=0) ax.xaxis_date() ax.plot(df_plot['Date'], ma_10_plot, label='MA-10') ax.plot(df_plot['Date'], ma_30_plot, label='MA-30') ax.legend() # KD line chart k_plot, d_plot = STOCH(df_plot['High'].values, df_plot['Low'].values, df_plot['Close'].values, fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3,
def generate_data(self, cst_d, n_ahead): """ Generate train data from cst data. Returns: train_data(pd.dataframe), with index of pd.TimeStamp type the feature columns of train_data are: ['close', 'PriceChangeRatio', 'dif', 'dea', 'macd', 'ma5', 'ma10', 'ma20', 'ma5-ma10', \ 'ma5-ma20', 'ma10-ma20', 'vol', 'VolChangeRatio'] and labels/turnouts of train_data are: ['after1d', 'after2d', 'after3d', 'after4d', 'after5d', 'after5dChange2%?', \ 'after3dChangeRatio', 'after5dChangeRatio'] """ # get time axis of the cst data DataTimeAxis = cst_d.index # PriceChangeRatio feature price_change_ratio = self.ChangeRatio(cst_d['close'].values) # MACD feature dif, dea, macd = self.MACD(cst_d['close'].values) # Moving average features ma5 = MA(cst_d['close'].values, 5) ma10 = MA(cst_d['close'].values, 10) ma20 = MA(cst_d['close'].values, 20) ma5_ma10 = ma5 - ma10 ma5_ma20 = ma5 - ma20 ma10_ma20 = ma10 - ma20 # VolChangeRatio feature vol_change_ratio = self.ChangeRatio(cst_d['volume'].values) # VolChangeRatioAverage: vol vs that of the average of pass 5 days vol_change_ratio_aver = self.ChangeRatioAverage( cst_d['volume'].values, 5) # skip extra data and create feature dataframe TimeAxis = DataTimeAxis[n_ahead:] cst_v = cst_d['close'].values[n_ahead:] df_features = pd.DataFrame({'close': cst_v}, index=TimeAxis) df_features = df_features.join(pd.DataFrame({'dif': dif[n_ahead:], 'dea': dea[n_ahead:], \ 'macd': macd[n_ahead:]}, index = TimeAxis)) df_features = df_features.join(pd.DataFrame({'ma5': ma5[n_ahead:], 'ma10': ma10[n_ahead:], \ 'ma20': ma20[n_ahead:], 'ma5-ma10': ma5_ma10[n_ahead:],'ma5-ma20': ma5_ma20[n_ahead:],\ 'ma10-ma20': ma10_ma20[n_ahead:]}, index = TimeAxis)) df_features['PriceChangeRatio'] = price_change_ratio[n_ahead:] df_features['VolChangeRatio'] = vol_change_ratio[n_ahead:] df_features['VolChangeRatioAverage'] = vol_change_ratio_aver[n_ahead:] df_features['vol'] = cst_d['volume'].values[n_ahead:] # to store tickers of the train data tmp_tickers = [] # to store features of the train data turnout = ['after1d', 'after2d', 'after3d', 'after4d', 'after5d', 'after5dChange2%?', \ 'after3dChangeRatio', 'after5dChangeRatio'] tmp_turnout = {column: [] for column in turnout} # flags. 'dc' is short for 'dead cross'; 'gc' is short for 'golden cross' wait_dc, wait_gc = False, False # start selecting useful data for i, ticker in enumerate(TimeAxis): # skip null value at the beginning if np.isnan(df_features.at[ticker, 'dif']) or np.isnan( df_features.at[ticker, 'dea']): continue # if golden cross or dead cross if ((wait_dc is True) and \ (df_features.at[ticker, 'dif'] < df_features.at[ticker, 'dea']))\ or ((wait_gc is True) and \ (df_features.at[ticker, 'dif'] > df_features.at[ticker, 'dea'])): # record useful data tmp_tickers.append(ticker) for day, column in enumerate(turnout[:5], start=1): tmp_turnout[column].append(cst_v[i + day]) after3dChangeRatio = (cst_v[i + 3] - cst_v[i]) / cst_v[i] tmp_turnout['after3dChangeRatio'].append(after3dChangeRatio) after5dChangeRatio = (cst_v[i + 5] - cst_v[i]) / cst_v[i] tmp_turnout['after5dChangeRatio'].append(after5dChangeRatio) if after5dChangeRatio >= 0.02: tmp_turnout['after5dChange2%?'].append('rise2%') elif after5dChangeRatio <= -0.02: tmp_turnout['after5dChange2%?'].append('fall2%') else: tmp_turnout['after5dChange2%?'].append('within2%') # change state if df_features.at[ticker, 'dif'] > df_features.at[ticker, 'dea']: wait_dc, wait_gc = True, False if df_features.at[ticker, 'dif'] < df_features.at[ticker, 'dea']: wait_dc, wait_gc = False, True # create train data train_data = df_features.loc[tmp_tickers, :] train_data = train_data.join( pd.DataFrame(tmp_turnout, index=tmp_tickers)) return train_data
def ma(candles: np.ndarray, period: int = 30, matype: int = 0, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ MA - (nearly) All Moving Averages of Jesse :param candles: np.ndarray :param period: int - default: 30 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ # Accept normal array too. if len(candles.shape) == 1: source = candles else: candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) if matype <= 8: from talib import MA res = MA(source, timeperiod=period, matype=matype) elif matype == 9: from . import fwma res = fwma(source, period, source_type=source_type, sequential=True) elif matype == 10: from . import hma res = hma(source, period, source_type=source_type, sequential=True) elif matype == 11: from talib import LINEARREG res = LINEARREG(source, period) elif matype == 12: from . import wilders res = wilders(source, period, source_type=source_type, sequential=True) elif matype == 13: from . import sinwma res = sinwma(source, period, source_type=source_type, sequential=True) elif matype == 14: from . import supersmoother res = supersmoother(source, period, source_type=source_type, sequential=True) elif matype == 15: from . import supersmoother_3_pole res = supersmoother_3_pole(source, period, source_type=source_type, sequential=True) elif matype == 16: from . import gauss res = gauss(source, period, source_type=source_type, sequential=True) elif matype == 17: from . import high_pass res = high_pass(source, period, source_type=source_type, sequential=True) elif matype == 18: from . import high_pass_2_pole res = high_pass_2_pole(source, period, source_type=source_type, sequential=True) elif matype == 19: from talib import HT_TRENDLINE res = HT_TRENDLINE(source, period) elif matype == 20: from . import jma res = jma(source, period, source_type=source_type, sequential=True) elif matype == 21: from . import reflex res = reflex(source, period, source_type=source_type, sequential=True) elif matype == 22: from . import trendflex res = trendflex(source, period, source_type=source_type, sequential=True) elif matype == 23: from . import smma res = smma(source, period, source_type=source_type, sequential=True) elif matype == 24: from . import vwma res = vwma(source, period, source_type=source_type, sequential=True) elif matype == 25: from . import pwma res = pwma(source, period, source_type=source_type, sequential=True) elif matype == 25: from . import swma res = swma(source, period, source_type=source_type, sequential=True) return res if sequential else res[-1]
def signal_line(series: np.array, period=10, matype=0): return MA(series, timeperiod=period, matype=matype)
def m_average(a_list, window): from talib import MA ma_array = np.asarray(a_list) return MA(ma_array, window)
def fetch(self, symbol: str, interval: Interval = Interval.DAY, window: Window = Window.YEAR, indicators: Indicators = [], verbose=False) -> pd.DataFrame: """ Fetch symbol stock OHLCV from Yahoo Finance API Args: symbol (str): Symbol to fetch interval (Interval, optional): Interval (hour, day, week, ...) of data. Defaults to Interval.DAY. window (Window, optional): Length (day, week, month, year) of interval. Defaults to Window.YEAR. indicators (Indicators, optional): Array of indicators to include in the result. Defaults to empty array. Returns: pd.DataFrame: OHLCV pandas DataFrame with interval on window length and indicators if specified """ try: if verbose: print( f"Fetching OHLCV {symbol} stock data on {interval.name} interval and {window.name} window" ) # Generic url to fetch url = f"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}?region=FR&lang=fr-FR&includePrePost=false&interval={interval.value}&range={window.value}&corsDomain=fr.finance.yahoo.com&.tsrc=finance" req = requests.get(url) # Testing request status code if req.status_code == 200: # Extracting data as json data = req.json() # Creating new DataFrame df = pd.DataFrame() # Extract date from object if interval in [ Interval.MINUTE, Interval.TWO_MINUTE, Interval.FIVE_MINUTE, Interval.FIFTEEN_MINUTE, Interval.THIRTY_MINUTE, Interval.HOUR ]: dateFromUnix = [ datetime.utcfromtimestamp(dt).strftime( "%Y-%m-%d %H:%M:%S") for dt in data["chart"]["result"][0]["timestamp"] ] else: dateFromUnix = [ datetime.utcfromtimestamp(dt).strftime("%Y-%m-%d") for dt in data["chart"]["result"][0]["timestamp"] ] # Date & OHLCV to DataFrame df["date"] = pd.to_datetime(dateFromUnix) df["open"] = data["chart"]["result"][0]["indicators"]["quote"][ 0]["open"] df["high"] = data["chart"]["result"][0]["indicators"]["quote"][ 0]["high"] df["low"] = data["chart"]["result"][0]["indicators"]["quote"][ 0]["low"] df["close"] = data["chart"]["result"][0]["indicators"][ "quote"][0]["close"] df["volume"] = data["chart"]["result"][0]["indicators"][ "quote"][0]["volume"] # Drop NaN on close col df.dropna(subset=["close"], inplace=True) # Divide volume column by a 1 000 df["volume"] = df["volume"].div(1000) # Set date column as index df.set_index("date", inplace=True) for indicator in indicators: # ADX if indicator == Indicators.ADX: df[indicator.value] = ADX(df["high"], df["low"], df["close"]) # BBANDS elif indicator == Indicators.BBANDS: df[Indicators.BBANDS.value[0]], df[ Indicators.BBANDS.value[1]], df[ Indicators.BBANDS.value[2]] = BBANDS( df["close"]) df["p_band"] = 100 - \ (df["l_band"] / df["u_band"] * 100) df["p_band_ma_5"] = MA(df["p_band"], timeperiod=5) # EMA elif indicator == Indicators.EMA: for ema in Indicators.EMA.value: df[ema] = EMA(df["close"], timeperiod=int(ema.split("_")[1])) # MA elif indicator == Indicators.MA: for ma in Indicators.MA.value: df[ma] = MA(df["close"], timeperiod=int(ma.split("_")[1])) # OBV elif indicator == Indicators.OBV: df[indicator.value] = OBV(df["close"], df["volume"]) df[indicator.value] = df[indicator.value].div(1000) # PSAR elif indicator == Indicators.PSAR: df[indicator.value] = SAR(df["high"], df["low"]) # PERCENT CHANGE elif indicator == Indicators.P_CHANGE: for p_change in Indicators.P_CHANGE.value: df[p_change] = df["close"].pct_change( int(p_change.split(" ")[1])) * 100 # RSI elif indicator == Indicators.RSI: df[indicator.value] = RSI(df["close"]) return df.round(decimals=2) except Exception as e: print(e)