华宝油气净值估算的PHP程序
2015年8月18日
眼看Qualcomm收购CSR股票的现金快要到账,最近我在琢磨在A股中国特色的QDII基金华宝油气和美股XOP之间套利。每天看Yahoo新浪等网站的股票行情,时不时还要用鼠标点开计算器算算转换价格,时间长了后有点烦。
后来我想起来5年前学习的PHP,于是打算写我的第二个PHP程序,统一把套利需要常看的行情显示在一起。
同时根据SPDR标普油气开采指数ETF(XOP)、标普油气开采指数(^SPSIOP)、以及美元对人民币的汇率计算华宝油气LOF(SZ162411)净值。今天出了第一版,记录下相关开发过程以备日后查阅。A股的QDII基金缺乏及时的信息更新,希望这里能够补上这个生态位空缺。
谢谢abkoooo帮助提供了新浪实时美股数据接口的格式。
美股、A股、期货和汇率都用新浪实时的数据接口:gb_xop,sz162411,hf_CL,USDCNY
一开始发现无论怎么弄fopen
打开这些链接都会失败,估计是我用的Yahoo网站服务不支持allow_url_fopen
。
在网上找解决方法,发现应该用早就有的curl。抄了2段curl代码,仿照file_get_contents
函数的名字加了个url_get_contents
函数。
为提高页面反应速度,使用2个文件gb_xop.txt和sz162411.txt分别保存最后更新的股票数据,同时实施以下优化:
- 跟文件时间在同一分钟内的页面请求直接使用原来文件内的数据。
- 美股盘后交易结束后的页面请求直接使用gb_xop.txt内的美股数据。
- A股闭市后的页面请求直接使用sz162411.txt内的A股数据。
类似的,原油期货数据缓存在文件hf_cl.txt,美元人民币汇率数据在usdcny.txt。
所有的代码最终都会烂到无法维护,成功的项目就是在烂掉之前发布出去的。

经典测试图像Lenna部分原始图片
2015年8月20日
为严格交易规则, 套利过程中我打算简单的在均线上下单买卖XOP. 这个版本加入下一个交易日XOP预计的常用SMA均线值,
以及当前成交价格相对于华宝油气对应净值的溢价.
作为一个懒人, 我给自己预定的交易模式是盘前下单, 交易时间不盯盘. 关注过新浪等网站提供的均线指标的都知道, 这些值是随着当天的交易一直在变动的.
因此我需要在盘前下单时先算出一个不动点用于买卖.
从最简单的5日线说起:
A5 = (X0 + X1 + X2 + X3 + X4) / 5;
其中X0是当天交易价, X1-X4是前4个交易日的收盘价. 为方便起见, 可以把 (X1 + X2 + X3 + X4) 写成 ∑X4. 按这个模式, 任意日的简单均线SMA可以表示成:
An = (X0 + ∑Xm) / n; 其中m = n - 1;
在什么时候会有一个不动点可以用于买卖呢? 显然是An = X0的时候, 这样An = (An + ∑Xm) / n, 从这个简单的一元一次方程可以解出An不依赖于X0的表达式:
An = ∑Xm / (n - 1); 或者 An = ∑Xm / m;
这样就很清楚了, 当我说5日线的时候, 我实际算的是前4个交易日收盘价的平均值. 当我说20周线的时候, 我实际算的是前19周每周最后一个交易日收盘价的平均值.
这样算出来的不动点是极限值, 所以我整天装神弄鬼说XOP过了什么什么均线算强势, 没过什么什么均线算弱势. 而这些装神弄鬼的背后, 其实用到的都是小学数学.
XOP历史数据每天只需要更新一次, 采用Yahoo股票历史数据: https://finance.yahoo.com/quote/XOP/history,
同样每天只需要更新一次的还有华宝油气基金官方净值, 来自于f_162411,
使用文件f_162411.txt缓存, 因为不知道什么时候更新当日数据, 只好采用一个小时更新一次的笨办法.
增加调试文件debug.txt用于临时查看数据.
2015年8月21日
发了这个工具小软件链接后,昨天翻墙出去看了一下Google Analytics的统计。上线三天,总共289个IP访问了584次。跟Palmmicro通常的客户访问网站极大不同的是,访问这个工具的有1/3用的是手机。于是匆忙加上为手机用户优化显示界面的代码。
使用http://mobiledetect.net判断是否手机用户访问,代码从github复制下来按照原开发者的建议单独放在/php/class/Mobile_Detect.php中。
2015年8月24日
每次进phpMyAdmin去看历史数据虽然不算麻烦,但是毕竟还是用自己写的网页看更有成就感!
历史价格
日期 | 开盘 | 最高 | 最低 | 价格 | 成交量 | 复权价格 |
2023-10-02 | 147.96 | 148.28 | 141.78 | 142.98 | 6676206 | 142.98 |
2023-09-29 | 151.01 | 151.01 | 147.33 | 147.91 | 5694762 | 147.91 |
2023-09-28 | 149.52 | 151.53 | 149.45 | 150.54 | 5741880 | 150.54 |
2023-09-27 | 147.78 | 150.92 | 147.12 | 149.73 | 6168896 | 149.73 |
2023-09-26 | 144.51 | 146.67 | 144.31 | 145.43 | 3797809 | 145.43 |
2023-09-25 | 143.39 | 146.19 | 143.12 | 146.06 | 3445821 | 146.06 |
2023-09-22 | 145.21 | 146.14 | 143.19 | 143.42 | 4927654 | 143.42 |
2023-09-21 | 146.41 | 147.12 | 143.52 | 143.84 | 5693045 | 143.84 |
2023-09-20 | 146.96 | 148.7 | 145.39 | 145.53 | 3975474 | 145.53 |
2023-09-19 | 150.92 | 151.26 | 147.05 | 147.8 | 4185866 | 147.8 |
2015年8月27日
整理代码最好的方式是多开发几个类似QDII工具。伴随最近抄底港股加入恒生ETF(SZ159920)和H股ETF(SH510900)净值计算工具,观摩美股崩盘期间顺手加入了标普500ETF(SH513500)净值计算工具,也许日后会用上。
牢记股市三大幻觉:A股要涨、美股见顶、港股便宜!

