news 2026/10/23 7:14:40

通达信DLL选股插件源码:C语言实现与离线回放验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
通达信DLL选股插件源码:C语言实现与离线回放验证

简介:面向通达信插件选股开发的VC++ 6.0示例源码与教程包,适合具备C++基础、希望理解通达信DLL插件接口和指标接口标准的量化爱好者与程序化交易开发者。压缩包共45个文件、约4.74MB,包含cpp/h源码、dll动态库、dsp/dsw工程文件、doc规范与用户手册,以及多张jpg操作步骤图,可对照完成工程打开、编译和插件加载验证。作者对原示例代码补充了注释,并修正了核心实现中的一处错误,使原本晦涩的接口说明更易理解;配套的编程规范、使用方法和选股结果截图,能帮助读者梳理DLL插件从注册、参数传递到文本输出的基本流程。已有6420人学习下载。需要说明的是,示例功能较简单,重在演示编程方法,距实盘应用尚有距离,适合用作接口研究、二次开发起步和排错参考,据此投资风险自负。

1. 通达信DLL选股插件源码:为什么老手宁可写 C 也不堆公式

收盘后翻两百只票,眼睛在 K 线和财务字段之间来回跳,手上一堆条件:量比、连续放量天数、均线斜率、换手率背离——这些条件单拎出来公式都能写,一旦串起来就变成嵌套七八层的 IF,改一个阈值要翻三屏,第二年自己都看不懂。这份通达信 DLL 选股插件源码要解决的就是这个场景:把整套判断逻辑从公式编辑器里搬到 C 代码里,编译成 DLL 挂进通达信的公式引擎,公式侧只剩一行XS_PICK(C,V,5,1.8),本质是给公式引擎加了一个自己写的内置函数。适合已经会用条件选股、但被公式复杂度和复用性卡住的从业者;也适合想把自己那套选股经验固化成可交付模块的人。VC++ 6.0 那一代的写法看着老,但在 32 位进程里它是最省心的组合。

2. 调用链路拆解:引擎从哪个目录把 DLL 拉进公式引擎

2.1 引擎怎么找到你的 DLL

通达信对自定义函数 DLL 的加载方式很朴素:认目录、认导出名,不认注册表也不认安装包。把编译好的 32 位 DLL 放进客户端安装目录下的扩展目录(常见路径形如安装目录\T0002\dlls\),重启客户端,公式引擎在初始化时会把该目录下所有 DLL 的导出函数扫一遍,登记成可调用函数。之后在公式编辑器里敲函数名,参数提示会跟着出来,跟内置函数没区别。

这里有两个容易忽略的细节。第一,函数名匹配是大小写敏感的,你导出XS_PICK,公式里写成xs_pick就找不到;我一般统一全大写加下划线前缀,避免和内置函数撞名。第二,扫描是启动时做的,换了 DLL 必须重启客户端,热替换不生效——这一点在反复调试阶段特别耗时间,所以下面会讲怎么用日志把调试周期压短。

提示:扩展目录的具体层级在不同版本里略有差别,源码包里通常会带一份目录说明,照着放,别自己猜。

2.2 参数怎么进、值怎么出:调用约定与返回类型

通达信调用自定义函数的方式是可变参数:引擎把公式里的实参按顺序压栈,同时把实参个数作为第一个参数传进来,函数里用va_arg逐个取。返回值是一个浮点数,公式引擎把它当成一个数值型函数结果参与后续运算——这意味着你的选股函数最终要收敛成"返回 1 表示命中、返回 0 表示不命中",或者返回一个连续的打分值,让公式侧用>阈值去做最终判断。

我倾向于后者。返回连续值的好处是:同一个函数既能当选股条件用,也能拿去做排序和分层。比如量价背离度返回 0 到 3 之间的一个数,公式里写XS_DIVERGE(C,V,20) > 1.5是选股,写XS_DIVERGE(C,V,20)放进排序指标就是排序,一份代码两处用。

