更新:
Pdex:内盘bitCNY价格
premium:溢价百分比
Premium0: 一小时前的溢价百分比
i=0; Ti=30; Td=2
while True:
if (上次执行后计时器已过去一小时):
i+=premium/Ti;
d=Td*(premium-premium0)
if -2%<premium<2%:
i=0.9i; /**溢价接近0时逐步减小积分环节影响,以免引起震荡
if premium<0%:
k=1+2*premium
if 0<premium<1%:
k=1+9.6*premium
if 1%<premium<2.4%:
k=1.096
if 2.4%<premium:
k=1+4*premium
feed price = Pdex*min((i+k+d),1.7)
有点意思,我的感觉如下。
0. 最重要的一点,传统 PID 都是直接反馈,而我们的喂价是间接反馈,所以不能简单套用。
因为你的喂价不是直接影响 premium 的,而是通过影响中间喂价(median feed)间接影响 premium,你的算法里没有把中间喂价加入计算,是个严重失误。当你的喂价离中间喂价很远时,不管你怎么调,积分再多,中间喂价还是不会动,进而 premium 也不会动,但这不是因为你的喂价不够高,而是别人的喂价不够高。在premium一直超过 2% 的情况下,你的积分会一直积累,可能导致你的喂价偏离合理值很多。
当然,现在负反馈喂价刚开始推行,premium超过2%很常见。等负反馈喂价推行一段时间后,如果premium保持在2%以内,你算法里的 i=0.9i 会很快减小偏差。
在不考虑中间喂价的情况下:
1. Ti 较大,也就是积分较慢,响应慢:30小时才积累 1*premium,相比 k 的 9.6*premium ,能起的作用很小;可能运行相当长时间后才有效果。
2. i=0.9i的问题
2.1. 如果premium一直在2%以下,这个动作会导致 i 达到premium/3后就不再增长,影响积分效果。
premium/3时,当前小时增加量为 premium/30,i=0.9i后结果为0.9*(1/3+1/30)=0.9*11/30=9.9/30<1/3
2.2. 如果premium超过2%积累了一段时间, i 相对较大时,变成 -2%<premium<2% 时的每小时 i=0.9i 导致的减小速度太快,反而可能会带来震荡;
2.3. 如果不加入 i=0.9i 的步骤,则只有当 premium 变成负数时, i 才可能减小,这样比较合理,有助于发现静差数值。
3. Td 微分系数 2 倍,这个感觉偏大,震荡明显
---------分割线----------
推演一下?
当 premium 一个小时从 0% 变成 1%,也就是 1.00变成1.01,此时 i=0.0003, k=1.096, d=0.02,喂价 1.1163(注意,这就超过10%的MSSR处理范围了)
premium维持1%不变,i=(0.0003+0.0003)*0.9=0.00054,k=1.096,d=0,喂价 1.09654(震荡)
premium 维持 1% ,i=(0.00054+0.0003)*0.9=0.00076,k=1.096,d=0,喂价1.09676(缓慢积累)
premium 从1%变成2%, i=(0.00076+0.0006)*0.9=0.00122,k=1.096,d=0.02,喂价1.11722(再次超过10%)
premium 维持 2%,i=(0.00122+0.0006)*0.9=0.00164,k=1.096,d=0,喂价1.09764(震荡)
premium 从2%变成3%,i=(0.00164+0.0009)=0.00254,k=1.12,d=0.02,喂价1.14254
premium 维持 3%,i=0.00254+0.0009=0.00344,k=1.12,d=0,喂价1.12344
先推到这里。。
确实,中间喂价需要纳入计算来确定喂价合理范围。
一些参数都需要更多优化,包括计算间隔,1小时是否合适?是否10分钟更合适?这个可以再考虑,先拿1小时作推演。
感觉溢价较低时让喂价快速向市场价方向回归还是需要的,i=0.9i是基于这方面考虑,可能需要选择更好收敛算法。
更新:
Pdex:内盘bitCNY价格
Pf: 当前喂价
premium:溢价百分比
Premium0: 一小时前的溢价百分比
Ti=10; Td=1;p=4
convergence factor = 0.96
get Pdex, Pf, premium;
premium0=premium;
k=1+p*pemium;
d=0, i= Pf/Pdex-k; ##设置初始值使得初始喂价等于当前喂价
while True:
get Pdex, Pf, premium;
if (上次执行后计时器已过去一小时):
i+=premium/Ti;
d=Td*(premium-premium0);
premium0=premium;
if -1%<premium<1%:
i=i*convergence factor; ##溢价接近0时逐步减小积分环节影响,以免引起震荡
k=1+p*pemium; ##去除产生k的复杂分段公式,直接线性,因为积分环节已经可以保证补偿不断增加,而且也无必要过多在意MSSR限制。
if i+k+d>1:
feed price = Pdex*min(i+k+d, 1.5, 1.2*Pf/Pdex) ##向上调价时,喂价不超过内盘价1.5倍,不超过当前喂价1.2倍
else:
feed price = Pdex*max(i+k+d, 0.91*Pf/Pdex)##向下调价时,喂价不得低于当前喂价0.91倍。
再推演下:
当 premium 一个小时从 0% 变成 1%,也就是 1.00变成1.01,此时 i=0.001, k=1.04, d=0.01,喂价 1.051
premium维持1%不变,i=(0.001+0.001)*0.96=0.00192,k=1.04,d=0,喂价 1.04192(震荡)
premium 维持 1% ,i=(0.00192+0.001)*0.96=0.0028,k=1.04,d=0,喂价1.0428(缓慢积累)
premium 从1%变成2%, i=(0.0028+0.002)=0.0048,k=1.08,d=0.01,喂价1.0948
premium 维持 2%,i=(0.0048+0.002)=0.0068, k=1.08,d=0,喂价1.0868(震荡)
premium 从2%变成3%,i=(0.0068+0.003)=0.0098,k=1.12,d=0.01,喂价1.1398
premium 维持 3%,i=0.0098+0.003=0.0128,k=1.12,d=0,喂价1.1328
premium 维持 3%再过10小时,i=0.0128+0.003*10 = 0.0428, k=1.12, d=0, 喂价1.1628