女士,如果一个地方我不知道如何走出去,就绝不会走进去。
2015年9月13日
跟我的第一个PHP程序结合起来, 用户登录后可以输入相关股票交易记录. 根据交易记录计算华宝油气和XOP对冲交易策略和数据.
交易记录的输入和处理分别在文件/woody/res/php/_edittransactionform.php和/woody/res/php/_submittransaction.php.
同时修改Visual C++的Woody的网站工具对_editXXXform.php名字格式的自动生成对应的_submitXXX.php文件.
开始自己写PHP的class类
2015年11月7日
分离数据和用户界面代码,把QDII用到的股票数据部分放到StockReference类中,用在QdiiAccount类中。
继续整理代码,为热心吃螃蟹的用户们增加纳指ETF、恒生H股、国泰商品、石油基金和诺安油气等页面.
2016年1月8日
在塔夫男等人的建议下,加入华宝油气基金历史表格记录每天的折价溢价情况。最近几天的直接显示在当前页面,同时增加单独显示全部历史数据的页面。
SZ162411的历史价格相对于净值的溢价 基金溢价记录
日期 | 价格 | 净值 | 溢价 | 官方估值 | 时间 | 误差 | XOP净值 |
2023-09-28 | 0.834 | 0.8274 | 0.8% | 0.828 | 05:15 | 0 | 149.85 |
2023-09-27 | 0.808 | 0.8046 | 0.42% | 0.805 | 05:57 | 0 | 145.42 |
2023-09-26 | 0.8 | 0.808 | -0.99% | 0.808 | 06:17 | 0 | 146.07 |
2023-09-25 | 0.796 | 0.7942 | 0.23% | 0.794 | 06:01 | 0 | 143.41 |
2023-09-22 | 0.799 | 0.7962 | 0.35% | 0.796 | 05:35 | 0 | 143.79 |
2023-09-21 | 0.787 | 0.8049 | -2.22% | 0.805 | 05:14 | 0 | 145.44 |
2023-09-20 | 0.801 | 0.8172 | -1.98% | 0.817 | 05:07 | 0 | 147.77 |
2023-09-19 | 0.822 | 0.8257 | -0.45% | 0.826 | 06:24 | 0 | 149.39 |
2023-09-18 | 0.834 | 0.8261 | 0.96% | 0.826 | 06:49 | 0 | 150.11 |
2023-09-15 | 0.844 | 0.8412 | 0.33% | 0.841 | 06:46 | 0 | 152.83 |
统一数据显示格式
2016年1月26日
在oldwain的建议下,在相关价格记录的时间中加入日期显示。原来版本中没有它是因为自己觉得交易日期很明显,完全没有必要出来占地方。不过既然有人觉得有问题,我就效仿白居易写诗先读给妇孺听的优良传统改了。
估计跟我从2000年开始就在美股赔钱不同,很多人还是不熟悉美国股市交易时间。而在这里,美股数据后面跟的是美东日期和时间。
虽说是个小的分离数据和显示改动,但是忍不住哗啦哗啦又整理优化了一大片代码。
把原来的StockReference
类作为基础类,原来期货和汇率数据读取分别改为继承自它的FutureReference
类和ForexReference
类,达到统一数据显示格式的目的。
参考数据
代码 | 价格 | 涨幅 | 日期 | 时间 | 名称 |
SZ162411 | 0.834 | 3.22% | 2023-09-28 | 15:00 | 华宝油气LOF |
2016年1月27日
不知不觉在前面写了很多QDII。其实QDII和华宝油气这个名称里后面的LOF,绝大多数的美国人都不会认识。
把Google设置成显示英文结果,然后查QDII,百度百科的中文页面显示在搜索结果的第2位,第3位是Wiki。听过一个笑话,一个腹黑的HR问程序员求职者碰到问题怎么办,回答去查百度的都会被默默的拒掉,因此我就不去看它了。
Wiki的QDII词条下显示了它是Qualified Domestic Institutional Investor的简称,同时用简体和繁体标注了合格境内机构投资者。
跟QDII一样,LOF也是一个出生和仅用于中国的英文简写。它更惨,英文的Google完全没有收录它的中国用途:Listed Open-Ended Fund的简写,意思是上市型开放式基金。
跟QDII和LOF不同,ETF是个货真价实的英文简写。常出现的XOP就是美股的ETF。对我来说,A股的ETF和LOF的区别按重要性排列如下:
- ETF通常都是100%仓位,而LOF一般不会超过95%的仓位。仓位上的细节会决定估值的准确度。
- A股可以从6位数字代码上区分。深市ETF代码从150000到159999,深市LOF代码从160000到169999。沪市ETF代码从510000到518999,沪市LOF代码从500000到509999。SH510900就是一个沪市ETF。
- A股ETF的申购门槛通常至少都是50万份或者100万份,我这种穷套利者玩不起,所以其实我到现在也没搞清楚具体到底是50万还是100万。在美股市场,ETF的申赎基本上都是由做市商完成的。可以看出,A股从制度上来说其实有利于套利群体。
- ETF的申赎会比同类型LOF早一个交易日确认。对有钱的套利者来说,就可以少担一个交易日的风险。
夜深忽梦少年事 梦啼妆泪红阑干
2016年2月22日
有人跟我指出基金溢价记录中净值的日期显示早了一天,我差点一口鲜血吐在了键盘上。用脚趾头想想,要计算华宝油气当天的交易溢价,肯定是要跟前一天的净值比较啊。当天的净值要等当晚美股收盘后才出来,否则的话我写这个净值估算有什么意义呢。
把当天的交易价格跟前一天的净值放在一起比较,其实也正是我平时最为推崇的不同数据显示方式引导不同思维模式的举措。
不过为了避免以后还有人搞混淆,我干脆另外加了一个单独的净值记录显示页面,算上最开始的历史价格,现在总共有3个历史数据页面了。
周期3意味着混沌
2016年2月26日
华宝油气持续溢价10%已经成了常态, 最近最高甚至到了17%, 华宝油气和XOP套利没法做了.
继续整理同类代码, 这次下手目标是MySQL相关部分. 加入MysqlReference类继承自StockReference类. 集中代码处理历史记录和净值校准等数据库内容.
再加入MyStockReference类继承自MysqlReference, 从此代替StockReference类作为股票数据实例.
FundReference, FutureReference和ForexReference同时也改为继承自MysqlReference.
从MysqlReference开始调用了数据库相关函数.
2016年3月14日
美国进入夏令时, 发现一个bug: date_default_timezone_set('EST')
是没有夏令时的, 要用date_default_timezone_set('America/New_York')
.
2016年3月25日
趁复活节假日的空挡为黄金基金ETF(SH518800)、黄金ETF(SH518880)、黄金ETF(SZ159934)和黄金ETF基金(SZ159937)增加黄金白银页面。
一直有用户建议我在华宝油气等QDII的基金溢价记录表格上加入预估净值比较栏目。除了不愿意直接打自己嘴巴外的心理因素外,我迟迟没有加上它的原因主要是估值是跟着美股交易实时变化的,一直想不清楚这个时间上的对应关系。
在QDII的代码中,单独的预估净值变量原本放在QdiiAccount
类中,而在新的GoldSilverAccount
类中又再次用到了FundReference
类。
自然而然的,我把预估净值的变量挪到了FundReference
类中。当预估净值和当日净值的变量排列在一起后,突然之间数据结构引导思维方式的例子再次爆发,没有比在记录当日净值的时候同时记录预估净值更合理的了!
同时记录和显示估值的时间,这样当看到估值时间落在美股交易结束前,那么有误差就是天经地义的事情,而不是我的算法有问题。计算估值是由用户访问页面的动作驱动的,如果某页面没有用户经常访问,那么就会出现这种异常时间估值。
由于在股票交易日的净值系列页面访问量已经稳定在了1000左右,最高的一天有接近1700,我一直在琢磨如何优化页面应对以后可能的更大的访问量高峰。
把只会每天变化一次的SMA计算结果保存下来是很容易想到的,但是之前一直没有做。写完这4个黄金ETF的页面后,我意识到同一个GLD的SMA要在包括黄金LOF的嘉实黄金LOF(SZ160719)、黄金主题LOF(SZ161116)和贵金属LOF(SZ164701)共7个页面各算一遍,觉得不能再忍下去了。
基于之前在网上找Mobile-Detect代码的经验,我极大的低估了找一个现成的读写配置文件的PHP类的难度。比较容易找到的是一个要收费5美元的,号称同时支持文件和MySQL读写配置。而我就是不想多搞MySQL的表才想用文件存的,不免觉得这5美元有点浪费。
最后好不容易才翻到免费的INIFile。这个类原本只支持在已经存在的配置文件上修改,让我这个PHP新手折腾改了好几个小时才顺利用上。
新浪实时港股数据
2016年4月23日
在均金无忌的帮助下使用新浪实时港股数据(rt_hk02828),
替代原来延迟15分钟的新浪股票数据.
刚过去的周4净值页面系列的当日总访问量创纪录的超过了2200, 激励我继续优化页面反应速度.
近几年来最低级的bug
2016年5月15日
上周人民币又开始贬值, 让华宝油气估值暴露出一个新bug, 到了13号周5的时候, 我的估值居然比官方数据高了差不多一个百分点了.
周末开始查问题, 发现最后一次自动校准还是12号晚上拿到11号的官方净值后, 而本应该在13号晚上拿到12号官方净值后的自动校准居然没有做. 也就是说, 在过去的一段时间内, 自动校准都不知不觉的晚了一天,
只不过在汇率平稳的情况下这个问题暴露不出来而已.
找到问题并不难, 春节后为了用最简单的方法解决中美轮流休市导致的估值问题, 因为只有港股QDII会出现QDII净值数据比ETF新的情况, 我按照是否港股QDII重新整理了部分代码,
对美股QDII就不考虑根据今天的QDII净值和昨天ETF价格校准的情况了. 结果无意改了个其实无关的代码,
把$iHours = STOCK_HOUR_END + ($this->usdhkd_ref ? 0 : 24);
写成了$iHours = STOCK_HOUR_END + ($this->usdhkd_ref) ? 0 : 24;
不过这个bug严重打击了我的自信心. 这一次我没法用自己是个6年的PHP新手来自嘲了, 在我自豪的写了25年的C语言中, 这同样是个超级低级的错误!
2016年6月5日
王小波总是不忘记唠叨他写了自己用的编辑软件,在20年前我是暗自嘲笑的。没想到过了这么些年以后,我也开始写自己用的炒股软件了。不同的年龄段心态是完全不同的。
持仓盈利功能刚完成的时候页面出来得奇慢无比,而接下来刷新就会快很多。因为对自己的MySQL水平没有自信心,我一头扎进了优化数据库的工作中。
优化了一些明显的问题,例如扩展了stockgroupitem表的内容,把stocktransaction表中groupitem_id相同的交易预先统计好存在stockgroupitem表中,避免每次都重新查询stocktransaction表然后重新计算一次。
不过折腾了一大圈后并没有明显的改善,倒是在这个过程中理清了原来闭着眼睛写的代码的内在逻辑,看出来了问题的根源。
在按member_id查询stockgroup表找到这个人所有的股票分组后,我会对每个stockgroup直接构造MyStockGroup
类,
在它原来的构造函数代码中,会马上对该stockgroup中的每个stock构建一个MyStockTransaction
类, 而MyStockTransaction
的构造函数又需要这个stock的MyStockReference
类作为参数,
如果没有现成的实例可用,就会新构造一个。结果就是在首次统计持仓盈利的过程中,我会把几乎所有股票的数据都去新浪拿一遍,难怪那么慢。
找到问题就好办了,首先判断stockgroup中stock对应的groupitem_id到底有没有交易记录,没有的话就不去构造MyStockTransaction
类。另外预先统计好有交易记录的stock,统一去预取一下新浪数据。
随后我把预取数据的思路用在了所有需要读取新浪数据的地方,包括华宝油气净值计算在内,所有的页面反应速度都有不同程度的提升。原来我说因为网站服务器在美国所以访问慢的理由看来并不是那么准确的!

一头特立独行的猪
用PHP把GB2312编码字符串转换成UTF-8
2016年6月9日
最近一直在扩展净值估算的软件。陆陆续续改了这么多年网页,原本计划的PA6488方案没有用上互联网管理功能,这里却眼看要成为业余股票网站了。
随着涉及的股票越来越多,我打算用直接采用新浪数据中的股票名称和说明,避免手工一个个输入。结果四年前碰到的问题又回来了,新浪的数据还在用GB2312编码,而我反复折腾mb_detect_encoding
和iconv
等PHP函数都无法把GB2312转换成UTF-8。
不过我已经不是当年的吴下阿蒙。我先上网找来了GB2312和UNICODE的对应码表,然后写了个转换工具,生成了按照GB2312作为key排序后的对应数组,最后在函数GbToUtf8
中把查表得到的UNICODE调用网上找来的unicode_to_utf8转换成UTF8。
整个过程耗时一个晚上一气呵成,感觉好极了!
QDII工具中考虑当日CL交易情况后的T+1估值
2016年8月18日
发现有人的Excel计算表格中有这一项,我也就顺应潮流把它加上了。大概是沿用集思录的叫法,把已经公布的净值称为T-1、把估算的官方将要公布的下一日净值称为T、而把考虑了当日美油期货CL变动的称为T+1估值,大致意思是用白天CL的变动预测晚上XOP的变动。
按我的看法,拉长到一年看CL和XOP对应关系可能是不错,但是具体到每一天就未必了,所以在自己的套利交易中目前是不考虑这个T+1估值的。当然需要进行期货交易也是我不做它的一个重要因素,怕不小心杠杆赌大了把自己搞破产。一手CL是1000桶,目前每桶油价大约50美元,也就是说每次要交易五万美元的货值。
因为特立独行的原因,我不喜欢T-1/T/T+1这种叫法。于是我在网页中把T-1直接写成了净值,T日估值称为官方估值,而把T+1估值称为实时估值。另外还有一个参考估值,接下来解释一下这些看上去混乱的估值名称。
参考估值和实时估值的区别仅仅是用不用CL的实时交易数据。实时估值假定SZ162411和CL关联程度是100%,XOP和USO关联程度也是按照100%估算。由于估值依赖CL和USO在美股交易时段的自动校准,而期货总是免不了升水贴水,每个月20日左右CL期货换月的当天实时估值是不准确的。
另外因为CL期货的每日结算价格通常跟收盘价不同,CL期货收盘比美股晚一个小时的收盘价也不同于我在估值中实际用来参考的美股收盘时的CL价格,有可能出现CL价格的显示高(或低)于上一日,而参考估值低(或高)于实时估值的情况。
先说明一下如何把华宝油气官方估值精确到0.001元。说实在话,刚开始我也不可能想到花了整整一年时间才做到这一点。
- 要使用^SPSIOP或者XOP的净值,而不是XOP的交易价,两者通常并不一致。
- 要使用美元人民币中间价,而不是新浪的美元汇率实时交易价格,更不是离岸人民币价格。
- LOF基金要按95%仓位的处理,而不是ETF基金的100%。
估值网页链接
代码 | 净值 | 官方估值 | 溢价 | 参考估值 | 溢价 | 实时估值 | 溢价 |
SZ162411 | 0.8274 | 0.832 | 0.22% | 0.792 | 5.35% | 0.787 | 5.92% |
估值因素 | 官方估值 | 参考估值 | 实时估值 |
T日美股交易 | XOP净值 | XOP净值 | XOP净值 |
CL期货 | 否 | 否 | 是 |
美元人民币中间价 | T日 | T/T+1日 | T/T+1日 |
相对于官方估值,当美元人民币中间价波动比较大的时候参考估值就值得关注了,此外在A股或者美股休市的日子里, 它也比官方估值更能反映实际的净值。
至于为什么叫它参考估值,那是因为我也不知道给它取什么名字好。事实上,在英文版本和软件代码中我给它取名为FairEst
,意思是一个公平的估值。
在A股开市日期的美股交易时段,这三个估值通常都是完全一致的,参考估值因此不会显示出来。如果偶尔出现官方估值和实时估值不同,那是因为CL和USO的数据没能在同一分钟内自动校准或者软件改出了新BUG。
显然在美股交易时段是没有T+1的美元人民币中间价的,此时的实时估值用的只能是T日的美元人民币中间价。此时所有的估值和校准都是为美股结束后的参考估值和实时估值做准备,用户只需要看官方估值即可。
在美股交易结束后,这3个估值就开始分道扬镳了。T日官方估值不会再变化。CL通常会在美股收盘后继续多交易一个小时,此时实时估值也就会随之变化。
等到第二天,软件会去自动拿通常在9点15分发布的T+1日美元人民币中间价,参考估值会因此改变固定在新值上,实时估值也会在这时候开始用T+1日美元人民币中间价。

