You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

交易数据阻力位、支撑位及枢轴点绘图异常问题

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
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 02:57:04