Files
gogo2/test_bybit_eth_futures_fixed.py
Dobromir Popov 9b72b18eb7 references
2025-07-22 16:53:36 +03:00

304 lines
11 KiB
Python

#!/usr/bin/env python3
"""
Fixed Bybit ETH futures trading test with proper minimum order size handling
"""
import os
import sys
import time
import logging
import json
# Add the project root to the path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# Load environment variables
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
if os.path.exists('.env'):
with open('.env', 'r') as f:
for line in f:
if line.strip() and not line.startswith('#'):
key, value = line.strip().split('=', 1)
os.environ[key] = value
from core.exchanges.bybit_interface import BybitInterface
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def get_instrument_info(bybit: BybitInterface, symbol: str) -> dict:
"""Get instrument information including minimum order size"""
try:
instruments = bybit.get_instruments("linear")
for instrument in instruments:
if instrument.get('symbol') == symbol:
return instrument
return {}
except Exception as e:
logger.error(f"Error getting instrument info: {e}")
return {}
def test_eth_futures_trading():
"""Test ETH futures trading with proper minimum order size"""
print("🚀 Starting Fixed Bybit ETH Futures Live Trading Test...")
print("=" * 60)
print("BYBIT ETH FUTURES LIVE TRADING TEST (FIXED)")
print("=" * 60)
print("⚠️ This uses LIVE environment with real money!")
print("⚠️ Will check minimum order size first")
print("=" * 60)
# Check if API credentials are set
api_key = os.getenv('BYBIT_API_KEY')
api_secret = os.getenv('BYBIT_API_SECRET')
if not api_key or not api_secret:
print("❌ API credentials not found in environment")
return False
# Create Bybit interface with live environment
bybit = BybitInterface(
api_key=api_key,
api_secret=api_secret,
test_mode=False # Use live environment
)
symbol = 'ETHUSDT'
# Test 1: Connection
print(f"\n📡 Testing connection to Bybit live environment...")
try:
if not bybit.connect():
print("❌ Failed to connect to Bybit")
return False
print("✅ Successfully connected to Bybit live environment")
except Exception as e:
print(f"❌ Connection error: {e}")
return False
# Test 2: Get instrument information to check minimum order size
print(f"\n📋 Getting instrument information for {symbol}...")
try:
instrument_info = get_instrument_info(bybit, symbol)
if not instrument_info:
print(f"❌ Failed to get instrument info for {symbol}")
return False
print("✅ Instrument information retrieved:")
print(f" Symbol: {instrument_info.get('symbol')}")
print(f" Status: {instrument_info.get('status')}")
print(f" Base Coin: {instrument_info.get('baseCoin')}")
print(f" Quote Coin: {instrument_info.get('quoteCoin')}")
# Extract minimum order size
lot_size_filter = instrument_info.get('lotSizeFilter', {})
min_order_qty = float(lot_size_filter.get('minOrderQty', 0.01))
max_order_qty = float(lot_size_filter.get('maxOrderQty', 10000))
qty_step = float(lot_size_filter.get('qtyStep', 0.01))
print(f" Minimum Order Qty: {min_order_qty}")
print(f" Maximum Order Qty: {max_order_qty}")
print(f" Quantity Step: {qty_step}")
# Use minimum order size for testing
test_quantity = min_order_qty
print(f" Using test quantity: {test_quantity} ETH")
except Exception as e:
print(f"❌ Instrument info error: {e}")
return False
# Test 3: Get account balance
print(f"\n💰 Checking account balance...")
try:
usdt_balance = bybit.get_balance('USDT')
print(f"USDT Balance: ${usdt_balance:.2f}")
# Calculate required balance (with some buffer)
current_price_data = bybit.get_ticker(symbol)
if not current_price_data:
print("❌ Failed to get current ETH price")
return False
current_price = current_price_data['last_price']
required_balance = current_price * test_quantity * 1.1 # 10% buffer
print(f"Current ETH price: ${current_price:.2f}")
print(f"Required balance: ${required_balance:.2f}")
if usdt_balance < required_balance:
print(f"❌ Insufficient USDT balance for testing (need at least ${required_balance:.2f})")
return False
print("✅ Sufficient balance for testing")
except Exception as e:
print(f"❌ Balance check error: {e}")
return False
# Test 4: Check existing positions
print(f"\n📊 Checking existing positions...")
try:
positions = bybit.get_positions(symbol)
if positions:
print(f"Found {len(positions)} existing positions:")
for pos in positions:
print(f" {pos['symbol']}: {pos['side']} {pos['size']} @ ${pos['entry_price']:.2f}")
print(f" PnL: ${pos['unrealized_pnl']:.2f}")
else:
print("No existing positions found")
except Exception as e:
print(f"❌ Position check error: {e}")
return False
# Test 5: Ask user confirmation before trading
print(f"\n⚠️ TRADING CONFIRMATION")
print(f" Symbol: {symbol}")
print(f" Quantity: {test_quantity} ETH")
print(f" Estimated cost: ${current_price * test_quantity:.2f}")
print(f" Environment: LIVE (real money)")
print(f" Minimum order size confirmed: {min_order_qty}")
response = input("\nDo you want to proceed with the live trading test? (y/N): ").lower()
if response != 'y' and response != 'yes':
print("❌ Trading test cancelled by user")
return False
# Test 6: Open a small long position
print(f"\n🚀 Opening small long position...")
try:
order = bybit.place_order(
symbol=symbol,
side='buy',
order_type='market',
quantity=test_quantity
)
if 'error' in order:
print(f"❌ Order failed: {order['error']}")
return False
print("✅ Long position opened successfully:")
print(f" Order ID: {order['order_id']}")
print(f" Symbol: {order['symbol']}")
print(f" Side: {order['side']}")
print(f" Quantity: {order['quantity']}")
print(f" Status: {order['status']}")
order_id = order['order_id']
except Exception as e:
print(f"❌ Order placement error: {e}")
return False
# Test 7: Wait a moment and check position
print(f"\n⏳ Waiting 5 seconds for position to be reflected...")
time.sleep(5)
try:
positions = bybit.get_positions(symbol)
if positions:
position = positions[0]
print("✅ Position confirmed:")
print(f" Symbol: {position['symbol']}")
print(f" Side: {position['side']}")
print(f" Size: {position['size']}")
print(f" Entry Price: ${position['entry_price']:.2f}")
print(f" Current PnL: ${position['unrealized_pnl']:.2f}")
print(f" Leverage: {position['leverage']}x")
else:
print("⚠️ No position found (may already be closed)")
except Exception as e:
print(f"❌ Position check error: {e}")
# Test 8: Close the position
print(f"\n🔄 Closing the position...")
try:
close_order = bybit.close_position(symbol)
if 'error' in close_order:
print(f"❌ Close order failed: {close_order['error']}")
# Don't return False here, as the position might still exist
print("⚠️ You may need to manually close the position")
else:
print("✅ Position closed successfully:")
print(f" Order ID: {close_order['order_id']}")
print(f" Symbol: {close_order['symbol']}")
print(f" Side: {close_order['side']}")
print(f" Quantity: {close_order['quantity']}")
print(f" Status: {close_order['status']}")
except Exception as e:
print(f"❌ Close position error: {e}")
print("⚠️ You may need to manually close the position")
# Test 9: Final position check
print(f"\n📊 Final position check...")
time.sleep(3)
try:
positions = bybit.get_positions(symbol)
if positions:
position = positions[0]
print("⚠️ Position still exists:")
print(f" Size: {position['size']}")
print(f" PnL: ${position['unrealized_pnl']:.2f}")
print("💡 You may want to manually close this position")
else:
print("✅ No open positions - trading test completed successfully")
except Exception as e:
print(f"❌ Final position check error: {e}")
# Test 10: Final balance check
print(f"\n💰 Final balance check...")
try:
final_balance = bybit.get_balance('USDT')
print(f"Final USDT Balance: ${final_balance:.2f}")
balance_change = final_balance - usdt_balance
if balance_change > 0:
print(f"💰 Profit: +${balance_change:.2f}")
elif balance_change < 0:
print(f"📉 Loss: ${balance_change:.2f}")
else:
print(f"🔄 No change: ${balance_change:.2f}")
except Exception as e:
print(f"❌ Final balance check error: {e}")
return True
def main():
"""Main function"""
print("🚀 Starting Fixed Bybit ETH Futures Live Trading Test...")
success = test_eth_futures_trading()
if success:
print("\n" + "=" * 60)
print("✅ BYBIT ETH FUTURES TRADING TEST COMPLETED")
print("=" * 60)
print("🎯 Your Bybit integration is fully functional!")
print("🔄 Position opening and closing works correctly")
print("💰 Account balance integration works")
print("📊 All trading functions are operational")
print("📏 Minimum order size handling works")
print("=" * 60)
else:
print("\n💥 Trading test failed!")
print("🔍 Check the error messages above for details")
return success
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)