赢了会所嫩模,输了下海挖沙!
写了这么多细节,最后着重列一下大家最关心的:
- 验证估值算法准确程度和测算申购赎回的成本,看官方估值。
- 按溢价折价决定当日是否套利和做跟XOP配对交易的,看参考估值。折价不申购,溢价不赎回。此外A股或者美股休市的日子里也应该看它。
- 做跟美油期货CL配对交易的,看实时估值。
2016年9月18日
不知不觉中宣传和实践华宝油气和XOP跨市场套利已经快2年了. 期间碰到过LIFEFORCE这种自己动手回测验证一下能赚钱就果断开干的,
也有老孙这种数学爱好者回测验证一下能赚个年化10%后就袖手旁观的,
还有常胜将军Billyye这种觉得华宝油气可以看成无非是XOP延长了的盘前盘后交易没有多少套利意义的.
最气人的是thanous这种, 总是喜欢说大资金如何牛, 如果白天华宝油气在大交易量下溢价, 晚上XOP必然是要涨的, 彻底否定套利的根基.
最近几个月华宝油气折价多溢价少, 经历了几次溢价的情况后, 发现thanous的说法基本靠谱, 我于是开始按他的名字命名为小心愿定律. 中秋节前最后一个交易日华宝油气又溢价了,
大熊宝宝--林某人建议我实际测算一下, 正好放假闲着也是闲着, 就削尖铅笔搞了个新页面测试小心愿佯谬.
我网站记录了从去年底以来所有的华宝油气数据, 跑了下从去年底到现在的统计结果没有觉得小心愿定律能成立, 于是改名为小心愿佯谬. 但是去掉春节前后华宝油气因为停止申购导致的长期溢价的影响, 只考虑最近100个交易日的情况后,
有趣的结果出现了:
这里只统计了94个数据, 因为美股休市没有交易的日子被忽略了. 在华宝油气折价交易的情况下, 当晚XOP依旧是涨跌互现没有什么规律. 但是在平价和溢价的时候, 小心愿定律的确是明显大概率成立的!
说白了, 如果你发现了什么交易上的规律, 只是因为交易得不够多而已.
2016年10月6日
在华宝油气估值的时候,每次拿到官方发布的净值后都会根据净值当天的美股数据和美元人民币中间价做一次自动校准,从现在开始全部在SZ162411校准记录页面记录下来,方便观察长期趋势。校准时间就是拿到新的官方净值后第一次访问的时间。
类似的版面上还有CL和USO校准记录,用在QDII基金的实时估值上。
碰到XOP分红除权的日子,就需要进行手工校准。否则的话要等下一次自动校准后,估值结果才会再次正确。
Palmmicro微信公众号sz162411
2016年10月14日
作为一个搞了16年互联网产品的公司,Palmmicro居然一直没有开发自己的手机App。世界变化快,现在貌似也不用自己开发App,大多数的需求用微信公众号就足够满足。
因为一年多前做华宝油气净值估算页面的时候就跟提供QDII基金估值的公众号小飞猪flyingpig33学习过,我一直觉得加公众号是件非常简单的事情,没想到在启用微信公众平台开发模式消息接口的时候就碰到了问题。
采用几乎是一目了然的微信示例PHP程序,我在设置服务器链接的时候不断被提示Token验证失败,反复调试一整晚后才意识到是因为Yahoo网站服务在我的每个页面后都加了一段javascript统计代码。
因为我早就在用Google Analytics做网站统计,其实我一直觉得Yahoo前两年加的这个功能是个累赘,没有提供什么新功能,反而拖累了网页反应速度。这下我就有了充分理由去掉它。在Yahoo Small Business的新网站Aabaco Small Business里面又找了好半天,终于关闭了它。
接下来增加功能,现在最直接的需求就是用微信查华宝油气净值。采用对话方式,在消息中用语音或者键盘输入162411或者华宝油气等获取它的各种估值以及具体估值的时间。
用户如果只输入1,会匹配到大量的结果。受微信消息长度2048字节的限制,只会显示匹配靠前的一部分出来。如果直接用微信语音的话,微信自带的语音识别貌似要小小的训练一下。例如,如果一开始就说162411,识别的结果可能不如人意,但是如果先用键盘输入一次162411,以后的语音识别就会畅通无阻。
开发过程中碰到一个问题,微信消息有必须在5秒之内返回的限制。而根据Google Analytics过去三十天5934次对华宝油气估值页面的Page Timings统计,平均反应时间是10秒,这样大概率会超过微信的5秒限制,导致消息回应失败。反应时间慢的主要原因是估值前可能需要先访问新浪股票数据和美元人民币中间价等不同网站。
只好挽起袖子搞优化,尽可能的多在本地存数据,减少每次查询中对外部网站的访问。最后勉强把最长的回应时间控制在4228毫秒,总算满足了要求。
回到公司的产品上来,这个微信公众号和本网站一起作为一个具体应用实例,为开发中的PA3288物联网IoT模块提供一个数据采集、存储和查询的总体解决方案。在这个基础上,我们可以提供全套的产品和软硬件技术,帮助客户建立自己的物联网数据管理分析应用系统。
虽然目前还没有多少功能,大家已经可以扫描下面的二维码添加Palmmicro微信公众订阅号。选用sz162411作为微信号既符合目前提供的数据,又是个没有办法的选择,因为我太喜欢用palmmicro这个名字,以至于它早早就被我自己的私人晒娃微信号占用了。

Palmmicro微信公众号sz162411小狐狸二维码
查询A股股票数据
2016年10月20日
今天发现有个微信公众号用户用语音查询交通银行,没查到因为数据库中根本没有它。不过因此刺激了我给加上查询所有股票交易数据的功能。
首先我要把A股3000多只股票都加到数据库中。开始我想直接开个大循环从000001到699999从新浪拿数据,后来觉得太蠢了,还担心新浪的数据接口把我列入黑名单。不过接下来我从https://vip.stock.finance.sina.com.cn/mkt/#hs_a找到了所有A股数据。
还有数量上几乎跟股票同一个量级的指数https://vip.stock.finance.sina.com.cn/mkt/#hs_s。
继续给数据库中加美股代码,希望https://vip.stock.finance.sina.com.cn/usstock/ustotal.php这个不完整的美股单子能满足绝大多数中国用户的查询。
查询A股基金数据
2016年10月28日
昨天让我广发证券网上开户的经理帮忙宣传一下微信公众号查股票数据,随即加进来两个人。其中一个上来就查159915,发现没有数据后立马取消了订阅,又刺激了我给数据库加上所有A股基金数据。
从https://vip.stock.finance.sina.com.cn/mkt/#open_fund找到了基金列表,没想到全市场居然有上万基金。然后继续写代码加入了其中可以场内交易ETF和LOF,从此应该不怕被查。
2017年1月28日
为了有效配合今年的打新计划,我打算扩大中国石化外的门票范围。但是同时沿用AH股价格比较的思路,只选取A股价格低于H股的作为门票。
微信公众号搞了几个月,使用者寥寥。不过开发的过程中有个意外收获,帮助我彻底区分了净值计算和用户显示界面的代码。为了充分利用这个好处,我打算把AH比较也包括在查询结果中,结果又牵扯出不少一开始未曾想到的改动。
首先要加入港股数据https://vip.stock.finance.sina.com.cn/mkt/#qbgg_hk。 面对跟A股差不多一样多的港股,我犹豫了,担心会进一步拖累消息回应时间。然后我又打起了优化的主意:
- 输入刚好是六位数字并且数值大于等于1000时,直接按照按照A股代码规律扩展后寻找唯一匹配。例如162411匹配SZ162411,600028匹配SH600028。
- 输入刚好是六位数字并且数值小于1000时,寻找可能的沪市指数和深市股票最多两个匹配。例如000001匹配上证指数SH000001和平安银行SZ000001。
- 当输入有非ASCII字符,比如中文华宝油气时,不查找代码,而是只在名称字段寻找可能的最多32个匹配。
- 其它情况如sz162411同时在代码和名称字段寻找可能的最多32个匹配。
这样一来,输入162411永远会反应最快,华宝油气第二,sz162411最慢。至于想输入hbyq拼音简称的,则什么都查不到!
AH数据来源:https://vip.stock.finance.sina.com.cn/mkt/#aplush
现在可以输入600028或者00386试试看,同时增加个对比页面:
A股和H股对比 AH历史价格比较
代码 | H股代码 | A股价格 | H股人民币¥ | A/H比价 | H/A比价 |
SH600028 | 00386 | 6.07 | 3.73 | 1.6293 | 0.6138 |
2017年3月9日
因为偶然注意到CL和USO校准记录的数据异乎寻常的多,让我发现了从去年11月中旬开始,就有一个网络爬虫从相连的两个IP地址以每秒两次的频率自动爬华宝油气等四个页面,持续爬了快四个月。
在惊讶之余,我的第一反应是每个月9.99美元跑PHP代码的Yahoo网站服务太值了,处理如此辛勤的爬虫,竟然没有让我这种最常用用户感觉到任何性能上的变化,看来未来即使正常访问量提高100倍都能应付过来。
其实我估值软件每分钟才访问一次新浪股票数据,所以爬虫每秒都来爬是没有任何意义的,每分钟来爬一次足够了。
我的第二反应,是赶快加了一个对单个IP地址访问Palmmicro.com的次数访问统计,每当访问次数累计到1000次就强制要求登录一次。爬虫很快就被暂时挡在了数据之外,不过这也会在以后给正常访问的常用用户带来一点小麻烦。
同时我很清醒的认识到,为了克服我设置的这个小障碍,爬虫要实现自动登录其实是很容易的。另外即使是目前这种状态,依旧有每秒两次的访问压在登录页面上,一样给服务器带来了不必要的额外压力。
十多年前当我在PA1688上做H.323的时候,曾经费尽心力从http://ipinfo.io/这种类似网站查询设备所在的公网IP地址,留下了很坎坷的回忆。
而今天在处理完网络爬虫的问题后,我突然意识到查询公网IP已经成了现成的副产品,激动之余写了这个IP地址数据的工具。为防止爬虫滥用,这个页面直接要求登录。
最后我感觉到每校准一次就增加一条记录没有必要,改成了每天只加一条记录,同时记下当天最后一次CL和USO校准的时间。
2017年4月2日
SMA均线交易XOP很有效, 但是有时候会在价格突破所有均线后失去用武之地, 因此我把布林线也加入进了交易系统, 跟SMA放同一个表格中显示.
同样为避免半夜盯盘, 我还是需要一个不动的布林线交易点. 这时候小学数学就不够了, 要用到一点初中数学知识. 沿用上面的SMA表达方式, 布林线的出发点依然是简单均线SMA, 可以换个符号写成:
B = An = (X0 + ∑Xm) / n; 其中m = n - 1;
在计算出B后, 继续计算标准差σ:
σ² = ((X0 - B)² + (X1 - B)² + (X2 - B)² + ... + (Xm - B)²) / n;
B和σ都计算出来后, 布林上轨是B + 2 * σ; 布林下轨是B - 2 * σ;
现在来计算用来交易的不动点, 为简化起见, 先只考虑布林下轨, 就是说当天交易价格X0刚好到布林下轨的情况, 用这个价格计算对应的布林值. 写成条件是:
X0 = B - 2 * σ;
带入到上面计算B的公式后得到:
B = (B - 2 * σ + ∑Xm) / n
从而解出σ = (∑Xm - (n - 1) * B) / 2; 或者 σ = (∑Xm - m * B) / 2;
再把条件 X0 = B - 2 * σ; 带入到计算σ的公式后得到:
σ² = (4 * σ² + (X1 - B)² + (X2 - B)² + ... + (Xm - B)²) / n;
定义∑Xm² = X1² + X2² + ... Xm²; 上面可以写成:
(n - 4) * σ² = ∑Xm² - 2 * ∑Xm * B + m * B²;
带入上面解出的σ = (∑Xm - m * B) / 2; 最后得到一个B的一元二次方程:
(n - 4) * (∑Xm - m * B)² = 4 * ∑Xm² - 8 * ∑Xm * B + 4 * m * B²;
令 k = n - 4; 写成标准的ax²+bx+c=0的格式:
a = k * m² - 4 * m;
b = (8 - 2 * k * m) * ∑Xm;
c = k * (∑Xm)² - 4 * ∑Xm²;
做计算机最擅长的事情, 解出这个方程的2个根得到2个不同B值.
然后数学的神奇魅力出现了, 虽然列方程的时候只考虑了布林下轨, 解出B的2个值以及对应的σ后, 却同时得到了不依赖于当天交易价X0的布林上轨和布林下轨值.
实际应用中我采用大家都用的20天布林线, 也就是说n = 20, 而我是用前19个交易日的收盘价算的当日不动点的布林上轨和布林下轨, 作为交易价格.
不像简单均线SMA的不动点, 可以从一元一次方程中解出一个很容易理解的表述: 20天的SMA不动点就是前19天收盘价的平均值.
解布林线一元二次方程得到的结果就没有一个类似的容易理解的表述了, 很难说它是什么, 但是可以很简单的说它不是什么, 它不是只算19天的布林上轨和布林下轨.
事实上, 因为考虑的都是极限因素, 20天布林上下轨不动点的开口要比只算前19天的布林上下轨大, 就是说, 下轨更低一点而上轨更高一点.
感觉好久没做这么复杂的数学了, 把计算过程拍了个照片留念一下.
你永远比你想象中更勇敢 -- 相信梦想
2017年4月10日
做完IP地址数据这个简单的单行输入然后把输入显示出来的用户界面后,发现自己无意中实现了一个副产品。
一直有人用各种参数试探攻击我的网页,所以早就想解码这些%3A%2F%2F然后显示出来看看到底是些什么参数,没想到这个界面调用urldecode
后就直接实现了这个功能。
另外一个一直想解码显示的是从1970年1月1日开始所有秒数Unix的时间戳,也顺手加了is_numeric
区分后显示出来。
最重要的是,随着curl
使用不断增加,经常要重复写代码测试读取某个数据接口。我干脆加了个判断,如果输入以http开头,就调用curl
函数去读一下,然后保存下来进一步调试。