参数类型上要留个心眼。绝大多数版本按 double 压栈,取参写va_arg(ap, double);但也有版本对整型实参做过优化,直接按键值传。稳妥做法是把公式侧的实参全部写成带小数点的形式,5写成5.0,让引擎统一按浮点处理,省掉一类玄学问题。这条不是理论推导,是踩过之后总结出来的。

2.3 为什么用 VC++ 6.0 编:运行时依赖与 32 位约束

现在还在用 VC++ 6.0,不是因为怀旧。三个现实原因:一是通达信客户端是 32 位进程,64 位 DLL 根本加载不进去,而 VC++ 6.0 默认就产出 32 位目标,不用折腾平台工具集;二是 VC++ 6.0 可以非常干净地静态链接 C 运行库(/MT),编出来的 DLL 丢到任何一台装了客户端的机器上都能跑,不会出现"开发机好好的,换台机器提示找不到某个运行时库";三是这套源码本身就是按 VC++ 6.0 的工程结构组织的,.dsp工程文件直接双击能开,省掉迁移成本。

代价也要说清楚:VC++ 6.0 的 C++ 标准支持停留在上个世纪,std::vector之类的能不用就不用,字符串处理老老实实用char缓冲区加sprintf,注意sprintf的越界问题,用_snprintf并在末尾手动补\0。另外它没有 64 位整数类型的完整支持,别在 DLL 里做超大数运算。

2.4 一份最小可编译骨架

源码包里通常会有一个统一导出声明的头文件,我把它简化成下面这个样子,方便你先跑通再往里塞逻辑:

/* tdx_export.h —— 统一导出声明,避免 C++ 名字修饰 */ #pragma once #include <windows.h> /* 引擎按 (参数个数, 参数表) 的方式调用, 返回值作为公式里的数值结果 */ #define TDX_EXPORT(name) \ extern "C" __declspec(dllexport) double WINAPI name(int nParamCount, ...)
/* xs_pick.c —— 最小可跑通的选股函数骨架 */ #include "tdx_export.h" #include <stdarg.h> #include <math.h> /* 从可变参数里取 need 个 double,取不满直接判失败 */ static int fetch_args(int nParamCount, va_list ap, double *buf, int need) { int i; for (i = 0; i < nParamCount; i++) { double v = va_arg(ap, double); /* 公式侧实参一律按 double 取 */ if (i < need) buf[i] = v; } return (nParamCount >= need) ? 1 : 0; } /* 公式写法:XS_PICK(C, V, 5.0, 1.8) 参数:收盘价、成交量、回看周期、量比阈值 返回:1 命中 / 0 不命中 */ TDX_EXPORT(XS_PICK) { double buf[4]; double sum = 0.0, ratio; int i; va_list ap; va_start(ap, nParamCount); if (!fetch_args(nParamCount, ap, buf, 4)) { va_end(ap); return 0.0; /* 参数不足,安全退出,别读脏栈 */ } va_end(ap); if (buf[2] < 1.0 || buf[1] <= 0.0) return 0.0; /* 除零与非法周期拦截 */ for (i = 1; i <= (int)buf[2]; i++) sum += buf[1] / (double)i; /* 占位计算 */ ratio = sum / (buf[1] * buf[2]); return (ratio > buf[3]) ? 1.0 : 0.0; }

TDX_EXPORT宏把三件事一次做完:extern "C"关掉 C++ 名字修饰,__declspec(dllexport)把函数放进导出表,double WINAPI固定返回类型和调用约定。少了任何一项,导出名就会变成?XS_PICK@@YANHZZ这种带修饰的形式,引擎扫不到。

fetch_args里那个if (i < need)判断是关键:即使用户在公式里多传了两个参数,也不会写越界。反过来,参数少传时函数返回 0,客户端不会崩——DLL 崩溃会带崩整个客户端进程,未保存的自选股和画线全部丢失,这个代价比算错一个信号大得多。

buf[1] <= 0.0的拦截看似多余,实盘里遇到停牌、新股首日时成交量为 0 是常态,一句除零就能让客户端直接退出。

3. 把选股因子写进 DLL:参数入参设计与公式侧调用

3.1 公式侧怎么调用

DLL 放好、客户端重启之后,在公式管理器里新建一个条件选股公式,主体就一行:

XS_PICK(CLOSE, VOL, 5.0, 1.8)

注意参数顺序必须和 C 代码里buf的下标严格对应,公式引擎不做类型检查和个数校验,传错位置它照样调用,只是结果荒谬。我见过把周期和阈值写反的,跑出来天天命中几十只票,查了两小时才发现是5.0和1.8换了位置。

调试阶段建议先建一个技术指标公式而不是条件选股公式,把返回值画成曲线:

XS_PICK(CLOSE, VOL, 5.0, 1.8); XS_RAW(CLOSE, VOL, 5.0)

第一行画 0/1 的阶跃线,第二行画连续值,两条线叠在一起看,能立刻发现"信号恒为 1"或者"信号恒为 0"这类低级错误。这比在条件选股里反复跑全市场快得多,因为指标只算当前这只票。

3.2 面板数据与逐股计算的差别:DLL 该做多少事

一个必须想清楚的设计问题:DLL 是被逐股、逐 bar 调用的,引擎不会把整个市场的面板数据一次性喂给你。也就是说,你在 DLL 里拿到的只有公式传进来的那几个序列的当前值,做不了跨股票的比较(比如"全市场换手率排名前 10%")。

这决定了功能边界。DLL 适合做的是:单只股票内部、基于时间序列的复杂计算——形态识别、多周期共振、条件组合、自定义平滑。不适合做的是:横截面排序、行业相对强弱、板块内排名。后者要么放到公式侧用RANK之类的内置函数拼,要么在 DLL 之外用脚本把全市场数据先算好落成文件,再让 DLL 读。

我一般的分工是:DLL 负责"这只票现在处于什么状态",公式侧负责"在所有处于这个状态的票里挑前 N 只"。职责一分开,DLL 就变成了纯粹的函数,无状态、可重入、好测试。

3.3 参数设计:把阈值、周期做成入参而不是常量

新手常犯的错是把阈值写死在 C 代码里,改一次参数就要重编译一次,重编译还要重启客户端,一轮调参五分钟。把周期、阈值、平滑系数全部做成入参之后,调参就变成了在公式编辑器里改数字,秒级反馈。

但入参也不是越多越好。参数超过六个,公式里那一行就没法读了,而且每加一个参数都要在fetch_args里对应扩buf数组,容易漏。我的经验是控制在三到五个:一个周期、一个主阈值、一个辅助阈值,剩下的用内部常量。

参数合法性检查必须写全。下面这张表是我在每个函数入口都会过一遍的清单:

参数合法范围非法时的处理不处理的后果
周期 N1 ~ 250返回 0负数导致循环不执行,结果恒为 0
阈值0.01 ~ 100钳位到边界传 0 时全部命中,选股失去意义
价格序列> 0返回 0停牌价为 0,除零崩溃
成交量>= 0返回 0同上

这张表不是形式主义。第三行和第四行对应的崩溃,是这类插件最常见的翻车原因,而且现象很迷惑——平时跑得好好的,某天扫到一只停牌股,客户端直接没了。

3.4 用条件选股做批量扫描与结果落盘

逻辑调通之后,走正式的批量路径:公式管理器里把公式类型设为条件选股,进入"条件选股"面板,选好公式、设定日期范围(一般取最近一个交易日),点"执行选股",结果会落到一个临时板块里。

这一步有三个实操要点。

第一,选股范围要先限定。全市场五千多只票,每次调用都要跑一遍你的 C 函数,如果函数里做了稍微重一点的计算(比如嵌套循环求斜率),整个扫描可能要几分钟。先用"沪深A股"再逐步缩小到自选板块,能省一半时间。

第二,日期范围不要跨太长。条件选股对历史区间的处理是逐日回算,跨一年等于把整个计算量乘以 240。要验证历史表现,用第 6 章讲的离线回放,比在客户端里硬跑高效得多。

第三,结果要落盘。选股结果存在临时板块里,重启客户端不一定还在。我的习惯是选中结果后立刻"另存为板块",命名带上日期,比如XS_20240315,后续复盘直接调板块看,不用重跑。

