# 網格買/賣單數量計算 - 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}") ```