成年人的生活中没有容易二字
200日和50日EMA均线
2017年10月1日
均线交易系统中加入美股最看重的牛熊分界线200日EMA均线和小牛熊分界线50日EMA均线。按美股标准,当50日EMA上穿200日时进入牛市,下穿则进入熊市。
考虑到50日EMA在数值上其实跟10周SMA差不多,而200日EMA则大致相当于10月SMA,为避免重复加减仓位,我并不在这2个EMA数据上进行交易,而仅仅只是看它们衍生显示的牛熊状态。
依旧是出于控制仓位的目的,熊市抄底做多时我只在日布林下轨或更低价格的周线SMA和月线SMA上加仓,牛市做空时我也只在日布林上轨或更高价格的周线SMA和月线SMA上进一步卖空。
用En表示今天的n日EMA值,其它沿用前面的符号:
En = k * X0 + (1 - k) * Em; 其中m = n - 1; k = 2 / (n + 1)
不动点En = X0,得到En = Em,就是说今天的不动点就是昨天的值。所以唯一要做的就是每天收盘后算一下当天的EMA。
2017年12月26日
记得2000年刚到硅谷工作,去电影院的时候总会在正片播放前看到一段让我自我感觉膨胀的广告。大意是如果你知道一个等号和两个等号的区别,就可以在我们这里找份工作了!
写PHP还需要知道三个等号跟前两个的区别,事实上对习惯了C语言的人来说是个坑,我今天就不幸踩了一个。
在修改用来方便记录股票交易的个人常用短语代码的时候,我无意中在https://www.php.net上看到有关strstr
的一个信息:
如果你仅仅想确定needle是否存在于haystack中,请使用速度更快、耗费内存更少的strpos函数。
总是热衷于代码优化,我马上如获至宝当即改了几十个地方,却发现有些像if (strpos($str, 'www.'))
的代码变得不工作了。原因是会返回位置0,这时候要写成if (strpos($str, 'www.') !== false)
,才跟原来if (strstr($str, 'www.'))
代码效果一致。
不过这不是我碰到的最深的PHP坑。最坑人的PHP函数是array_merge
,它在全数字下标的时候居然会把所有数字下标从头开始排序!
这时候要把$ar = array_merge($arA, $arH, $arUS)
简单写成$ar = $arA + $arH + $arUS
。反过来,加法也不能随便写,无下标数组写加法也会出错!
从MySQL表中查找GB2312对应的UNICODE
2018年2月16日
随着我的股票网站软件功能越来越繁多,对网站的访问也越来越不稳定,经常需要重新刷新一次才能正常显示页面。很久以来我一直认为是从中国访问在美国的Yahoo网站服务不稳定造成的,也就一直没有深究。
这个春节在圣地亚哥溜娃一个月,我很悲哀的发现,在美国访问网站也经常需要重新刷新。联想到Google总是利用Chrome浏览器的输入抢先一步爬一下我要访问的网页的坏习惯,我意识到一定是程序哪里出现了执行效率问题,不能正确回应两个几乎同时的页面请求。
庞大的UTF-8全局数组马上成了最大的疑犯。
在我把全局数组放进函数后,情况更加恶化了。需要重新刷新的情况看上去像是少了一点,却出现了其它全局数据被莫名其妙的冲掉的新问题。
好在经过这么多年后,我对MySQL已经没有那么畏惧,在溜娃间隙中削尖铅笔加了一个GB2312和UNICODE的对应表,把查内存中的大数组改成了查数据库,终于解决了这个困扰了我一年半的刷新问题。发现帮助傻瓜编程的PHP也对程序优化有要求还是挺让我兴奋的,觉得这么多年来的优化软件经验终于又有了用武之地。

