量化分析:股票的筹码分布和获利比例

news/2024/12/15 6:34:45/

筹码分布

筹码分布是股票分析里面的一个比较简单的部分,通过查看筹码的分布图形,判断当前的股票的压力的指数,通过查看获利的比例来计算有多少人愿意出,有多少人愿意保持价格

目前的很多工具也是可以直接去查看的,但是因为可能需要直接计算多个股票的筹码分布和历史分布,所以我们需要使用的代码来进行一些量化计算,当然需要获取一些数据,这个大家可以依靠自己的数据的接口来获取

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from typing import Dict, List, Tuple
import tushare as ts#plt字体
plt.rcParams['font.family'] = ['SimHei']
def prepare_data(df: pd.DataFrame,latest_factor:float) -> pd.DataFrame:"""预处理 tushare 数据- vol: 成交量(手)需要转换为股数- close_x: 收盘价- adj_factor: 复权因子"""data = df.copy()# 将成交量从手转换为股data['volume'] = data['vol'] * 100# 计算复权后的收盘价#latest_factor = data['adj_factor'].iloc[-1]data['adj_close'] = data['close_x'] * data['adj_factor'] / latest_factor# 确保日期格式正确data['trade_date'] = pd.to_datetime(data['trade_date'])return dataclass ChipDistribution:def __init__(self):self.distribution: Dict[float, float] = {}self.fifo_queue: List[Tuple[float, float]] = []def adjust_price_and_volume(self, price: float, volume: float, old_factor: float, new_factor: float) -> Tuple[float, float]:"""同时调整价格和成交量"""ratio = new_factor / old_factornew_price = price * rationew_volume = volume / ratioreturn new_price, new_volumedef adjust_distribution(self, old_factor: float, new_factor: float) -> None:"""调整整个分布的价格和成交量"""new_distribution = {}new_queue = []for price, volume in self.distribution.items():new_price, new_volume = self.adjust_price_and_volume(price, volume, old_factor, new_factor)new_distribution[new_price] = new_volumefor price, volume in self.fifo_queue:new_price, new_volume = self.adjust_price_and_volume(price, volume, old_factor, new_factor)new_queue.append((new_price, new_volume))self.distribution = new_distributionself.fifo_queue = new_queuedef initialize_distribution(self, historical_data: pd.DataFrame) -> None:"""初始化筹码分布"""init_period = min(60, len(historical_data))data = historical_data.iloc[:init_period]latest_factor = historical_data['adj_factor'].iloc[-1]# 调整成交量adjusted_volume = data['volume'] * (data['adj_factor'] / latest_factor)# 计算VWAPvwap = (data['adj_close'] * adjusted_volume).sum() / adjusted_volume.sum()total_shares = adjusted_volume.sum()# 计算价格范围price_std = data['adj_close'].std()price_range = np.linspace(vwap - 3*price_std, vwap + 3*price_std, 100)# 生成正态分布distribution = np.exp(-((price_range - vwap)**2) / (2*price_std**2))distribution = distribution / distribution.sum() * total_sharesself.distribution = dict(zip(price_range, distribution))self.fifo_queue = [(price, volume) for price, volume in zip(price_range, distribution)]def process_transaction(self, price: float, volume: float, is_buy: bool) -> None:"""处理单次交易"""if is_buy:self.distribution[price] = self.distribution.get(price, 0) + volumeself.fifo_queue.append((price, volume))else:remain_volume = volumewhile remain_volume > 0 and self.fifo_queue:oldest_price, oldest_volume = self.fifo_queue[0]if oldest_volume <= remain_volume:remain_volume -= oldest_volumeself.distribution[oldest_price] -= oldest_volumeif self.distribution[oldest_price] <= 0:del self.distribution[oldest_price]self.fifo_queue.pop(0)else:self.distribution[oldest_price] -= remain_volumeself.fifo_queue[0] = (oldest_price, oldest_volume - remain_volume)remain_volume = 0def calculate_distribution(self, data: pd.DataFrame) -> None:"""计算整体筹码分布"""self.initialize_distribution(data)latest_factor = data['adj_factor'].iloc[-1]prev_factor = latest_factorfor _, row in data.iterrows():if row['adj_factor'] != prev_factor:self.adjust_distribution(prev_factor, row['adj_factor'])prev_factor = row['adj_factor']adjusted_volume = row['volume'] * (row['adj_factor'] / latest_factor)adj_price = row['adj_close']self.process_transaction(adj_price, adjusted_volume/2, True)self.process_transaction(adj_price, adjusted_volume/2, False)def plot_distribution(self, current_price: float, title: str = None) -> None:"""绘制筹码分布图"""if not self.distribution:returnprices = np.array(list(self.distribution.keys()))volumes = np.array(list(self.distribution.values()))volumes = volumes / volumes.sum()profit_ratio = sum(v for p, v in zip(prices, volumes) if p <= current_price)loss_ratio = 1 - profit_ratioplt.figure(figsize=(10, 12))profit_mask = prices <= current_priceloss_mask = prices > current_priceplt.barh(prices[profit_mask], volumes[profit_mask], height=0.1, alpha=0.6, color='red', label='获利筹码')plt.barh(prices[loss_mask], volumes[loss_mask], height=0.1, alpha=0.6, color='green', label='套牢筹码')plt.axhline(y=current_price, color='blue', linestyle='--', label=f'当前价格: {current_price:.2f}')plt.xlabel('筹码占比')plt.ylabel('价格')if title:plt.title(f'{title}\n获利: {profit_ratio:.2%} 套牢: {loss_ratio:.2%}')else:plt.title(f'筹码分布\n获利: {profit_ratio:.2%} 套牢: {loss_ratio:.2%}')plt.grid(True, alpha=0.3)plt.legend()price_range = current_price * 0.5plt.ylim(current_price - price_range, current_price + price_range)plt.tight_layout()plt.show()def analyze_chip_distribution(df: pd.DataFrame,latest_adj_factor: float, stock_code: str = None) -> ChipDistribution:"""主函数:分析并展示筹码分布"""# 预处理数据data = prepare_data(df,latest_adj_factor)# 按日期排序data = data.sort_values('trade_date')# 创建筹码分布对象chip_dist = ChipDistribution()# 计算分布chip_dist.calculate_distribution(data)# 绘制分布图current_price = data['adj_close'].iloc[-1]title = f'筹码分布 - {stock_code}' if stock_code else Nonechip_dist.plot_distribution(current_price, title)return chip_dist# 使用示例:
"""
# 假设 df 是从 tushare 获取的数据
chip_dist = analyze_chip_distribution(df, '000001.SZ')
"""#使用tushare获取过去1-2年的价格数据,复权因子的数据,成交量的数据
def get_stock_data_chip_distribution(ts_code,start_date,end_date):#具体的获取数据的方法在这,#df里面需要包含历史的close的价格,成交量,adj复权因子等analyze_chip_distribution(df,latest_adj_factor, stock_code=ts_code)return df   # 分析筹码分布
chip_dist = get_stock_data_chip_distribution("688268.SH","20220101","20241211")

