用Python构建筹码分布分析工具从数据估算到交易决策当你在交易软件上看到那些五彩斑斓的K线图时是否曾好奇过背后隐藏的市场情绪传统的技术分析往往只关注价格走势却忽略了另一个关键维度——市场参与者的持仓成本分布。这就是筹码分析的价值所在它能够揭示不同价格区间上投资者的盈亏状况为我们提供更全面的市场视角。1. 理解筹码分布的核心逻辑筹码分布分析的核心在于估算市场上投资者在不同价格区间的持仓比例。由于我们无法获取每个投资者的实际持仓数据只能通过成交量、换手率等公开信息进行合理估算。1.1 筹码分布的基本原理假设某只股票总流通量为1000万股第一天平均成交价为10元换手率为0%第二天换手率为20%平均成交价为11元第三天换手率为30%平均成交价为12元那么第三天的筹码分布计算如下价格区间计算公式持仓量(万股)10元1000×(1-0.2)×(1-0.3)56011元1000×0.2×(1-0.3)14012元1000×0.3300这种估算方法基于一个合理假设新成交的筹码会替代部分旧筹码而未被替代的旧筹码则继续保留在原价格区间。1.2 获利盘比例的计算获利盘比例是指在当前价格下持仓成本低于当前价格的筹码占总筹码的比例。计算这个比例需要确定当前价格汇总所有低于当前价格的筹码量计算其占总筹码的比例def calculate_profit_ratio(chip_distribution, current_price): 计算获利盘比例 参数: chip_distribution -- 字典键为价格值为对应持仓量 current_price -- 当前价格 返回: 获利盘比例(0-1之间) total_chips sum(chip_distribution.values()) profitable_chips sum(amount for price, amount in chip_distribution.items() if price current_price) return profitable_chips / total_chips if total_chips 0 else 02. 构建Python筹码分析工具现在让我们将这些理论转化为实际的Python工具。我们将使用pandas进行数据处理matplotlib进行可视化。2.1 数据准备与预处理首先需要获取以下数据历史成交量历史成交额换手率数据import pandas as pd import numpy as np import matplotlib.pyplot as plt def prepare_data(stock_code, start_date, end_date): 准备基础数据 参数: stock_code -- 股票代码 start_date -- 开始日期 end_date -- 结束日期 返回: 包含成交量、成交额、换手率的DataFrame # 这里假设我们已经通过某种API获取了原始数据 raw_data get_market_data(stock_code, start_date, end_date) # 计算平均成交价格 raw_data[avg_price] raw_data[amount] / raw_data[volume] # 处理缺失值和异常值 data raw_data[raw_data[volume] 0].copy() data[turnover] data[turnover].fillna(0) return data2.2 筹码分布计算实现基于前面的理论我们可以实现筹码分布的计算def calculate_chip_distribution(data): 计算每日的筹码分布 参数: data -- 包含成交量、换手率等信息的DataFrame 返回: 包含每日筹码分布的字典 chip_distributions {} total_shares 1.0 # 假设总流通量为1(比例表示) for i, row in data.iterrows(): date row.name avg_price row[avg_price] turnover row[turnover] if i 0: # 第一天所有筹码都在当日平均价 chip_distributions[date] {avg_price: total_shares} else: # 获取前一天的筹码分布 prev_date data.index[i-1] prev_dist chip_distributions[prev_date].copy() # 计算新筹码分布 new_dist {} for price, amount in prev_dist.items(): new_dist[price] amount * (1 - turnover) # 添加今日新筹码 new_dist[avg_price] new_dist.get(avg_price, 0) total_shares * turnover # 存储结果 chip_distributions[date] new_dist return chip_distributions注意实际应用中总流通量应该使用实际的流通股本数据。这里使用1.0是为了简化计算结果表示的是比例而非绝对数量。3. 高级分析与可视化有了基础的筹码分布数据后我们可以进行更深入的分析和可视化。3.1 动态获利盘比例分析我们可以计算每日的获利盘比例并观察其与价格走势的关系def analyze_profit_ratio(chip_distributions, close_prices): 分析每日获利盘比例 参数: chip_distributions -- 每日筹码分布字典 close_prices -- 收盘价Series 返回: 包含每日获利盘比例的Series profit_ratios [] for date, dist in chip_distributions.items(): close_price close_prices[date] profit_ratio calculate_profit_ratio(dist, close_price) profit_ratios.append(profit_ratio) return pd.Series(profit_ratios, indexclose_prices.index)3.2 筹码分布热力图为了直观展示筹码分布随时间的变化我们可以创建热力图def plot_chip_heatmap(chip_distributions, price_bins20): 绘制筹码分布热力图 参数: chip_distributions -- 每日筹码分布字典 price_bins -- 价格区间数量 # 准备数据 all_dates sorted(chip_distributions.keys()) all_prices [price for dist in chip_distributions.values() for price in dist.keys()] # 确定价格区间 min_price min(all_prices) max_price max(all_prices) bin_edges np.linspace(min_price, max_price, price_bins1) # 初始化热力图数据 heatmap_data np.zeros((len(all_dates), price_bins)) for i, date in enumerate(all_dates): dist chip_distributions[date] for price, amount in dist.items(): # 确定价格所属的区间 bin_idx np.digitize(price, bin_edges) - 1 bin_idx max(0, min(bin_idx, price_bins-1)) heatmap_data[i, bin_idx] amount # 绘制热力图 plt.figure(figsize(12, 8)) plt.imshow(heatmap_data.T, aspectauto, cmaphot, extent[0, len(all_dates), min_price, max_price], originlower) plt.colorbar(label筹码密度) plt.xlabel(交易日) plt.ylabel(价格区间) plt.title(筹码分布热力图) # 调整x轴刻度 tick_step max(1, len(all_dates) // 10) plt.xticks(np.arange(0, len(all_dates), tick_step), [all_dates[i].strftime(%Y-%m-%d) for i in range(0, len(all_dates), tick_step)], rotation45) plt.tight_layout() plt.show()4. 多指标融合与交易策略单纯的筹码分析可能不够全面我们需要将其与其他技术指标结合使用。4.1 筹码与成交量结合分析成交量是验证筹码分布变化的重要指标def analyze_volume_with_chips(data, chip_distributions): 分析成交量与筹码变化的关系 参数: data -- 原始数据DataFrame chip_distributions -- 每日筹码分布字典 返回: 包含分析结果的DataFrame result pd.DataFrame(indexdata.index) result[volume] data[volume] result[price] data[avg_price] # 计算每日筹码变化量 chip_changes [] prev_dist None for date, dist in chip_distributions.items(): if prev_dist is None: chip_changes.append(0) else: # 计算筹码变化总量 change sum(abs(dist.get(p,0) - prev_dist.get(p,0)) for p in set(dist)|set(prev_dist)) chip_changes.append(change) prev_dist dist result[chip_change] chip_changes # 计算筹码变化与成交量的比率 result[chip_volume_ratio] result[chip_change] / result[volume] return result4.2 构建综合交易信号结合筹码分析、均线和成交量我们可以构建更可靠的交易信号def generate_trading_signals(data, chip_distributions, short_window5, long_window20): 生成综合交易信号 参数: data -- 原始数据DataFrame chip_distributions -- 每日筹码分布字典 short_window -- 短期均线窗口 long_window -- 长期均线窗口 返回: 包含交易信号的DataFrame signals pd.DataFrame(indexdata.index) signals[price] data[avg_price] # 计算均线 signals[short_ma] signals[price].rolling(windowshort_window).mean() signals[long_ma] signals[price].rolling(windowlong_window).mean() # 计算获利盘比例 profit_ratios analyze_profit_ratio(chip_distributions, signals[price]) signals[profit_ratio] profit_ratios # 计算筹码稳定性指标 chip_stability [] prev_dist None for date, dist in chip_distributions.items(): if prev_dist is None: chip_stability.append(0) else: # 计算筹码分布的变化程度 change sum(abs(dist.get(p,0) - prev_dist.get(p,0)) for p in set(dist)|set(prev_dist)) chip_stability.append(1 - change) prev_dist dist signals[chip_stability] chip_stability # 生成交易信号 signals[signal] 0 # 条件1: 短期均线上穿长期均线 signals.loc[signals[short_ma] signals[long_ma], signal] 1 # 条件2: 获利盘比例在合理区间(30%-70%) signals.loc[(signals[profit_ratio] 0.3) (signals[profit_ratio] 0.7), signal] 1 # 条件3: 筹码稳定性高于阈值 signals.loc[signals[chip_stability] 0.7, signal] 1 # 综合信号: 当满足至少2个条件时产生交易信号 signals[final_signal] signals[signal] 2 return signals提示实际应用中应该在不同的市场环境下测试和优化这些参数和条件以找到最适合特定股票或市场的设置。
别再只看K线了!用Python自制筹码分布与获利盘分析工具,辅助你的交易决策
用Python构建筹码分布分析工具从数据估算到交易决策当你在交易软件上看到那些五彩斑斓的K线图时是否曾好奇过背后隐藏的市场情绪传统的技术分析往往只关注价格走势却忽略了另一个关键维度——市场参与者的持仓成本分布。这就是筹码分析的价值所在它能够揭示不同价格区间上投资者的盈亏状况为我们提供更全面的市场视角。1. 理解筹码分布的核心逻辑筹码分布分析的核心在于估算市场上投资者在不同价格区间的持仓比例。由于我们无法获取每个投资者的实际持仓数据只能通过成交量、换手率等公开信息进行合理估算。1.1 筹码分布的基本原理假设某只股票总流通量为1000万股第一天平均成交价为10元换手率为0%第二天换手率为20%平均成交价为11元第三天换手率为30%平均成交价为12元那么第三天的筹码分布计算如下价格区间计算公式持仓量(万股)10元1000×(1-0.2)×(1-0.3)56011元1000×0.2×(1-0.3)14012元1000×0.3300这种估算方法基于一个合理假设新成交的筹码会替代部分旧筹码而未被替代的旧筹码则继续保留在原价格区间。1.2 获利盘比例的计算获利盘比例是指在当前价格下持仓成本低于当前价格的筹码占总筹码的比例。计算这个比例需要确定当前价格汇总所有低于当前价格的筹码量计算其占总筹码的比例def calculate_profit_ratio(chip_distribution, current_price): 计算获利盘比例 参数: chip_distribution -- 字典键为价格值为对应持仓量 current_price -- 当前价格 返回: 获利盘比例(0-1之间) total_chips sum(chip_distribution.values()) profitable_chips sum(amount for price, amount in chip_distribution.items() if price current_price) return profitable_chips / total_chips if total_chips 0 else 02. 构建Python筹码分析工具现在让我们将这些理论转化为实际的Python工具。我们将使用pandas进行数据处理matplotlib进行可视化。2.1 数据准备与预处理首先需要获取以下数据历史成交量历史成交额换手率数据import pandas as pd import numpy as np import matplotlib.pyplot as plt def prepare_data(stock_code, start_date, end_date): 准备基础数据 参数: stock_code -- 股票代码 start_date -- 开始日期 end_date -- 结束日期 返回: 包含成交量、成交额、换手率的DataFrame # 这里假设我们已经通过某种API获取了原始数据 raw_data get_market_data(stock_code, start_date, end_date) # 计算平均成交价格 raw_data[avg_price] raw_data[amount] / raw_data[volume] # 处理缺失值和异常值 data raw_data[raw_data[volume] 0].copy() data[turnover] data[turnover].fillna(0) return data2.2 筹码分布计算实现基于前面的理论我们可以实现筹码分布的计算def calculate_chip_distribution(data): 计算每日的筹码分布 参数: data -- 包含成交量、换手率等信息的DataFrame 返回: 包含每日筹码分布的字典 chip_distributions {} total_shares 1.0 # 假设总流通量为1(比例表示) for i, row in data.iterrows(): date row.name avg_price row[avg_price] turnover row[turnover] if i 0: # 第一天所有筹码都在当日平均价 chip_distributions[date] {avg_price: total_shares} else: # 获取前一天的筹码分布 prev_date data.index[i-1] prev_dist chip_distributions[prev_date].copy() # 计算新筹码分布 new_dist {} for price, amount in prev_dist.items(): new_dist[price] amount * (1 - turnover) # 添加今日新筹码 new_dist[avg_price] new_dist.get(avg_price, 0) total_shares * turnover # 存储结果 chip_distributions[date] new_dist return chip_distributions注意实际应用中总流通量应该使用实际的流通股本数据。这里使用1.0是为了简化计算结果表示的是比例而非绝对数量。3. 高级分析与可视化有了基础的筹码分布数据后我们可以进行更深入的分析和可视化。3.1 动态获利盘比例分析我们可以计算每日的获利盘比例并观察其与价格走势的关系def analyze_profit_ratio(chip_distributions, close_prices): 分析每日获利盘比例 参数: chip_distributions -- 每日筹码分布字典 close_prices -- 收盘价Series 返回: 包含每日获利盘比例的Series profit_ratios [] for date, dist in chip_distributions.items(): close_price close_prices[date] profit_ratio calculate_profit_ratio(dist, close_price) profit_ratios.append(profit_ratio) return pd.Series(profit_ratios, indexclose_prices.index)3.2 筹码分布热力图为了直观展示筹码分布随时间的变化我们可以创建热力图def plot_chip_heatmap(chip_distributions, price_bins20): 绘制筹码分布热力图 参数: chip_distributions -- 每日筹码分布字典 price_bins -- 价格区间数量 # 准备数据 all_dates sorted(chip_distributions.keys()) all_prices [price for dist in chip_distributions.values() for price in dist.keys()] # 确定价格区间 min_price min(all_prices) max_price max(all_prices) bin_edges np.linspace(min_price, max_price, price_bins1) # 初始化热力图数据 heatmap_data np.zeros((len(all_dates), price_bins)) for i, date in enumerate(all_dates): dist chip_distributions[date] for price, amount in dist.items(): # 确定价格所属的区间 bin_idx np.digitize(price, bin_edges) - 1 bin_idx max(0, min(bin_idx, price_bins-1)) heatmap_data[i, bin_idx] amount # 绘制热力图 plt.figure(figsize(12, 8)) plt.imshow(heatmap_data.T, aspectauto, cmaphot, extent[0, len(all_dates), min_price, max_price], originlower) plt.colorbar(label筹码密度) plt.xlabel(交易日) plt.ylabel(价格区间) plt.title(筹码分布热力图) # 调整x轴刻度 tick_step max(1, len(all_dates) // 10) plt.xticks(np.arange(0, len(all_dates), tick_step), [all_dates[i].strftime(%Y-%m-%d) for i in range(0, len(all_dates), tick_step)], rotation45) plt.tight_layout() plt.show()4. 多指标融合与交易策略单纯的筹码分析可能不够全面我们需要将其与其他技术指标结合使用。4.1 筹码与成交量结合分析成交量是验证筹码分布变化的重要指标def analyze_volume_with_chips(data, chip_distributions): 分析成交量与筹码变化的关系 参数: data -- 原始数据DataFrame chip_distributions -- 每日筹码分布字典 返回: 包含分析结果的DataFrame result pd.DataFrame(indexdata.index) result[volume] data[volume] result[price] data[avg_price] # 计算每日筹码变化量 chip_changes [] prev_dist None for date, dist in chip_distributions.items(): if prev_dist is None: chip_changes.append(0) else: # 计算筹码变化总量 change sum(abs(dist.get(p,0) - prev_dist.get(p,0)) for p in set(dist)|set(prev_dist)) chip_changes.append(change) prev_dist dist result[chip_change] chip_changes # 计算筹码变化与成交量的比率 result[chip_volume_ratio] result[chip_change] / result[volume] return result4.2 构建综合交易信号结合筹码分析、均线和成交量我们可以构建更可靠的交易信号def generate_trading_signals(data, chip_distributions, short_window5, long_window20): 生成综合交易信号 参数: data -- 原始数据DataFrame chip_distributions -- 每日筹码分布字典 short_window -- 短期均线窗口 long_window -- 长期均线窗口 返回: 包含交易信号的DataFrame signals pd.DataFrame(indexdata.index) signals[price] data[avg_price] # 计算均线 signals[short_ma] signals[price].rolling(windowshort_window).mean() signals[long_ma] signals[price].rolling(windowlong_window).mean() # 计算获利盘比例 profit_ratios analyze_profit_ratio(chip_distributions, signals[price]) signals[profit_ratio] profit_ratios # 计算筹码稳定性指标 chip_stability [] prev_dist None for date, dist in chip_distributions.items(): if prev_dist is None: chip_stability.append(0) else: # 计算筹码分布的变化程度 change sum(abs(dist.get(p,0) - prev_dist.get(p,0)) for p in set(dist)|set(prev_dist)) chip_stability.append(1 - change) prev_dist dist signals[chip_stability] chip_stability # 生成交易信号 signals[signal] 0 # 条件1: 短期均线上穿长期均线 signals.loc[signals[short_ma] signals[long_ma], signal] 1 # 条件2: 获利盘比例在合理区间(30%-70%) signals.loc[(signals[profit_ratio] 0.3) (signals[profit_ratio] 0.7), signal] 1 # 条件3: 筹码稳定性高于阈值 signals.loc[signals[chip_stability] 0.7, signal] 1 # 综合信号: 当满足至少2个条件时产生交易信号 signals[final_signal] signals[signal] 2 return signals提示实际应用中应该在不同的市场环境下测试和优化这些参数和条件以找到最适合特定股票或市场的设置。