甘氏矩阵图价格推算代码:螺旋生成、平方根换算与PDF校验
简介《甘氏矩阵图价格推算》汇编PDF面向股票、外汇、期货等金融市场的技术分析学习者与交易者帮助读者跳出繁杂指标与线条用一张方形数字矩阵理解行情的进退节奏与趋势拐点。全书围绕甘氏矩阵图的原理展开从基数「1」的螺旋排列讲起详解两条对角角线、水平线与垂直十字线所构成的角度区域并列出各条线上的关键数字序列说明支撑、压力与多空动能的判断依据同时给出近、远期价位的推算思路与「大数推算」方法强调以固定、有序的数字规律替代主观情绪减少心理弱点与人为陷阱的干扰。压缩包内为1个PDF文件大小约4.01MB内容完整、便于归档查阅。目前已有340人学习下载适合作为技术分析专题的系统入门与工具手册。1. 甘氏矩阵图价格推算落成代码要解决的核心问题行情软件里那张螺旋排布的九宫格绝大多数人只把它当装饰。真要用它推算价位麻烦立刻出现手工在图上数格子一圈一圈往外数数到第六圈眼睛就花了一份《甘氏矩阵图价格推算[汇编]》几百页翻到某一页某个基准价对应的 90 度阻力位抄错一位小数就把整条交易计划带偏。更现实的问题是汇编里的数字是死的行情是活的基准价一变整张表的推算结果全部作废。把这件事写成代码核心就三件事用确定性的规则把螺旋矩阵生成出来用平方根和角度的换算把任意基准价的上下档位一次性算出来再把 PDF 汇编里的历史数据抽成结构化字段回算校验确认自己理解的规则和汇编作者一致。适合做量化复盘、做日内价位带、或者单纯想把技术分析里的模糊步骤变精确的人。2. 甘氏矩阵图的螺旋生成从中心 1 到 9×9 网格的正确落位甘氏矩阵图Square of 9国内常叫甘氏九宫格的骨架是一个从中心向外逆时针盘旋的数字方阵。中心放 1向右走一格放 2然后向上、向左、向下依次绕行每绕半圈步长加一。这个规则听着简单但落到代码里有三处细节必须钉死否则生成出来的矩阵和别人手里的图镜像对不上后面所有角度推算都是错的。2.1 起点、旋向与步长决定矩阵长相的三个量第一个量是起点方向。中心值为 1 时2 放在 1 的正右方还是正上方直接决定整套图是顺时针还是逆时针。业内通行的版本是 2 居中宫之右此后按右、上、左、下循环转向这样得到的图里1、9、25、49、81 这几个奇数平方数会整齐地落在从中心出发的右下对角线上。第二个量是步长序列走完一段直线才转向步长依次为 1、1、2、2、3、3、4、4……不是等步长。第三个量是中心值实盘推算时有人固定用 1也有人把当前基准价直接放中心再铺开两种做法的角度换算公式完全一致只是查表口径不同。下表把常见参数组合和后果列清楚参数常见取值改错后的现象起始方向右图整体镜像45 度位与 315 度位互换转向顺序右→上→左→下变成顺时针螺旋平方数落到左上对角线步长增长每两个方向 1等步长会出现空洞数字总数对不上中心值1 或基准价只影响读数口径不影响相对角度2.2 一个生成函数把矩阵画出来把上面三个量写进一个函数就够了。下面这段代码按radius控制半径radius4生成 9×9 的方阵返回值用坐标作键y 轴向上为正方便后面直接算角度。def build_square_of_nine(radius4, start1): 生成 (2*radius1)^2 的九宫格矩阵。 radius: 半径4 表示 9x9 start : 中心起始值 返回 grid[(x, y)] valuey 轴向上为正 total (2 * radius 1) ** 2 grid {(0, 0): start} x y 0 value start dirs [(1, 0), (0, 1), (-1, 0), (0, -1)] # 右、上、左、下 step_len 1 # 当前方向连续走几步 d 0 # 方向指针 while len(grid) total: for _ in range(2): # 每个步长覆盖两个方向 dx, dy dirs[d % 4] for _ in range(step_len): if len(grid) total: break x dx y dy value 1 grid[(x, y)] value d 1 step_len 1 # 每绕半圈步长加一 return grid def render(grid, radius4): for y in range(radius, -radius - 1, -1): row [f{grid.get((x, y), 0):6} for x in range(-radius, radius 1)] print(.join(row)) render(build_square_of_nine(4))跑出来的结果应该是这样注意右下角那条对角线65 64 63 62 61 60 59 58 57 66 37 36 35 34 33 32 31 56 67 38 17 16 15 14 13 30 55 68 39 18 5 4 3 12 29 54 69 40 19 6 1 2 11 28 53 70 41 20 7 8 9 10 27 52 71 42 21 22 23 24 25 26 51 72 43 44 45 46 47 48 49 50 73 74 75 76 77 78 79 80 81step_len 1放在内层循环之外是为了保证每两个方向走完后步长才增长一次如果写在内层循环里步长会变成每换向就加一矩阵立刻变形。d % 4用来循环方向指针不取模会越界。total的边界判断放在三层循环的最里面是因为最后一圈通常走不满越界写入会污染坐标。2.3 用 25、49、81 落位反查生成是否正确生成完不要急着往下算先做一次落位校验。奇数平方数在标准甘氏矩阵图里必须落在同一条对角线上而且方向一致。上面那张图里1 在 (0,0)9 在 (1,-1)25 在 (2,-2)49 在 (3,-3)81 在 (4,-4)全部压在主对角线上。可以用三行代码断言grid build_square_of_nine(4) squares {1: (0, 0), 9: (1, -1), 25: (2, -2), 49: (3, -3), 81: (4, -4)} for v, pos in squares.items(): assert grid[pos] v, f{v} 应该落在 {pos}实际是 {grid.get(pos)} print(落位校验通过)任何一条断言失败都说明起始方向或者转向顺序被改动了这时候先别怀疑公式回到 2.1 的三个参数逐一比对。这份校验一次写好以后换中心值、换半径都能复用比自己盯屏幕数格子靠谱得多。3. 角度与平方根换算甘氏矩阵图价格推算公式的推导与参数矩阵只是底图真正用来推算价格的是平方根和角度之间的那条线性关系。很多人直接把sqrt(价格) ± 0.25当口诀背下来用是能用但一旦遇到 135 度、270 度这种非整档角度就卡壳也不知道该加几圈。把推导走一遍参数就能自己算。3.1 一圈 360 度为什么等于平方根加 2看 2.2 那张图的右下方对角线。同一角度方向上相邻两圈的数字分别是 (2k1)² 和 (2k3)² 附近例如 9、25、49、81。把它们的平方根取出来3、5、7、9差值恒定是 2。换句话说在甘氏矩阵图上绕中心走完整整一圈 360 度对应的平方根增加量就是 2。这个关系是整个价格推算法则的地基它不是拟合出来的经验值而是螺旋方阵本身的几何性质。既然 360 度对应平方根增量 2角度到增量的换算是纯线性的$$\Delta\sqrt{P} 2 \times \frac{\theta}{360} \frac{\theta}{180}$$于是 45 度对应 0.2590 度对应 0.5180 度对应 1360 度对应 2。反过来说已知某个价位想求它相对基准价的角度把两个价位分别开方相减再乘 180 就得到角度差。这就是为什么老手看盘时习惯先算开方——所有角度关系在平方根尺度上才是一把直尺。3.2 45/90/180/360 度价位表与常用参数把公式写成表格更直观。以基准价 100 为例sqrt(100) 10上下各档位如下角度Δsqrt上方阻力下方支撑说明22.50.125102.5297.52半分位用于窄幅整理450.25105.0695.06最常用日内第一阻力900.5110.2590.25次级结构位1350.75115.5685.56常被忽略实盘有反应1801.0121.0081.00强支撑阻力整数平方2701.5132.2572.25跨圈位用于大级别3602.0144.0064.00一整圈趋势反转参考表里 180 度那行最值得记基准价 100 的上下 180 度位正好是 121 和 81两个完全平方数。选基准价时如果刻意避开整数平方附近反而会让 180 度位落在小数上读数不干净。这是选基准价的一个实用偏好。提示角度超过 360 度就进入第二圈公式不变但实务中很少用到三圈以外因为误差积累和噪音会淹没信号。3.3 从矩阵落点到价格写一个 level 函数把公式封成函数输入基准价和角度序列直接输出上下档位。注意支持位可能算出负数需要做保护。import math def sq9_levels(base_price, angles(22.5, 45, 90, 135, 180, 270, 360)): 按甘氏矩阵图平方根法推算上下档位。 base_price: 基准价必须为正数 angles : 要推算的角度序列单位度 返回 list[dict] if base_price 0: raise ValueError(基准价必须为正数) root math.sqrt(base_price) rows [] for a in angles: delta a / 180.0 up_root root delta down_root root - delta rows.append({ angle: a, delta_sqrt: round(delta, 4), resistance: round(up_root ** 2, 4), support: round(down_root ** 2, 4) if down_root 0 else None, }) return rows for r in sq9_levels(100): print(r)base_price 0的检查不能省负数开方会直接抛异常而基准价来自行情接口或 PDF 解析结果时脏数据很常见。down_root 0的判断同样必要当基准价很小、角度很大时例如基准价 1.2 推 360 度sqrt(1.2) - 2是负数平方之后得到一个虚假的正支撑位这种位必须返回 None 而不是数字。delta_sqrt单独保留在返回值里是为了排查时能一眼看出用的是哪个换算口径——有人按 0.125 的倍数记有人按角度记两者等价但混用就会出现四分之一档的偏差。4. 解析甘氏矩阵图价格推算[汇编].pdf表格抽取与矩阵反查校验手上有《甘氏矩阵图价格推算[汇编]》这类 PDF 时最省事的做法是把里面的价位抽出来用第 3 章的公式反算一遍对得上说明规则一致对不上就得去看是汇编用了别的口径还是自己抄错了。PDF 解析的坑集中在两点矩阵页和表格页的取数方式完全不同。4.1 pdfplumber 抽文本层与表格层的取舍带线框的表格页extract_tables()能直接给出二维列表省事但依赖线框完整而九宫格矩阵页通常没有线框数字是一个个独立的文本对象只能靠坐标还原。这时候用extract_words()拿到每个词的包围盒再按 y 坐标聚类成行、按 x 坐标排序成列。import pdfplumber import re def extract_numeric_words(pdf_path, page_index): 从指定页抽取所有纯数字文本及其坐标。 with pdfplumber.open(pdf_path) as pdf: page pdf.pages[page_index] words page.extract_words(keep_blank_charsFalse) cells [] for w in words: t w[text].strip().replace(,, ) if re.fullmatch(r\d(\.\d)?, t): cells.append({ value: float(t), x: round(w[x0], 1), y: round(w[top], 1), }) return cells def group_rows(cells, tol3.0): 按 y 坐标把数字聚成行容差 tol 单位是 pt。 rows [] for c in sorted(cells, keylambda c: c[y]): if rows and abs(c[y] - rows[-1][0][y]) tol: rows[-1].append(c) else: rows.append([c]) return [sorted(r, keylambda c: c[x]) for r in rows]keep_blank_charsFalse是为了避免空格被当成独立文本对象混进来。re.fullmatch而不是search是防止「12.5%」这类带单位的字符串被误判成数字。tol3.0这个容差是经验值正常 PDF 同一行内数字的top抖动在 1 到 3 pt 之间字号越大抖动越大正文字号 10 pt 左右取 3 就够如果发现同一行被拆成两行把 tol 调到字号的一半再试。4.2 列名标准化与基准价对齐抽出来的行只是数字序列还得映射到「基准价 / 角度 / 价位」这三个语义字段。汇编的排版习惯不一样有的把基准价放在页眉有的把角度写成「45°」「45度」「1/8 圈」混用。清洗时统一成数值。原始形态标准化目标处理方式45°、45度45.0正则提取数字1/8 圈、1/4 圈45.0、90.0分数乘 3601,234.51234.5去掉千分位逗号页眉里的基准价单独字段从页首文本块提取不参与行聚类对齐基准价有个常见误区把页面上出现的第一个大数字当基准价。汇编排版里页眉的页码、章节号往往和基准价字号接近。稳妥做法是记录页面上所有数字的坐标取位于页面上部四分之一区域、且字号最大的那个再人工抽查前几页确认。4.3 用生成矩阵反查校验解析结果抽完之后立刻做回算校验这一步能挡掉八成以上的低级错误。import math def verify_level(price, base, angle, rel_tol0.001): 校验某个价位是否符合 sqrt 角度公式rel_tol 为相对误差上限。 expect (math.sqrt(base) angle / 180.0) ** 2 return abs(price - expect) expect * rel_tol, expect ok, expect verify_level(121.2, 100, 180) print(ok, round(expect, 2)) # True 121.0rel_tol用相对误差而不是绝对误差是因为汇编里价位往往保留两位小数基准价越大绝对误差越大。0.1% 的相对容差对 100 附近的价位相当于 0.12对 10000 附近的价位相当于 12这个尺度变化正好对应排版精度。如果某个价位的回算偏差稳定在某个固定比例上比如总是偏 0.13%那多半不是抄错而是汇编作者用了 0.125 的整数倍做档位、或者把一个圆周按 8 等分而不是按角度插值。这种系统性偏差要用「偏差是否同号」来区分随机正负是抄录错误同号同幅是口径差异。注意解析结果不要直接进交易信号至少人工核对前 5 页确认基准价字段和角度口径与自己的实现一致之后再批量跑。5. 多周期共振与价格推算偏差排查的实战技巧5.1 用多个基准价做平方根共振筛选单个基准价算出来的档位噪音大。实务里更常用的做法是选多个基准价——比如一段区间的最高价、最低价、整数关口——分别推档位然后看哪些价位被重复命中。命中次数越多这个价位越值得盯。def resonance(hits, rel_tol0.002): 把多个来源推出来的价位聚成簇返回 (中心价, 命中次数)。 hits sorted(hits) clusters [] for p in hits: if clusters and abs(p - clusters[-1][0]) / clusters[-1][0] rel_tol: clusters[-1].append(p) else: clusters.append([p]) return [(round(sum(c) / len(c), 4), len(c)) for c in clusters] bases [98.5, 100.0, 103.2] hits [] for b in bases: for r in sq9_levels(b): hits.append(r[resistance]) if r[support]: hits.append(r[support]) print([c for c in resonance(hits) if c[1] 2])rel_tol0.002是聚簇的关键参数。调大不同来源的档位会被合并成一簇看着命中多其实是虚的调小同一个理论价位因为各基准价取整方式不同会被拆开。判断标准很简单用纯随机价位跑一遍如果聚出来的簇数量和真实数据差不多容差就设得太松了。if c[1] 2只保留至少被两个基准价命中过的价位这是最基础的一层过滤。5.2 偏差排查的三步顺序推算结果和盘中实际反应对不上时按下面顺序查不要跳步顺序检查项典型症状定位手段1角度口径所有档位整体偏移 1 到 2 个点打印delta_sqrt看是否为 0.125 的整数倍2基准价更新时间只有某一段行情偏差大对齐基准价的时间戳与 K 线时间3矩阵落位平方数不在对角线复用 2.3 的断言脚本第一步永远先查角度口径因为它是全局性的一错全错。只有当偏差是局部出现时才去怀疑基准价取错或矩阵生成有问题。矩阵落位出错的情况其实很少因为 2.3 的断言只要跑过一次就会暴露但换了起始方向之后忘了重跑断言图会悄悄镜像这时候 45 度位和 315 度位互换盘中表现是「明明该是阻力却一穿而过」。5.3 一个容易被忽略的收尾动作每换一个品种或者换一个基准价区间把共振簇的中心价和当前实际价位一起打印出来做一次目视比对。共振簇如果出现连续三档中心价间隔都接近同一个数值说明这几个基准价选得太近等于在同一个价位上重复计数命中次数会虚高。这时候把基准价的间隔拉大到至少 180 度档位差的两倍簇的分布才会重新变得有区分度。这个参数没有理论最优值只能靠每次重跑共振函数时看一眼簇间距来调。本文还有配套的精品资源点击获取