YON CISE

网格价格计算

接触过量化的一定都知道网格策略,根据网格间隔的计算方式不同又可分为等差网格和等比网格。等差网格每个网格买卖挂单之间的价差是一样的,等比网格每个网格买卖挂单之间的价差都是当前网格价格的固定比例。以等比网格为例,假设初始价格是 \(P_0\),网格价差比例是 d,我们现在在初始价格下第 n 个网格 (n0开始),那么我们上下挂单的价格就是:

\[ P_{Buy} = P_0 * (1 - d)^{n+1} \newline P_{Sell} = P_0 * (1 - d)^{n} * (1 + d) \]

但是前段时间看发明者上的网格策略 [1] [2],发现文章里的计算公式是这样的:

买入价 = (网格值 * 价差 - 网格值 * 初始价格) / ((初始币量 - 当前持币量) * 价差 - 网格值)

卖出价 = (-网格值 * 价差 - 网格值 * 初始价格) / ((初始币量 - 当前持币量) * 价差 - 网格值)

和这样的:

buy_price = (value / pct - value) / ((value / pct) / init_price + e.account[symbol]['amount'])
sell_price = (value / pct + value) / ((value / pct) / init_price + e.account[symbol]['amount'])

当时好奇上面的公式怎么来的,问了大模型也是各种胡扯。一开始因为不知道他们的网格到底是等比还是等差所以只能逆着来推导,一直推不出来。后来忽然想到可以先按照公式算几个挂单价看看是等比还是等差,最后发现两个公式算出来的都是等比网格的挂单价格。知道了是等比网格后面的推导就很简单了。

首先我们观察式子可以发现最大的区别就是我们一开始的公式里有个 n 而发明者的公式里是 网格价值持币量,所以我们就是要看怎么把 n 或者说是 \((1 - d) ^n\) 用其它的变量来表示。假设持币量是 C,网格价值是 G

\[ C = \frac{G}{P_0 * (1 - d)} + \frac{G}{P_0 * (1 - d)^2} + \dots + \frac{G}{P_0 * (1 - d)^{n}} \newline C = G * (\frac{(1 - d)^{n-1} + (1 - d)^{n-2} + \dots + 1}{P_0 * (1 - d)^{n}}) \newline C = \frac{G}{P_0} * (\frac{1 - (1 - d)^n}{d * (1 - d)^n}) \newline (1 - d)^n = \frac{G}{G + C * P_0 * d} \]

于是挂单价就是:

\[ P_{Buy} = \frac{P_0 * G * (1 - d)}{G + C * P_0 * d} \]

再做些简单的转换就可以得到文章里的公式了,例如:

buy_price = (value / pct - value) / ((value / pct) / init_price + e.account[symbol]['amount'])

换成我们的符号的话就是:

\[ P_{Buy} = \frac{\frac{G}{d} - G}{\frac{G}{d * P_0} + C} \]

再例如:

买入价 = (网格值 * 价差 - 网格值 * 初始价格) / ((初始币量 - 当前持币量) * 价差 - 网格值)

换成我们的符号(价差 = 初始价格 x d)就是:

\[ P_{Buy} = \frac{G * P_0 * d - G * P_0}{(0 - C) * P_0 * d - G} \]

用发明者文章里的计算公式来计算挂单价格有什么好处呢?好处就是我们不用自己记录 n,直接基于持币量就能计算当前的挂单价格了,这样我们的挂单价格比单纯的用 n 来计算会更精细,因为考虑合约的最小价值和手续费的话,我们每次成交后得到的币和理论的单个网格应获得的币是有误差的。

[1] 经典现货多币种网格策略

[2] 永续合约网格策略参数优化详解