def draw_bars(self, dataframe): what = 'Volume' vmax = dataframe[what].max() if vmax == 0: return candle_left = 0 candle_right = len(dataframe) + self.candlesrightfree color = (192, 192, 192) for index in range(0, len(dataframe)): row = dataframe.iloc[index] # Draw body x1 = index x2 = index + (1 - self.candlesmargin) start_point = (int( utils.translate(x1, candle_left, candle_right, self.left, self.right)), int( utils.translate(row[what], 0, vmax, self.bottom, self.top))) end_point = (int( utils.translate(x2, candle_left, candle_right, self.left, self.right)), self.bottom) thickness = -1 cv2.rectangle(self.canvas, start_point, end_point, color, thickness)
def find_trendlines(dataframe, clearance=5, what=SUPPORTS): '''Calculates trendlines for the given dataframe. :param dataframe: Dataframe containing the price data. :param clearance: Nr of candles to clear on both sides of the peak :param what: Selects whether SUPPORTS or RESISTS will be returned. :type dataframe: pandas :type clearance: int :type what: const :returns: lines :rtype: array .. note:: The dataframe must contain the columns 'High' and 'Low'. .. note:: The returned array of lines are in the format (x1,y1,x2,y2) where x1 and x2 are indexes into the dataframe and Y1 and Y2 are actual price points. ''' results = [] if what == SUPPORTS: peaks = find_peaks(dataframe, clearance=clearance, method=MODERN, what=BOTTOMS) if what == RESISTS: peaks = find_peaks(dataframe, clearance=clearance, method=MODERN, what=TOPS) for i in range(0, len(peaks)): for j in range(0, len(peaks)): if j <= i: continue x1 = peaks[i] x2 = peaks[j] reach = int(x2 + ((x2 - x1) * trendline_reach)) if reach < len(dataframe): continue if what == SUPPORTS: y1 = dataframe['Low'].iloc[x1] y2 = dataframe['Low'].iloc[x2] if what == RESISTS: y1 = dataframe['High'].iloc[x1] y2 = dataframe['High'].iloc[x2] valid = True for k in range(i, len(dataframe)): y3 = utils.translate(k, x1, x2, y1, y2) if what == SUPPORTS: if dataframe['Low'].iloc[k] < y3: valid = False if what == RESISTS: if dataframe['High'].iloc[k] > y3: valid = False if valid is True: results.append((x1, y1, k, y3)) return results
def main(): # We download the S&P 500 df = yf.download('^GSPC', start='2019-06-01', end='2020-01-01', progress=False) # Create a graph and clear it graph = dt.Graph(width=1280, height=1280) graph.clear() graph.draw_candles(df) lines = [] lines += [ta.find_regression_line(df)] # This wil be all values above and below the regression line above = [] below = [] # Extract the parameters of the regression line x1, y1, x2, y2 = lines[0] for x in range(x1, x2): # Go through the entire dataframe y = ut.translate(x, x1, x2, y1, y2) # Get the current height of the regression line above.append(df['High'].iloc[x] - y) below.append(df['Low'].iloc[x] - y) above.sort(reverse=True) below.sort(reverse=False) top_max_line = (x1, y1+above[0], x2, y2+above[0]) bottom_max_line = (x1, y1+below[0], x2, y2+below[0]) lines += [top_max_line, bottom_max_line] # Method 1, have 20% of candles in top zone and 20% in bottom zone # nr_candles = int(len(df)*0.2) # top_safe_line = (x1, y1+above[nr_candles], x2, y2+above[nr_candles]) # top_bottom_line = (x1, y1+below[nr_candles], x2, y2+below[nr_candles]) # lines += [top_safe_line, top_bottom_line] # Method 2, have 30% of price in top zone and 30% in bottom zone # top_safe_line = (x1, y1+above[0]*0.7, x2, y2+above[0]*0.7) # top_bottom_line = (x1, y1+below[0]*0.7, x2, y2+below[0]*0.7) # lines += [top_safe_line, top_bottom_line] # Draw the lines graph.draw_lines(df, lines) # Draw the line # Show the finished graph cv2.imshow('Technical analysis', graph.canvas) cv2.waitKey(0) return
def draw_lines(self, dataframe, lines=[]): if len(lines) == 0: return candle_bottom = dataframe['Low'].min() candle_top = dataframe['High'].max() height_diff = (candle_top - candle_bottom) * self.heightmargin candle_bottom -= height_diff candle_top += height_diff candle_left = 0 candle_right = len(dataframe) + self.candlesrightfree color = (192, 192, 192) for x1, y1, x2, y2 in lines: # Draw line start_point = (int( utils.translate(x1, candle_left, candle_right, self.left, self.right)), int( utils.translate(y1, candle_bottom, candle_top, self.bottom, self.top))) end_point = (int( utils.translate(x2, candle_left, candle_right, self.left, self.right)), int( utils.translate(y2, candle_bottom, candle_top, self.bottom, self.top))) thickness = 1 cv2.line(self.canvas, start_point, end_point, color, thickness) lable = str(y2)[:7] end_point = (int( utils.translate(x2 + 1, candle_left, candle_right, self.left, self.right)), int( utils.translate(y2, candle_bottom, candle_top, self.bottom, self.top)) + 3) cv2.putText(self.canvas, lable, end_point, cv2.FONT_HERSHEY_SIMPLEX, 0.35, (255, 255, 255), 1, cv2.LINE_AA)
def draw_candles(self, dataframe, greens=[], reds=[]): candle_bottom = dataframe['Low'].min() candle_top = dataframe['High'].max() height_diff = (candle_top - candle_bottom) * self.heightmargin candle_bottom -= height_diff candle_top += height_diff candle_left = 0 candle_right = len(dataframe) + self.candlesrightfree # Draw candles for index in range(0, len(dataframe)): row = dataframe.iloc[index] # Color color = (192, 192, 192) if index in greens: color = (0, 192, 0) if index in reds: color = (0, 0, 192) # Body high and low if row['Open'] > row['Close']: body_high = row['Open'] body_low = row['Close'] else: body_high = row['Close'] body_low = row['Open'] # Draw body top line x1 = index + (1 - self.candlesmargin) / 2 x2 = x1 start_point = (int( utils.translate(x1, candle_left, candle_right, self.left, self.right)), int( utils.translate(row['High'], candle_bottom, candle_top, self.bottom, self.top))) end_point = (int( utils.translate(x2, candle_left, candle_right, self.left, self.right)), int( utils.translate(body_high, candle_bottom, candle_top, self.bottom, self.top))) thickness = 1 cv2.line(self.canvas, start_point, end_point, color, thickness) # Draw body bottom line x1 = index + (1 - self.candlesmargin) / 2 x2 = x1 start_point = (int( utils.translate(x1, candle_left, candle_right, self.left, self.right)), int( utils.translate(body_low, candle_bottom, candle_top, self.bottom, self.top))) end_point = (int( utils.translate(x2, candle_left, candle_right, self.left, self.right)), int( utils.translate(row['Low'], candle_bottom, candle_top, self.bottom, self.top))) thickness = 1 cv2.line(self.canvas, start_point, end_point, color, thickness) # Draw body x1 = index x2 = index + (1 - self.candlesmargin) start_point = (int( utils.translate(x1, candle_left, candle_right, self.left, self.right)), int( utils.translate(row['Open'], candle_bottom, candle_top, self.bottom, self.top))) end_point = (int( utils.translate(x2, candle_left, candle_right, self.left, self.right)), int( utils.translate(row['Close'], candle_bottom, candle_top, self.bottom, self.top))) thickness = -1 cv2.rectangle(self.canvas, start_point, end_point, color, thickness)
def find_peaks(dataframe, clearance=5, method=CLASSIC, what=TOPS): '''Calculates peaks for the given dataframe. :param dataframe: Dataframe containing the price data. :param clearance: Nr of candles to clear on both sides of the peak :param method: User CLASSIC or MODERN style for peak detection :param what: Selects whether TOPS or BOTTOMS will be returned. :type dataframe: pandas :type clearance: int :type what: const :returns: indexes :rtype: array .. note:: The dataframe must contain the columns 'High' and 'Low'. .. note:: CLASSIC peak stick out on a horizontal level. MODERN peaks also consider the trend of surrounding candles. ''' result = [] if what == TOPS: element = 'High' if what == BOTTOMS: element = 'Low' for i in range(clearance, len(dataframe) - clearance): target = dataframe[element].iloc[i] isTop = True if method == CLASSIC: for j in range(1, clearance + 1): left = dataframe[element].iloc[i - j] right = dataframe[element].iloc[i + j] if what == TOPS: thresHold = max(left, right) if target <= thresHold: isTop = False break if what == BOTTOMS: thresHold = min(left, right) if target >= thresHold: isTop = False break if method == MODERN: left = dataframe[element].iloc[i - 1] right = dataframe[element].iloc[i + 1] if what == TOPS: if target <= (left + right) / 2: # Quick optimization continue if what == BOTTOMS: if target >= (left + right) / 2: # Quick optimization continue for k in range(i - clearance, i + clearance + 1): if k == i: continue elif k > i: x = i y = k elif k < i: x = k y = i isTop = True left = dataframe[element].iloc[x] right = dataframe[element].iloc[y] for l in range(i - clearance, i + clearance + 1): if l == i or l == k: continue pp = dataframe[element].iloc[l] t = utils.translate(l, x, y, left, right) if what == TOPS: if pp >= t: isTop = False break if what == BOTTOMS: if pp <= t: isTop = False break if isTop is True: break if isTop is True: result.append(i) return result