4. VC++ 6.0 编译与部署:一次跑通的七个核对点

4.1 工程设置:三个必须改的开关

打开源码包里的.dsp工程,先别急着编译,把这三处确认一遍:

Project -> Settings -> C/C++ -> Code Generation Use run-time library: Multithreaded (/MT) Project -> Settings -> Link Category: General -> Output file name: 你的模块名.dll Object/library modules: kernel32.lib user32.lib Project -> Settings -> C/C++ Category: Preprocessor -> Preprocessor definitions: WIN32;_WINDOWS;NDEBUG

/MT是静态链接 C 运行库,这一项决定了 DLL 能不能在别人的机器上跑。如果用了/MD,编出来的 DLL 依赖msvcr71.dll,开发机上因为装了 VC++ 6.0 所以有,客户机上大概率没有,加载直接失败,而且报错信息非常含糊,只提示"初始化失败"。

kernel32.lib和user32.lib按需加。如果 DLL 里只是想写个调试日志,用OutputDebugString就够了,不需要额外的库;但要注意这个函数在 Release 下会被编译器优化掉,调试阶段用 Debug 配置编。

预处理器定义里NDEBUG决定assert是否生效。发布版本一定要带上,否则某个assert失败会弹出对话框阻塞引擎线程,整个客户端卡死——这个现象比崩溃还难查,因为进程还在,就是不响应。

4.2 导出表核对:用 dumpbin 看一眼

编译成功不等于导出正确。VC++ 6.0 自带dumpbin,在命令行里跑:

dumpbin /exports 你的模块名.dll

正常情况下应该看到:

ordinal hint RVA name 1 0 00001000 XS_PICK 2 1 00001120 XS_RAW

如果看到的是?XS_PICK@@YANHZZ这种带问号的形式,说明extern "C"没生效,检查头文件里的宏有没有被正确包含,或者源文件后缀是不是.cpp而宏里漏了extern "C"。

如果导出表是空的,多半是.def文件在工程里但没被加进链接器,或者源码用了__declspec(dllexport)但函数被声明成了static。这两种情况我都遇到过,前者是工程迁移时漏配,后者是自己手滑。

4.3 部署与位宽核对

把 DLL 复制到扩展目录,重启客户端。第一次部署建议做一个三步核对:

第一步,确认目标目录对不对。用资源管理器打开客户端安装目录,找那个约定好的扩展文件夹,把 DLL 放进去,同时确认目录里没有同名的旧版本——同名文件会被占用,复制时提示"文件正在使用",如果强行覆盖失败,实际加载的还是旧的。

第二步,确认位宽。在任务管理器里看客户端进程,32 位进程后面会标(32 位)。如果你的 DLL 是 64 位的,加载会失败但不一定有明确提示。用dumpbin /headers 你的模块名.dll看machine字段,14C是 x86,8664是 x64。

第三步,确认函数可见。在公式编辑器里敲函数名,如果能自动补全,说明引擎扫到了;如果敲完提示"未定义的函数",回到上一步查导出表。

4.4 用日志和探针函数做黑匣子排查

DLL 在引擎进程里跑,出问题时没法打断点。我的做法是加一个独立的探针函数,专门用来输出内部状态:

/* 调试探针:公式里单独调用 XS_DEBUG(C,V,5.0) 看内部中间值 */ TDX_EXPORT(XS_DEBUG) { double buf[3]; va_list ap; char msg[128]; va_start(ap, nParamCount); fetch_args(nParamCount, ap, buf, 3); va_end(ap); _snprintf(msg, sizeof(msg) - 1, "[XS] c=%.3f v=%.3f n=%.0f\n", buf[0], buf[1], buf[2]); msg[sizeof(msg) - 1] = '\0'; OutputDebugStringA(msg); /* 用 DebugView 之类的工具接 */ return buf[0]; }

这个函数返回值原样透传收盘价,所以把它加进指标公式不会破坏图形。日志一定要限流——逐 bar 打印会在几秒内写出几十兆文本,把调试工具拖死。实际使用中我一般只在关键分支打印,或者用一个静态计数器每 500 次打一条。

