交易数据阻力位、支撑位及枢轴点绘图异常问题
K线/收盘价折线图与枢轴点、阻力/支撑位绘图优化
我有一组交易数据,尝试在图表中绘制K线、枢轴点(Pivot Points)以及阻力位、支撑位区间。代码运行无报错,但绘图结果过于紧凑,无法清晰区分各元素。期望生成清晰的图表,也可改用收盘价折线图替代K线。
现有代码
import pandas as pd import numpy as np import math from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mpl_dates import matplotlib.pyplot as plt df = pd.read_csv('data.csv') # 判断支撑位(看涨分型) def is_support(df, i): cond1 = df['low'][i] < df['low'][i-1] cond2 = df['low'][i] < df['low'][i+1] cond3 = df['low'][i+1] < df['low'][i+2] cond4 = df['low'][i-1] < df['low'][i-2] return (cond1 and cond2 and cond3 and cond4) # 判断阻力位(看跌分型) def is_resistance(df, i): cond1 = df['high'][i] > df['high'][i-1] cond2 = df['high'][i] > df['high'][i+1] cond3 = df['high'][i+1] > df['high'][i+2] cond4 = df['high'][i-1] > df['high'][i-2] return (cond1 and cond2 and cond3 and cond4) # 检查价位是否与已有水平位足够远 def is_far_from_level(value, levels, df): ave = np.mean(df['high'] - df['low']) return np.sum([abs(value-level) < ave for _, level in levels]) == 0 # 存储支撑和阻力位 levels = [] for i in range(2, df.shape[0] - 2): if is_support(df, i): low = df['low'][i] if is_far_from_level(low, levels, df): levels.append((i, low)) elif is_resistance(df, i): high = df['high'][i] if is_far_from_level(high, levels, df): levels.append((i, high)) # 转换时间戳格式 df['timestamp'] = pd.to_datetime(df['timestamp']) df['timestamp'] = mpl_dates.date2num(df['timestamp']) # 绘制函数 def plot_all(levels, df): fig, ax = plt.subplots(figsize=(16, 9)) candlestick_ohlc(ax, df.values, width=0.6, colorup='green', colordown='red', alpha=0.8) date_format = mpl_dates.DateFormatter('%d %b %Y') ax.xaxis.set_major_formatter(date_format) for level in levels: plt.hlines(level[1], xmin=df['timestamp'][level[0]], xmax=max(df['timestamp']), colors='blue', linestyle='--') plt.show() # 计算枢轴点 pivots = [] max_list = [] min_list = [] for i in range(5, len(df)-5): # 取9根K线的区间 high_range = df['high'][i-5:i+4] current_max = high_range.max() if current_max not in max_list: max_list = [] max_list.append(current_max) if len(max_list)==5 and is_far_from_level(current_max,pivots,df): pivots.append((high_range.idxmax(), current_max)) low_range = df['low'][i-5:i+5] current_min = low_range.min() if current_min not in min_list: min_list = [] min_list.append(current_min) if len(min_list)==5 and is_far_from_level(current_min,pivots,df): pivots.append((low_range.idxmin(), current_min)) plot_all(pivots, df)
数据样本
timestamp,open,high,low,close 19/05/23 9:16,344.2,361.7,333.35,347.1 19/05/23 9:17,352.5,362.5,343.7,358.85 19/05/23 9:18,364.6,373.05,358.6,369 19/05/23 9:19,364.3,370.2,350.05,366.3 19/05/23 9:20,357.8,365.25,356.55,357.65 19/05/23 9:21,379.6,379.75,363.5,378.9 19/05/23 9:22,365.9,379.8,357.65,359.45 19/05/23 9:23,349.9,361.5,348.35,357.1 19/05/23 9:24,362.6,367.35,355.4,362.35 19/05/23 9:25,353.6,360.4,345,348.15 19/05/23 9:26,339.2,350.05,338.1,342.6 19/05/23 9:27,346.7,351.25,334.9,344.15 19/05/23 9:28,342.9,346.95,335.55,336.2 19/05/23 9:29,335.8,344.9,332.25,341.7 19/05/23 9:30,342.4,348.75,334.75,343.65 19/05/23 9:31,354.7,357.5,344.15,354.65 19/05/23 9:32,360.7,367.5,354.7,358.6 19/05/23 9:33,345.3,360.2,344.85,351.65 19/05/23 9:34,358,363.95,350.95,356.9 19/05/23 9:35,366.2,367.05,356.5,358.9 19/05/23 9:36,359.4,371.75,359.35,371 19/05/23 9:37,399.5,402.85,364.85,393.75
优化后的解决方案
方案1:优化K线图布局与可读性
调整图表元素样式、添加标注,解决紧凑问题:
import pandas as pd import numpy as np from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mpl_dates import matplotlib.pyplot as plt df = pd.read_csv('data.csv') # 判断支撑位(看涨分型) def is_support(df, i): cond1 = df['low'][i] < df['low'][i-1] cond2 = df['low'][i] < df['low'][i+1] cond3 = df['low'][i+1] < df['low'][i+2] cond4 = df['low'][i-1] < df['low'][i-2] return (cond1 and cond2 and cond3 and cond4) # 判断阻力位(看跌分型) def is_resistance(df, i): cond1 = df['high'][i] > df['high'][i-1] cond2 = df['high'][i] > df['high'][i+1] cond3 = df['high'][i+1] > df['high'][i+2] cond4 = df['high'][i-1] > df['high'][i-2] return (cond1 and cond2 and cond3 and cond4) # 检查价位是否与已有水平位足够远 def is_far_from_level(value, levels, df): ave = np.mean(df['high'] - df['low']) return np.sum([abs(value-level) < ave for _, level in levels]) == 0 # 存储支撑和阻力位(区分类型) levels = [] for i in range(2, df.shape[0] - 2): if is_support(df, i): low = df['low'][i] if is_far_from_level(low, levels, df): levels.append((i, low, 'support')) elif is_resistance(df, i): high = df['high'][i] if is_far_from_level(high, levels, df): levels.append((i, high, 'resistance')) # 转换时间戳格式(指定解析规则) df['timestamp'] = pd.to_datetime(df['timestamp'], format='%d/%m/%y %H:%M') df['timestamp'] = mpl_dates.date2num(df['timestamp']) # 计算枢轴点(区分类型) pivots = [] max_list = [] min_list = [] for i in range(5, len(df)-5): high_range = df['high'][i-5:i+4] current_max = high_range.max() if current_max not in max_list: max_list = [] max_list.append(current_max) if len(max_list)==5 and is_far_from_level(current_max,pivots,df): pivots.append((high_range.idxmax(), current_max, 'resistance')) low_range = df['low'][i-5:i+5] current_min = low_range.min() if current_min not in min_list: min_list = [] min_list.append(current_min) if len(min_list)==5 and is_far_from_level(current_min,pivots,df): pivots.append((low_range.idxmin(), current_min, 'support')) # 合并所有水平位 all_levels = levels + pivots # 优化绘图函数 def plot_all(levels, df): fig, ax = plt.subplots(figsize=(18, 10)) # 绘制K线,减小宽度避免拥挤 candlestick_ohlc(ax, df.values, width=0.3, colorup='#00ff00', colordown='#ff0000', alpha=0.7) # 设置时间轴格式,显示时分 date_format = mpl_dates.DateFormatter('%d/%m %H:%M') ax.xaxis.set_major_formatter(date_format) plt.xticks(rotation=45) # 绘制支撑/阻力线,区分颜色并添加标注 for level in levels: x_pos = df['timestamp'][level[0]] price = level[1] line_color = '#006600' if level[2] == 'support' else '#cc0000' # 绘制水平线 ax.hlines(price, xmin=x_pos, xmax=df['timestamp'].max(), colors=line_color, linestyle='--', linewidth=1.5, alpha=0.8) # 添加价位标注 ax.text(x_pos, price + 1, f'{price:.2f}', fontsize=9, color=line_color, ha='left', va='bottom') # 添加图表标题和坐标轴标签 ax.set_title('交易数据K线图 - 支撑/阻力位与枢轴点', fontsize=14, pad=20) ax.set_xlabel('时间', fontsize=12) ax.set_ylabel('价格', fontsize=12) # 调整布局,防止标签被截断 plt.tight_layout() plt.grid(axis='y', linestyle='--', alpha=0.3) plt.show() plot_all(all_levels, df)
方案2:切换为收盘价折线图(更简洁)
如果K线仍显复杂,改用折线图展示收盘价,搭配高低点标记:
import pandas as pd import numpy as np import matplotlib.dates as mpl_dates import matplotlib.pyplot as plt df = pd.read_csv('data.csv') # 判断支撑位(看涨分型) def is_support(df, i): cond1 = df['low'][i] < df['low'][i-1] cond2 = df['low'][i] < df['low'][i+1] cond3 = df['low'][i+1] < df['low'][i+2] cond4 = df['low'][i-1] < df['low'][i-2] return (cond1 and cond2 and cond3 and cond4) # 判断阻力位(看跌分型) def is_resistance(df, i): cond1 = df['high'][i] > df['high'][i-1] cond2 = df['high'][i] > df['high'][i+1] cond3 = df['high'][i+1] > df['high'][i+2] cond4 = df['high'][i-1] > df['high'][i-2] return (cond1 and cond2 and cond3 and cond4) # 检查价位是否与已有水平位足够远 def is_far_from_level(value, levels, df): ave = np.mean(df['high'] - df['low']) return np.sum([abs(value-level) < ave for _, level in levels]) == 0 # 存储支撑和阻力位(区分类型) levels = [] for i in range(2, df.shape[0] - 2): if is_support(df, i): low = df['low'][i] if is_far_from_level(low, levels, df): levels.append((i, low, 'support')) elif is_resistance(df, i): high = df['high'][i] if is_far_from_level(high, levels, df): levels.append((i, high, 'resistance')) # 转换时间戳格式(指定解析规则) df['timestamp'] = pd.to_datetime(df['timestamp'], format='%d/%m/%y %H:%M') df['timestamp_num'] = mpl_dates.date2num(df['timestamp']) # 计算枢轴点(区分类型) pivots = [] max_list = [] min_list = [] for i in range(5, len(df)-5): high_range = df['high'][i-5:i+4] current_max = high_range.max() if current_max not in max_list: max_list = [] max_list.append(current_max) if len(max_list)==5 and is_far_from_level(current_max,pivots,df): pivots.append((high_range.idxmax(), current_max, 'resistance')) low_range = df['low'][i-5:i+5] current_min = low_range.min() if current_min not in min_list: min_list = [] min_list.append(current_min) if len(min_list)==5 and is_far_from_level(current_min,pivots,df): pivots.append((low_range.idxmin(), current_min, 'support')) # 合并所有水平位 all_levels = levels + pivots # 绘制收盘价折线图 def plot_close_with_levels(levels, df): fig, ax = plt.subplots(figsize=(18, 10)) # 绘制收盘价折线 ax.plot(df['timestamp_num'], df['close'], color='#0066cc', linewidth=2, label='收盘价') # 标记支撑/阻力点 for level in levels: x_pos = df['timestamp_num'][level[0]] price = level[1] marker_color = '#006600' if level[2] == 'support' else '#cc0000' marker_style = '^' if level[2] == 'support' else 'v' # 标记关键点位 ax.scatter(x_pos, price, color=marker_color, marker=marker_style, s=100, zorder=5
相关产品推荐
相关产品推荐