圣地亚哥海洋世界的美人鱼
走火入魔的T+1均线
2018年3月27日
从宇宙观上来说,我是不相信历史能够预测未来的,当然也就不相信技术分析能够预测市场。但是交易XOP这4年多来,我却在技术指标上一步一步加码。从SMA均线、布林线到美股牛熊分界线EMA均线,我都觉得自己变成了一个神棍。
现在居然搞起了T+1均线,原因是我发现XOP的SMA周线和月线经常能做出非常准的交易价格预测,但是SMA日线和和布林线就不如前2者。
而另外一方面,XOP的收盘价却经常会刚好在第2天我计算出来的SMA日线或者布林线上。这让我猜想每天交易结束前也许有人偷跑,会提前估算在第二天的均线位置上交易。
偷跑也可以解释为什么我觉得周线和月线准确,因为要在周5和月末最后一个交易日才会出现周线和月线上的偷跑,总体概率就小了。
计算SMA的偷跑很简单,沿用前面SMA的表述:
An = (X0 + ∑Xm) / n; 其中m = n - 1; 改写为
An = (X0 + X1 + ∑Xm) / n; 其中m = n - 2;
偷跑的情况下,不动点是An = X0 = X1,这样An = (An + An + ∑Xm) / n,从这可以解出An不依赖于X0和X1的表达式:
An = ∑Xm / (n - 2); 或者 An = ∑Xm / m;
这个结果可以非常简单的理解成,5日SMA偷跑的T+1结果,就是算一下前3天的SMA均线而已。
再来依葫芦画瓢算布林线的偷跑:
B = An = (X0 + X1 + ∑Xm) / n; 其中m = n - 2;
还是先只考虑布林下轨,偷跑交易的不动点写成条件是:
X0 = X1 = B - 2 * σ; 带入上面得到:
B = (B - 2 * σ + B - 2 * σ + ∑Xm) / n;
从而解出σ = (∑Xm - (n - 2) * B) / 4; 或者 σ = (∑Xm - m * B) / 4;
在把条件X0 = X1 = B - 2 * σ; 带入标准差σ计算公式:σ² = ((X0 - B)² + (X1 - B)² + (X2 - B)² + ... + (Xm - B)²) / n; 得到:
σ² = (4 * σ² + 4 * σ² + (X2 - B)² + ... + (Xm - B)²) / n;
定义∑Xm² = X2² + ... Xm²; 上面可以写成:
(n - 8) * σ² = ∑Xm² - 2 * ∑Xm * B + m * B²;
带入上面解出的σ = (∑Xm - m * B) / 4; 最后得到一个B的一元二次方程:
(n - 8) * (∑Xm - m * B)² = 16 * ∑Xm² - 32 * ∑Xm * B + 16 * m * B²;
令 k = n - 8; 写成标准的ax²+bx+c=0的格式:
a = k * m² - 16 * m;
b = (32 - 2 * k * m) * ∑Xm;
c = k * (∑Xm)² - 16 * ∑Xm²;
最后解出结果。
EMA设计精巧,不存在偷跑的问题,所以没有T+1估值。
XOP 2023-10-02数据 牛市 历史价格
均线 | 估值 | 溢价 | T+1估值 | 溢价 | SZ162411估值 | T+1估值 |
5日 | 147.79 | -3.25% | 147.14 | -2.83% | 0.817 | 0.814 |
10日 | 146.16 | -2.18% | 146.24 | -2.23% | 0.809 | 0.809 |
20日 | 148.5 | -3.72% | 148.38 | -3.64% | 0.821 | 0.821 |
布林上轨 | 155.55 | -8.08% | 157.12 | -9% | 0.858 | 0.866 |
布林下轨 | 141.46 | 1.07% | 139.65 | 2.38% | 0.784 | 0.775 |
5周 | 148.29 | -3.58% | 146.91 | -2.68% | 0.82 | 0.813 |
10周 | 147.62 | -3.14% | 148.13 | -3.48% | 0.817 | 0.819 |
20周 | 137.06 | 4.32% | 137.96 | 3.64% | 0.761 | 0.766 |
周布林上轨 | 162.65 | -12.09% | 168.17 | -14.98% | 0.896 | 0.925 |
周布林下轨 | 111.47 | 28.27% | 107.76 | 32.69% | 0.627 | 0.607 |
5月 | 141.53 | 1.02% | 146.03 | -2.09% | 0.785 | 0.808 |
10月 | 133.62 | 7% | 133.05 | 7.46% | 0.743 | 0.74 |
20月 | 133.85 | 6.82% | 134.11 | 6.61% | 0.744 | 0.746 |
月布林上轨 | 158.58 | -9.84% | 165.06 | -13.38% | 0.874 | 0.908 |
月布林下轨 | 109.11 | 31.04% | 103.17 | 38.59% | 0.614 | 0.583 |
小牛熊分界 | 144.83 | -1.28% | | | 0.802 | |
牛熊分界 | 135.57 | 5.47% | | | 0.753 | |
2018年4月4日
雪球创始人方三文,自称不明真相的群众。平时总是苦口婆心的把盈亏同源放在嘴边,鼓动大家通过雪球资管做资产配置。但是他却认为自己对互联网企业有深刻理解,在推销自己私募的时候总是鼓吹腾讯和FB,又把盈亏同源抛在脑后了。
最近2个月腾讯结束了屡创新高的行情,开始跟FB一起下跌,引发了大家抄底雪球方丈的热情。不仅港股腾讯00700每天巨量交易,就连它在美股粉单市场的ADR在雪球上都热闹非凡。
这吸引了我的注意力,然后发现港股还有其它不少股票也有美股市场的American Depositary Receipt(ADR)。于是我按照原来A股和H股对比的套路增加了个页面蹭一下热度。同时也加入到了微信公众号的查询中:输入腾讯或者00700试试看。
数据来源:http://www.aastocks.com/tc/usq/quote/adr.aspx?sort=0&order=1&type=0
从数据库的表格开始,TableSql
是所有表格的基类,它本身也可以用在只有一个整数id的表格。
ValSql
基于TableSql
,试图包括所有一个整数id和一个val的表格,它本身可以用于id+浮点数的表格,例如基金仓位fundposition表。
DateSql
和IntSql
都基于ValSql
,分别对应id+YMD日期和id+整数的表格。
PairSql
基于IntSql
,额外为反向查询加上了索引,这样刚好用于A/H的情况:id是A股的stock_id,它对应的整数值是H股的stock_id。
StockPairSql
基于PairSql
,额外加上了从stock_id到symbol的来回转换,ahpair表就是直接来自它。
跟A股和H股总是1:1不同,每股ADR可以对应100、1或者0.5等各种不同数值的H股。因此一个自然的做法是继续从StockPairSql
派生adrpair表,加上这个额外的对应数值。不过这样一来,A/H和ADR/H比较页面能共用的代码就不多了。
在QDII估值中原本就有基金仓位fundposition表,我脑洞一开,想到每股ADR对应多少股H股其实也是一种仓位上的体现,就把不是1:1的ADR/H对应数值也存到了这个表中。
更妙的是,想通了比例对应仓位后,A/H和ADR/H之间的价格转换跟QDII估值比较就只差一个校准记录的概念了。具体的看,在A/H情况下,其实相当于校准值永远是1。而在ADR/H的情况下,校准值其实就是固定的(1/仓位)。
这样一来,我不仅统一了A/H和ADR/H比较页面的代码,还顺便统一了目前用到的各种价格转换计算,顿时感觉打通了任督二脉!
Life is like a snowball. The important thing is finding wet snow and a really long hill. — Warren Buffett
ADR和H股对比
代码 | H股代码 | ADR价格 | H股美元$ | ADR/H比价 | H/ADR比价 |
TCEHY | 00700 | 38.45 | 38.09 | 1.0095 | 0.9905 |
2018年4月5日
折腾完H股后觉得意犹未尽,一鼓作气继续加上AB股对比。其实我自己连B股账户都没有,写这个就是完全为了测试一下现有代码的可扩展性。此外,因为B股规模远小于A股,以后可以用来方便测试二者的共同代码。
数据来自https://vip.stock.finance.sina.com.cn/mkt/#hs_b。
输入查000488或者200488试试看。
A股和B股对比
代码 | B股代码 | A股价格 | B股人民币¥ | A/B比价 | B/A比价 |
SZ000488 | SZ200488 | 4.58 | 1.59 | 2.885 | 0.3466 |
人民币汇率
2018年4月10日
沉寂已久的微信公众号在清明假期中突然有人来查了下人民币汇率,因为没有任何匹配,这个查询通知到了我的电子邮件中,让我感觉一下子打了鸡血,学习微信小程序开发的劲头一下子足了好多。
微信订阅号中查不到用来估值的人民币汇率的确有点奇怪。原因是为了加快反应时间,向微信发的查询是不会去再去拿每天更新一次的人民币中间价数据的。
当然这现在已经难不倒我,可以从数据库中把最近两天的中间价找出来,拼成跟其他数据类似的格式提供给用户。按惯例,又全面整理好几天代码,直到今天才完工。
因为微信查找中我没有做中文分词,因此人民币汇率这种五个字的长查询其实是很难匹配的。为了保证下次用户能查到,我还特意手工把数据库中USCNY的说明从美元人民币中间价改成了美元人民币汇率中间价。
2018年4月16日
在给微信公众号增加了A股和B股对比的数据后, 意外发现SZ200168股票名字中的喆(zhe2)在转UTF-8后成了乱码。发现了一只蟑螂就说明有一窝。我把数据库中所有股票名字查看了一遍后,果然发现了SZ002752和SZ300208中的昇(sheng1)也是乱码。
产生乱码的原因很明显,这两个生僻字本身就不在只有六千多汉字的GB2312中。这意味着我需要一个GB18030和UNICODE的对应码表来扩展我的MySQL数据表。花了差不多一天功夫做完这些几乎算是推倒重来的修补后,我不禁又有了一种神功已成的感觉。
欲练神功,必先自宫;虽然自宫,未必成功;如不自宫,也可成功。
2018年5月3日
交易了几年XOP下来, 发现它的收盘价经常跟净值有个1分2分的偏差, 不知道这其中是否有套利机会.
净值价格比较
日期 | 价格 | 净值 | y溢价 | x涨幅 | 份额(万) | 换手 |
2023-10-02 | 142.98 | 142.8755 | 0.07% | -3.33% |
2023-09-29 | 147.91 | 147.8533 | 0.04% | -1.75% |
2023-09-28 | 150.54 | 150.5907 | -0.03% | 0.54% |
2023-09-27 | 149.73 | 149.8456 | -0.08% | 2.96% |
2023-09-26 | 145.43 | 145.4206 | 0.01% | -0.43% |
2023-09-25 | 146.06 | 146.0733 | -0.01% | 1.84% |
2023-09-22 | 143.42 | 143.4061 | 0.01% | -0.29% |
2023-09-21 | 143.84 | 143.7943 | 0.03% | -1.16% |
2023-09-20 | 145.53 | 145.4401 | 0.06% | -1.54% |
2023-09-19 | 147.8 | 147.7701 | 0.02% | -1.1% |
增加这个页面倒是让我突然下了决心删除英文版本. 压死骆驼的最后一根稻草是这行代码, 混在其中的中文冒号让我恶向胆边生, 彻底放弃了本来就几乎没有什么浏览量的英文版本股票软件.
echo UrlGetQueryDisplay('symbol').($bChinese ? '净值和收盘价比较' : ' NetValue Close History Compare');
从软件开发的角度来说, 遍布我PHP代码的1000多个$bChinese肯定意味着某种代码结构缺陷, 希望这次代码清理完成后能让我醒悟过来.
冷静下来后仔细想想, 发现自己早有停止英文版的意图背后其实有个更深层的原因. 三年来的各种跨市场套利经历, 让我深深体会到了对手盘的重要性和A股韭菜的可贵, 从而不愿意留个英文版让外面的世界进来抢着割这么嫩的韭菜.
If you've been playing poker for half an hour and you still don't know who the patsy is, you're the patsy. — Warren Buffett

巴菲特和盖茨一起打桥牌
2018年6月20日
配合抄底A股指数加入沪深300ETF(SH510300)页面,根据沪深300指数SH000300估算SH510300和ASHR的净值,看看有没有华宝油气和XOP这种跨市场套利的机会。
为了避免原有代码进一步走向混沌,不想从原有的FundReference
类扩展这种新估值模式,从MysqlReference
类继承了一个新的FundPairReference
。
2019年4月12日
昨天是王小波忌日,让我对最近的胸闷和牙疼症状充满了警惕。整理华宝油气净值的软件代码真有种死去活来的感觉,经常怀疑自己到底在干什么。今天看到这个图片,觉得该做点简单的东西恢复一下信心,就削尖铅笔写了这个分解质因数的工具。

激励我写分解质因数工具的图片
算法可以用最直接的方式实现。对指定的数字n,从2开始一个个反复除到n的平方根为止就行。下面用数字68举个具体的例子:
- 68的平方根在8和9之间,从2到8都除一遍就可以。68/2=34;68=2*?。
- 因为34还是偶数,继续来除2。34/2=17;68=2*2*?。
- 17不是3的整数倍数。
- 17不是4的整数倍数。这里可以看到,虽然原来68是4的整数倍数,但是已经在前面处理过了。
- 对数字5来说,因为5*5已经比17大,不用继续除下去。最终结果就是68=2*2*17。
接下来一个最直接的优化想法,就是先把一定范围内的已知质数算出来,这样在进行上面的计算时,就不用算17是不是4的整数倍数。
基于GB2312大数组的教训,这次直接把前4972个质数存到了MySQL的表中。不过结果让我很失望,查数据库中已知质数表的结果反而要比直接算要明显的慢。
网上查了下效率更高的算法,读过陶哲轩写的Pollard Rho的文章后觉得自己到底还是个数学白痴,放弃。
不过我还是很积极的在php下新建了一个子目录tutorial,把这个新文件primenumber.php放了进去。同时开始憧憬几年后真的开始自己做软硬件课件教林近岚编程序的话,今天这些工作可以做为其中的一节软件课。
做人要是没有梦想,跟咸鱼有什么两样?
微信流量主
2019年6月1日
两年多过去,微信公众号上现有517个用户,感觉基本上体现了目前华宝油气套利群体的规模。
佛前五百罗汉,田横五百壮士;微信用户超过五百人就可以开通流量主收广告费了。

