# 網格買/賣單數量計算
- base_diff_ratio :
- 此值動態計算得到, 如果大於1則設定為1
- 網格預估需要的base數量與實際外站能買到base數量比例
- ex: 網格預估5顆 但實際外站買到4.5顆, - base_diff_ratio = (4.5 / 5) = 0.9
- 各價位點計算
```py
def round_to_rule(value: float, rule: str) -> float:
return round(value, int(rule))
def round_to_rule_floor(n, decimals=0):
multiplier = 10 ** int(decimals)
return math.floor(n * multiplier) / multiplier
# 網格間距
grid_step = round_to_rule_floor((upper_limit - lower_limit) / float(grid_count), quotePrecision)
price_points = []
price_points.append(upper_limit)
while True:
price_point = round_to_rule(price_points[-1] - grid_step, quotePrecision)
if upper_limit >= price_point and price_point >= lower_limit:
price_points.append(price_point)
if price_point <= lower_limit:
print(f"各價位點:{price_points}")
break
```
## 全買單 (現價 > 上限)
`註: 全買單沒有站外買幣需要因此 base_diff_ratio 固定為1`
```
current_price = 658990
capital = 1000
grid_count = 2
upper_limit = 4
lower_limit = 1
base_diff_ratio = 1
```
```
# capital = capital * base_diff_ratio * 0.998;
1000 * 1 * 0.998 = 998
# grid_position = capital / (SUM(各價位點, 不包含最下面那格)
round(998 / (4+3+2), 8) = 110.88888888888889
# fee = (grid_position * 最高價 * 0.002 * grid_count) + (1 * grid_count)
(110.88888888888889 * 4 * 0.002 * 2) + (1 * 2) = 3.774222222222222
# capital = capital - fee
(998 - 3.774222222222222) = 994.2257777777778
# grid_position = capital / (SUM(各價位點, 不包含最下面那格)
round(994.2257777777778 / (4+3+2), 8) = 110.46953086
```
## 全賣單 (現價 < 下限)
`註: 全賣單會先預扣買單所需要手續費 `
```
current_price = 658990
capital = 1000
grid_count = 2
upper_limit = 800000
lower_limit = 700000
base_diff_ratio = 1.0894263392162356
```
```
# grid_position = capital / (SUM(各價位點, 不包含最下面那格)
round(1000 / (800000 + 750000), 8) = 0.00064516
# fee = (grid_position * 最高價 * 0.002 * grid_count) + (1 * grid_count)
(0.00064516 * 800000 * 0.002 * 2) + (1 * 2) = 4.064512000000001
# capital = (capital - fee) * 1 * 0.998; # base_diff_ratio 大於1則設定為1
(1000 - 4.064512000000001) * 1 * 0.998 = 993.943617024
# grid_position = capital / (SUM(各價位點, 不包含最下面那格)
round(993.943617024 / (800000 + 750000), 8) = 0.00064125
```
## 部份買單/賣單 (上限> 現價 >下限)
```
current_price = 658990
capital = 1000
grid_count = 2
upper_limit = 800000
lower_limit = 600000
base_diff_ratio = 0.86
```
```
# capital = capital * base_diff_ratio * 0.998
(1000 * 0.86 * 0.998) = 858.28
# grid_position = capital / (SUM(各價位點, 不包含最下面那格)
round(858.28 / (800000 + 700000), 8) = 0.00057219
# fee = (grid_position * 最高價 * 0.002 * grid_count) + (1 * grid_count)
(0.00057219 * 800000 * 0.002 * 2) + (1 * 2) = 3.8310079999999997
# capital = capital - fee
(858.28 - 3.8310079999999997) = 854.448992
# grid_position = capital / (SUM(各價位點, 不包含最下面那格)
round(854.448992 / (800000 + 700000), 8) = 0.00056963
```
# 網格顆數計算
```py
import math
def round_to_rule(value: float, rule: str) -> float:
return round(value, int(rule))
def round_to_rule_floor(n, decimals=0):
multiplier = 10 ** int(decimals)
return math.floor(n * multiplier) / multiplier
def get_fee(upper_limit, lower_limit, grid_count, basePrecision, quotePrecision):
price_points = []
grid_step = round_to_rule_floor(
(upper_limit - lower_limit) / float(grid_count), quotePrecision
)
print(f"grid step:{grid_step}")
price_points.append(upper_limit)
while True:
price_point = round_to_rule(price_points[-1] - grid_step, quotePrecision)
if upper_limit >= price_point and price_point >= lower_limit:
price_points.append(price_point)
if price_point <= lower_limit:
print(f"各價位點:{price_points}")
break
# round(998 / (200000+ 160080.0+ 120160.0+ 80240.0+ 40320.0), 8) = 0.00166112
grid_position = round_to_rule(capital / sum(price_points[:-1]), basePrecision)
# print(grid_position)
return (
(grid_position * price_points[0] * 0.002 * grid_count) + (1 * grid_count),
price_points,
)
def get_grid_position(
capital, upper_limit, lower_limit, grid_count, basePrecision, quotePrecision
):
fee, price_points = get_fee(
upper_limit, lower_limit, grid_count, basePrecision, quotePrecision
)
# 資金扣除預留手續費
# 998 - ((0.0016611185086551265 * 200000 * 0.002 * 5) + (1+5)) = 988.6777629826897
if current_price < lower_limit:
fee = 0
print(f"get_grid_position fee:{fee}")
capital = capital - fee
print(f"扣除手續費後的資金:{capital}")
# 扣掉預留費用,每格該下的btc數量,之後下單以這個為準
grid_position = round_to_rule(capital / sum(price_points[:-1]), basePrecision)
return grid_position
if __name__ == "__main__":
current_price = # Test Log - base price bitopro
capital = 1000
grid_count = 2
upper_limit = 800000
lower_limit = 600000
base_diff_ratio = # Test Log - base difference ratio
basePrecision = 8
quotePrecision = 0
fee = 0
# 目前價格小於網格最低價
if current_price < lower_limit:
fee, _ = get_fee(
upper_limit, lower_limit, grid_count, basePrecision, quotePrecision
)
if base_diff_ratio > 1.0:
capital = (capital - fee) * 0.998
else:
capital = (capital - fee) * base_diff_ratio * 0.998
print(f"capital:{capital}, fee:{fee}")
grid_position = get_grid_position(
capital, upper_limit, lower_limit, grid_count, basePrecision, quotePrecision
)
print(f"grid position:{grid_position}")
```