206
main.py
206
main.py
@@ -8,19 +8,8 @@ from dataclasses import dataclass
|
|||||||
import mexc_spot_v3
|
import mexc_spot_v3
|
||||||
|
|
||||||
# 配置日志
|
# 配置日志
|
||||||
CUSTOM_DEBUG_LEVEL = 15
|
|
||||||
logging.addLevelName(CUSTOM_DEBUG_LEVEL, "CUSTOM_DEBUG")
|
|
||||||
|
|
||||||
|
|
||||||
class CustomLogger(logging.getLoggerClass()):
|
|
||||||
def custom_debug(self, msg, *args, **kwargs):
|
|
||||||
if self.isEnabledFor(CUSTOM_DEBUG_LEVEL):
|
|
||||||
self._log(CUSTOM_DEBUG_LEVEL, msg, args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
logging.setLoggerClass(CustomLogger)
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=CUSTOM_DEBUG_LEVEL,
|
level=logging.DEBUG,
|
||||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||||
handlers=[
|
handlers=[
|
||||||
logging.FileHandler("output/mexc_spot_grid_bot.log", encoding="utf-8"),
|
logging.FileHandler("output/mexc_spot_grid_bot.log", encoding="utf-8"),
|
||||||
@@ -28,9 +17,6 @@ logging.basicConfig(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logger.custom_debug = lambda msg, *args, **kwargs: logger._log( # pylint: disable=W0212
|
|
||||||
CUSTOM_DEBUG_LEVEL, msg, args, **kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -60,7 +46,7 @@ class GridTradingBot:
|
|||||||
- reserve_base: 保留的基础货币数量 (如 1 BTC)
|
- reserve_base: 保留的基础货币数量 (如 1 BTC)
|
||||||
- reserve_quote: 保留的报价货币数量 (如 100 USDC)
|
- reserve_quote: 保留的报价货币数量 (如 100 USDC)
|
||||||
"""
|
"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.__init__] Initializing GridTradingBot with config: %r",
|
"[GridTradingBot.__init__] Initializing GridTradingBot with config: %r",
|
||||||
conf,
|
conf,
|
||||||
)
|
)
|
||||||
@@ -83,7 +69,7 @@ class GridTradingBot:
|
|||||||
self.current_sell_levels = 0
|
self.current_sell_levels = 0
|
||||||
|
|
||||||
# 初始化API
|
# 初始化API
|
||||||
logger.custom_debug("[GridTradingBot.__init__] Initializing MEXC API clients")
|
logger.debug("[GridTradingBot.__init__] Initializing MEXC API clients")
|
||||||
self.api_trade = mexc_spot_v3.mexc_trade()
|
self.api_trade = mexc_spot_v3.mexc_trade()
|
||||||
self.api_market = mexc_spot_v3.mexc_market()
|
self.api_market = mexc_spot_v3.mexc_market()
|
||||||
|
|
||||||
@@ -165,14 +151,14 @@ class GridTradingBot:
|
|||||||
|
|
||||||
def api_get_price(self) -> float:
|
def api_get_price(self) -> float:
|
||||||
"""获取当前市场价格"""
|
"""获取当前市场价格"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_get_price] Fetching current market price for symbol: %s",
|
"[GridTradingBot.api_get_price] Fetching current market price for symbol: %s",
|
||||||
self.symbol,
|
self.symbol,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
ticker = self.api_market.get_price({"symbol": self.symbol})
|
ticker = self.api_market.get_price({"symbol": self.symbol})
|
||||||
price = float(ticker["price"])
|
price = float(ticker["price"])
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_get_price] Current market price: %f", price
|
"[GridTradingBot.api_get_price] Current market price: %f", price
|
||||||
)
|
)
|
||||||
return price
|
return price
|
||||||
@@ -191,7 +177,7 @@ class GridTradingBot:
|
|||||||
base_available = 0.0
|
base_available = 0.0
|
||||||
quote_available = 0.0
|
quote_available = 0.0
|
||||||
|
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_get_balances] Fetching balances for %s and %s",
|
"[GridTradingBot.api_get_balances] Fetching balances for %s and %s",
|
||||||
base_currency,
|
base_currency,
|
||||||
quote_currency,
|
quote_currency,
|
||||||
@@ -201,20 +187,20 @@ class GridTradingBot:
|
|||||||
for balance in balances.get("balances", []):
|
for balance in balances.get("balances", []):
|
||||||
if balance["asset"] == base_currency:
|
if balance["asset"] == base_currency:
|
||||||
base_available = float(balance["free"])
|
base_available = float(balance["free"])
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_get_balances] Base currency (%s) available: %f",
|
"[GridTradingBot.api_get_balances] Base currency (%s) available: %f",
|
||||||
base_currency,
|
base_currency,
|
||||||
base_available,
|
base_available,
|
||||||
)
|
)
|
||||||
elif balance["asset"] == quote_currency:
|
elif balance["asset"] == quote_currency:
|
||||||
quote_available = float(balance["free"])
|
quote_available = float(balance["free"])
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_get_balances] Quote currency (%s) available: %f",
|
"[GridTradingBot.api_get_balances] Quote currency (%s) available: %f",
|
||||||
quote_currency,
|
quote_currency,
|
||||||
quote_available,
|
quote_available,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_get_balances] Final balances - base: %f, quote: %f",
|
"[GridTradingBot.api_get_balances] Final balances - base: %f, quote: %f",
|
||||||
base_available,
|
base_available,
|
||||||
quote_available,
|
quote_available,
|
||||||
@@ -229,7 +215,7 @@ class GridTradingBot:
|
|||||||
def calculate_order_value(self, price: float) -> float:
|
def calculate_order_value(self, price: float) -> float:
|
||||||
"""计算订单价值 (价格 * 数量)"""
|
"""计算订单价值 (价格 * 数量)"""
|
||||||
value = price * self.order_amount
|
value = price * self.order_amount
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.calculate_order_value] Calculated order value: price=%f * amount=%f = %f",
|
"[GridTradingBot.calculate_order_value] Calculated order value: price=%f * amount=%f = %f",
|
||||||
price,
|
price,
|
||||||
self.order_amount,
|
self.order_amount,
|
||||||
@@ -241,7 +227,7 @@ class GridTradingBot:
|
|||||||
"""检查订单价值是否满足最小挂单要求"""
|
"""检查订单价值是否满足最小挂单要求"""
|
||||||
value = self.calculate_order_value(price)
|
value = self.calculate_order_value(price)
|
||||||
is_valid = value >= self.min_order_value
|
is_valid = value >= self.min_order_value
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.is_order_value_valid] Order value validation: %f >= %f? %s",
|
"[GridTradingBot.is_order_value_valid] Order value validation: %f >= %f? %s",
|
||||||
value,
|
value,
|
||||||
self.min_order_value,
|
self.min_order_value,
|
||||||
@@ -261,7 +247,7 @@ class GridTradingBot:
|
|||||||
返回:
|
返回:
|
||||||
计算后的价格
|
计算后的价格
|
||||||
"""
|
"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.calculate_grid_price] Calculating grid price: base=%f, level=%d, side=%s",
|
"[GridTradingBot.calculate_grid_price] Calculating grid price: base=%f, level=%d, side=%s",
|
||||||
base_price,
|
base_price,
|
||||||
level,
|
level,
|
||||||
@@ -270,7 +256,7 @@ class GridTradingBot:
|
|||||||
|
|
||||||
if side == "BUY":
|
if side == "BUY":
|
||||||
price = base_price / (1 + self.grid_percentage) ** level
|
price = base_price / (1 + self.grid_percentage) ** level
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.calculate_grid_price] Calculated BUY price: %f / (1 + %f)^%d = %f",
|
"[GridTradingBot.calculate_grid_price] Calculated BUY price: %f / (1 + %f)^%d = %f",
|
||||||
base_price,
|
base_price,
|
||||||
self.grid_percentage,
|
self.grid_percentage,
|
||||||
@@ -280,7 +266,7 @@ class GridTradingBot:
|
|||||||
return price
|
return price
|
||||||
elif side == "SELL":
|
elif side == "SELL":
|
||||||
price = base_price * (1 + self.grid_percentage) ** level
|
price = base_price * (1 + self.grid_percentage) ** level
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.calculate_grid_price] Calculated SELL price: %f * (1 + %f)^%d = %f",
|
"[GridTradingBot.calculate_grid_price] Calculated SELL price: %f * (1 + %f)^%d = %f",
|
||||||
base_price,
|
base_price,
|
||||||
self.grid_percentage,
|
self.grid_percentage,
|
||||||
@@ -306,7 +292,7 @@ class GridTradingBot:
|
|||||||
返回:
|
返回:
|
||||||
订单ID (如果下单成功) 或 None (如果失败)
|
订单ID (如果下单成功) 或 None (如果失败)
|
||||||
"""
|
"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_place_order] Attempting to place %s order at price: %f",
|
"[GridTradingBot.api_place_order] Attempting to place %s order at price: %f",
|
||||||
side,
|
side,
|
||||||
price,
|
price,
|
||||||
@@ -323,9 +309,6 @@ class GridTradingBot:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# logger.custom_debug(
|
|
||||||
# "[GridTradingBot.api_place_order] Sending order request to exchange"
|
|
||||||
# )
|
|
||||||
order_detail = self.api_trade.post_order(
|
order_detail = self.api_trade.post_order(
|
||||||
{
|
{
|
||||||
"symbol": self.symbol,
|
"symbol": self.symbol,
|
||||||
@@ -364,7 +347,7 @@ class GridTradingBot:
|
|||||||
|
|
||||||
def api_cancel_order(self, order_id: str):
|
def api_cancel_order(self, order_id: str):
|
||||||
"""取消订单"""
|
"""取消订单"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_cancel_order] Attempting to cancel order: %s", order_id
|
"[GridTradingBot.api_cancel_order] Attempting to cancel order: %s", order_id
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
@@ -383,7 +366,7 @@ class GridTradingBot:
|
|||||||
|
|
||||||
def api_cancel_all_orders(self):
|
def api_cancel_all_orders(self):
|
||||||
"""取消所有活跃订单"""
|
"""取消所有活跃订单"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_cancel_all_orders] Attempting to cancel all open orders for symbol: %s",
|
"[GridTradingBot.api_cancel_all_orders] Attempting to cancel all open orders for symbol: %s",
|
||||||
self.symbol,
|
self.symbol,
|
||||||
)
|
)
|
||||||
@@ -405,65 +388,82 @@ class GridTradingBot:
|
|||||||
|
|
||||||
def api_update_order_statuses(self):
|
def api_update_order_statuses(self):
|
||||||
"""更新所有活跃订单的状态"""
|
"""更新所有活跃订单的状态"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.api_update_order_statuses] Updating status for %d active orders",
|
"[GridTradingBot.api_update_order_statuses] Updating status for %d active orders",
|
||||||
len(self.active_orders),
|
len(self.active_orders),
|
||||||
)
|
)
|
||||||
|
|
||||||
for order_id in list(self.active_orders.keys()):
|
# 分别处理买单和卖单
|
||||||
try:
|
for side in ["BUY", "SELL"]:
|
||||||
logger.custom_debug(
|
# 获取当前方向的所有订单并按价格排序
|
||||||
"[GridTradingBot.api_update_order_statuses] Checking status for order: %s",
|
orders = self.get_active_orders_by_side(side)
|
||||||
order_id,
|
|
||||||
)
|
|
||||||
order_info = self.api_trade.get_order(
|
|
||||||
{"symbol": self.symbol, "orderId": order_id}
|
|
||||||
)
|
|
||||||
|
|
||||||
# 更新订单状态
|
# 买单从高到低排序,卖单从低到高排序
|
||||||
old_status = self.active_orders[order_id].status
|
if side == "BUY":
|
||||||
new_status = order_info["status"]
|
orders.sort(key=lambda x: float(x.price), reverse=True)
|
||||||
self.active_orders[order_id].status = new_status
|
else:
|
||||||
|
orders.sort(key=lambda x: float(x.price))
|
||||||
|
|
||||||
# 记录状态变化
|
# 遍历订单
|
||||||
if old_status != new_status:
|
for order in orders:
|
||||||
logger.info(
|
order_id = order.order_id
|
||||||
"[GridTradingBot.api_update_order_statuses] Order %s status changed from %s to %s",
|
try:
|
||||||
|
logger.debug(
|
||||||
|
"[GridTradingBot.api_update_order_statuses] Checking status for order: %s",
|
||||||
order_id,
|
order_id,
|
||||||
old_status,
|
)
|
||||||
new_status,
|
order_info = self.api_trade.get_order(
|
||||||
|
{"symbol": self.symbol, "orderId": order_id}
|
||||||
)
|
)
|
||||||
|
|
||||||
# 如果订单已完成,记录成交时间
|
# 更新订单状态
|
||||||
if new_status == "FILLED":
|
old_status = self.active_orders[order_id].status
|
||||||
self.active_orders[order_id].filled_time = time.time()
|
new_status = order_info["status"]
|
||||||
logger.custom_debug(
|
self.active_orders[order_id].status = new_status
|
||||||
"[GridTradingBot.api_update_order_statuses] Order %s filled at %f",
|
|
||||||
order_id,
|
|
||||||
self.active_orders[order_id].filled_time,
|
|
||||||
)
|
|
||||||
self.record_transaction(order_info)
|
|
||||||
|
|
||||||
if new_status in ["CANCELED"]:
|
# 记录状态变化
|
||||||
logger.custom_debug(
|
if old_status != new_status:
|
||||||
"[GridTradingBot.api_update_order_statuses] Removing order %s from active orders (status: %s)",
|
logger.info(
|
||||||
order_id,
|
"[GridTradingBot.api_update_order_statuses] Order %s status changed from %s to %s",
|
||||||
new_status,
|
order_id,
|
||||||
)
|
old_status,
|
||||||
self.active_orders.pop(order_id)
|
new_status,
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
# 如果订单已完成,记录成交时间
|
||||||
logger.error(
|
if new_status == "FILLED":
|
||||||
"[GridTradingBot.api_update_order_statuses] Failed to get status for order %s: %s",
|
self.active_orders[order_id].filled_time = time.time()
|
||||||
order_id,
|
logger.debug(
|
||||||
str(e),
|
"[GridTradingBot.api_update_order_statuses] Order %s filled at %f",
|
||||||
)
|
order_id,
|
||||||
self.api_update_order_statuses()
|
self.active_orders[order_id].filled_time,
|
||||||
|
)
|
||||||
|
self.record_transaction(order_info)
|
||||||
|
|
||||||
|
if new_status in ["CANCELED"]:
|
||||||
|
logger.debug(
|
||||||
|
"[GridTradingBot.api_update_order_statuses] Removing order %s from active orders (status: %s)",
|
||||||
|
order_id,
|
||||||
|
new_status,
|
||||||
|
)
|
||||||
|
self.active_orders.pop(order_id)
|
||||||
|
|
||||||
|
if new_status == "NEW":
|
||||||
|
logger.debug("[GridTradingBot.api_update_order_statuses] NEW order detected for %s side, skipping.", side)
|
||||||
|
break
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
"[GridTradingBot.api_update_order_statuses] Failed to get status for order %s: %s",
|
||||||
|
order_id,
|
||||||
|
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]:
|
||||||
"""获取指定方向的所有活跃订单"""
|
"""获取指定方向的所有活跃订单"""
|
||||||
orders = [order for order in self.active_orders.values() if order.side == side]
|
orders = [order for order in self.active_orders.values() if order.side == side]
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.get_active_orders_by_side] Found %d active %s orders",
|
"[GridTradingBot.get_active_orders_by_side] Found %d active %s orders",
|
||||||
len(orders),
|
len(orders),
|
||||||
side,
|
side,
|
||||||
@@ -485,7 +485,7 @@ class GridTradingBot:
|
|||||||
max([order.price for order in sell_orders]) if sell_orders else None
|
max([order.price for order in sell_orders]) if sell_orders else None
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.get_extreme_prices] Extreme prices - lowest buy: %s, highest sell: %s",
|
"[GridTradingBot.get_extreme_prices] Extreme prices - lowest buy: %s, highest sell: %s",
|
||||||
lowest_buy,
|
lowest_buy,
|
||||||
highest_sell,
|
highest_sell,
|
||||||
@@ -509,7 +509,7 @@ class GridTradingBot:
|
|||||||
# 初始下单: 买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.debug(
|
||||||
"[GridTradingBot.initialize_grid] Initial buy price: %f, sell price: %f",
|
"[GridTradingBot.initialize_grid] Initial buy price: %f, sell price: %f",
|
||||||
buy_price,
|
buy_price,
|
||||||
sell_price,
|
sell_price,
|
||||||
@@ -525,13 +525,13 @@ class GridTradingBot:
|
|||||||
|
|
||||||
# 下单买1
|
# 下单买1
|
||||||
if quote_balance > self.reserve_quote:
|
if quote_balance > self.reserve_quote:
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.initialize_grid] Quote balance sufficient (%f > %f), checking order value",
|
"[GridTradingBot.initialize_grid] Quote balance sufficient (%f > %f), checking order value",
|
||||||
quote_balance,
|
quote_balance,
|
||||||
self.reserve_quote,
|
self.reserve_quote,
|
||||||
)
|
)
|
||||||
if self.is_order_value_valid(buy_price):
|
if self.is_order_value_valid(buy_price):
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.initialize_grid] Order value valid, placing buy order"
|
"[GridTradingBot.initialize_grid] Order value valid, placing buy order"
|
||||||
)
|
)
|
||||||
buy_order_id = self.api_place_order(buy_price, "BUY")
|
buy_order_id = self.api_place_order(buy_price, "BUY")
|
||||||
@@ -563,13 +563,13 @@ class GridTradingBot:
|
|||||||
|
|
||||||
# 下单卖1
|
# 下单卖1
|
||||||
if base_balance > self.reserve_base:
|
if base_balance > self.reserve_base:
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.initialize_grid] Base balance sufficient (%f > %f), checking order value",
|
"[GridTradingBot.initialize_grid] Base balance sufficient (%f > %f), checking order value",
|
||||||
base_balance,
|
base_balance,
|
||||||
self.reserve_base,
|
self.reserve_base,
|
||||||
)
|
)
|
||||||
if self.is_order_value_valid(sell_price):
|
if self.is_order_value_valid(sell_price):
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.initialize_grid] Order value valid, placing sell order"
|
"[GridTradingBot.initialize_grid] Order value valid, placing sell order"
|
||||||
)
|
)
|
||||||
sell_order_id = self.api_place_order(sell_price, "SELL")
|
sell_order_id = self.api_place_order(sell_price, "SELL")
|
||||||
@@ -609,7 +609,7 @@ class GridTradingBot:
|
|||||||
|
|
||||||
def extend_grid(self):
|
def extend_grid(self):
|
||||||
"""扩展网格,保证两侧都有指定个数的挂单"""
|
"""扩展网格,保证两侧都有指定个数的挂单"""
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] Extending grid - current buy levels: %d/%d, sell levels: %d/%d",
|
"[GridTradingBot.extend_grid] Extending grid - current buy levels: %d/%d, sell levels: %d/%d",
|
||||||
self.current_buy_levels,
|
self.current_buy_levels,
|
||||||
self.grid_count,
|
self.grid_count,
|
||||||
@@ -632,24 +632,24 @@ class GridTradingBot:
|
|||||||
lowest_buy = self.calculate_grid_price(
|
lowest_buy = self.calculate_grid_price(
|
||||||
highest_sell, self.grid_count, "BUY"
|
highest_sell, self.grid_count, "BUY"
|
||||||
)
|
)
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] lowest_buy was None, calculating based on highest_sell"
|
"[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.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",
|
||||||
lowest_buy,
|
lowest_buy,
|
||||||
new_buy_price,
|
new_buy_price,
|
||||||
)
|
)
|
||||||
|
|
||||||
if quote_balance > self.reserve_quote:
|
if quote_balance > self.reserve_quote:
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] Quote balance sufficient (%f > %f), checking order value",
|
"[GridTradingBot.extend_grid] Quote balance sufficient (%f > %f), checking order value",
|
||||||
quote_balance,
|
quote_balance,
|
||||||
self.reserve_quote,
|
self.reserve_quote,
|
||||||
)
|
)
|
||||||
if self.is_order_value_valid(new_buy_price):
|
if self.is_order_value_valid(new_buy_price):
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] Order value valid, placing extended buy order"
|
"[GridTradingBot.extend_grid] Order value valid, placing extended buy order"
|
||||||
)
|
)
|
||||||
buy_order_id = self.api_place_order(new_buy_price, "BUY")
|
buy_order_id = self.api_place_order(new_buy_price, "BUY")
|
||||||
@@ -690,24 +690,24 @@ class GridTradingBot:
|
|||||||
highest_sell = self.calculate_grid_price(
|
highest_sell = self.calculate_grid_price(
|
||||||
lowest_buy, self.grid_count, "SELL"
|
lowest_buy, self.grid_count, "SELL"
|
||||||
)
|
)
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] highest_sell was None, calculating based on lowest_buy"
|
"[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.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",
|
||||||
highest_sell,
|
highest_sell,
|
||||||
new_sell_price,
|
new_sell_price,
|
||||||
)
|
)
|
||||||
|
|
||||||
if base_balance > self.reserve_base:
|
if base_balance > self.reserve_base:
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] Base balance sufficient (%f > %f), checking order value",
|
"[GridTradingBot.extend_grid] Base balance sufficient (%f > %f), checking order value",
|
||||||
base_balance,
|
base_balance,
|
||||||
self.reserve_base,
|
self.reserve_base,
|
||||||
)
|
)
|
||||||
if self.is_order_value_valid(new_sell_price):
|
if self.is_order_value_valid(new_sell_price):
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.extend_grid] Order value valid, placing extended sell order"
|
"[GridTradingBot.extend_grid] Order value valid, placing extended sell order"
|
||||||
)
|
)
|
||||||
sell_order_id = self.api_place_order(new_sell_price, "SELL")
|
sell_order_id = self.api_place_order(new_sell_price, "SELL")
|
||||||
@@ -756,9 +756,7 @@ class GridTradingBot:
|
|||||||
1. 取消最低价买单
|
1. 取消最低价买单
|
||||||
2. 在买单侧挂一个更高价的买单(买0)
|
2. 在买单侧挂一个更高价的买单(买0)
|
||||||
3. 在卖单侧挂一个更高价的卖单(卖n)"""
|
3. 在卖单侧挂一个更高价的卖单(卖n)"""
|
||||||
logger.custom_debug(
|
logger.debug("[GridTradingBot.adjust_grid] Adjusting grid with symmetric logic")
|
||||||
"[GridTradingBot.adjust_grid] Adjusting grid with symmetric logic"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 获取当前所有订单的快照
|
# 获取当前所有订单的快照
|
||||||
@@ -772,9 +770,7 @@ class GridTradingBot:
|
|||||||
]
|
]
|
||||||
|
|
||||||
if newly_filled_orders:
|
if newly_filled_orders:
|
||||||
logger.custom_debug(
|
logger.debug("[GridTradingBot.adjust_grid] Newly filled orders found")
|
||||||
"[GridTradingBot.adjust_grid] Newly filled orders found"
|
|
||||||
)
|
|
||||||
# 处理每个新成交的订单
|
# 处理每个新成交的订单
|
||||||
for filled_order in newly_filled_orders:
|
for filled_order in newly_filled_orders:
|
||||||
filled_side = filled_order.side
|
filled_side = filled_order.side
|
||||||
@@ -925,9 +921,7 @@ class GridTradingBot:
|
|||||||
# 主循环
|
# 主循环
|
||||||
while self.running:
|
while self.running:
|
||||||
try:
|
try:
|
||||||
logger.custom_debug(
|
logger.debug("[GridTradingBot.run] Starting main loop iteration")
|
||||||
"[GridTradingBot.run] Starting main loop iteration"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 更新订单状态
|
# 更新订单状态
|
||||||
self.api_update_order_statuses()
|
self.api_update_order_statuses()
|
||||||
@@ -940,16 +934,16 @@ class GridTradingBot:
|
|||||||
self.extend_grid()
|
self.extend_grid()
|
||||||
|
|
||||||
# 等待一段时间再检查
|
# 等待一段时间再检查
|
||||||
sleep_time = 0
|
sleep_time = 1
|
||||||
logger.custom_debug(
|
logger.debug(
|
||||||
"[GridTradingBot.run] Sleeping for %d seconds", sleep_time
|
"[GridTradingBot.run] Sleeping for %d seconds", sleep_time
|
||||||
)
|
)
|
||||||
time.sleep(sleep_time)
|
time.sleep(sleep_time)
|
||||||
|
|
||||||
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 = 1
|
sleep_time = 3
|
||||||
logger.custom_debug(
|
logger.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