田横五百壮士
微信公众号不提供查询的数据
2019年7月13日
昨天有人在微信公众号上查019547没有匹配。看了一下sh019547,发现居然是国债。软件工具有人用终归是好事情,不过以前我好像听说过资产一千万美元以下的不应该考虑债券投资,所以还是按捺住了兴奋的心情,没有再次削尖铅笔给我的数据库加上所有A股债券数据。
还有一个更加深刻的原因是,因为查询时会从头到尾遍历一遍股票数据库,现在的查询速度已经快要慢到了公众号的极限,实在不能想象再加一两万条债券进去会怎么样。
基于相同的原因,既拖慢速度我自己又不用,公众号也不提供场外基金的数据查询。
2019年9月5日
过去两个月XOP持续暴跌吸引了大量抄底华宝油气的,在很短时间内耗光了华宝基金公司的外汇额度。从7月31日起单日单个基金账户累计申购金额上限设置为10万,8月2日周五限额变成了1万,8月9日限额变成1000元人民币。
就像超新星爆发给天文学家提供了难得的测距参考一样,限购给我提供了少有的观察套利者的机会,所以我每天都在乐此不疲的追踪相关数据。
8月29日收盘价0.387,跟8月28日0.385的净值比溢价0.52%。很多溢价申购套利老手都不会放弃这个蚂蚁也是肉的赚钱机会。
9月5日场内新增72万股,由于9月2日美股休市暂停申购,这个数据可以看成是对应8月29日场外申购后转场内的份额。假如都是在华宝官网0.1折最低费用申购的话,限购1000块人民币下满额申购了:
720000/(998.5/0.397) = 286场外帐户
再回头看一下9月3日,场内新增695万股。假如这些新增都来自场内申购的话,对应8月29日场内限购1000块人民币下满额申购了:
6950000/(985/0.397) = 2801场内账户
之前还有一个机会可以同样看到在同一天场外申购的账户数比场内申购的账户数小一个数量级的情形,可以跟这个结果交叉验证。
8月13日场内新增7408万股,假定全部来自于8月6日(溢价1.78%)场外申购转场内和8月8日(溢价2.3%)的场内申购。假定每户都是用满1万申购额度,8月8日场内申购的净值为0.402,场内一折券商实际使用了9850块申购,每户实际到账2.450万股。
假定场外都是使用华宝官网0.1折,实际使用申购金额为9998.5,8月6日申购的净值为0.391,每户实际到账2.557万股。用未知数x表示场内申购的账户数,未知数y表示场外申购转场内的账户数,假定在我们考虑的最近一段时间这2个账户数都是固定不变的。由此得出第一个方程:
2.450 * x + 2.557 * y = 7408
8月14日场内新增810万股,本来按上面的逻辑新增应该全部来自于8月7日(溢价1.53%)场外申购转场内和8月9日(折价0.25%)的场内申购。8月9日是场内申购限购1000的第一天,不过可惜这天场内交易折价0.25%,应该同时出现了大量不限金额的赎回。多了一个无法定量的赎回变量,导致8月14日的数据无法像上面那列第2个方程。
8月15日场内新增1099万股,继续按前面的假设列方程。对应最后一天限购1万的8月8日(溢价2.3%)场外转场内,和限购1000的8月12日(溢价1.01%)场内申购。8日申购净值是0.402,12日申购净值是0.393。可以列出方程:
(985/0.393/10000) * x + (9998.5/0.402/10000) * y = 1099
保留4位有效数字合并常数后得到第二个方程:
0.2506 * x + 2.487 * y = 1099
使用Cramer法则解二元一次方程组的通用工具,得到场内申购户数 x = 2864,场外申购户数 y = 153。
原则上来说按我的假设,任何两天的数据都可以用来联立一个二元一次方程组,解出场内申购和场外申购的账户数。我一定要选择从限购1万到限购1000的变化时两天的数据来估算是出于计算精度的考虑,为了避免两个大数字相减后得到一个跟误差范围同一数量级的小数字,让整个结论失去意义。

用Cramer法则计算步骤
And what in heaven's name brought you to Casablanca?
My health. I came to Casablanca for the waters.
The waters? What waters? We're in the desert.
I was misinformed.
2019年9月20日
在使用Cramer法则解二元一次方程组得到华宝油气场内和场外申购账户数后,其实真正有帮助的结论只是场外申购账户比场内申购账户少一个数量级。因为其中我只区分了折价和溢价两种情况进行数据分析,但是实际上不同溢价时申购账户的区别其实是很大的。
因为场外账户远少于场内账户,我可以放心的忽略二者在不同申购日期下不同净值等细节,把所有申购都假设成为场内申购计算。做一个通用工具,把限购1000人民币以来所有溢价申购日期数据统一做线性回归,可以得到结果:基金场内申购账户

线性回归计算步骤
2019年10月25日
华宝油气在国庆假期后持续高溢价,到今天已经连续第13个交易日。吃瓜群众们充分利用华宝油气限购1000的机会,开始了新开1+6拖拉机账户溢价申购套利的狂欢之旅,从10月11号到现在测算的申购账户数一直在创历史新高。
不断新开的账户把我线性回归统计基金场内申购账户的结果活生生搞成了非线性。
10月22日那天场内新增了5766万股,对应限购1000人民币下场内满额申购了22127户,全部场内份额已经接近65亿股。好几个人看到迅速增加的份额后都问我华宝油气会不会继续把限额降到100块或者是彻底关门。
我暗自一笑,回答说你们想多了。华宝基金有对它来说更聪明应对方式,其实在8月份刚开始限额申购后的那一轮溢价申购时已经表现出来了。
这个聪明方法是主动降低股票持仓仓位比例,把大家新申购的人民币拿在手里除了收管理费以外什么都不做。
我修改了一下平时基本闲置的净值记录页面,统计了过去4年来的华宝油气仓位估算结果。
可以看出在今年8月份之前,基本上都是稳定维持在基金说明书中写的95%附近;8月份降到了85%-90%,9月份经过连续11个交易日折价大量赎回后,9月底时仓位又回到了95%。
为了避免一般的华宝油气官方估值的误差来源的影响,我在这里只选择了XOP当晚净值涨跌幅度大于4%的日子进行仓位估算,因为仓位回到95%以后没有这样的大波动,这样的话当前华宝油气具体仓位依然是个谜。
下一个XOP大涨或者大跌后不出意外的话,肯定是会再次看到华宝油气上涨跟不上涨幅,下跌也跟不上跌幅的。
显然华宝油气在雪球的工作人员对目前仓位降低的问题是了然于胸的。昨天我的估值软件给出10月23日的净值是0.387,而他在雪球狡猾的给出了0.386,结果公布后果然是他对了。
XOP净值在10月21到23日连续每天小涨,没有一天达到了我定的4%的标准,所以我一直没能有效的测算目前的实际仓位。
不过这3天累计的涨幅达到了5.14%,我于是灵机一动,想到了可以优化一下算法:不用拘泥于单日的涨跌,只要连续几天的累计涨幅或者跌幅超过了4%就计算一次仓位。
这样我又增加了一个专门估算仓位的新页面:仓位估算
加了新页面后继续脑洞大开,我又加了一行输入界面,从此可以自行设置4%的阈值。
既然现在有了实测的数据,当然要把它们派上用场。不过我暂时只把SZ162411和SZ160216仓位用在了估值上,而其它的LOF依旧使用缺省的95%仓位。如果小于1,在估值页面上会显示实际使用的估值仓位。
国泰商品跟华宝油气是2011到2012年基本上同时代的第一批QDII基金,开始几年没啥人气。2015年传说中的著名网络写手烟雨江南邱晓华卸任基金经理前,把名字上依然保持着大宗商品的SZ160216改造成了一个纯油基金,净值几乎100%跟随USO和美油期货CL。
也就是说,我可以用USO准确的给这4年以来的国泰商品估值。
100%跟随CL就意味着可以套利。在CL砸向2016初的26美元那一轮中,可以抄底油价又可以套利的国泰商品跟华宝油气一样迅速成长起来,QDII场内流动性仅次于华宝油气。在华宝油气2016年1月21日因为外汇额度彻底关门后,国泰商品也在2016年2月24日彻底关门。
接下来神奇的事情发生了。随着油价迅速反弹,华宝油气很快就在2016年3月25日恢复了每日10万限额的申购,到了当年4月8日更是恢复到了50万。而国泰商品却一直到2017年的5月11日才恢复每日1000的限额申购,然后2018年8月21日至今一直是每日限额1万。
民间传说是国泰基金把外汇额度挪到其它产品上去了。可能是因为关门时间太长,之前累积起来的流动性一去不复返,以至于现在都要被后来者追上了。
事实上,当南方原油LOF计划在2016年中间上市的时候,我看到的套利群体是对它寄予厚望的,希望它能重复国泰商品100%跟CL的模式方便大家赚钱。可惜南方基金没采用现成的套利促进流动性的模式,所以它到现在的流动性也还是苦哈哈。
因为国内监管的要求,FOF的持仓不能过于集中。SZ160216费了不少力气让自己的持仓跟USO保持100%一致。因为美股市场上没有足够多的原油ETF品种选择,它同时持有了小部分2倍日内杠杆的原油ETF和看多美元的ETF,甚至还有一点点贵金属ETF,说白了就是为了满足监管的分散要求。
而南方原油LOF(SH501018)更离谱,它持仓了很大一部分欧洲市场上的原油ETF,由于市场收盘时间不同,市场假期也有差异,我用USO给它估值就不准了,反向计算出来的仓位就更加不靠谱。
想给它正确估值,使用SZ162411的这种单一品种参考模式是不行的。惊艳大师计算QDII净值的Excel虽然在我的网页工具出来后落寞了许多,不过他说了,用XOP估算华宝油气净值只是小学生水平,能够用实际的详细持仓明细估算净值才算初中生水平!
魏大户在雪球和公众号上写了一系列A股大时代的故事,一直用这个封面图片。因为我今天也忍不住开始讲原油基金历史的故事,就东施效颦也放个图。

不要怕,是技术性调整,不要怕。
美国夏令时结束带来的软件BUG
2019年11月7日
没想到9月份写的基金场内申购账户让我意外发现了一个跟夏令时开始配对的BUG。
我昨天看了一下11月4日轻微折价下的场内申购预估数量。 因为我平时做线性回归是不用折价日的申购数据的,所以特意留心了一下。结果今天发现基金溢价记录中11月4日的数据竟然没有显示出来。
查了半天终于找到了问题:我原来用11月1日周五的日期加上3天的秒数,期望得到11月4日的日期。却没料到赶上了11月3日结束夏令时,3天的秒数不够,结果得到的是11月3日的日期。这个问题隐藏了好几年,但是以前一直没有像现在这样每天盯着折价溢价数据看,所以一直没发现。
2019年11月14日
本福特定律

Benford's Law equation
2019年11月15日
Pearson卡方检验