4.5 性能预算:全市场扫描的时间尺度

五千只票、每只一次调用,如果单次调用耗时 1 毫秒,总耗时就是 5 秒,可以接受;如果单次 20 毫秒,总耗时接近两分钟,用户会以为卡死了。

判断标准很简单:DLL 里不要有文件 IO,不要有new/delete密集操作,不要有对参数序列的二次遍历嵌套。所有能在公式侧用内置函数算完的东西,不要搬进 C 里重算一遍——引擎的内置函数是优化过的,你手写的循环大概率更慢。

5. 避坑排查:五类让客户端直接退出的现场

5.1 公式里能敲出来,选股时报"函数不存在"

现象:在指标公式里调用一切正常,切到条件选股就提示函数未定义。

原因:条件选股和指标公式走的是两条加载路径,部分版本对条件选股里可用的自定义函数做了额外校验,或者只认特定前缀。另一种可能是 DLL 放在了指标准确目录,但客户端启动时该目录被安全软件锁了一下,扫描跳过。

解决:先把 DLL 复制到扩展目录的上一级做一次对照测试;再用探针函数确认引擎到底扫到了哪些导出名。如果确实只认前缀,把函数名统一改成带固定前缀的形式重新编译,比反复猜规则快。

5.2 扫描到一半客户端直接消失

现象:平时正常,某天扫全市场时进度条走到一半,客户端进程没了,没有任何错误提示。

原因:某只票触发了除零或数组越界。最典型的是停牌股成交量为 0,或者新股上市首日历史数据不足,回看周期 N 大于实际 bar 数时读到了未初始化内存。

解决:在函数入口把所有入参做一遍合法性拦截,价格 <= 0、成交量 <= 0、周期大于可用 bar 数,一律返回 0。同时给回看循环加上边界判断,宁可少算一只票,也不能让进程崩。这个坑我吃过一次,丢了一整天的画线。

5.3 昨天选出来 12 只,今天同样的参数选出 40 只

现象:参数一个字没改,两天的选股结果差异巨大。

原因:函数里用了未来数据。最常见的是在计算里引用了收盘后才更新的字段,或者用了REF方向的偏移取到了当根之后的值。另一种可能是 DLL 里有静态全局变量,第一只票算完残留的状态影响了第二只票,导致结果和调用顺序相关。

解决:把 DLL 改成无状态函数,所有中间变量放在栈上,禁止static变量参与计算;公式侧检查有没有引用未来周期的函数。验证方法很简单:同一组参数连跑三次,结果必须完全一致,不一致就是有状态残留。

5.4 开发机能跑,换台机器加载失败

现象:自己的机器上一切正常,把 DLL 连同公式导出发给同事,对方导入公式后函数全部失效。

原因:编的是 Debug 版本,或者运行库设成了/MD,目标机器没装对应的运行时;也可能是同事装的是不同位宽的客户端。

解决:发布前一律用 Release 配置加/MT重新编译,用dumpbin /dependents检查依赖表,只应该看到KERNEL32.dll、USER32.dll这类系统库。看到msvcr71.dll就说明静态链接没生效,回去改工程设置。

5.5 扫描慢到以为程序假死

现象:点了执行选股,进度条几乎不动,等了十分钟还在跑。

原因:函数内部做了重活。常见的是在每次调用里重新打开文件读参数表,或者在循环里拼字符串做日志。五千次调用里做五千次文件打开,光系统调用就能吃掉几分钟。

解决:参数表在 DLL 加载时读一次,缓存在静态区(只读,不会有状态污染问题);日志改成计数器限流,每 N 次打一条。如果逻辑确实重,把它拆成两级——粗筛用公式侧的内置函数先过滤掉 80% 的票,剩下 20% 再进 DLL 精算。

6. 进阶验证:用离线回放把插件调成确定性函数

调参调到后期,最浪费时间的不是写代码,是"改一个数、重启客户端、跑一遍全市场、看结果"这个循环。我后来把这件事拆开了:把 DLL 当纯函数,在客户端外面回放。

