url = 'https://finance.naver.com/item/sise_day.nhn?code=028300&page=1' with urlopen(url) as doc: html = BeautifulSoup(doc, 'lxml') pgrr = html.find('td', class_='pgRR') s = str(pgrr.a['href']).split('=') last_page = s[-1] df = pd.DataFrame() sise_url = 'https://finance.naver.com/item/sise_day.nhn?code=028300' for page in range(1, int(last_page) + 1): page_url = '{}&page={}'.format(sise_url, page) df = df.append(pd.read_html(page_url, header=0)[0]) df = df.dropna() df = df.iloc[0:30] df = df.sort_values(by='날짜') for idx in range(0, len(df)): dt = datetime.strptime(df['날짜'].values[idx], '%Y.%m.%d').date() df['날짜'].values[idx] = mdates.date2num(dt) ohlc = df[['날짜', '시가', '고가', '저가', '종가']] plt.figure(figsize=(9, 6)) ax = plt.subplot(1, 1, 1) plt.title('HLB candle stick') candlestick_ohlc(ax, ohlc.values, width=0.7, colorup='red', colordown='blue') ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) plt.xticks(rotation=45) plt.grid(color='gray', linestyle='--') plt.show()
def plot_chart(outputpath, data, title): data.to_excel(title + '.xlsx') print(data) fig = plt.figure() #创建绘图区,包含四个子图 fig.set_size_inches((20, 16)) ax_candle = fig.add_axes((0, 0.75, 1, 0.25)) #蜡烛图子图 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8 ax_macd = fig.add_axes((0, 0.60, 1, 0.15), sharex=ax_candle) #macd子图 ax_rsi = fig.add_axes((0, 0.45, 1, 0.15), sharex=ax_candle) #rsi子图 ax_vol = fig.add_axes((0, 0.30, 1, 0.15), sharex=ax_candle) #成交量子图 ax_kjd = fig.add_axes((0, 0.15, 1, 0.15), sharex=ax_candle) ax_candle.grid(True) # ax_macd.grid(True) # ax_rsi.grid(True) # ax_vol.grid(True) # ax_kjd.grid(True) # print(data) ohlc = [] #存放行情数据,candlestick_ohlc需要传入固定格式的数据 row_number = 0 for date, row in data.iterrows(): date, highp, lowp, openp, closep = row[:5] ohlc.append([row_number, openp, highp, lowp, closep]) row_number = row_number + 1 # print(ohlc) date_tickers = data.Date.values #获取Date数据 # print(date_tickers) #绘制蜡烛图 candlestick_ohlc(ax_candle, ohlc, colorup="r", colordown="g") def format_date(x, pos=None): # 由于前面股票数据在 date 这个位置传入的都是int # 因此 x=0,1,2,... # date_tickers 是所有日期的字符串形式列表 if x < 0 or x > len(date_tickers) - 1: return '' return date_tickers[int(x)] # ax_candle = fig.add_axes((0, 0.75, 1, 0.25)) # 蜡烛图子图 # stockData=data.copy() # stockData['Date'] = pd.to_datetime(stockData['Date']) # stockData.set_index('Date',inplace=True) # mpf.plot(stockData, type='candle', figscale=0.9,ax=ax_candle) ax_candle.plot(data.index, data["ma10"], label="MA10") ax_candle.plot(data.index, data["ma30"], label="MA30") ax_candle.xaxis.set_major_formatter(ticker.FuncFormatter(format_date)) ax_candle.xaxis.set_major_locator(ticker.MultipleLocator(2)) # 设置间隔为6个交易日 ax_candle.grid(True) ax_candle.set_title(title, fontsize=20) ax_candle.legend() for label in ax_kjd.xaxis.get_ticklabels(): label.set_rotation(60) # 绘制MACD ax_macd.plot(data.index, data["macd"], label="macd") ax_macd.bar(data.index, data["macd_hist"] * 3, label="hist") ax_macd.plot(data.index, data["macd_signal"], label="signal") ax_macd.set_title('MACD') ax_macd.legend() #绘制RSI ax_rsi.set_ylabel("(%)") ax_rsi.plot(data.index, [70] * len(data.index), label="overbought") ax_rsi.plot(data.index, [30] * len(data.index), label="oversold") ax_rsi.plot(data.index, data["rsi"], label="rsi") ax_rsi.set_title('RSI') ax_rsi.legend() #绘制成交量 ax_vol.bar(data.index, data["Volume"] / 1000000) ax_vol.set_ylabel("(Million)") #KDJ ax_kjd.plot(data.index, data["K"], label="K", color='blue') ax_kjd.plot(data.index, data["D"], label="D", color='g') ax_kjd.plot(data.index, data["J"], label="J", color='r') ax_kjd.set_title('KDJ') # graph_KDJ.plot(np.arange(0, len(figData.index)), figData['K'], 'blue', label='K') # K # graph_KDJ.plot(np.arange(0, len(figData.index)), figData['D'], 'g--', label='D') # D # graph_KDJ.plot(np.arange(0, len(figData.index)), figData['J'], 'r-', label='J') # J ax_kjd.legend() #这里个人选择不要plt.show(),因为保存图片到本地的 #plt.show() # 保存图片到本地 fig.savefig(outputpath, bbox_inches="tight") return outputpath
# 黄昏之星 函数名:CDLEVENINGSTAR data['EveningStar'] = talib.CDLEVENINGSTAR(Open, High, Low, Close) data[data['EveningStar'] == -100] # 负100 # 乌云压顶 函数名:CDLDARKCLOUDCOVER data['DarkCloud'] = talib.CDLDARKCLOUDCOVER(Open, High, Low, Close) data[data['DarkCloud'] == -100] # 负100 from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mdates date_wewannaanalyse = data['2018-05-10':'2018-06-05'] ax1 = plt.subplot() ax1.xaxis_date() df_ohlc = date_wewannaanalyse[['open', 'high', 'low', 'close']] df_ohlc = df_ohlc.reset_index() df_ohlc['trade_date'] = df_ohlc['trade_date'].map(mdates.date2num) candlestick_ohlc(ax1, df_ohlc.values, width=1, colordown='green', colorup='red', alpha=0.75) plt.title('浦发银行历史股价K线图') plt.show() # 预测信号并不一定正确,不能只靠信号判断,要综合各种信息 # 尝试使用别的形态识别函数
import pandas_datareader.data as web from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mdates style.use("ggplot") #Start date for series start = dt.datetime(2000, 1, 1) #End date for series, can be changed to a specific date end = dt.datetime.today() #The tikcer name, can be found on yahoo ticker = "AZN" df = web.DataReader(ticker, "yahoo", start, end) #"Adj Close" can be edited, and so can resampling size df_ohlc = df["Adj Close"].resample("5D").ohlc() #"Volume" can be edited, but is a useful insight, resampling resolution can be changed df_volume = df["Volume"].resample("5D").sum() df_ohlc.reset_index(inplace=True) df_ohlc["Date"] = df_ohlc["Date"].map(mdates.date2num) ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan=5, colspan=1) plt.title(f"{ticker} Candlestick and Volume") ax2 = plt.subplot2grid((6, 1), (5, 0), rowspan=1, colspan=1, sharex=ax1) ax1.xaxis_date() candlestick_ohlc(ax1, df_ohlc.values, width=2, colorup="g") ax2.fill_between(df_volume.index.map(mdates.date2num), df_volume.values, 0) plt.show()
# Map traded to matplotlib date df['traded'] = df['traded'].map(mdates.date2num) # Create 10-day and 3-day moving averages over settlement price # (for demonstration purposes, not for analysis) df['10ma'] = df['settlement'].rolling(window=10).mean() df['3ma'] = df['settlement'].rolling(window=3).mean() # Apply ggplot style to matplotlib charts style.use('ggplot') # Create two subplots (5-to-1 ratio) ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan=5, colspan=1) ax2 = plt.subplot2grid((6, 1), (5, 0), rowspan=1, colspan=1, sharex=ax1) ax1.xaxis_date() # Add OHLC and moving averages to upper plot candlestick_ohlc(ax1, df[['traded', 'open', 'high', 'low', 'close']].values, width=0.5, colorup='g', colordown='r') ax1.plot(df['traded'], df['10ma']) ax1.plot(df['traded'], df['3ma']) # Add volume to lower plot ax2.bar(df['traded'], df['volume']) # Display plot plt.show()
df_volume = df['Volume'].resample('5D').sum() df_ohlc.reset_index(inplace=True) df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num) print(df_ohlc.head()) df.dropna(inplace=True) print(df.head()) ax1 = plt.subplot2grid((10, 1), (0, 0), rowspan=5, colspan=1) ax2 = plt.subplot2grid((10, 1), (5, 0), rowspan=1, colspan=1, sharex=ax1) # Will take MDates and make them 'nice' looking showing actual text ax1.xaxis_date() # Define size of candlesticks and color, I have blue set to up and red set to down candlestick_ohlc(ax1, df_ohlc.values, width=3, colorup='b') # Have to map for the x and then the volume will be the y (the zero will fill x and y) ax2.fill_between(df_volume.index.map(mdates.date2num), df_volume.values, 0) ax1.plot(df.index, df['Adj Close']) #ax1.plot(df.index, df['100ma']) ax2.bar(df.index, df['Volume']) print(df[['Open', 'High']].head()) df.plot() # Generates second grid where you can see legend and more data plt.legend(loc='best') plt.show()
df['number'] = df.index.map(mdates.date2num) ohlc = df[['number', 'open', 'high', 'low', 'close']] ndays_high = df.high.rolling(window=14, min_periods=1).max() ndays_low = df.low.rolling(window=14, min_periods=1).min() fast_k = (df.close - ndays_low) / (ndays_high - ndays_low) * 100 slow_d = fast_k.rolling(window=3).mean() df = df.assign(fast_k=fast_k, slow_d=slow_d).dropna() plt.figure(figsize=(9, 9)) p1 = plt.subplot(3, 1, 1) plt.title('Triple Screen Trading (NCSOFT)') plt.grid(True) candlestick_ohlc(p1, ohlc.values, width=.6, colorup='red', colordown='blue') p1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) plt.plot(df.number, df['ema130'], color='c', label='EMA130') for i in range(1, len(df.close)): if df.ema130.values[i - 1] < df.ema130.values[i] and df.slow_d.values[ i - 1] >= 20 and df.slow_d.values[i] < 20: plt.plot(df.number.values[i], 40000, 'r^') elif df.ema130.values[i - 1] > df.ema130.values[i] and df.slow_d.values[ i - 1] <= 80 and df.slow_d.values[i] > 80: plt.plot(df.number.values[i], 40000, 'bv') plt.legend(loc='best') p2 = plt.subplot(3, 1, 2) plt.grid(True) p2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) plt.bar(df.number, df['macdhist'], color='m', label='MACD-Hist')
mondays = WeekdayLocator(MONDAY) # major ticks on the mondays alldays = DayLocator() # minor ticks on the days weekFormatter = DateFormatter('%b %d') # e.g., Jan 12 dayFormatter = DateFormatter('%d') # e.g., 12 ax.xaxis.set_major_locator(mondays) #ax.xaxis.set_minor_locator(alldays) ax.xaxis.set_major_formatter(weekFormatter) #ax.xaxis.set_minor_formatter(dayFormatter) plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right') # grid plt.rc('axes', grid=True) # the plots candlestick_ohlc(ax, zip(mdates.date2num(amzn_piece_d.index.to_pydatetime()), amzn_piece_d['Open'], amzn_piece_d['High'],amzn_piece_d['Low'], amzn_piece_d['Close']), colorup='g', colordown='r', width=0.6) ax.plot(amzn_bm_piece_bm['Close'].index, amzn_bm_piece_bm['Close'], label='AMZN monthly') ax.plot(amzn_bm_piece_bm['Close'].index, amzn_bm_piece_bm['Close'], label='AMZN marker', marker='o', markersize=16, color='C0') ax.plot(amzn_piece_d['SMA25'].index, amzn_piece_d['SMA25'], label='AMZN sma25') # other configurations ax.set_title('AMZN') #ax.set_xlabel('Date') ax.set_ylabel('Price') ax.legend() plt.savefig('plot.with.candle.daily.monthly.points.monthly.line.sma.25.matplotlib.style.little.range.png') # the previous plot with matplotlib style without gaps import numpy as np
df_train = pd.read_csv('./data/training.csv', header=None) df_train.columns = ['Open', 'High', 'Low', 'Close'] # open-high-low-close ############################################################################ fig, ax = plt.subplots(2, 1, sharex=True) # CANDLESTICK ohlc = df_train ohlc['Date'] = range(len(ohlc.index)) ohlc = ohlc.loc[:, ['Date', 'Open', 'High', 'Low', 'Close']] ohlc = ohlc[-180:] candlestick_ohlc(ax[0], ohlc.values, width=0.8, colorup='green', colordown='red', alpha=0.8) ax[0].set_xticklabels([]) # KD def KD(data): data_df = data.copy() data_df['min'] = data_df['Low'].rolling(9).min() data_df['max'] = data_df['High'].rolling(9).max() data_df['RSV'] = (data_df['Close'] - data_df['min']) / \ (data_df['max'] - data_df['min']) data_df = data_df.dropna() # 計算K # K的初始值定為50 K_list = [50]
def candlestick(candles): candlestick_ohlc(plt.axes(), candles)
df_ohlc = df['Adj Close'].resample('240H').ohlc() df_volume = df['Volume'].resample('240H').sum() #print(df_ohlc.head()) ax1 = plt.subplot(111) # plot 1 ax1.xaxis_date() ax1.plot(df.index, df['Adj Close'], label = "close") ax1.plot(df.index, df['10RollMean'], label = "10d rolling mean") ax1.plot(df.index, df['100RollMean'], label = "100d rolling mean") df_ohlc.reset_index(inplace=True) # reset index so all columns consist of data df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num) candlestick_ohlc(ax1, df_ohlc.values, width = 5, colorup = 'g') # ---- # # CURRENTLY DEVELOPING. Need to fix date history # call FTSE function to plot over company trends. # see 8.1.7 for timestamp definition - https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior print(FTSE100_index_price()[0]) #df_FTSE_date = df_FTSE_date.map(mdates.date2num) #ax1.plot(FTSE[0], FTSE[1], label = "FTSE index") ax1.set_facecolor('w') ax1.legend(fancybox = True, framealpha = 1, facecolor = 'white') ax1.grid(color = 'xkcd:grey')
def render(self, df, net_worth, trades): Date = df["Date"] Open = df["Open"] High = df["High"] Low = df["Low"] Close = df["Close"] Volume = df["Volume"] # append volume and net_worth to deque list self.Volume.append(Volume) self.net_worth.append(net_worth) # before appending to deque list, need to convert Date to special format Date = mpl_dates.date2num([pd.to_datetime(Date)])[0] self.render_data.append([Date, Open, High, Low, Close]) # Clear the frame rendered last step self.ax1.clear() candlestick_ohlc(self.ax1, self.render_data, width=0.8 / 24, colorup='green', colordown='red', alpha=0.8) # Put all dates to one list and fill ax2 sublot with volume Date_Render_range = [i[0] for i in self.render_data] self.ax2.clear() self.ax2.fill_between(Date_Render_range, self.Volume, 0) if self.Show_indicators: self.Plot_indicators(df, Date_Render_range) # draw our net_worth graph on ax3 (shared with ax1) subplot self.ax3.clear() self.ax3.plot(Date_Render_range, self.net_worth, color="blue") # beautify the x-labels (Our Date format) self.ax1.xaxis.set_major_formatter(self.date_format) self.fig.autofmt_xdate() minimum = np.min(np.array(self.render_data)[:, 1:]) maximum = np.max(np.array(self.render_data)[:, 1:]) RANGE = maximum - minimum # sort sell and buy orders, put arrows in appropiate order positions for trade in trades: trade_date = mpl_dates.date2num([pd.to_datetime(trade['Date'])])[0] if trade_date in Date_Render_range: if trade['type'] == 'buy': high_low = trade['Low'] - RANGE * 0.02 ycoords = trade['Low'] - RANGE * 0.08 self.ax1.scatter(trade_date, high_low, c='green', label='green', s=120, edgecolors='none', marker="^") else: high_low = trade['High'] + RANGE * 0.02 ycoords = trade['High'] + RANGE * 0.06 self.ax1.scatter(trade_date, high_low, c='red', label='red', s=120, edgecolors='none', marker="v") if self.Show_reward: try: self.ax1.annotate('{0:.2f}'.format(trade['Reward']), (trade_date - 0.02, high_low), xytext=(trade_date - 0.02, ycoords), bbox=dict(boxstyle='round', fc='w', ec='k', lw=1), fontsize="small") except: pass # we need to set layers every step, because we are clearing subplots every step self.ax2.set_xlabel('Date') self.ax1.set_ylabel('Price') self.ax3.set_ylabel('Balance') # I use tight_layout to replace plt.subplots_adjust self.fig.tight_layout() """Display image with matplotlib - interrupting other tasks""" # Show the graph without blocking the rest of the program #plt.show(block=False) # Necessary to view frames before they are unrendered #plt.pause(0.001) """Display image with OpenCV - no interruption""" # redraw the canvas self.fig.canvas.draw() # convert canvas to image img = np.fromstring(self.fig.canvas.tostring_rgb(), dtype=np.uint8, sep='') img = img.reshape(self.fig.canvas.get_width_height()[::-1] + (3, )) # img is rgb, convert to opencv's default bgr image = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) # display image with OpenCV or any operation you like cv2.imshow("Bitcoin trading bot", image) if cv2.waitKey(25) & 0xFF == ord("q"): cv2.destroyAllWindows() return else: return img
def draw_stock_data(stock, draw_candle_stick=True, draw_roi=True, draw_share_holder=True, period=Constants.MONTH, save_fig=False): # read and reformat data stock_data_dict = pandas.read_csv( Financial.get_stock_data_file_name(stock), parse_dates=True, index_col=0) stock_data_dict.reset_index(inplace=True) stock_data_dict['date'] = mdates.date2num(stock_data_dict['date']) # setup moving average models x = stock_data_dict['date'] roi = stock_data_dict['roi'] # # EMA_1_span = 7 # EMA_1 = stock_data['Close'].ewm(span=EMA_1_span, min_periods=EMA_1_span).mean() # # EMA_2_span = 30 # EMA_2 = stock_data['Close'].ewm(span=EMA_2_span, min_periods=EMA_2_span).mean() # # SMA_2_span = EMA_2_span # SMA_2 = stock_data['Close'].rolling(window=SMA_2_span, center=False).mean() # # MACD = EMA_1 - EMA_2 financial_data_file_name = Financial.get_financial_data_file_name(stock) if not os.path.exists(financial_data_file_name): print(financial_data_file_name + " not exist, return") return financial_data_dict = pandas.read_csv( Financial.get_financial_data_file_name(stock), parse_dates=True, index_col=0) financial_data_dict.reset_index(inplace=True) financial_data_dict['date'] = mdates.date2num(financial_data_dict['date']) x1 = financial_data_dict['date'] roe = financial_data_dict['roe'] book_value_per_share = financial_data_dict['book_value_per_share'] net_profit_per_share = financial_data_dict['net_profit_per_share'] * 10 cash_flow_per_share = financial_data_dict['cash_flow_per_share'] total_current_assets = financial_data_dict['total_current_assets'] total_assets = financial_data_dict['total_assets'] total_long_term_liabilities = financial_data_dict[ 'total_long_term_liabilities'] main_business_income = financial_data_dict['main_business_income'] financial_expenses = financial_data_dict['financial_expenses'] net_profit = financial_data_dict['net_profit'] # roe = financial_data_dict['roe'] share_bonus_file_name = Financial.get_share_bonus_file_name(stock) if not os.path.exists(share_bonus_file_name): print(share_bonus_file_name + " not exist, return") return share_bonus_dict = pandas.read_csv(share_bonus_file_name, parse_dates=True, index_col=0) share_bonus_dict.reset_index(inplace=True) share_bonus_dict['date'] = mdates.date2num(share_bonus_dict['date']) x2 = share_bonus_dict['date'] dividend = share_bonus_dict['dividend'] if draw_share_holder: share_holder_file_name = Financial.get_share_holder_file_name(stock) if not os.path.exists(share_holder_file_name): print(share_holder_file_name + " not exist, return") return share_holder_dict = pandas.read_csv(share_holder_file_name, parse_dates=True, index_col=0) share_holder_dict.reset_index(inplace=True) share_holder_dict['date'] = mdates.date2num(share_holder_dict['date']) x3 = share_holder_dict['date'] holder_number = share_holder_dict['number'] share_ratio = share_holder_dict['ratio'] # plot fig, (ax1, ax3) = plt.subplots(2, sharex=True, figsize=(10, 12)) # plot candlestick, SAM, EMA in subplot_1 if draw_candle_stick: candlestick_ohlc(ax1, stock_data_dict.values, width=0.5, colorup='r', colordown='g') # p1 = ax.plot(x, EMA_1, label='EMA(' + str(EMA_1_span) + ')') # p2 = ax.plot(x, EMA_2, label='EMA(' + str(EMA_2_span) + ')') # p3 = ax.plot(x, SMA_2, label='SMA(' + str(SMA_2_span) + ')') ax1.step(x1, roe, label='Roe') ax1.step(x1, cash_flow_per_share, label='CashFlowPerShare') ax1.step(x1, net_profit_per_share, label='NetProfitPerShare') ax1.step(x1, book_value_per_share, label='BookValuePerShare') ax1.step(x2, dividend, label='Dividend') if draw_roi: ax1.step(x, roi, label='ROI') if draw_share_holder: ax1.step(x3, holder_number, label='HolderNumber') ax1.step(x3, share_ratio, label='ShareRatio') ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax1.xaxis.set_major_locator(mdates.MonthLocator([1, 4, 7, 10])) ax1.xaxis.set_major_formatter(mdates.DateFormatter("%b '%y")) ax1.set_ylabel('Price', fontsize=16) ax1.legend() # plot volume in subplot_2 # ax2.bar(x, stock_data_dict['volume']) # ax2.set_ylabel('volume', fontsize=16) # plot MACD in subplot_3 # ax3.plot(x, MACD, label='MACD (' + 'EMA(' + str(EMA_1_span) + '), ' + 'EMA(' + str(EMA_2_span) + '))') # ax3.plot(x1, total_current_assets, label='TotalCurrentAssets') # ax3.plot(x1, total_assets, label='TotalAssets') ax3.plot(x1, total_long_term_liabilities, label='TotalLongTermLiabilities') ax3.plot(x1, main_business_income, label='MainBusinessIncome') ax3.plot(x1, financial_expenses, label='FinancialExpenses') ax3.plot(x1, net_profit, label='NetProfit') # ax3.plot(x1, roe, label='ROE') ax3.axhline(0, color='gray', linestyle='--') ax3.set_xlabel('date') ax3.set_ylabel('MACD', fontsize=16) ax3.legend() # # Pandas 无法显示中文问题 解决方案## plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 plt.title(stock.to_string()) if save_fig: fig.savefig(Constants.DATA_FIGURE_PATH + stock.get_name()) plt.close(fig) else: plt.show()
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--driver', default=None, choices=['inky', 'inkyphat', 'waveshare_epd']) parser.add_argument("--pair", default='XETHZUSD', help="currency pair") parser.add_argument('--flip', dest='flip', action='store_true', help="rotate the display") parser.set_defaults(flip=False) parser.add_argument("--output", help="save plot as png") args = parser.parse_args() yesterday = datetime.now() - timedelta(hours=12) quotes = quotes_historical_kraken_ohlc(args.pair, yesterday, interval=15) if not quotes: raise ValueError('Empty OHLC data') candlestick_ohlc(ax, quotes, width=1) ax.xaxis_date() ax.autoscale_view() ymin, ymax = ax.get_ylim() last_low = quotes[-1][3] last_high = quotes[-1][2] last_close = quotes[-1][4] ttf = pkg_resources.open_binary(fonts, '04B_03__.TTF') font = ImageFont.truetype(ttf, 8) RED = (255,0,0) BLACK = (0,0,0) display = None driver = args.driver if driver == 'inky': from inky import InkyPHAT RED = InkyPHAT.RED BLACK = InkyPHAT.BLACK display = InkyPHAT('black') elif driver == 'inkyphat': from inkyphat import RED as inky_RED, BLACK as inky_BLACK, set_image as _set_image, show as _show RED = inky_RED BLACK = inky_BLACK class InkyPHAT(): def __init__(*args): pass set_image = staticmethod(_set_image) show = staticmethod(_show) display = InkyPHAT() elif driver == 'waveshare_epd': from waveshare_epd import epd2in13_V2 class EPD(): def __init__(self, *args): self.epd = epd2in13_V2.EPD() self.epd.init(self.epd.FULL_UPDATE) self.buf = [] def set_image(self, image): self.buf = self.epd.getbuffer(image) def show(self): self.epd.display(self.buf) display = EPD() with io.BytesIO() as f: fig.savefig(f, dpi=dpi, cmap="bwr", interpolation="none", origin="lower", pad_inches=0) f.seek(0) i = Image.open(f) d = ImageDraw.Draw(i) ypos = 0 if ymax - last_high > last_low - ymin else h - 6 d.text((148, ypos), '{:.2f}'.format(last_close), BLACK, font) d.text((176, ypos), args.pair, RED, font) if args.flip: i = i.transpose(Image.ROTATE_180) if display: display.set_image(i.convert("P")) display.show() if args.output: i.save(args.output)
def plot_ticker_analysis(market, ticker): ticker_file = 'stock_data/'+ticker+'.csv' df = pd.read_csv(ticker_file, parse_dates=True, index_col=0) df_rsi = df.copy() #df['100ma'] = df['Adj Close'].rolling(window=100, min_periods=0).mean() df_ohlc = df['Adj Close'].resample('2D').ohlc() df_volume = df['Volume'] #.resample('2D').sum() #df_vol_mean = df['Volume'].mean() #print(df_vol_mean) df_ohlc.reset_index(inplace=True) df_ohlc['Date'] = df_ohlc['Date'].map(dates.date2num) df.drop(['Open','High','Low','Close','Volume'],1,inplace=True) ## Bollinger Computation ********************* mma_30 = df.rolling(window=20).mean() std_30 = df.rolling(window=20).std() upper = mma_30 + (std_30 * 2) lower = mma_30 - (std_30 * 2) ## ******************************************* ## RSI Computation *************************** close = df['Adj Close'] delta = close.diff() delta = delta[1:] up, down = delta.copy(), delta.copy() up [up < 0] = 0 down [down > 0] = 0 #roll_up1 = pd.DataFrame.ewm( up, 14) #roll_dn1 = pd.DataFrame.ewm(down, 14) #RS1 = roll_up1 / roll_dn1 #RSI1 = 100.0 - (100.0 / (1.0 + RS1)) roll_up2 = up.rolling(window=14).mean().abs() roll_dn2 = down.rolling(window=14).mean().abs() RS2 = roll_up2 / roll_dn2 RSI2 = 100.0 - (100.0 / (1.0 + RS2)) ## ******************************************* ## MACD Computation ************************** exp1 = df.ewm(span=12, adjust=False).mean() exp2 = df.ewm(span=26, adjust=False).mean() macd = exp1-exp2 exp3 = macd.ewm(span=9, adjust=False).mean() ## ******************************************* ## Graph organization *********************** #ax1 = plt.subplot2grid((10,1),(0,0), rowspan=4, colspan=1 ) #ax2 = plt.subplot2grid((10,1),(4,0), rowspan=3, colspan=1 ) #ax3 = plt.subplot2grid((10,1),(7,0), rowspan=1, colspan=1 ) #ax4 = plt.subplot2grid((10,1),(8,0), rowspan=2, colspan=1 ) fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, sharex=True) #ax3.xaxis_date() ax3.xaxis.set_major_formatter(day_fmt) ax3.xaxis.set_minor_formatter(day_fmt) ## Plot ADJ CLOSE ax1.plot(df['Adj Close'], label = 'Adj Close', color = 'blue') ## Plot Bollinger upper and lower ax1.plot(upper, label = 'upper', color = 'black', lw=0.3) ax1.plot(lower, label = 'lower', color = 'black', lw=0.3) ax1.plot(mma_30, label = 'mma', color = 'black' , lw=0.3) ## Plot candlestick candlestick_ohlc(ax1, df_ohlc.values, width=2, colorup='g') #ax3.plot(df_volume) ax3.fill_between(df_volume.index.map(dates.date2num), df_volume.values, 0) #ax3.plot(df_vol_mean, label='Volume mean',color = 'black') #ax4.plot(RSI1, label = 'RSI EWMA', color = 'green') ax4.plot(RSI2, label = 'RSI SMA ', color = 'red') ax2.plot(macd, label='MACD', color = 'black' ) ax2.plot(exp3, label='Signal', color = 'red' ) #plt.setp(ax1.get_xticklabels(), visible=False) #plt.setp(ax2.get_xticklabels(), visible=False) multi = MultiCursor(fig.canvas, (ax1, ax2, ax3, ax4), color = 'r', lw=1) cursor1 = Cursor(ax1, useblit=True, color='red', linewidth=2 ) cursor2 = Cursor(ax2, useblit=True, color='red', linewidth=2 ) cursor3 = Cursor(ax3, useblit=True, color='red', linewidth=2 ) cursor4 = Cursor(ax4, useblit=True, color='red', linewidth=2 ) plt.show()
dayFormatter = DateFormatter('%d') # e.g., 12 infile = os.path.join('data', 'yahoofinance-INTC-19950101-20040412.csv') quotes = pd.read_csv(infile, index_col=0, parse_dates=True, infer_datetime_format=True) # select desired range of dates quotes = quotes[(quotes.index >= date1) & (quotes.index <= date2)] fig, ax = plt.subplots() fig.subplots_adjust(bottom=0.2) ax.xaxis.set_major_locator(mondays) ax.xaxis.set_minor_locator(alldays) ax.xaxis.set_major_formatter(weekFormatter) # ax.xaxis.set_minor_formatter(dayFormatter) # plot_day_summary(ax, quotes, ticksize=3) candlestick_ohlc(ax, zip(mdates.date2num(quotes.index.to_pydatetime()), quotes['Open'], quotes['High'], quotes['Low'], quotes['Close']), width=0.6) ax.xaxis_date() ax.autoscale_view() plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right') plt.show()
def chart1(): # 1データからチャートをplotする def get_OHLC(before, after): # ここからデータ取得 url = 'https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc' query = { 'periods': 60, 'before': before, 'after': after, } res = requests.get(url, params=query).json()['result']['60'] return res # UNIX時間に変換するためのもの # 4取得した現在時刻をUNIX時間に変換 def unixTime(y, m, d, h): return int(time.mktime(datetime(y, m, d, h).timetuple())) # 3現在時刻を取得 now = datetime.now() y, m, d, h = now.year, now.month, now.day, now.hour # 5直近1時間の間のデータを取得する data = get_OHLC(unixTime(y, m, d, h), unixTime(y, m, d, h - 1)) # 空リスト Time, Open, High, Low, Close = [], [], [], [], [] # 6取得したデータをfor文で仕分ける for i in data: Time.append(datetime.fromtimestamp(i[0])) Open.append(i[1]) High.append(i[2]) Low.append(i[3]) Close.append(i[4]) # 7取得したデータを表示 pd.DataFrame({ 'date': Time, 'open': Open, 'high': High, 'low': Low, 'close': Close }) # チャートに描画 Date = [ datetime(y, m, d, h - 1) + dt.timedelta(minutes=mi) for mi in range(60) ] ohlc = zip(mdates.date2num(Date), Open, High, Low, Close) ax = plt.subplot() # 時間を15分単位で区切る ax.xaxis.set_major_locator(mdates.MinuteLocator([0, 15, 30, 45])) ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) # mpl_financeのメソッドを仕様。(描画幅やチャートの色などを指定。デフォルトは赤黒) # 上昇の時は緑、下落は赤 candlestick_ohlc(ax, ohlc, width=(1 / 24 / 60) * 0.7, colorup='g', colordown='r') # チャートタイトルのテキスト plt.title('BTC / JPY by Cryptowatch API') plt.savefig('app/static/price.png')
def pandas_candlestick_ohlc(dat, days='day', adj=False, otherseries=None): mondays = WeekdayLocator(MONDAY) all_days = DayLocator() fields = ['Open', 'High', 'Low', 'Close'] transdat = dat.loc[:, fields] # Selects single column or subset of columns by label transdat.columns = pd.Index(['Open', 'High', 'Low', 'Close']) if (type(days) == str): if days == "day": plotdat = transdat days = 1 elif days in ['week', 'month', 'year']: if days == 'week': transdat['week'] = pd.to_datetime(transdat.index).map( lambda x: x.isocalender()[1] ) #Return a 3-tuple, (ISO year, ISO week number, ISO weekday). elif days == 'month': transdat['month'] = pd.to_datetime( transdat.index).map(lambda x: x.month) transdat['year'] = pd.to_datetime( transdat.index).map(lambda x: x.isocalendar()[0]) grouped = transdat.groupby(list({'year', days})) plotdat = pd.DataFrame({ "Open": [], "High": [], "Low": [], "Close": [] }) for name, group in grouped: plotdat = plotdat.append( pd.DataFrame( { 'Open': group.iloc[0, 0], 'High': max(group.High), 'Low': min(group.Low), 'Close': group.iloc[-1, 3] }, index=[group.index[0]])) if days == 'week': days = 5 elif days == 'month': days = 30 elif days == 'year': days = 365 elif (type(days) == int and days >= 1): transdat['stick'] = [ pd.np.floor(i / days) for i in range(len(transdat.index)) ] grouped = transdat.groupby('stick') plotdat = pd.DataFrame({ "Open": [], "High": [], "Low": [], "Close": [] }) for name, group in grouped: plotdat = plotdat.append( pd.DataFrame( { 'Open': group.iloc[0, 0], 'High': max(group.High), 'Low': min(group.Low), 'Close': group.iloc[-1, 3] }, index=[group.index[0]])) else: raise ValueError( 'Valid inputs - "days" include the strings or a positive integer') # Set plot parameters, including the axis object ax used for plotting fig, ax = plt.subplots() fig.subplots_adjust(bottom=0.2) if plotdat.index[-1] - plotdat.index[0] < pd.Timedelta('730 days'): weekFormatter = DateFormatter('%b %d') # for example Jan 12 ax.xaxis.set_major_locator(mondays) ax.xaxis.set_minor_locator(all_days) else: weekFormatter = DateFormatter('%b %d, %Y') ax.xaxis.set_major_formatter(weekFormatter) ax.grid(True) # Create the candelstick chart candlestick_ohlc(ax, list( zip(list(date2num(plotdat.index.tolist())), plotdat["Open"].tolist(), plotdat["High"].tolist(), plotdat["Low"].tolist(), plotdat["Close"].tolist())), colorup="black", colordown="red", width=days * .4) # Plot other series (such as moving averages) as lines if otherseries != None: if type(otherseries) != list: otherseries = [otherseries] dat.loc[:, otherseries].plot(ax=ax, lw=1.3, grid=True) ax.xaxis_date() ax.autoscale_view() plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right') plt.show()
def draw(listStockPrices, begin=None, end=None, field="Close", date_format=None, existing=None, axis=1, ax=None, label_prefix=None, color=None, **args): """ Draws a graph showing one or several time series. The example was taken `date_demo.py <https://matplotlib.org/examples/api/date_demo.html>`_. @param listStockPrices list of @see cl StockPrices (or one @see cl StockPrices if it is the only one) @param begin first date (datetime) or None to take the first one @param end last included date (datetime) or None to take the last one @param field Open, High, Low, Close, Adj Close, Volume @param date_format ``%Y`` or ``%Y-%m`` or ``%Y-%m-%d`` or None if you prefer the function to choose @param args other arguments to send to ``plt.subplots`` @param axis 1 or 2, it only works if existing is not None. If axis is 2, the function draws the curves on the second axis. @param label_prefix to prefix curve label @param color curve color @param args other parameters to give method ``plt.subplots`` @param ax use existing `axes <http://matplotlib.org/api/axes_api.html>`_ @return `axes <http://matplotlib.org/api/axes_api.html>`_ The parameter ``figsize`` of the method `subplots <https://matplotlib.org/api/pyplot_api.html?highlight=subplots#matplotlib.pyplot.subplots>`_ can change the graph size (see the example below). .. exref:: :title: graph of a financial series :: from pyensae.finance import StockPrices stocks = [ StockPrices("NASDAQ:MSFT", folder = cache), StockPrices("NASDAQ:GOOGL", folder = cache), StockPrices("NASDAQ:AAPL", folder = cache)] fig, ax, plt = StockPrices.draw(stocks) fig.savefig("image.png") fig, ax, plt = StockPrices.draw(stocks, begin="2010-01-01", figsize=(16,8)) plt.show() You can also chain the graphs and add a series on a second graph: :: from pyensae.finance import StockPrices stock = StockPrices("NASDAQ:MSFT", folder = cache) stock2 = StockPrices "NASDAQ:GOOGL", folder = cache) fig, ax, plt = stock.plot(figsize=(16,8)) fig, ax, plt = stock2.plot(existing=(fig,ax), axis=2) plt.show() .. versionchanged:: 1.1 Parameter *existing* was removed and parameter *ax* was added. If the date overlaps, the method `autofmt_xdate <https://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.autofmt_xdate>`_ should be called. """ if isinstance(listStockPrices, StockPrices): listStockPrices = [listStockPrices] data = StockPrices.available_dates(listStockPrices, missing=False, field=field) if begin is None: if end is not None: data = data[data.index <= end] else: if end is not None: data = data[(data.index >= begin) & (data.index <= end)] else: data = data[data.index >= begin] dates = [datetime.datetime.strptime(_, '%Y-%m-%d') for _ in data.index] begin = dates[0] end = dates[-1] def price(x): "local formatting" return '%1.2f' % x import matplotlib.pyplot as plt # pylint: disable=C0415 import matplotlib.dates as mdates # pylint: disable=C0415 if ax is not None: ex_h, ex_l = ax.get_legend_handles_labels() ex_l = tuple(ex_l) ex_h = tuple(ex_h) if axis == 2: ax = ax.twinx() fig = None else: if 'label' in args: args_ = {k: v for k, v in args.items() if k not in ('label', )} else: args_ = args fig, ax = plt.subplots(**args_) ex_h, ex_l = tuple(), tuple() curve = [] if field == "ohlc": from mplfinance.original_flavor import candlestick_ohlc # pylint: disable=E0401 ohlc = list( list(data.iloc[i, :4]) for i in range(0, data.shape[0])) ohlc = [[mdates.date2num(t)] + v for t, v in zip(dates, ohlc)] candlestick_ohlc(ax, ohlc, colorup="g") else: if label_prefix is None: label_prefix = "" add_args = {} if color: add_args['c'] = color for stock in data.columns: if axis == 2: curve.append( ax.plot(dates, data[stock], "r", linestyle='solid', label=label_prefix + str(stock), **add_args)) else: curve.append( ax.plot(dates, data[stock], linestyle='solid', c=color, label=label_prefix + str(stock), **add_args)) if existing is None: ax.format_xdata = mdates.DateFormatter('%Y-%m-%d') if len(dates) < 30: days = mdates.DayLocator() ax.xaxis.set_major_locator(days) ax.xaxis.set_minor_locator(days) if date_format is not None: fmt = mdates.DateFormatter(date_format) ax.xaxis.set_major_formatter(fmt) else: ax.xaxis.set_major_formatter( mdates.DateFormatter("%Y-%m-%d")) elif len(dates) < 500: months = mdates.MonthLocator() days = mdates.DayLocator() ax.xaxis.set_major_locator(months) ax.xaxis.set_minor_locator(days) ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m")) if date_format is not None: fmt = mdates.DateFormatter(date_format) ax.xaxis.set_major_formatter(fmt) else: ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m")) else: years = mdates.YearLocator() months = mdates.MonthLocator() ax.xaxis.set_major_locator(years) ax.xaxis.set_minor_locator(months) if date_format is not None: fmt = mdates.DateFormatter(date_format) ax.xaxis.set_major_formatter(fmt) else: ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y")) ax.set_xlim(begin, end) ax.format_ydata = price if fig is not None: fig.autofmt_xdate() if axis == 2: if isinstance(curve, list): curve = [_[0] for _ in curve] ax.legend(ex_h + tuple(curve), ex_l + tuple(data.columns)) else: ax.grid(True) ax.legend(ex_l + tuple(data.columns)) return ax
def plot_stock_curve(self): self.fig = plt.figure() ax2 = self.fig.add_subplot(111, ylabel='Stock value: %') ohlc = self.stock_data[['open', 'high', 'low', 'close']] ohlc = ohlc.reset_index().to_numpy() date = date2num(ohlc[:, 0]) ohlc[:, 0] = date le_y = self.summary_recording[self.summary_recording['direction'] == 'LONG']['close_price'] le_x = self.summary_recording[self.summary_recording['direction'] == 'LONG'].index.to_list() le_x_value = date2num(le_x) le_y_value = le_y.values lexit_y = self.summary_recording[self.summary_recording['direction'] == 'EXIT']['close_price'] lexit_x = self.summary_recording[self.summary_recording['direction'] == 'EXIT'].index.to_list() lexit_x_value = date2num(lexit_x) lexit_y_value = lexit_y.to_numpy() candlestick_ohlc(ax2, ohlc, width=0.4, colorup='red', colordown='green') for label in ax2.xaxis.get_ticklabels(): label.set_rotation(45) ax2.plot(le_x_value, le_y_value, '^', color='lime', markersize=8, label='long enter') for index in range(len(le_x_value)): plt.text(le_x_value[index], le_y_value[index] * 1.05, "Buy", ha='center', va='bottom', fontsize=8) ax2.plot(lexit_x_value, lexit_y_value, 'v', color='red', markersize=8, label='Exit') plt.text(lexit_x_value[0], lexit_y_value[0] * 1.05, "Sell", ha='center', va='bottom', fontsize=8) ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax2.xaxis.set_major_locator(mticker.MaxNLocator(10)) plt.grid(True) plt.show()
from matplotlib import pyplot as plt from matplotlib import style import pandas as pd import matplotlib.dates as mdates from mplfinance.original_flavor import candlestick_ohlc import csv style.use('ggplot') Analysis = "2313.TW.csv" data = pd.read_csv(Analysis, parse_dates=True, index_col='Date') price = data['Close'] price.head() moving_avg = price.rolling(20).mean() fig = plt.figure() ax1 = fig.add_subplot(111) data = data.reset_index() data['Date'] = data['Date'].apply(lambda d: mdates.date2num(d.to_pydatetime())) candlestick = [tuple(x) for x in data[['Date','Open','High','Low','Close']].values] candlestick_ohlc(ax1, candlestick[-120:], width=0.7,colorup='r',colordown='green',alpha=0.8) plt.plot(moving_avg[-120:],linewidth=1,alpha=0.7,label="MA20") plt.legend() plt.show()
lastD = prices['D'][i] lastLow = prices['Low'][i] lastClose = prices['Adj Close'][i] lastLowBB = prices['LowerBand'][i] #Plot moving averages and BBands for x in smasUsed: sma = x prices['SMA_' + str(sma)].plot(label='close') prices['UpperBand'].plot(label='close', color='lightgray') prices['LowerBand'].plot(label='close', color='lightgray') #plot candlesticks candlestick_ohlc(ax1, ohlc, width=.5, colorup='k', colordown='r', alpha=0.75) ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax1.xaxis.set_major_locator(mticker.MaxNLocator(8)) plt.tick_params(axis='x', rotation=45) #Pivot Points pivots = [] dates = [] counter = 0 lastPivot = 0 Range = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] dateRange = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
from matplotlib import style from mplfinance.original_flavor import candlestick_ohlc from matplotlib.dates import date2num import pandas as pd import pandas_datareader.data as web style.use('ggplot') #set a plot style df = pd.read_csv('nflx.csv', parse_dates=True, index_col=0) #read csv file as pandas dataframe df_ohlc = df['Adj Close'].resample( '10D').ohlc() #create a new dataframe with resampling of 10 days df_volume = df['Volume'].resample( '10D').sum() ##create a new dataframe with resampling of 10 days df_ohlc.reset_index(inplace=True) #reset date as index df_ohlc['Date'] = df_ohlc['Date'].map( date2num) #convert datetime object to matplotlib dates print(df_ohlc.head()) #print the first five rows of the dataframe ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan=5, colspan=1) #add first subplot ax2 = plt.subplot2grid((6, 1), (5, 0), rowspan=1, colspan=1, sharex=ax1) #add second subplot ax1.xaxis_date() candlestick_ohlc(ax1, df_ohlc.values, width=2, colorup='g') #plot a candlestick chart ax2.fill_between(df_volume.index.map(date2num), df_volume.values, 0) plt.show() #display the figure
def candlestickIt(data, inc, name, useCsv): tickName = name if useCsv == 1: dataFrame = pd.read_csv("CsvFolder/" + tickName + ".csv", parse_dates=['Date']) df = dataFrame else: df = data increment = inc #matplot figure allows for multiple instances/windows to be made plt.figure(increment) plt.suptitle(tickName) df = data print(df.head()) #creates and resamples the dataframe to show the weekly change #do not resample to less than 4D - bad things happen(down bars disappear) df_ohlc = df['Adj Close'].resample('4D').ohlc() df_volume = df['Adj Close'].resample('4D').sum() df_ohlc.reset_index(inplace=True) df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num) #create subplots to represent data ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan=5, colspan=1) #need ax2 to match ax1 so that when zooming on one graph the other matches ax2 = plt.subplot2grid((6, 1), (5, 0), rowspan=5, colspan=1, sharex=ax1) ax2.set_title('Volume') #date format for x axis ax1.xaxis_date() #formats the y axis ticker to represent dollars formatter = ticker.FormatStrFormatter('$%1.2f') ax1.yaxis.set_major_formatter(formatter) for tick in ax1.yaxis.get_major_ticks(): tick.label1.set_visible(False) tick.label2.set_visible(True) #tick.label2.set_color('green') #sets ticker to the left side ax1.yaxis.tick_left() ax1.yaxis.set_label_position("left") #Build candlestick chart try: candlestick_ohlc(ax1, df_ohlc.values, width=1.8, colorup='#00eeff', colordown='#ff0044', alpha=.4) except: print("ERROR build went wrong within candlestick method") main() ax2.fill_between(df_volume.index.map(mdates.date2num), df_volume.values, 0) #add spacing between subplots plt.subplots_adjust(hspace=0.7) ax1.grid(b=True, which='major', color='grey', linestyle='-', alpha=0.4) #maximizes window #this backend is: TkAgg manager = plt.get_current_fig_manager() manager.resize(*manager.window.maxsize()) return
def rsiCheck(_shcode="", hname=''): global g_rsiTgt global g_simpleMA9Tgt now = time.localtime() tempToday = "%04d%02d%02d" % (now.tm_year, now.tm_mon, now.tm_mday) if not os.path.exists(tempToday): os.mkdir(tempToday) df1475 = orderManager.t1475(_shcode) if df1475.shape[0] == 0: print("t1475 responded null") elif df1475.shape[0] != 0 and float(df1475['당일VP'].values[0]) < 100: strTemp = "체결강도 100 미만으로 후보 탈락:" + hname print(strTemp) # botManager.sendTeleMsg(strTemp) return 0 df = orderManager.t8412(단축코드=_shcode, 단위="2", 요청건수="36") if df.shape[0] > 0: # rsi 9 구하기 try: taadx = ta.ADX(df['고가'], df['저가'], df['종가'], 9) taadxSig = ta.MA(taadx, timeperiod=9) taadx = np.asarray(taadx) taadxSig = np.asarray(taadxSig) print("ADX ", taadx) print("ADX Sig", taadxSig) if float(taadx[-1]) <= float(taadxSig[-1]): print("ADX condition mismatched") return 0 adxgrad, intercept, adi_r_square, p_value, std_err = stats.linregress( list(range(len(taadx[-30:-1]))), taadx[-30:-1]) if adxgrad < 0: print("ADX downturn") return 0 except Exception as e: print("Exception Occur : ", e) # adi = calcADI(df) # # mincond = adi['ADI'] < 0 # # adi = adi[mincond] # tempY = list(map(float, np.asarray(adi))) # sortTemp = sorted(tempY) # sortTemp = sortTemp[0:5] # print("저점 ADI: ",sortTemp) # newTempY = [] # for i in tempY: # if i in sortTemp: # newTempY.append(i) # print("저점 정렬 ADI: ", newTempY) # tempX = list(range(len(newTempY))) # adigrad, intercept, adi_r_square, p_value, std_err = stats.linregress(tempX, newTempY) # print("adi 저점정보", adigrad, intercept, adi_r_square, p_value, std_err) rsi9 = ta.RSI(np.asarray(df['종가']), 9) rsi9 = rsi9[~np.isnan(rsi9)] # remove nan if rsi9.size == 0: print("rsi size exception") return 0 rsiTgt = rsi9[-1] simpleMA9 = ta.MA(rsi9, timeperiod=9) simpleMA9Tgt = simpleMA9[-1] print('----------[RSI SIGNAL JUDGE]----------') if int(rsiTgt) < int(simpleMA9Tgt): # or int(rsiTgt) >= 75: print('rsi', rsiTgt, 'signal', simpleMA9Tgt) return 1 # elif int(rsiTgt) > int(simpleMA9Tgt) and int(rsiTgt) <= 30: # print('rsi > ', rsiTgt, '>', 'signal', simpleMA9Tgt) # g_rsiTgt = round(rsiTgt, 2) # g_simpleMA9Tgt = round(simpleMA9Tgt,2) # return 2 obv = ta.OBV(np.asarray(df['종가'], dtype=np.double), np.asarray(df['거래량'], dtype=np.double)) if obv[-1] < 8000: print("latest obv cut", obv[-1]) return 1 if obv[-1] - obv[-3] <= 0 or obv[-1] - obv[-2] <= 0: print("obv is downturned") return 1 obvSignal = ta.MA(obv, timeperiod=9) #obvSignal = obvSignal[~np.isnan(obvSignal)] # if obvSignal[-1] < 0: # print("latest obv signal is under zero") # return 1 tempX = list(range(len(obv))) tempY = list(map(float, obv)) obvgrad, intercept, r_square, p_value, std_err = stats.linregress( tempX, tempY) print("OBV ", obvgrad, intercept, r_square, p_value, std_err) if obvgrad <= 0: print("OBV grad <= 0") return 1 tempXSignal = list(range(len(obvSignal))) tempYSignal = list(map(float, obvSignal)) tempXSignal = tempXSignal[-16:-1] tempYSignal = tempYSignal[-16:-1] obvSignalgrad, intercept, r_square, p_value, std_err = stats.linregress( tempXSignal, tempYSignal) print("OBV Signal ", obvSignalgrad, intercept, r_square, p_value, std_err) # if obvSignalgrad <=0: # print("obvSignalgrad grad <= 0") # return 1 # plt.show() # print(obv) # print(obvSignal) #obv always above 0, but signal can be lower than 0 if obv[-1] < obvSignal[-1] or obv[-2] < obvSignal[-2]: print("Signal Condition Unsuited") return 1 # if abs(obvSignal[-1]) / (obv[-1] + (obvSignal[-1] < 0 and abs(obvSignal[-1]) or 0)) > 0.9 or abs(obvSignal[-2]) / (obv[-2]+(obvSignal[-1] < 0 and abs(obvSignal[-1]) or 0)) > 0.9: # print("OBV Gap Flattened") # return 1 # RSI Gap Condition Check : reg grad +, abs(gap[-1]) < 10 # rsiGap = rsi9 - simpleMA9 # rsiGap = rsiGap[~np.isnan(rsiGap)] # rsiGap = abs(rsiGap) # print("rsi gap : ", rsiGap) # tempX = list(range(len(rsiGap))) # tempY = list(map(float, rsiGap)) # tempX = tempX[-8:-1] # tempY = tempY[-8:-1] # g_rsiTgt = round(rsiTgt, 2) # g_simpleMA9Tgt = round(simpleMA9Tgt, 2) # grad, intercept, r_square, p_value, std_err = stats.linregress(tempX, tempY) # print("regression result: ", grad, intercept, r_square, p_value, std_err) # print("type rsi... ",type(rsi9[-1])) if rsi9[-1] - rsi9[-3] <= 0 or rsi9[-1] - rsi9[-2] <= 0: print("rsi is downturned") return 0 print("type simpleMA9... ", type(simpleMA9[-1])) # if grad <= 0 and rsi9[-1] > simpleMA9[-1] and rsi9[-2] > simpleMA9[-2]: # and r_square <= -0.6 and p_value < 0.05 and rsiGap[-2] >= rsiGap[-1]: if rsi9[-1] > simpleMA9[-1] and rsi9[-2] > simpleMA9[ -2]: # and r_square <= -0.6 and p_value < 0.05 and rsiGap[-2] >= rsiGap[-1]: # gapFlag = 0 # for i in tempY: # if i > 11: # gapFlag += 1 # if gapFlag < 2: # print("no rsi condition(gap flag is flatten) matched") # return 0 print("RSI Gap Condition Check OK") plt.figure(figsize=(30, 30)) plt.subplot(221) plt.title(str(_shcode)) plt.plot(obv) plt.plot(obvSignal) plt.text(0, 10, "og:" + str(format(obvgrad, "8.2%"))) plt.legend(["obv", "obv signal"]) # tempStr = tempToday + "/" + str(_shcode) + " obv" + ".png" # plt.savefig(tempStr) # botManager.sendImage(tempStr) plt.subplot(222) plt.plot(rsi9) plt.plot(simpleMA9) # plt.text(0, 10, "rg:" + str(format(grad, "3.2%"))) plt.legend(["rsi", "rsi signal"]) # plt.subplot(413) # plt.plot(newTempY) # plt.text(0, newTempY[0], "g"+str(format(adigrad,"3.2%"))+"r^2:" + str(format(adi_r_square*adi_r_square,"3.2%"))) # plt.legend(["new adi"]) plt.subplot(223) plt.plot(taadx) plt.plot(taadxSig) plt.text(20, taadxSig[-1], "g:" + str(format(adxgrad, "3.2%"))) plt.legend(["adx", "adx sig"]) ax = plt.subplot(224) dfnew = df[['시가', '고가', '저가', '종가']] day_list = range(len(df)) dfnew.insert(0, '시각', day_list) #dfnew = dfnew.set_index('날짜') dfnew = dfnew.apply(pd.to_numeric) candlestick_ohlc(ax, dfnew.values, width=0.5, colorup='r', colordown='b') plt.grid() tempStr = tempToday + "/" + str(_shcode) + " " + hname + ".png" plt.savefig(tempStr) plt.close() # botManager.sendImage(tempStr) # msrate check added return 3 else: print("no rsi condition matched") return 0 print("RSI Calc Err") return 0
#ax1.plot(df.index, df["vwap"], lw=1, alpha=0.8, # label="Bitcoin Price (BitMex)") dfn = df.resample('60min').agg({'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last', 'vwap': 'mean'}) dfn["open_adj"] = np.where(dfn.open < dfn.low, dfn.low, np.where(dfn.open > dfn.high, dfn.high, dfn.open)) quotes = zip(mdates.date2num(dfn.index.to_pydatetime()), dfn.open_adj, dfn.high, dfn.low, dfn.close) candlestick_ohlc(ax1, quotes, width=0.01, colorup='g') ema_fast_plot = ax1.plot( df.index, df["ema-5hr"], lw=1, alpha=0.8, label="EMA (Exponential Moving Average) - 5 hours") ema_slow_plot = ax1.plot( df.index, df["ema-1day"], lw=1, alpha=0.8, label="EMA 1 day") buy_signal_plot = ax1.plot( df.loc[df["position"] == 1.0].index, df["ema-5hr"][df["position"] == 1.0], '^', markersize=10, color='#009900', label="Buy signal") sell_signal_plot = ax1.plot( df.loc[df["position"] == -1.0].index,
def chart_plot_upload(stock): yf.pdr_override() smaUsed = [5, 10, 20] timed = dt.timedelta(120) now = dt.datetime.now() start = now - timed - dt.timedelta(max(smaUsed)) # Within one year print(start) # start = dt.datetime(2010,1,1) # stock = input("Enter the stock symbol: ") #Asks for stock ticker # stock = 'BRK-B' prices = pdr.get_data_yahoo( stock, start, now) #Fetches stock price data, saves as data frame # Set Plot Grid fig, (axc, axkd) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [3, 1]}, sharex=True, figsize=(15, 10)) axv = axc.twinx() # Caculated All SMA for x in smaUsed: prices['SMA_' + str(x)] = prices['Adj Close'].rolling(window=x).mean() # Caculate Boolinger Bands BBperiod = 15 stdev = 2 prices['Boolinger Band SMA' + str(BBperiod)] = prices.iloc[:, 4].rolling(window=BBperiod).mean() prices['STDEV'] = prices.iloc[:, 4].rolling(window=BBperiod).std() prices['LowerBand'] = prices['Boolinger Band SMA' + str(BBperiod)] - stdev * prices['STDEV'] prices['UpperBand'] = prices['Boolinger Band SMA' + str(BBperiod)] + stdev * prices['STDEV'] prices['Date'] = mdates.date2num( prices.index ) #creates a date column stored in number format (for OHCL bars) # Caculated 10.4.4 KD Value Period = 10 K = 4 D = 4 prices['RolHigh'] = prices['High'].rolling(window=Period).max() prices['RolLow'] = prices['Low'].rolling(window=Period).min() prices["stok"] = ((prices["Adj Close"] - prices["RolLow"]) / (prices["RolHigh"] - prices["RolLow"])) * 100 prices["K"] = prices["stok"].rolling(window=K).mean() #Finds 10.4 stoch prices["D"] = prices["K"].rolling(window=D).mean() #Finds 10.4.4 stoch prices["GD"] = prices["High"] #Create GD column to store green dots prices = prices[max(smaUsed):] ohlc = [] for i in prices.index: append_me = prices['Date'][i], prices['Open'][i], prices['High'][ i], prices["Low"][i], prices["Adj Close"][i], prices["Volume"][i] ohlc.append(append_me) print(ohlc) print(prices) # Plot # Moving average for x in smaUsed: axc.plot(prices['SMA_' + str(x)], label='SMA_' + str(x)) # Volume axv.plot(prices['Volume'], color='Navy') # axv.axes.yaxis.set_ticklabels(range(0, 10000000)) axv.set_ylim(0, 5 * max(prices['Volume'])) axv.set_ylabel("Volume (K)") axv.fill_between(prices['Date'], prices['Volume'], facecolor='Navy', alpha=0.25) # axv.yaxis.set_major_formatter(mticker.FormatStrFormatter('%0.0e')) axv.yaxis.set_major_formatter( mticker.FuncFormatter(lambda x, p: format(int(x / 1000), ','))) candlestick_ohlc( axc, ohlc, width=.5, colorup='g', colordown='r', alpha=0.75, ) axc.xaxis.set_major_formatter( mdates.DateFormatter('%Y-%m-%d')) #change x axis back to datestamps axc.xaxis.set_major_locator( mticker.MaxNLocator(8)) #add more x axis labels axc.legend() axkd.plot(prices['K'], label='K') axkd.plot(prices['D'], label='D') axkd.axhline(y=80, xmin=0, xmax=1, color='gray', linestyle='--') axkd.axhline(y=20, xmin=0, xmax=1, color='gray', linestyle='--') axkd.legend(loc='center left', bbox_to_anchor=(1, 0.85)) axkd.tick_params(axis='x', rotation=45) #rotate dates for readability axc.set_title(stock) # build folder # basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) # newdir = os.path.join(basedir, 'chart') # if os.path.exists(newdir) == False: # os.mkdir(newdir) print("Starting Saving....") BASE_DIR = os.path.dirname(os.path.abspath(__file__)) print('Base_dir:' + BASE_DIR) fig.savefig(os.path.join(BASE_DIR, 'chart/fig1.png')) CLIENT_ID = "f99b6417ee666d3" PATH = os.path.join(BASE_DIR, 'chart/fig1.png') im = pyimgur.Imgur(CLIENT_ID) uploaded_image = im.upload_image(PATH, title="Uploaded with PyImgur") # print(uploaded_image.link) return (uploaded_image.link)
def draw(days: DataFrame, trades=None): """作图""" days['date'] = pd.to_datetime(days['date']) days['date'] = days['date'].apply(lambda x: dates.date2num(x)) # drop the date index from the dataframe & make a copy days_reshape = days.reset_index() days_reshape.drop('volume', axis=1, inplace=True) days_reshape = days_reshape.reindex( columns=['date', 'open', 'high', 'low', 'close']) fig = plt.figure(facecolor='#07000d', figsize=(days.__len__() * 0.1, 10)) ax = plt.subplot2grid((6, 4), (1, 0), rowspan=4, colspan=4) ax.set_facecolor('#07000d') candlestick_ohlc(ax, days_reshape.values, width=.6, colorup='#ff1717', colordown='#53c156') # 添加均线 short_rolling = days_reshape.close.rolling(window=slow_ma).mean() long_rolling = days_reshape.close.rolling(window=fast_ma).mean() SP = len(days_reshape.date.values[fast_ma - 1:]) ax.plot(days_reshape.date.values[-SP:], short_rolling[-SP:], '#e1edf9', label=str(slow_ma) + 'SMA', linewidth=1.5) ax.plot(days_reshape.date.values[-SP:], long_rolling[-SP:], '#4ee6fd', label=str(fast_ma) + 'SMA', linewidth=1.5) # 样式设置 ax.grid(True, color='w') ax.xaxis.set_major_locator( ticker.MaxNLocator(math.floor(days_reshape.__len__() / 22))) ax.xaxis.set_major_formatter(dates.DateFormatter('%Y-%m-%d')) ax.yaxis.label.set_color("w") ax.spines['bottom'].set_color("#5998ff") ax.spines['top'].set_color("#5998ff") ax.spines['left'].set_color("#5998ff") ax.spines['right'].set_color("#5998ff") ax.tick_params(axis='y', colors='w') plt.gca().yaxis.set_major_locator(ticker.MaxNLocator(prune='upper')) ax.tick_params(axis='x', colors='w') ax.set_ylabel('Stock price and Volume') # 1、绘制成交量 volumeMin = 0 ax1v = ax.twinx() ax1v.fill_between(days.date.values, volumeMin, days.volume.values, facecolor='#00ffe8', alpha=.4) ax1v.axes.yaxis.set_ticklabels([]) ax1v.grid(False) # Edit this to 3, so it's a bit larger ax1v.set_ylim(0, 3 * days.volume.values.max()) ax1v.spines['bottom'].set_color("#5998ff") ax1v.spines['top'].set_color("#5998ff") ax1v.spines['left'].set_color("#5998ff") ax1v.spines['right'].set_color("#5998ff") ax1v.tick_params(axis='x', colors='w') ax1v.tick_params(axis='y', colors='w') # 2、绘制RSI maLeg = plt.legend(loc=9, ncol=2, prop={'size': 7}, fancybox=True, borderaxespad=0.) maLeg.get_frame().set_alpha(0.4) textEd = pylab.gca().get_legend().get_texts() pylab.setp(textEd[0:5], color='w') ax0 = plt.subplot2grid((6, 4), (0, 0), sharex=ax, rowspan=1, colspan=4) ax0.set_facecolor('#07000d') rsi = vutil.relative_strength_index(days_reshape, 5)['RSI_5'] rsiCol = '#c1f9f7' posCol = '#386d13' negCol = '#8f2020' ax0.plot(days_reshape.date.values[-SP:], rsi[-SP:], rsiCol, linewidth=1.5) ax0.axhline(70, color=negCol) ax0.axhline(30, color=posCol) ax0.fill_between(days_reshape.date.values[-SP:], rsi[-SP:], 70, where=(rsi[-SP:] >= 70), facecolor=negCol, edgecolor=negCol, alpha=0.5) ax0.fill_between(days_reshape.date.values[-SP:], rsi[-SP:], 30, where=(rsi[-SP:] <= 30), facecolor=posCol, edgecolor=posCol, alpha=0.5) ax0.set_yticks([30, 70]) ax0.yaxis.label.set_color("w") ax0.spines['bottom'].set_color("#5998ff") ax0.spines['top'].set_color("#5998ff") ax0.spines['left'].set_color("#5998ff") ax0.spines['right'].set_color("#5998ff") ax0.tick_params(axis='y', colors='w') ax0.tick_params(axis='x', colors='w') ax0.set_ylabel('RSI') # 2、绘制MACD ax2 = plt.subplot2grid((6, 4), (5, 0), sharex=ax, rowspan=1, colspan=4) ax2.set_facecolor('#07000d') fillcolor = '#00ffe8' nslow = 26 nfast = 12 nema = 9 df = vutil.macd(days_reshape, 12, 26) ema9 = df['MACDsign_12_26'] macd = df['MACD_12_26'] ax2.plot(days_reshape.date.values[-SP:], macd[-SP:], color='#4ee6fd', lw=2) ax2.plot(days_reshape.date.values[-SP:], ema9[-SP:], color='#e1edf9', lw=1) # 红色填充大于0区域、绿色填充小于0区域 ax2.fill_between(days_reshape.date.values[-SP:], macd[-SP:] - ema9[-SP:], 0, where=(macd[-SP:] - ema9[-SP:] > 0), alpha=0.5, facecolor=negCol, edgecolor=negCol) ax2.fill_between(days_reshape.date.values[-SP:], macd[-SP:] - ema9[-SP:], 0, where=(macd[-SP:] - ema9[-SP:] < 0), alpha=0.5, facecolor=posCol, edgecolor=posCol) plt.gca().yaxis.set_major_locator(ticker.MaxNLocator(prune='upper')) ax2.spines['bottom'].set_color("#5998ff") ax2.spines['top'].set_color("#5998ff") ax2.spines['left'].set_color("#5998ff") ax2.spines['right'].set_color("#5998ff") ax2.tick_params(axis='x', colors='w') ax2.tick_params(axis='y', colors='w') plt.ylabel('MACD', color='w') ax2.yaxis.set_major_locator(ticker.MaxNLocator(nbins=5, prune='upper')) for label in ax2.xaxis.get_ticklabels(): label.set_rotation(45) ax2.set_ylabel('MACD') # 增加提示点 plt.suptitle('000001.XSHG', color='w') plt.setp(ax0.get_xticklabels(), visible=False) plt.setp(ax.get_xticklabels(), visible=False) # buy and sell annotate # TODO: 箭头的长度可以根据ATR确定 if trades is not None: for trade in trades.values(): info = '%s,%s,%s' % (trade.datetime.strftime("%Y/%m/%d"), round_to(trade.price, 0.01), trade.volume) if Direction.LONG == trade.direction: ax.annotate(info, xy=(dates.date2num(trade.datetime), trade.price), xycoords='data', color='yellow', bbox=dict(boxstyle="round", fc="none", ec="yellow"), xytext=(0, -40), textcoords='offset points', ha='center', arrowprops=dict(color='yellow', arrowstyle="->")) if Direction.SHORT == trade.direction: ax.annotate(info, xy=(dates.date2num(trade.datetime), trade.price), xycoords='data', color='green', bbox=dict(boxstyle="round", fc="none", ec="green"), xytext=(0, 40), textcoords='offset points', ha='center', arrowprops=dict(color='green', arrowstyle="->")) plt.subplots_adjust(left=.09, bottom=.14, right=.94, top=.95, wspace=.20, hspace=0) plt.show()
dfc = df.copy() dfc['VolumePositive'] = dfc['Open'] < dfc['Adj Close'] #dfc = dfc.dropna() dfc = dfc.reset_index() dfc['Date'] = mdates.date2num(dfc['Date'].astype(dt.date)) from mplfinance.original_flavor import candlestick_ohlc fig = plt.figure(figsize=(14, 7)) ax1 = plt.subplot(2, 1, 1) ax1.plot(df['MA5'], label='MA5') ax1.plot(df['MA200'], label='MA200') candlestick_ohlc(ax1, dfc.values, width=0.5, colorup='g', colordown='r', alpha=1.0) ax1.xaxis_date() ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y')) ax1.grid(True, which='both') ax1.minorticks_on() ax1v = ax1.twinx() colors = dfc.VolumePositive.map({True: 'g', False: 'r'}) ax1v.bar(dfc.Date, dfc['Volume'], color=colors, alpha=0.4) ax1v.axes.yaxis.set_ticklabels([]) ax1v.set_ylim(0, 3 * df.Volume.max()) ax1.set_title('Stock ' + symbol + ' Closing Price') ax1.set_ylabel('Price') ax1.legend(loc='best')
def plot_cols(df, y='fClose', moving_averages=None, vol=False, candle=False, figsize=(16, 8)): """Plot stock data. y can be a list.""" import matplotlib.pyplot as plt from matplotlib import style style.use('ggplot') cols = df.columns df = df.copy() if candle: import mplfinance as mpf from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mdates # Determine if the date column is datetime (it should be) # fClose is the default adjusted closing price ma_list = ['10', '20', '50', '200'] try: if df['date'].dtype != '<M8[ns]': df['date'] = pd.to_datetime(df['date'], infer_datetime_format=True) df['date_keys'] = df['date'] df = df.set_index(keys='date') except KeyError: print('Could not find date column') pass if vol and not candle: fig = plt.figure(figsize=figsize) ax1 = plt.subplot2grid((7, 1), (0, 0), rowspan=4, colspan=1) ax2 = plt.subplot2grid((7, 1), (5, 0), rowspan=2, colspan=1, sharex=ax1) # ax1.plot(df.index, df[y], label='Close') df_index = df.index.get_level_values('date') df.plot(x='date_keys', y='fOpen', label='fOpen', kind='scatter', ax=ax1, color='black') df.plot(x='date_keys', y='fClose', label='fClose', kind='scatter', ax=ax1, color='blue') df.plot(x='date_keys', y='fHigh', label='fHigh', kind='scatter', ax=ax1, color='green') df.plot(x='date_keys', y='fLow', label='fLow', kind='scatter', ax=ax1, color='red') # print(dir(ax1)) if 'volume' in cols: ax2.bar(df.index, df['volume'], label='Volume') elif 'fVolume' in cols: ax2.bar(df.index, df['vol/mil'], label='Volume (in millions)', color='Blue') if moving_averages: ma = moving_averages for m in ma_list: ax1.plot(df.index, df[f"{ma}_{m}"], label=f"{ma.upper()} {m}") elif not vol and not candle: df[y].plot(label='Close', figsize=figsize, grid=True) if moving_averages: ma = moving_averages df[f"{ma}_10"].plot(label=f"{ma.upper()} 10") df[f"{ma}_20"].plot(label=f"{ma.upper()} 20") df[f"{ma}_50"].plot(label=f"{ma.upper()} 50") df[f"{ma}_200"].plot(label=f"{ma.upper()} 200") elif vol and candle: # df_mod = df.reset_index().copy(deep=True) df_ohlc = df[['fOpen', 'fHigh', 'fLow', 'fClose']].copy(deep=True) df_ohlc.reset_index(inplace=True) df_ohlc['date'] = df_ohlc['date'].map(mdates.date2num) fig = plt.figure(figsize=figsize) ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan=4, colspan=1) ax2 = plt.subplot2grid((6, 1), (5, 0), rowspan=1, colspan=1, sharex=ax1) ax1.xaxis_date() candlestick_ohlc(ax1, df_ohlc.values, colorup='g') if moving_averages: ma = moving_averages for m in ma_list: ax1.plot(df.index, df[f"{ma}_{m}"], label=f"{ma.upper()} {m}") # ax2.fill_between(df.index, df['volume'], 0) ax2.bar(df.index, df['volume'], label='Volume') return df_ohlc plt.legend()