Pearson卡方检验方程和曲线
华宝油气的C类份额
2020年1月13日
流动性是个很神奇的东西,我一直喜欢用高速公路上的车流来比喻它。不知道什么时候原本高速行驶的车流会突然慢下来塞住,又不知道什么时候会逐步缓解直到重新一路畅通。
今天收盘后,华宝基金发布了一个给我当头一棒的公告,要开始销售C类华宝油气份额。0申购费、7日后0赎回费、同时还降低管理费率的场外C类份额无疑会严重打击场内SZ162411的流动性。我感觉华宝基金在犯一个明显的错误,一旦流动性开始下降,紧跟着会下降的就是市场规模了。
国泰商品已经只剩大半桶油
2020年3月26日
从仓位估算可以看到,之前国泰商品仓位一直中规中矩的保持在LOF标准的95%附近。不过在3月6日开始的这一轮CL断崖式下跌后,它的仓位也随着断崖式下跌了。目前估算仓位59%,已经只有大半桶油。
国泰商品在3月13日停止了申购,紧接着的3月16日周一广发石油也停止了申购。因为海外账户保证金不够的原因,突然的大额申购可能会让SZ160216和SZ162719这种QDII基金在随后的大约一周内出现明显的仓位降低。
可以看到SZ162719仓位在3月20日就恢复到了正常的95%附近。那么,SZ160216一直没有恢复仓位,是不是它也采用了SZ162411类似的降仓位保申购的方式,尽可能吸引流动性?要知道,早已经在2月14日再次关门后的华宝油气因为美元资产净值的大幅降低,它如今的仓位已经由基金公司恪守的80%底线被动降低到了75%。
这个问题其实难于判断,因为在基金公司有意降低仓位保申购的可能性外,还有另外一个解释:在国泰商品的持仓中,能保持迅速跟上当月CL跌幅的USO只是其中之一,此外还有大量像USL这种持仓很多远期CL的,所以看上去表现就像SZ160216仓位不足了。
无论是什么原因,既然表现出来的仓位已经如此之低,用CL对冲的要小心,很容易一下子多空36%的仓位,一旦油价快速反弹就亏惨。
基于类似的逻辑,持有XLE、XOP和IXC等多只美股原油股票ETF的诺安油气也会显示出它相对于XLE波动的仓位区别,为避免莫名其妙的亏钱,用XLE对冲前一定要记得看一眼实际表现出来的SZ163208仓位!
跟踪纳斯达克100的SZ161130近期溢价申购套利回顾
2020年9月15日
跟上次听无敌哥讲那油气交易爆仓和破产的事情一样,雪球运营人员总是在我的华宝油气和XOP亏得不能自理的时候让我做直播。不过常年卖惨这种人设只有元神元卫南才能乐此不疲的坚持下来,于是建议聊聊最近自己袖手旁观没有参与的纳斯达克100LOF(SZ161130)溢价申购套利。
9月11日直播的视频在下面。讲得不好,准备的纳斯达克内容二十分钟就讲完了,后来基本上又回到了油气的东拉西扯上。本文是增强的文字版本,同时更新了最新的数据。
sz161130.mp4
美股市场指数代码总是五花八门。雪球上纳斯达克100显示的代码是.NDX,而YAHOO上的代码是^NDX。通常大家都觉得它代表美股科技股,其实更确切的分类说法是除金融公司外的一百家最大公司按市值加权的指数。跟踪它的ETF很多,最热门的有QQQ一倍做多、PSQ一倍做空、TQQQ三倍做多和SQQQ三倍做空等。

9月11日QQQ官网显示的前十大持仓
这个指数群众基础非常好,可以从QQQ官网上9月11日前十大持仓比例看出,全部都是人民群众喜闻乐见的高科技公司。其中GOOGL和GOOG其实都是谷歌,二者加起来3.64+3.56=7.2%,在苹果、亚马逊和微软之后排第四。今年以来股价暴涨了好几倍的特斯拉目前排在第六,超过了上一个因为人工智能暴涨的NVDA。

9月14日芝商所官网显示的MNQ行情
芝商所对应的期货有NQ和MNQ等。NQ货值是MNQ的十倍。说起来MNQ也是芝商所今年跟负油价一起搞出来的创新,这样能有更多散户参与股指期货的交易。一手MNQ按当前一万多点的指数乘以2美元计算,目前货值2万多美元,20倍左右的杠杆,1/3货值的保证金。
A股市场上跟踪的基金也不少。除了不能套利的160213等场外基金,场内的SH513100长期关门,SZ159941每次一百万份起步每天限购一百万份,也就是每天一个幸运儿,这样每天每账户限购五百人民币的SZ161130成了套利党的香馍馍。

9月14日stockchars.com显示的NDX技术分析图
NDX八月份进入连续创历史新高的模式,除了在8月10日那周回调了一次二十日SMA,也就是布林中轨,其它时间一直在沿布林上轨上涨不停新高。目前这一轮回调到了号称是美股小牛熊分界线五十日EMA,有可能会继续跌到布林下轨附近。
SZ161130对上涨一开始是犹豫的,8月21日之前都是折价。8月24日开始,追高的来了,把它拉到了溢价,然后溢价一路上涨,9月3日最高值为7.99%。
不排除有易方达基金公司为了省广告费有意推波助澜的可能性,迄今为止我记录的最大溢价申购套利规模就是它导演的。今年3月24日有235530户参与了原油LOF易方达(SZ161129)限额五百块的申购,对应接近六万人参与,当时场内交易溢价67%。
有溢价的地方就有套利党。9月3日测算基金场内申购账户是59882,对应差不多一万自然人。测算场外申购了419户,就是说这一万人当中有大约四百人同时还做了场外申购,然后马上转场内了。不转场内的价值投资者是用场内新增数据测算不出来的。要不是近日来纳指大跌,9月8日场内就砸折价了,实际溢价1.63%。
本来各个基金公司的QDII额度在今年3月份就被原油QDII基金狠狠坑了一把,现在更不够了,仓位估算的实际值下降到了90%左右。主动降仓位最低的在华宝油气上见过80%。
对冲还是不对冲?不要怂就是干有它的道理。对于想做多的来说,只要有溢价就应该申购,上涨赚净值下跌赚溢价。从概率上来说长期肯定是赚钱的,不过要尽可能多的操作,概率是通过大数据回归的。
亏钱的都不是价值投资,失败的套利都是赌博。A股市场钱多人傻,但是收割工具并不多,跨市场套利是真正的圣杯。一股QQQ相当于大约1100股SZ161130,一个拖拉机三千块对应1.5股QQQ,不容易精确对冲。MNQ可以实时对冲,一手MNQ的货值大约相当于8万股SZ161130,等SZ161130流动性好了后大有可为。

咦,那个人看上去好像一条狗!
增加电报机器人
2021年2月27日
因为微信个人订阅号的各种限制,最近削尖铅笔基于Telegram电报API开发了机器人@palmmicrobot,把微信公众号上的查询功能完全复制到了电报软件上。同时创建了@palmmicrocast频道,用来主动发布用户在各种渠道查询过程中碰到的可能需要提醒的信息。
电报是开源的,而且鼓励大家把它无缝集成到各种应用场景中。墙内使用电报可以从https://0.plus下载安装Btok手机APP,也可以使用非官方的WEB版本https://web.telegram.im。
互联网不是法外之地,虽然墙外的电报软件能畅所欲言并且避免恶意举报,请大家记住Palmmicro的一切都是实名可以抓到我的,不要在电报中有关Palmmicro的地方乱说话!
不忘初心,接下来打算写个用电报机器人管理的基于MQTT协议的IoT模块。
微信公众号剩余群发次数为0
2021年3月20日
微信公众号发文章时出现剩余群发次数为0的错误信息后,上网搜了一圈没找到解决方案。后来发现是最近写文章太积极,在已经发出文章的19日就开始写了20日的开头,等到20日要群发时,系统还没反应过来。
解决方法很简单,先保存到公众号创作管理的图文素材中,然后再重新打开编辑后发送,或者直接发送都可以。
微信公众平台进去后显示白板
2021年6月13日
前几天微信公众平台进去后显示白板,隔一段时间后恢复正常,以为是临时审查工作过度繁忙导致。结果后来再次发作后一直不恢复了,等了几天后开始在网上查解决方案,发现是因为网站cookie过多,清除后解决问题。
UTF-8的双字节空格字符
2021年6月22日
收到来自微信公众号的通知邮件,说有用户查询161116 没有找到匹配的信息,我简直不敢相信自己的眼睛。
登录公众号管理系统,把其中用户发送的内容复制到微信PC版本的输入界面中,显示除了161116外,还额外换了两行。果然这样发出去是会匹配失败的,其中应该包含了没想到过的未知字符。
在简单测试用户界面加上十六进制显示后,发现161116后多出一个0x20的空格。我猜可能因为输入控件是单行的所以换行被过滤掉了,干脆就放弃自己分析未知字符。
目前我用的jEdit编辑器没有十六进制显示的功能,于是去下载很多年没再用过的UltraEdit,然而它显示161116后是20 0D 0A,这3个太正常了,早已经在$strText = trim($strText, " ,.\n\r\t\v\0")
中处理过。
这下搞得黔驴技穷,只好找用户问到底输入的是什么。被告知是从一篇公众号文章复制过来的,我跑去看文章页面源代码,发现原文是161116 ,微信复制后产生了一个UTF-8的双字节空格字符。加一句$strText = str_replace("\xC2\xA0", '', $strText)
后终于解决问题。
2021年6月24日
虽然原则上来说XOP也可以使用这个页面,但是它其实是为同时有港股和美股的KWEB持仓准备的。
QDII基金总是越跌规模越大,流动性越好,前些年是华宝油气,而今年最热门的变成了中概互联。按SZ162411对应XOP的模式,中概互联的小弟SZ164906之前是用KWEB估值的。
不过因为中国互联有1/3的港股持仓,它的净值在港股交易时段会继续变化,所以原来的SZ164906页面其实没有什么实际用处。唯一的好处是在基金溢价记录中累积了几年的官方估值误差数据,帮我确认了用KWEB持仓估值中国互联的可行性。
跟A股LOF基金每个季度才公布一次前10大持仓不同,美股ETF每天都会公布自己的净值和详细持仓比例。因为KWEB和中国互联跟踪同一个中证海外中国互联网指数H11136,这样可以从KWEB官网下载持仓文件后,根据它的实际持仓估算出净值。然后SZ164906的参考估值也就可以跟随白天的港股交易变动了。
写了快6年的估值软件终于从小学生水平进化到了初中生水平,还是有些成就感的。暑假即将来到,了不起的狐狸爸爸要开始教已经读了一年小学的娃在Roblox上编程了。

了不起的狐狸爸爸会干很多事情,但是刺猬才会干大事。
2021年7月2日
罗布乐思Roblox骰子验证码。

