fix: a lot of things
This commit is contained in:
		
							
								
								
									
										295
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										295
									
								
								main.py
									
									
									
									
									
								
							@@ -110,9 +110,9 @@ class GridTradingBot:
 | 
				
			|||||||
            side = order_response["side"]
 | 
					            side = order_response["side"]
 | 
				
			||||||
            trade_type = "买入" if side == "BUY" else "卖出"
 | 
					            trade_type = "买入" if side == "BUY" else "卖出"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            timestamp = datetime.fromtimestamp(order_response["updateTime"] / 1000).strftime(
 | 
					            timestamp = datetime.fromtimestamp(
 | 
				
			||||||
                "%Y-%m-%dT%H:%M"
 | 
					                order_response["updateTime"] / 1000
 | 
				
			||||||
            )
 | 
					            ).strftime("%Y-%m-%dT%H:%M")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            row = [
 | 
					            row = [
 | 
				
			||||||
                timestamp,
 | 
					                timestamp,
 | 
				
			||||||
@@ -182,7 +182,7 @@ class GridTradingBot:
 | 
				
			|||||||
                self.symbol,
 | 
					                self.symbol,
 | 
				
			||||||
                str(e),
 | 
					                str(e),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            raise
 | 
					            return self.api_get_price()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def api_get_balances(self) -> Tuple[float, float]:
 | 
					    def api_get_balances(self) -> Tuple[float, float]:
 | 
				
			||||||
        """获取基础货币和报价货币的可用余额(不包括冻结金额)"""
 | 
					        """获取基础货币和报价货币的可用余额(不包括冻结金额)"""
 | 
				
			||||||
@@ -224,7 +224,7 @@ class GridTradingBot:
 | 
				
			|||||||
            logger.error(
 | 
					            logger.error(
 | 
				
			||||||
                "[GridTradingBot.api_get_balances] Failed to get balances: %s", str(e)
 | 
					                "[GridTradingBot.api_get_balances] Failed to get balances: %s", str(e)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            raise
 | 
					            return self.api_get_balances()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def calculate_order_value(self, price: float) -> float:
 | 
					    def calculate_order_value(self, price: float) -> float:
 | 
				
			||||||
        """计算订单价值 (价格 * 数量)"""
 | 
					        """计算订单价值 (价格 * 数量)"""
 | 
				
			||||||
@@ -360,7 +360,7 @@ class GridTradingBot:
 | 
				
			|||||||
                price,
 | 
					                price,
 | 
				
			||||||
                str(e),
 | 
					                str(e),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            return None
 | 
					            return self.api_place_order(price, side)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def api_cancel_order(self, order_id: str):
 | 
					    def api_cancel_order(self, order_id: str):
 | 
				
			||||||
        """取消订单"""
 | 
					        """取消订单"""
 | 
				
			||||||
@@ -379,6 +379,7 @@ class GridTradingBot:
 | 
				
			|||||||
                order_id,
 | 
					                order_id,
 | 
				
			||||||
                str(e),
 | 
					                str(e),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            self.api_cancel_order(order_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def api_cancel_all_orders(self):
 | 
					    def api_cancel_all_orders(self):
 | 
				
			||||||
        """取消所有活跃订单"""
 | 
					        """取消所有活跃订单"""
 | 
				
			||||||
@@ -388,15 +389,19 @@ class GridTradingBot:
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self.api_trade.delete_openorders({"symbol": self.symbol})
 | 
					            self.api_trade.delete_openorders({"symbol": self.symbol})
 | 
				
			||||||
 | 
					            self.active_orders.clear()
 | 
				
			||||||
            logger.info(
 | 
					            logger.info(
 | 
				
			||||||
                "[GridTradingBot.api_cancel_all_orders] Successfully canceled all open orders for %s",
 | 
					                "[GridTradingBot.api_cancel_all_orders] Successfully canceled all open orders for %s",
 | 
				
			||||||
                self.symbol,
 | 
					                self.symbol,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            self.current_buy_levels = 0
 | 
				
			||||||
 | 
					            self.current_sell_levels = 0
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            logger.error(
 | 
					            logger.error(
 | 
				
			||||||
                "[GridTradingBot.api_cancel_all_orders] Failed to cancel all open orders: %s",
 | 
					                "[GridTradingBot.api_cancel_all_orders] Failed to cancel all open orders: %s",
 | 
				
			||||||
                str(e),
 | 
					                str(e),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            self.api_cancel_all_orders()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def api_update_order_statuses(self):
 | 
					    def api_update_order_statuses(self):
 | 
				
			||||||
        """更新所有活跃订单的状态"""
 | 
					        """更新所有活跃订单的状态"""
 | 
				
			||||||
@@ -453,6 +458,7 @@ class GridTradingBot:
 | 
				
			|||||||
                    order_id,
 | 
					                    order_id,
 | 
				
			||||||
                    str(e),
 | 
					                    str(e),
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					                self.api_update_order_statuses()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_active_orders_by_side(self, side: str) -> List[Order]:
 | 
					    def get_active_orders_by_side(self, side: str) -> List[Order]:
 | 
				
			||||||
        """获取指定方向的所有活跃订单"""
 | 
					        """获取指定方向的所有活跃订单"""
 | 
				
			||||||
@@ -500,7 +506,7 @@ class GridTradingBot:
 | 
				
			|||||||
                market_price,
 | 
					                market_price,
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # 初始下单:买1和卖1
 | 
					            # 初始下单: 买1和卖1
 | 
				
			||||||
            buy_price = self.calculate_grid_price(market_price, 1, "BUY")
 | 
					            buy_price = self.calculate_grid_price(market_price, 1, "BUY")
 | 
				
			||||||
            sell_price = self.calculate_grid_price(market_price, 1, "SELL")
 | 
					            sell_price = self.calculate_grid_price(market_price, 1, "SELL")
 | 
				
			||||||
            logger.custom_debug(
 | 
					            logger.custom_debug(
 | 
				
			||||||
@@ -593,14 +599,13 @@ class GridTradingBot:
 | 
				
			|||||||
                    self.reserve_base,
 | 
					                    self.reserve_base,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for _ in range(1, self.grid_count):
 | 
					            self.extend_grid()
 | 
				
			||||||
                self.extend_grid()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            logger.error(
 | 
					            logger.error(
 | 
				
			||||||
                "[GridTradingBot.initialize_grid] Failed to initialize grid: %s", str(e)
 | 
					                "[GridTradingBot.initialize_grid] Failed to initialize grid: %s", str(e)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            raise
 | 
					            self.initialize_grid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def extend_grid(self):
 | 
					    def extend_grid(self):
 | 
				
			||||||
        """扩展网格,保证两侧都有指定个数的挂单"""
 | 
					        """扩展网格,保证两侧都有指定个数的挂单"""
 | 
				
			||||||
@@ -613,11 +618,23 @@ class GridTradingBot:
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
 | 
					            # 如果两侧都没有挂单 (如: 插针) 则重启机器人
 | 
				
			||||||
            lowest_buy, highest_sell = self.get_extreme_prices()
 | 
					            lowest_buy, highest_sell = self.get_extreme_prices()
 | 
				
			||||||
            base_balance, quote_balance = self.api_get_balances()
 | 
					            if lowest_buy is None and highest_sell is None:
 | 
				
			||||||
 | 
					                self.stop()
 | 
				
			||||||
 | 
					                self.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # 扩展买单网格 (向下)
 | 
					            # 扩展买单网格 (向下)
 | 
				
			||||||
            if lowest_buy is not None and self.current_buy_levels < self.grid_count:
 | 
					            while self.current_buy_levels < self.grid_count:
 | 
				
			||||||
 | 
					                lowest_buy, highest_sell = self.get_extreme_prices()
 | 
				
			||||||
 | 
					                base_balance, quote_balance = self.api_get_balances()
 | 
				
			||||||
 | 
					                if lowest_buy is None:
 | 
				
			||||||
 | 
					                    lowest_buy = self.calculate_grid_price(
 | 
				
			||||||
 | 
					                        highest_sell, self.grid_count, "BUY"
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    logger.custom_debug(
 | 
				
			||||||
 | 
					                        "[GridTradingBot.extend_grid] lowest_buy was None, calculating based on highest_sell"
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
                new_buy_price = self.calculate_grid_price(lowest_buy, 1, "BUY")
 | 
					                new_buy_price = self.calculate_grid_price(lowest_buy, 1, "BUY")
 | 
				
			||||||
                logger.custom_debug(
 | 
					                logger.custom_debug(
 | 
				
			||||||
                    "[GridTradingBot.extend_grid] Extending buy grid - current lowest: %f, new price: %f",
 | 
					                    "[GridTradingBot.extend_grid] Extending buy grid - current lowest: %f, new price: %f",
 | 
				
			||||||
@@ -656,15 +673,26 @@ class GridTradingBot:
 | 
				
			|||||||
                            new_buy_price * self.order_amount,
 | 
					                            new_buy_price * self.order_amount,
 | 
				
			||||||
                            self.min_order_value,
 | 
					                            self.min_order_value,
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    logger.error(
 | 
					                    logger.error(
 | 
				
			||||||
                        "[GridTradingBot.extend_grid] Insufficient quote balance for extended buy: %f <= %f",
 | 
					                        "[GridTradingBot.extend_grid] Insufficient quote balance for extended buy: %f <= %f",
 | 
				
			||||||
                        quote_balance,
 | 
					                        quote_balance,
 | 
				
			||||||
                        self.reserve_quote,
 | 
					                        self.reserve_quote,
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # 扩展卖单网格 (向上)
 | 
					            # 扩展卖单网格 (向上)
 | 
				
			||||||
            if highest_sell is not None and self.current_sell_levels < self.grid_count:
 | 
					            while self.current_sell_levels < self.grid_count:
 | 
				
			||||||
 | 
					                lowest_buy, highest_sell = self.get_extreme_prices()
 | 
				
			||||||
 | 
					                base_balance, quote_balance = self.api_get_balances()
 | 
				
			||||||
 | 
					                if highest_sell is None:
 | 
				
			||||||
 | 
					                    highest_sell = self.calculate_grid_price(
 | 
				
			||||||
 | 
					                        lowest_buy, self.grid_count, "SELL"
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    logger.custom_debug(
 | 
				
			||||||
 | 
					                        "[GridTradingBot.extend_grid] highest_sell was None, calculating based on lowest_buy"
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
                new_sell_price = self.calculate_grid_price(highest_sell, 1, "SELL")
 | 
					                new_sell_price = self.calculate_grid_price(highest_sell, 1, "SELL")
 | 
				
			||||||
                logger.custom_debug(
 | 
					                logger.custom_debug(
 | 
				
			||||||
                    "[GridTradingBot.extend_grid] Extending sell grid - current highest: %f, new price: %f",
 | 
					                    "[GridTradingBot.extend_grid] Extending sell grid - current highest: %f, new price: %f",
 | 
				
			||||||
@@ -703,26 +731,28 @@ class GridTradingBot:
 | 
				
			|||||||
                            new_sell_price * self.order_amount,
 | 
					                            new_sell_price * self.order_amount,
 | 
				
			||||||
                            self.min_order_value,
 | 
					                            self.min_order_value,
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    logger.error(
 | 
					                    logger.error(
 | 
				
			||||||
                        "[GridTradingBot.extend_grid] Insufficient base balance for extended sell: %f <= %f",
 | 
					                        "[GridTradingBot.extend_grid] Insufficient base balance for extended sell: %f <= %f",
 | 
				
			||||||
                        base_balance,
 | 
					                        base_balance,
 | 
				
			||||||
                        self.reserve_base,
 | 
					                        self.reserve_base,
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            logger.error(
 | 
					            logger.error(
 | 
				
			||||||
                "[GridTradingBot.extend_grid] Failed to extend grid: %s", str(e)
 | 
					                "[GridTradingBot.extend_grid] Failed to extend grid: %s", str(e)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            raise
 | 
					            self.extend_grid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def adjust_grid(self):
 | 
					    def adjust_grid_for_filled(self):
 | 
				
			||||||
        """调整网格 - 优化后的对称逻辑:
 | 
					        """调整网格 - 优化后的对称逻辑:
 | 
				
			||||||
        买单成交时:
 | 
					        买单成交时:
 | 
				
			||||||
          1. 取消最高价卖单
 | 
					          1. 取消最高价卖单
 | 
				
			||||||
          2. 在卖单侧挂一个更低价的卖单(卖0)
 | 
					          2. 在卖单侧挂一个更低价的卖单(卖0)
 | 
				
			||||||
          3. 在买单侧挂一个更低价的买单(买n)
 | 
					          3. 在买单侧挂一个更低价的买单(买n)
 | 
				
			||||||
        卖单成交时:
 | 
					        卖单成交时:
 | 
				
			||||||
          1. 取消最低价买单
 | 
					          1. 取消最低价买单
 | 
				
			||||||
          2. 在买单侧挂一个更高价的买单(买0)
 | 
					          2. 在买单侧挂一个更高价的买单(买0)
 | 
				
			||||||
          3. 在卖单侧挂一个更高价的卖单(卖n)"""
 | 
					          3. 在卖单侧挂一个更高价的卖单(卖n)"""
 | 
				
			||||||
@@ -741,113 +771,145 @@ class GridTradingBot:
 | 
				
			|||||||
                if order.order_id in current_order_ids and order.status == "FILLED"
 | 
					                if order.order_id in current_order_ids and order.status == "FILLED"
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not newly_filled_orders:
 | 
					            if newly_filled_orders:
 | 
				
			||||||
                logger.custom_debug(
 | 
					                logger.custom_debug(
 | 
				
			||||||
                    "[GridTradingBot.adjust_grid] No newly filled orders found"
 | 
					                    "[GridTradingBot.adjust_grid] Newly filled orders found"
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                return
 | 
					                # 处理每个新成交的订单
 | 
				
			||||||
 | 
					                for filled_order in newly_filled_orders:
 | 
				
			||||||
            # 处理每个新成交的订单
 | 
					                    filled_side = filled_order.side
 | 
				
			||||||
            for filled_order in newly_filled_orders:
 | 
					                    filled_price = filled_order.price
 | 
				
			||||||
                filled_side = filled_order.side
 | 
					                    filled_id = filled_order.order_id
 | 
				
			||||||
                filled_price = filled_order.price
 | 
					                    self.active_orders.pop(filled_id, None)
 | 
				
			||||||
                filled_id = filled_order.order_id
 | 
					 | 
				
			||||||
                self.active_orders.pop(filled_id, None)
 | 
					 | 
				
			||||||
                logger.info(
 | 
					 | 
				
			||||||
                    "[GridTradingBot.adjust_grid] Processing newly filled %s order at price %f",
 | 
					 | 
				
			||||||
                    filled_side,
 | 
					 | 
				
			||||||
                    filled_price,
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                # 获取当前活跃订单
 | 
					 | 
				
			||||||
                active_buys = [
 | 
					 | 
				
			||||||
                    o
 | 
					 | 
				
			||||||
                    for o in self.active_orders.values()
 | 
					 | 
				
			||||||
                    if o.side == "BUY" and o.status == "NEW"
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
                active_sells = [
 | 
					 | 
				
			||||||
                    o
 | 
					 | 
				
			||||||
                    for o in self.active_orders.values()
 | 
					 | 
				
			||||||
                    if o.side == "SELL" and o.status == "NEW"
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if filled_side == "BUY" and active_sells:
 | 
					 | 
				
			||||||
                    # 买单成交时的处理逻辑
 | 
					 | 
				
			||||||
                    self.current_buy_levels -= 1
 | 
					 | 
				
			||||||
                    # 1. 取消最高价卖单
 | 
					 | 
				
			||||||
                    highest_sell = max(active_sells, key=lambda x: x.price)
 | 
					 | 
				
			||||||
                    self.api_cancel_order(highest_sell.order_id)
 | 
					 | 
				
			||||||
                    self.active_orders.pop(highest_sell.order_id, None)
 | 
					 | 
				
			||||||
                    logger.info(
 | 
					                    logger.info(
 | 
				
			||||||
                        "[GridTradingBot.adjust_grid] Cancelled highest SELL order at %f (order_id: %s)",
 | 
					                        "[GridTradingBot.adjust_grid] Processing newly filled %s order at price %f",
 | 
				
			||||||
                        highest_sell.price,
 | 
					                        filled_side,
 | 
				
			||||||
                        highest_sell.order_id,
 | 
					                        filled_price,
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    # 2. 在卖单侧挂一个更低价的卖单(卖0)
 | 
					 | 
				
			||||||
                    # 使用最近成交的买单价格作为基准
 | 
					 | 
				
			||||||
                    new_sell_price = self.calculate_grid_price(filled_price, 1, "SELL")
 | 
					 | 
				
			||||||
                    # 检查余额和订单价值
 | 
					 | 
				
			||||||
                    base_balance, _ = self.api_get_balances()
 | 
					 | 
				
			||||||
                    if base_balance > self.reserve_base and self.is_order_value_valid(
 | 
					 | 
				
			||||||
                        new_sell_price
 | 
					 | 
				
			||||||
                    ):
 | 
					 | 
				
			||||||
                        sell_order_id = self.api_place_order(new_sell_price, "SELL")
 | 
					 | 
				
			||||||
                        if sell_order_id:
 | 
					 | 
				
			||||||
                            self.active_orders[sell_order_id] = Order(
 | 
					 | 
				
			||||||
                                order_id=sell_order_id,
 | 
					 | 
				
			||||||
                                price=new_sell_price,
 | 
					 | 
				
			||||||
                                quantity=self.order_amount,
 | 
					 | 
				
			||||||
                                side="SELL",
 | 
					 | 
				
			||||||
                                status="NEW",
 | 
					 | 
				
			||||||
                            )
 | 
					 | 
				
			||||||
                            logger.info(
 | 
					 | 
				
			||||||
                                "[GridTradingBot.adjust_grid] Placed new lower SELL order at %f (order_id: %s)",
 | 
					 | 
				
			||||||
                                new_sell_price,
 | 
					 | 
				
			||||||
                                sell_order_id,
 | 
					 | 
				
			||||||
                            )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                elif filled_side == "SELL" and active_buys:
 | 
					                    # 获取当前活跃订单
 | 
				
			||||||
                    # 卖单成交时的处理逻辑
 | 
					                    active_buys = [
 | 
				
			||||||
                    self.current_sell_levels -= 1
 | 
					                        o
 | 
				
			||||||
                    # 1. 取消最低价买单
 | 
					                        for o in self.active_orders.values()
 | 
				
			||||||
                    lowest_buy = min(active_buys, key=lambda x: x.price)
 | 
					                        if o.side == "BUY" and o.status == "NEW"
 | 
				
			||||||
                    self.api_cancel_order(lowest_buy.order_id)
 | 
					                    ]
 | 
				
			||||||
                    self.active_orders.pop(lowest_buy.order_id, None)
 | 
					                    active_sells = [
 | 
				
			||||||
 | 
					                        o
 | 
				
			||||||
 | 
					                        for o in self.active_orders.values()
 | 
				
			||||||
 | 
					                        if o.side == "SELL" and o.status == "NEW"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    logger.info(
 | 
					                    if filled_side == "BUY":
 | 
				
			||||||
                        "[GridTradingBot.adjust_grid] Cancelled lowest BUY order at %f (order_id: %s)",
 | 
					                        self.current_buy_levels -= 1
 | 
				
			||||||
                        lowest_buy.price,
 | 
					                    elif filled_side == "SELL":
 | 
				
			||||||
                        lowest_buy.order_id,
 | 
					                        self.current_sell_levels -= 1
 | 
				
			||||||
                    )
 | 
					                    if filled_side == "BUY" and active_sells:
 | 
				
			||||||
                    # 2. 在买单侧挂一个更高价的买单(买0)
 | 
					                        # 买单成交时的处理逻辑
 | 
				
			||||||
                    # 使用最近成交的卖单价格作为基准
 | 
					                        # 1. 取消最高价卖单
 | 
				
			||||||
                    new_buy_price = self.calculate_grid_price(filled_price, 1, "BUY")
 | 
					                        highest_sell = max(active_sells, key=lambda x: x.price)
 | 
				
			||||||
                    # 检查余额和订单价值
 | 
					                        self.api_cancel_order(highest_sell.order_id)
 | 
				
			||||||
                    _, quote_balance = self.api_get_balances()
 | 
					                        self.active_orders.pop(highest_sell.order_id, None)
 | 
				
			||||||
                    if (
 | 
					                        logger.info(
 | 
				
			||||||
                        quote_balance > self.reserve_quote
 | 
					                            "[GridTradingBot.adjust_grid] Cancelled highest SELL order at %f (order_id: %s)",
 | 
				
			||||||
                        and self.is_order_value_valid(new_buy_price)
 | 
					                            highest_sell.price,
 | 
				
			||||||
                    ):
 | 
					                            highest_sell.order_id,
 | 
				
			||||||
                        buy_order_id = self.api_place_order(new_buy_price, "BUY")
 | 
					                        )
 | 
				
			||||||
                        if buy_order_id:
 | 
					                        # 2. 在卖单侧挂一个更低价的卖单(卖0)
 | 
				
			||||||
                            self.active_orders[buy_order_id] = Order(
 | 
					                        # 使用最近成交的买单价格作为基准
 | 
				
			||||||
                                order_id=buy_order_id,
 | 
					                        new_sell_price = self.calculate_grid_price(
 | 
				
			||||||
                                price=new_buy_price,
 | 
					                            filled_price, 1, "SELL"
 | 
				
			||||||
                                quantity=self.order_amount,
 | 
					                        )
 | 
				
			||||||
                                side="BUY",
 | 
					                        # 检查余额和订单价值
 | 
				
			||||||
                                status="NEW",
 | 
					                        base_balance, _ = self.api_get_balances()
 | 
				
			||||||
                            )
 | 
					                        if (
 | 
				
			||||||
                            logger.info(
 | 
					                            base_balance > self.reserve_base
 | 
				
			||||||
                                "[GridTradingBot.adjust_grid] Placed new higher BUY order at %f (order_id: %s)",
 | 
					                            and self.is_order_value_valid(new_sell_price)
 | 
				
			||||||
                                new_buy_price,
 | 
					                        ):
 | 
				
			||||||
                                buy_order_id,
 | 
					                            sell_order_id = self.api_place_order(new_sell_price, "SELL")
 | 
				
			||||||
                            )
 | 
					                            if sell_order_id:
 | 
				
			||||||
 | 
					                                self.active_orders[sell_order_id] = Order(
 | 
				
			||||||
 | 
					                                    order_id=sell_order_id,
 | 
				
			||||||
 | 
					                                    price=new_sell_price,
 | 
				
			||||||
 | 
					                                    quantity=self.order_amount,
 | 
				
			||||||
 | 
					                                    side="SELL",
 | 
				
			||||||
 | 
					                                    status="NEW",
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                                logger.info(
 | 
				
			||||||
 | 
					                                    "[GridTradingBot.adjust_grid] Placed new lower SELL order at %f (order_id: %s)",
 | 
				
			||||||
 | 
					                                    new_sell_price,
 | 
				
			||||||
 | 
					                                    sell_order_id,
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    elif filled_side == "SELL" and active_buys:
 | 
				
			||||||
 | 
					                        # 卖单成交时的处理逻辑
 | 
				
			||||||
 | 
					                        # 1. 取消最低价买单
 | 
				
			||||||
 | 
					                        lowest_buy = min(active_buys, key=lambda x: x.price)
 | 
				
			||||||
 | 
					                        self.api_cancel_order(lowest_buy.order_id)
 | 
				
			||||||
 | 
					                        self.active_orders.pop(lowest_buy.order_id, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        logger.info(
 | 
				
			||||||
 | 
					                            "[GridTradingBot.adjust_grid] Cancelled lowest BUY order at %f (order_id: %s)",
 | 
				
			||||||
 | 
					                            lowest_buy.price,
 | 
				
			||||||
 | 
					                            lowest_buy.order_id,
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                        # 2. 在买单侧挂一个更高价的买单(买0)
 | 
				
			||||||
 | 
					                        # 使用最近成交的卖单价格作为基准
 | 
				
			||||||
 | 
					                        new_buy_price = self.calculate_grid_price(
 | 
				
			||||||
 | 
					                            filled_price, 1, "BUY"
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                        # 检查余额和订单价值
 | 
				
			||||||
 | 
					                        _, quote_balance = self.api_get_balances()
 | 
				
			||||||
 | 
					                        if (
 | 
				
			||||||
 | 
					                            quote_balance > self.reserve_quote
 | 
				
			||||||
 | 
					                            and self.is_order_value_valid(new_buy_price)
 | 
				
			||||||
 | 
					                        ):
 | 
				
			||||||
 | 
					                            buy_order_id = self.api_place_order(new_buy_price, "BUY")
 | 
				
			||||||
 | 
					                            if buy_order_id:
 | 
				
			||||||
 | 
					                                self.active_orders[buy_order_id] = Order(
 | 
				
			||||||
 | 
					                                    order_id=buy_order_id,
 | 
				
			||||||
 | 
					                                    price=new_buy_price,
 | 
				
			||||||
 | 
					                                    quantity=self.order_amount,
 | 
				
			||||||
 | 
					                                    side="BUY",
 | 
				
			||||||
 | 
					                                    status="NEW",
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                                logger.info(
 | 
				
			||||||
 | 
					                                    "[GridTradingBot.adjust_grid] Placed new higher BUY order at %f (order_id: %s)",
 | 
				
			||||||
 | 
					                                    new_buy_price,
 | 
				
			||||||
 | 
					                                    buy_order_id,
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            logger.error(
 | 
					            logger.error(
 | 
				
			||||||
                "[GridTradingBot.adjust_grid] Failed to adjust grid: %s", str(e)
 | 
					                "[GridTradingBot.adjust_grid] Failed to adjust grid: %s", str(e)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            raise
 | 
					            self.adjust_grid_for_filled()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def adjust_grid_for_violation(self):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            market_price = self.api_get_price()
 | 
				
			||||||
 | 
					            lowest_buy, highest_sell = self.get_extreme_prices()
 | 
				
			||||||
 | 
					            if lowest_buy is None and market_price < self.calculate_grid_price(
 | 
				
			||||||
 | 
					                highest_sell, self.grid_count + 1, "BUY"
 | 
				
			||||||
 | 
					            ):
 | 
				
			||||||
 | 
					                logger.warning(
 | 
				
			||||||
 | 
					                    "[GridTradingBot.adjust_grid_for_violation] Price varied too low, restarting grid."
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.api_cancel_all_orders()
 | 
				
			||||||
 | 
					                self.initialize_grid()
 | 
				
			||||||
 | 
					            elif highest_sell is None and market_price > self.calculate_grid_price(
 | 
				
			||||||
 | 
					                lowest_buy, self.grid_count + 1, "SELL"
 | 
				
			||||||
 | 
					            ):
 | 
				
			||||||
 | 
					                logger.warning(
 | 
				
			||||||
 | 
					                    "[GridTradingBot.adjust_grid_for_violation] Price varied too high, restarting grid."
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                self.api_cancel_all_orders()
 | 
				
			||||||
 | 
					                self.initialize_grid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            logger.error(
 | 
				
			||||||
 | 
					                "[GridTradingBot.adjust_grid_for_violation] Failed to adjust grid: %s",
 | 
				
			||||||
 | 
					                str(e),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            self.adjust_grid_for_violation()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run(self):
 | 
					    def run(self):
 | 
				
			||||||
        """运行网格交易机器人"""
 | 
					        """运行网格交易机器人"""
 | 
				
			||||||
@@ -871,7 +933,8 @@ class GridTradingBot:
 | 
				
			|||||||
                    self.api_update_order_statuses()
 | 
					                    self.api_update_order_statuses()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    # 调整网格
 | 
					                    # 调整网格
 | 
				
			||||||
                    self.adjust_grid()
 | 
					                    self.adjust_grid_for_filled()
 | 
				
			||||||
 | 
					                    self.adjust_grid_for_violation()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    # 尝试扩展网格
 | 
					                    # 尝试扩展网格
 | 
				
			||||||
                    self.extend_grid()
 | 
					                    self.extend_grid()
 | 
				
			||||||
@@ -885,7 +948,7 @@ class GridTradingBot:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                except Exception as e:
 | 
					                except Exception as e:
 | 
				
			||||||
                    logger.error("[GridTradingBot.run] Error in main loop: %s", str(e))
 | 
					                    logger.error("[GridTradingBot.run] Error in main loop: %s", str(e))
 | 
				
			||||||
                    sleep_time = 3
 | 
					                    sleep_time = 1
 | 
				
			||||||
                    logger.custom_debug(
 | 
					                    logger.custom_debug(
 | 
				
			||||||
                        "[GridTradingBot.run] Error occurred, sleeping for %d seconds",
 | 
					                        "[GridTradingBot.run] Error occurred, sleeping for %d seconds",
 | 
				
			||||||
                        sleep_time,
 | 
					                        sleep_time,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user