具体做法是用导出的日线数据生成一份 CSV,每行一只票一个交易日,列就是公式会传进去的那几个序列值,然后写一个小驱动,用LoadLibrary把 DLL 加载起来,按行喂参数:

/* replay.c —— 用同一份 DLL 在客户端外回放,验证逻辑一致性 */ #include <windows.h> #include <stdio.h> typedef double (WINAPI *PFN)(int, ...); int main(void) { HMODULE h = LoadLibraryA("你的模块名.dll"); PFN fn; FILE *fp; double c, v, n, th; int hit = 0, total = 0; if (!h) { printf("load fail: %lu\n", GetLastError()); return 1; } fn = (PFN)GetProcAddress(h, "XS_PICK"); /* 名字必须与导出表一致 */ if (!fn) { printf("symbol not found\n"); return 1; } fp = fopen("sample.csv", "r"); if (!fp) return 1; while (fscanf(fp, "%lf,%lf,%lf,%lf", &c, &v, &n, &th) == 4) { total++; if (fn(4, c, v, n, th) > 0.5) hit++; /* 参数个数在前,与引擎一致 */ } fclose(fp); FreeLibrary(h); printf("total=%d hit=%d rate=%.4f\n", total, hit, total ? (double)hit / total : 0.0); return 0; }

这个驱动的价值在于它复用了同一份 DLL、同一套参数顺序,所以它算出来的命中率可以直接和客户端里的选股结果对拍。两边对不上,就说明问题出在引擎调用环节(参数顺序、类型、目录),而不是逻辑本身——把排查范围一刀切成两半,效率差别很大。用 VC++ 6.0 编这个控制台程序,同样/MT,同样 32 位,免得加载 32 位 DLL 时踩位宽不匹配。

回放还有一个副产品:它能跑出历史每一期的命中明细,把命中率、平均持有天数、最大回撤这些指标算出来。到了这一步,选股插件就不再是"感觉挺好用"的玄学,而是一个有数据支撑的模块。

那张对拍表我一般会留一份,格式是这样:

验证项客户端结果离线回放判定
命中只数1212一致
命中率0.02400.0240一致
重复跑三次12/12/1212/12/12无状态

第三行是我最看重的。只要出现 12/13/11 这种波动,立刻回去查静态变量和未来数据,别急着调参——参数再好,逻辑不确定就是白搭。

源码包里的教程部分建议按"先跑通最小骨架、再加自己的因子、最后做离线对拍"这个顺序看,别一上来就扎进完整工程,那份代码里的历史包袱不少。压缩包我放在下面了,需要的话自取。

从那以后我每次改完 DLL,都强制走一遍"导出表核对 + 三次一致性回放",再进客户端跑全市场。这个习惯让我少加了很多次班,也少丢了几次画线。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 7:13:05

客户反馈管理系统实战:状态机闭环、SLA与发件箱设计

简介&#xff1a;客户反馈管理系统是一套面向企业客服、产品运营与质量管理人员的反馈处理方案&#xff0c;围绕客户评价的收集、分类归档、分析报告、问题跟踪与满意度评分展开&#xff0c;帮助团队把分散的客户声音沉淀为可追踪、可量化的改进依据&#xff0c;也适合作为CRM集…

作者头像 李华
网站建设 2026/10/23 7:12:40

代码辅助工具入门指南:安装、配置与界面中文化实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 7:11:54

GParted Live ISO:Linux分区调整与根分区扩容实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 7:09:57

整点秒杀前端实战:时间同步、状态机与防重复请求

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 7:09:42

SillyTavern 内存优化实战:三步降低浏览器内存占用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 7:08:39

MATLAB光纤色散仿真与链路预算:D/β2换算、SSFM和眼图Q值

简介&#xff1a;面向光纤通信与MATLAB仿真学习者的色散研究代码包&#xff0c;适合具备通信原理基础、希望用脚本复现光纤模式分布与色散补偿思路的读者。压缩包共14个文件&#xff0c;均为.m脚本&#xff0c;大小约14KB&#xff0c;主要包含LP模式系列函数与三维极化绘图函数…

作者头像 李华