罗布乐思4个骰子加14验证码
2021年7月14日
相对于净值记录等其它历史数据,这个页面来得实在是比较晚,主要是之前做华宝油气套利时不需要特别关注每天的场内新增份额,反正流动性足够好。不过随着XOP一路上涨,华宝油气的上百亿场内规模只剩下了零头,失去了流动性的华宝油气和XOP跨市场套利变成了屠龙之技。
我也被迫开始关注像中国互联这种流动性不是那么好的品种,为以后的套利早做打算。
历史数据页面汇总:历史价格 基金溢价记录 净值记录 净值价格比较 基金场内份额 校准记录 仓位估算 基金场内申购账户 小心愿佯谬
SZ162411的成交量相对于场内份额(万)的换手比例 基金场内份额
日期 | 份额(万) | 场内新增(万) | 成交量 | 换手 | 新增换手 |
2023-09-28 | 94624.83 | 3.73 | 83816197 | 8.86% | 224708% |
2023-09-27 | 94621.1 | 606.93 | 40431939 | 4.27% | 666% |
2023-09-26 | 94014.17 | -411.15 | 63426646 | 6.75% |
2023-09-25 | 94425.32 | -99.86 | 30350889 | 3.21% |
2023-09-22 | 94525.18 | 11.43 | 68969026 | 7.3% | 60340% |
2023-09-21 | 94513.75 | 920.5 | 123391166 | 13.06% | 1340% |
2023-09-20 | 93593.25 | 54.99 | 100852520 | 10.78% | 18340% |
2023-09-19 | 93538.26 | 648.02 | 73290195 | 7.84% | 1131% |
2023-09-18 | 92890.24 | 3 | 57371460 | 6.18% | 191238% |
2023-09-15 | 92887.24 | 11.03 | 69489225 | 7.48% | 63000% |
为中丐互怜增加混合QDII工具系列
2021年7月28日
从QDII中分出来,采用跟踪成分股变化的方式对同时有美股和港股持仓的SH513050等进行净值估算。
A股大妈最喜欢干的事情就是抄底。随着过去半年来中概互联一路跌成了中丐互怜,中概互联网ETF的市场规模和流动性都在暴涨,就连原来叫中国互联的SZ164906都蹭热度借增加扩位简称的机会改名成了中概互联网LOF。看得我口水流一地,忍不住想做点什么蹭蹭热点。
跟SZ164906和KWEB跟踪同一个指数H11136不同,SH513050跟踪的是另外一个不同的中证海外中国互联网50指数H30533。H30533和H11136在成分股选择上基本一致,但是H30533对单一成分股最大仓位限制是30%,而H11136限制10%的最大仓位,这样导致它们俩在腾讯和阿里持仓比例上区别巨大。
在中间的是跟踪中证海外中国互联网30指数930604的SZ159605和SZ159607,限制15%的最大仓位。另外,顾名思义930604的成分股数量要少50-30=20只。
SH513050的成分股和比例来自于上交所官网的ETF申购赎回清单,SZ159605和SZ159607来自深交所官网的ETF申购赎回清单,这样未来可以方便的继续扩大新成员。SZ164906的成分股和比例依旧还是来自KWEB官网公布的每日基金持仓更新。
把SZ164906从老QDII挪到新的混合QDII其实是个相当痛苦的过程,原来以SZ162411为模板写的仓位估算等功能都要从QDII拓展出来,香港QDII在这个过程中也跟着沾了光。
官方估值跟原来QDII工具一样,不过参考估值有所不同。除了当日汇率的变化外,参考估值在港股开盘后还会反应当日港股成分股的变动对净值的影响。

依稀往梦似曾见,心内波澜现。
2021年11月29日
今天很不高兴,写的《中丐互怜LOF(164906)限购1000》的文章竟然几小时后就被人举报删除了。死了张屠夫,不吃有毛猪,以后还是要努力坚持做自己的网站。
其实早在因为举报连续被封了八个QQ群,附带被封了用了二十多年的QQ号之后,我就预感到了微信迟早也会被封。如今离开了QQ没有关系,没有微信的话可是刷不了绿码连门都出不了,只能彻底放弃腾讯家包括公众号在内的一切公开使用了。

拉倒吧,联的大清都亡了!
2022年1月21日
在新浪股票数据接口加上Referer检查后,直接在浏览器中点开http://hq.sinajs.cn/list=sz162411只能看到日文的Kinsoku jikou desu! 相当于英文的Forbidden。从此加上新浪股票接口调试工具页面看结果。
跟IP地址数据一样,是先从WEB服务器使用加Referer的HTTPHEADER查询数据,再显示出来。为防止愚昧爬虫过度访问触发过多查询导致我的WEB服务器被新浪封杀,这个页面也需要登录。
为混合QDII补充A股成分股的持仓处理
2022年9月14日
在美军从越南撤退的时候,美国政府估计其中有相当大比例的染上了毒瘾。按当时的普遍研究,吸毒者复发的可能性高达90%以上,如何面对预期中几十万退伍的瘾君子成了一个严峻的问题。然后让严阵以待的社会学家们完全没有想到的是,事实上复发的比例不到5%。
于是研究者们又挖空心思搞了一个新理论出来:只要远离了原来上瘾的环境,就不容易再次上瘾。
在我刚开始混雪球和搞微信公众号的时候,对成为股票套利大V曾经是满怀希望的。这个希望破灭在QQ群和号被封后。我意识到套利者群体中其实不少人是满怀敌意的。而且即使不举报我,出于秘籍不能外传的心理,绝大多数套利者也不会愿意主动帮我分享,因此这条大V之路其实走不通。
不幸的是,我发现我上瘾了,每天花了大量的时间搞无效的网络社交。于是开始有意的让自己远离上瘾环境。公众号在去年11月因为举报封了我一篇文章,我就不再更新文章,放弃微信上6000多的订阅者;雪球在今年2月删除了我一条宣传网站的评论,我就弃用了13000多粉丝的woody1234帐号。从此彻底戒断大V梦想。
戒断上瘾总会有副作用,对我来说,就是口头上喊着要努力专心做好自己的网站,实际上在很长时间内却再也提不起兴致,以至于经常放在嘴边自嘲的每天20行代码都断了很久。
7月份的时候,我注意到中丐互怜来了个新成员全球互联ETF(SH513220),本来想简单的通过拷贝复制加上,却发现跟其它老丐帮成员不同,它居然还有A股成分股。一下子我的拖延症就犯了,一直拖到这个月才动手。
既然加上了A股成分股的处理,那么把老的同样同时有美股、港股和A股成分股的教育ETF(SH513360)加上也就成了简单的拷贝复制。剩下就看在没有网络宣传的情况下,搜索引擎们能多有效的帮助用户找到这些估值网页了。

年轻人,我这儿有本秘籍。
2023年5月21日
四个跟踪日经225的ETF上市好几年来一直不愠不火,我觉得它们流动性不好就没有去搞估值。直到19日周五收盘日经225ETF易方达(SH513000)场内溢价拉到了20%,让我觉得不能再观望下去了!毕竟只要有人来拉溢价,流动性就可能会好起来。
能够拉溢价的原因是多方面的,比如巴菲特月初开股东大会宣传增持日本五大商社,日本股市最近几天创下三十多年新高接近1990年最高水平,但是关键还是在于限购。
易方达基金公司因为中丐互怜缺QDII额度,SH513000每天限制申购50万份。而作为ETF,它又要求每次最少申购50万份,这样每天只有一个幸(kai)运(hou)儿(men)能申购到。
SH513520同样因为限购总份额50万份也被拉到了接近20%的溢价,而SH513880和SZ159866则因为分别限购1500万和1亿份而基本上平价。
日本QDII跟香港QDII的估值模式基本上是一致的。中国和日本股市都开市的日子里,用新浪日经225指数数据znb_NKY做官方估值,日本股市北京时间下午两点收盘后官方估值就不再改变,直到晚上跟公布的实际净值比较和自动校准。
同时全天都用新浪日经225指数期货数据hf_NK做实时估值,可以反映日本股市收盘后的变化。
配张日本美女图。

1991年宫泽理惠Santa Fe写真
2023年5月25日
华安基金公司的QDII基金不仅有跟踪美国和日本股市的ETF,还有德国和法国的。之前我都用美股市场上的ETF给德国ETF(SH513030)和法国CAC40ETF(SH513080),误差一直很大。
专门去看过它们的季报持仓,发现它们还真是在德国和法国市场上买股票,这样就像南方原油LOF的估值一样,连收市时间都差几个小时,当然不准。
在加了日本QDII后,我意识到可以用同样的模式给这两个ETF估值,股指数据分别来自于新浪的znb_DAX和znb_CAC。目前德国和法国都在夏令时,北京时间下午三点开市,晚上11点半收市。
隔一段日子后到基金溢价记录页面看估值误差,就知道这个改动是否成功了。

命运赠送的礼物都早已暗中标好了价格
增加全球芯片LOF和海外科技LOF的估值
2023年5月30日
NVDA上周创历史的财报预期后,掀起了全球芯片股票的高潮,让我实在坐不住了。按Forest_g一个半月前的具体建议在混合QDII中加上了同时持有美国和中国芯片股的全球芯片LOF(SH501225)估值页面。

老黄路边KTV
不知道是持有多地上市股票的基金是今年的新潮流,还是只是为了躲开纳斯达克QDII基金的拥挤,华宝基金还搞了一个同时持有纳斯达克和香港科技的海外科技LOF(SH501312),顺便一并加了进来。
纳斯达克100期货升水和美元利息的关系
2023年6月14日
随着纳指基金(SZ159501)今天开始交易,场内纳斯达克100基金已经到了两只手都要数不过来的边缘,而其中一半都是今年新开的,可见其受欢迎的程度。
这些基金的实时估值使用的是新浪数据中的纳斯达克100期货NQ。新浪的期货数据总是提供所谓的主力合约,也就是说它可能会切换得较早。比如NQ的数据,新浪在前两天就切换到了九月到期的合约。最近一年来,每当这种时候总有人问,为什么实时估值高那么多?
因为随着美元的加息,纳斯达克100和标普500的期货一直在持续升水。

纳斯达克100期货和现货价格比较
这是在写之前尽我所能的截屏。芝商所的数据延迟十分钟,雪球数据基本上是实时的。可以看出,6月16日结算的合约(14983)跟现货(十分钟前大约14980)比已经只有很少的升水,但是九月合约相对于六月有(15169/14983=1.012)大约1.2%的升水。十二月相对于九月也是同样1.2%的升水。
大家都喜欢说期货反应预期,所以这个升水很容易被解读成群众相信美股永远涨,但是这是错误的。就像我在2020年写的原油期货升水和油轮运费的关系一样,升水反应的是套利者之间的博弈。
具体来算一下。假如持有QQQ的多仓,可以把它换成三个月后的NQ合约。因为期货收不到分红,这样会损失掉过几天后大约每股五毛的分红,也就是0.014%。但是在5%的美元利息下,从QQQ中腾出来的现金在三个月中可以收1.25%的利息。当然,因为NQ合约也要占用大约3.4%的现金,这个利息应该调整为1.201%,扣除分红损失后收益为1.187%。
也就是说,如果NQ不升水,那么所有持有QQQ的都可以用NQ替代,然后每三个月多赚1.187%的利息。天下没有免费的午餐,套利者博弈的结果,就是NQ每三个月固定升水1.2%。