从同花顺到Jupyter Notebook:我的缠论量化分析工作流搭建实录
记得第一次接触缠论时,我还在用同花顺的K线图手动画线段、中枢。那些深夜对着屏幕数笔、画分型的日子,虽然充满探索的乐趣,但效率实在太低。直到发现Python的量化分析能力,才真正打开了缠论应用的新世界。本文将分享我如何将同花顺的直观盘感与Python的量化分析能力结合,打造一套高效的缠论分析工作流。
1. 数据获取:从同花顺到Python的桥梁搭建
同花顺作为国内主流看盘软件,其数据丰富性和界面友好度毋庸置疑。但要做深度量化分析,我们需要将数据导出到Python环境。这里推荐两种高效的数据获取方式:
方法一:同花顺数据导出+Python清洗
- 在同花顺中选中目标股票,右键选择"数据导出"
- 勾选需要的字段(开盘价、最高价、最低价、收盘价、成交量等)
- 导出为Excel或CSV格式
import pandas as pd # 读取导出的数据 df = pd.read_csv('ths_data.csv', parse_dates=['日期']) df.rename(columns={ '日期': 'date', '开盘': 'open', '最高': 'high', '最低': 'low', '收盘': 'close', '成交量': 'volume' }, inplace=True)方法二:使用akshare库直接获取对于不想手动导出的用户,可以使用Python的akshare库直接获取同花顺数据:
import akshare as ak stock_zh_a_daily = ak.stock_zh_a_daily( symbol="sh600000", adjust="hfq" )提示:akshare数据需要网络连接,且返回字段名称与TA-Lib要求一致,更适合自动化流程
2. 缠论核心指标的计算与实现
缠论分析的核心在于分型、笔、线段和中枢的识别。虽然TA-Lib提供了一些蜡烛图模式识别函数,但完整的缠论实现需要更复杂的逻辑。以下是关键步骤的实现:
2.1 分型识别算法
分型是缠论的最小单位,包括顶分型和底分型。我们可以用以下函数识别:
def identify_fractals(df): highs = df['high'].values lows = df['low'].values # 顶分型条件:中间K线最高价最高,且最低价也最高 top_fractals = [] for i in range(1, len(highs)-1): if highs[i] > highs[i-1] and highs[i] > highs[i+1] and \ lows[i] > lows[i-1] and lows[i] > lows[i+1]: top_fractals.append(i) # 底分型条件:中间K线最低价最低,且最高价也最低 bottom_fractals = [] for i in range(1, len(lows)-1): if lows[i] < lows[i-1] and lows[i] < lows[i+1] and \ highs[i] < highs[i-1] and highs[i] < highs[i+1]: bottom_fractals.append(i) return top_fractals, bottom_fractals2.2 笔的生成算法
笔是连接相邻顶底分型的线段,需要满足以下条件:
- 至少5根K线
- 顶分型和底分型之间有非包含关系的K线
def generate_strokes(top_fractals, bottom_fractals, df): strokes = [] all_points = sorted(top_fractals + bottom_fractals) i = 0 while i < len(all_points)-1: current = all_points[i] next_point = all_points[i+1] # 检查是否满足笔的条件 if (current in top_fractals and next_point in bottom_fractals) or \ (current in bottom_fractals and next_point in top_fractals): if abs(next_point - current) >= 4: # 至少5根K线 strokes.append((current, next_point)) i += 1 # 跳过下一个分型 i += 1 return strokes3. 可视化分析:Jupyter Notebook中的动态展示
Jupyter Notebook的强大之处在于可以交互式地展示分析结果。以下是使用matplotlib和plotly实现缠论可视化的方法:
3.1 基础K线图绘制
import matplotlib.pyplot as plt from mplfinance.original_flavor import candlestick_ohlc import matplotlib.dates as mdates fig, ax = plt.subplots(figsize=(12, 6)) # 转换日期格式 df['date_num'] = mdates.date2num(df['date']) # 绘制K线 candlestick_ohlc( ax, df[['date_num', 'open', 'high', 'low', 'close']].values, width=0.6, colorup='r', colordown='g' ) # 标记分型 top_fractals, bottom_fractals = identify_fractals(df) for i in top_fractals: ax.plot(df['date_num'].iloc[i], df['high'].iloc[i], 'v', markersize=10, color='red') for i in bottom_fractals: ax.plot(df['date_num'].iloc[i], df['low'].iloc[i], '^', markersize=10, color='green') # 设置x轴为日期格式 ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) plt.xticks(rotation=45) plt.title('缠论分型识别') plt.show()3.2 交互式可视化(Plotly)
对于更复杂的交互需求,plotly是更好的选择:
import plotly.graph_objects as go fig = go.Figure(data=[go.Candlestick( x=df['date'], open=df['open'], high=df['high'], low=df['low'], close=df['close'] )]) # 添加分型标记 fig.add_trace(go.Scatter( x=df['date'].iloc[top_fractals], y=df['high'].iloc[top_fractals], mode='markers', marker=dict(symbol='triangle-down', size=10, color='red'), name='顶分型' )) fig.add_trace(go.Scatter( x=df['date'].iloc[bottom_fractals], y=df['low'].iloc[bottom_fractals], mode='markers', marker=dict(symbol='triangle-up', size=10, color='green'), name='底分型' )) # 添加笔的连线 strokes = generate_strokes(top_fractals, bottom_fractals, df) for start, end in strokes: fig.add_trace(go.Scatter( x=[df['date'].iloc[start], df['date'].iloc[end]], y=[df['high'].iloc[start] if start in top_fractals else df['low'].iloc[start], df['low'].iloc[end] if end in bottom_fractals else df['high'].iloc[end]], mode='lines', line=dict(color='blue', width=2), showlegend=False )) fig.update_layout( title='缠论分析可视化', xaxis_rangeslider_visible=False ) fig.show()4. 策略回测与绩效评估
完整的缠论分析工作流离不开策略回测。下面介绍如何使用backtrader库进行回测:
4.1 回测框架搭建
import backtrader as bt class ChanStrategy(bt.Strategy): params = ( ('fractal_period', 5), ('stroke_min_k', 5) ) def __init__(self): self.dataclose = self.datas[0].close self.order = None def next(self): if self.order: return # 获取最近50根K线数据 recent_data = self.datas[0].close.get(size=50) # 识别分型和笔(简化版) top, bottom = identify_fractals_simplified(recent_data) strokes = generate_strokes_simplified(top, bottom, recent_data) # 简单策略:出现底分型且无持仓时买入 if len(bottom) > 0 and not self.position: self.buy() # 出现顶分型且有持仓时卖出 elif len(top) > 0 and self.position: self.sell() def identify_fractals_simplified(self, data): # 简化版分型识别 pass def generate_strokes_simplified(self, top, bottom, data): # 简化版笔生成 pass4.2 回测执行与结果分析
# 创建回测引擎 cerebro = bt.Cerebro() # 添加数据 data = bt.feeds.PandasData(dataname=df.set_index('date')) cerebro.adddata(data) # 添加策略 cerebro.addstrategy(ChanStrategy) # 设置初始资金 cerebro.broker.setcash(100000.0) # 添加分析器 cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe') cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown') cerebro.addanalyzer(bt.analyzers.Returns, _name='returns') # 运行回测 results = cerebro.run() strat = results[0] # 打印结果 print('最终资产价值: %.2f' % cerebro.broker.getvalue()) print('夏普比率:', strat.analyzers.sharpe.get_analysis()['sharperatio']) print('最大回撤:', strat.analyzers.drawdown.get_analysis()['max']['drawdown']) print('年化收益率:', strat.analyzers.returns.get_analysis()['rnorm100'])5. 工作流优化与实用技巧
经过几个月的实践,我总结出以下提升缠论分析效率的技巧:
数据预处理加速技巧
- 使用numba加速分型识别计算
- 将常用股票数据缓存到本地SQLite数据库
- 使用Dask处理大规模历史数据
from numba import jit @jit(nopython=True) def fast_fractal_detection(highs, lows): # 使用numba加速的分型检测 passJupyter Notebook实用插件
- jupyter_contrib_nbextensions:提供代码折叠、目录等功能
- qgrid:实现DataFrame的交互式过滤和排序
- ipywidgets:创建交互式控件
常用代码片段将常用功能封装成函数,保存为单独模块:
# chan_utils.py def plot_chan_analysis(df): """绘制缠论分析图表""" pass def backtest_chan_strategy(df, params): """回测缠论策略""" pass实际使用中发现,将同花顺的盘感与Python的量化分析结合,需要特别注意时间周期的统一。我通常在同花顺中先观察大周期(日线、周线)的趋势,然后在Python中分析小周期(30分钟、60分钟)的买卖点。这种"望远镜+显微镜"的组合方式,既能把握大方向,又能精确捕捉买卖时机。