drl-trading-bot-dev2 / src /ui /testnet_server.py
DRL Trading Bot
Feature: HTF Agent integration โ€” live trading, API endpoints, UI tab
fc115d5
Raw
History Blame Contribute Delete
7.48 kB
"""
Server-side Binance Testnet Integration
Uses BinanceConnector on the local server (direct testnet access, no proxy needed).
"""
import streamlit as st
import os
from src.api.binance import BinanceConnector
import pandas as pd
def render_testnet_tab_server(api_key: str, api_secret: str):
"""
Render testnet tab with server-side API calls.
Requires the server to run locally (direct access to testnet.binance.vision).
"""
try:
api_key = api_key.strip() if api_key else ''
api_secret = api_secret.strip() if api_secret else ''
if not api_key or not api_secret:
st.error("โŒ API keys are empty after sanitization!")
return
if len(api_key) < 20 or len(api_secret) < 20:
st.error(f"โŒ API keys seem too short (key: {len(api_key)}, secret: {len(api_secret)})")
return
st.info(f"๐Ÿ”‘ API Key: {api_key[:8]}...{api_key[-4:]} ({len(api_key)} chars)")
testnet = BinanceConnector(
api_key=api_key,
api_secret=api_secret,
testnet=True
)
# Test connectivity
try:
connectivity = testnet.test_connectivity()
if connectivity:
st.success("โœ… Connected to Binance Testnet")
else:
st.warning("โš ๏ธ Connectivity test returned false, but trying anyway...")
except Exception as e:
st.error(f"โŒ Connectivity test failed: {e}")
import traceback
st.code(traceback.format_exc())
return
# Get balances
try:
balances = testnet.get_all_balances()
except Exception as e:
st.error(f"โŒ Failed to get balances: {e}")
import traceback
st.code(traceback.format_exc())
return
if not balances:
st.error("โŒ No balances found. Account might be empty or API keys invalid.")
st.warning("๐Ÿ’ก Tip: Go to testnet.binance.vision and claim test funds")
return
st.info(f"๐Ÿ“Š Retrieved {len(balances)} balance entries")
# Calculate portfolio value
portfolio_value = 0.0
positions_data = []
usdt_balance = 0.0
for currency, amounts in balances.items():
total = float(amounts.get('total', 0))
if total > 0:
if currency == 'USDT':
portfolio_value += total
usdt_balance = float(amounts.get('free', 0))
else:
try:
ticker = testnet.get_ticker(f"{currency}/USDT")
price = float(ticker.get('last', 0))
if price > 0:
value_usdt = total * price
portfolio_value += value_usdt
positions_data.append({
'Asset': currency,
'Amount': f"{total:.6f}",
'Price': f"${price:,.2f}",
'Value (USDT)': f"${value_usdt:,.2f}"
})
except Exception:
pass
# Portfolio overview
col1, col2, col3 = st.columns(3)
with col1:
st.metric(
label="๐Ÿ’ฐ Portfolio Value",
value=f"${portfolio_value:,.2f}",
delta=None
)
with col2:
st.metric(label="๐Ÿ’ต USDT Balance", value=f"${usdt_balance:,.2f}")
with col3:
st.metric(
label="๐Ÿ“Š Total P&L %",
value="N/A",
delta=None
)
st.markdown("---")
if positions_data:
st.markdown("### ๐Ÿ“Š Current Positions")
st.dataframe(pd.DataFrame(positions_data), use_container_width=True, hide_index=True)
else:
st.info("No open positions. Portfolio is 100% USDT")
st.markdown("---")
# Trading controls
st.markdown("### ๐ŸŽฎ Trading Controls")
col1, col2 = st.columns(2)
with col1:
trade_symbol = st.selectbox(
"Select Pair",
options=['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'XRP/USDT'],
key="testnet_symbol"
)
with col2:
trade_amount = st.number_input(
"Amount (USDT)",
min_value=10.0,
max_value=float(usdt_balance) if usdt_balance > 10 else 10000.0,
value=100.0,
step=10.0,
key="testnet_amount"
)
col1, col2, col3 = st.columns(3)
if col1.button("๐ŸŸข BUY (Market)", key="testnet_buy", use_container_width=True):
try:
ticker = testnet.get_ticker(trade_symbol)
current_price = float(ticker['last'])
amount_base = trade_amount / current_price
order = testnet.place_market_order(symbol=trade_symbol, side='buy', amount=amount_base)
if order:
st.success(f"โœ… BUY order placed: {amount_base:.6f} {trade_symbol.split('/')[0]} @ ${current_price:,.2f}")
st.rerun()
else:
st.error("โŒ Order failed")
except Exception as e:
st.error(f"โŒ Order failed: {e}")
if col2.button("๐Ÿ”ด SELL (Market)", key="testnet_sell", use_container_width=True):
try:
base_currency = trade_symbol.split('/')[0]
base_balance = balances.get(base_currency, {}).get('free', 0)
if float(base_balance) == 0:
st.warning(f"No {base_currency} to sell")
else:
order = testnet.place_market_order(symbol=trade_symbol, side='sell', amount=float(base_balance))
if order:
st.success(f"โœ… SELL order placed: {base_balance} {base_currency}")
st.rerun()
else:
st.error("โŒ Order failed")
except Exception as e:
st.error(f"โŒ Order failed: {e}")
if col3.button("๐Ÿ“‹ Open Orders", key="testnet_orders", use_container_width=True):
try:
open_orders = testnet.get_open_orders()
if open_orders:
st.write(open_orders)
else:
st.info("No open orders")
except Exception as e:
st.error(f"โŒ Failed to fetch orders: {e}")
st.markdown("---")
st.markdown("### โ„น๏ธ Testnet Information")
info_col1, info_col2 = st.columns(2)
with info_col1:
st.info("""
**About Testnet:**
- Zero real money risk
- Test trading strategies
- Same API as production
- Perfect for learning
""")
with info_col2:
st.warning("""
**Important Notes:**
- Using testnet.binance.vision
- Testnet funds reset periodically
- Use for testing only
- Get free testnet funds from Binance
""")
except Exception as e:
st.error(f"โŒ Error: {e}")
import traceback
st.code(traceback.format_exc())