这个是我计算出来的结果,20241212,基本上和我在招商证券上看到的筹码分布图形非常类似,大家可以作为参考自己去评估和摸索
在这里插入图片描述

Talk is cheap , 直接分享了code,拿走不谢


http://www.ppmy.cn/news/1555231.html

相关文章

02-51单片机的C语言基础与最小系统

C语言基础 一个简单的单片机C程序要有什么 #include<reg51.h> void main() {while(1){} }C语言中常用语句略&#xff0c;if,while,do…while,for,switch…case 函数略 C&#xff0d;51的数据类型扩充定义 sfr:特殊功能寄存器声明sfr 变量名地址值&#xff1b;*特殊功…

从万维网到人工智能:改变生活的11项技术里程碑

1984 年 1 月 24 日&#xff0c;苹果公司推出了 Macintosh 128K&#xff0c;从此永远改变了个人电脑的面貌。 史蒂夫・乔布斯&#xff08;Steve Jobs&#xff09;这款小巧且用户友好的电脑向全世界引入了图形用户界面&#xff0c;标志着个人技术发展历程中的一个关键时刻。 从…

笔墨游戏 蒙养生活 了解林曦老师的中国画美育直播课

你觉得&#xff0c;美是什么?一张画&#xff0c;一个雕塑&#xff0c;一段音乐      是&#xff0c;也不仅仅是这样      “美者&#xff0c;甘也”美&#xff0c;是一种甘甜的味道      是对生活的兴味与体验它关乎一种畅达而自如的人生在林曦老师的中国画美育课…

【0x000A】HCI_Reject_Connection_Request命令详解

目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Reject_Connection_Request命令格式 2.2. 参数说明 2.2.1. BD_ADDR&#xff08;蓝牙设备地址&#xff09; 2.2.2. Reason&#xff08;拒绝原因&#xff09; 三、返回事件及参数说明 3.1. 返回参数 3.2. 生成的事件…

Flink一些常用API的使用(Flink中的Source以及Flink中的一些常用算子)

文章目录 一、Source1、预定义Source2、自定义Source【重要】3、Kafka Source【重要】 二、Transformation-转换算子1、union和connect-合并和连接2、Side Outputs&#xff08;侧道输出&#xff09;--分流 一、Source 1、预定义Source 基于本地集合的source&#xff08;Colle…

Vue前端开发-axios对象实例创建和配置的过程

在Vue 3中&#xff0c;由于所有的组件都可能去请求数据&#xff0c;因此&#xff0c;针对axios模块的配置应该是全局性的&#xff0c;在进行axios模块的全局配置之前&#xff0c;需要了解axios实例的创建、配置对象和响应对象的结构内容&#xff0c;接下来我们分别来进行介绍。…

opencv腐蚀和膨胀

腐蚀的核心在于把图片中白色的细微线条去除,膨胀则会将白线条扩大 # 导入OpenCV库&#xff0c;用于图像处理 import cv2 import numpy as np # 从matplotlib库中导入pyplot模块&#xff0c;用于绘制图像 from matplotlib import pyplot as plt # 创建一个名为window…

金融信息分析基础(1)

1.金融数据 金融数据分为&#xff1a;交易数据&#xff08;低频数据&#xff0c;高频数据&#xff0c;超高频数据&#xff09;&#xff0c;报表数据&#xff08;财务报表&#xff0c;研报&#xff09;&#xff0c;金融社交媒体数据 低频数据&#xff1a; 以日、周、月、季、年…