better sticks
This commit is contained in:
parent
73c5ecb0d2
commit
b9d2a36e50
1940
realtime.py
1940
realtime.py
File diff suppressed because it is too large
Load Diff
@ -107,6 +107,12 @@ class RLTrainingIntegrator:
|
||||
self.trade_count = 0
|
||||
self.win_count = 0
|
||||
|
||||
# Add session-wide PnL tracking
|
||||
self.session_pnl = 0.0
|
||||
self.session_trades = 0
|
||||
self.session_wins = 0
|
||||
self.session_balance = 100.0 # Start with $100 balance
|
||||
|
||||
# Track current position state
|
||||
self.in_position = False
|
||||
self.entry_price = None
|
||||
@ -151,7 +157,28 @@ class RLTrainingIntegrator:
|
||||
# Calculate profit if we have entry data
|
||||
pnl = None
|
||||
if self.entry_price is not None:
|
||||
pnl = (price - self.entry_price) / self.entry_price
|
||||
# Calculate percentage change
|
||||
pnl_pct = (price - self.entry_price) / self.entry_price
|
||||
|
||||
# Cap extreme PnL values to more realistic levels (-90% to +100%)
|
||||
pnl_pct = max(min(pnl_pct, 1.0), -0.9)
|
||||
|
||||
# Apply to current balance
|
||||
trade_amount = self.session_balance * 0.1 # Use 10% of balance per trade
|
||||
trade_profit = trade_amount * pnl_pct
|
||||
self.session_balance += trade_profit
|
||||
|
||||
# Ensure session balance doesn't go below $1
|
||||
self.session_balance = max(self.session_balance, 1.0)
|
||||
|
||||
# For normalized display in charts and logs
|
||||
pnl = pnl_pct
|
||||
|
||||
# Update session-wide PnL
|
||||
self.session_pnl += pnl
|
||||
self.session_trades += 1
|
||||
if pnl > 0:
|
||||
self.session_wins += 1
|
||||
|
||||
# Log the complete trade on the chart
|
||||
if self.chart:
|
||||
@ -162,10 +189,12 @@ class RLTrainingIntegrator:
|
||||
# Record the trade with PnL
|
||||
if hasattr(self.chart, 'add_trade'):
|
||||
self.chart.add_trade(
|
||||
action=action_str,
|
||||
price=price,
|
||||
timestamp=timestamp,
|
||||
pnl=pnl
|
||||
pnl=pnl,
|
||||
amount=0.1,
|
||||
action=action_str,
|
||||
type=action_str # Add explicit type
|
||||
)
|
||||
|
||||
# Update trade counts
|
||||
@ -185,6 +214,21 @@ class RLTrainingIntegrator:
|
||||
'reward': reward,
|
||||
'timestamp': timestamp.isoformat()
|
||||
})
|
||||
else:
|
||||
# Hold action
|
||||
action_str = "HOLD"
|
||||
timestamp = datetime.now()
|
||||
|
||||
# Update chart trading info
|
||||
if self.chart and hasattr(self.chart, 'update_trading_info'):
|
||||
# Determine current position size (0.1 if in position, 0 if not)
|
||||
position_size = 0.1 if self.in_position else 0.0
|
||||
self.chart.update_trading_info(
|
||||
signal=action_str,
|
||||
position=position_size,
|
||||
balance=self.session_balance,
|
||||
pnl=self.session_pnl
|
||||
)
|
||||
|
||||
# Track reward for all actions (including hold)
|
||||
self.reward_history.append(reward)
|
||||
@ -205,6 +249,23 @@ class RLTrainingIntegrator:
|
||||
logger.info(f" Win rate: {info['win_rate']:.4f}")
|
||||
logger.info(f" Trades: {info['trades']}")
|
||||
|
||||
# Log session-wide PnL
|
||||
session_win_rate = self.session_wins / self.session_trades if self.session_trades > 0 else 0
|
||||
logger.info(f" Session Balance: ${self.session_balance:.2f}")
|
||||
logger.info(f" Session Total PnL: {self.session_pnl:.4f}")
|
||||
logger.info(f" Session Win Rate: {session_win_rate:.4f}")
|
||||
logger.info(f" Session Trades: {self.session_trades}")
|
||||
|
||||
# Update chart trading info with final episode information
|
||||
if self.chart and hasattr(self.chart, 'update_trading_info'):
|
||||
# Reset position since we're between episodes
|
||||
self.chart.update_trading_info(
|
||||
signal="HOLD",
|
||||
position=0.0,
|
||||
balance=self.session_balance,
|
||||
pnl=self.session_pnl
|
||||
)
|
||||
|
||||
# Reset position state for new episode
|
||||
self.in_position = False
|
||||
self.entry_price = None
|
||||
@ -441,8 +502,8 @@ async def start_realtime_chart(symbol="BTC/USDT", port=8050):
|
||||
|
||||
try:
|
||||
logger.info(f"Initializing RealTimeChart for {symbol}")
|
||||
# Create the chart
|
||||
chart = RealTimeChart(symbol)
|
||||
# Create the chart with sample data enabled and no-ticks warnings disabled
|
||||
chart = RealTimeChart(symbol, use_sample_data=True, log_no_ticks_warning=False)
|
||||
|
||||
# Start the WebSocket connection in a separate thread
|
||||
# The _start_websocket_thread method already handles this correctly
|
||||
@ -466,10 +527,18 @@ async def start_realtime_chart(symbol="BTC/USDT", port=8050):
|
||||
logger.error(traceback.format_exc())
|
||||
raise
|
||||
|
||||
def run_training_thread(chart, num_episodes=5000, max_steps=2000):
|
||||
"""Run the RL training in a separate thread"""
|
||||
def run_training_thread(chart):
|
||||
"""Start the RL training in a separate thread"""
|
||||
integrator = RLTrainingIntegrator(chart)
|
||||
thread = Thread(target=lambda: integrator.start_training(num_episodes, max_steps))
|
||||
|
||||
def training_thread_func():
|
||||
try:
|
||||
# Use a small number of episodes to test termination handling
|
||||
integrator.start_training(num_episodes=2, max_steps=500)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in training thread: {str(e)}")
|
||||
|
||||
thread = threading.Thread(target=training_thread_func)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
logger.info("Started RL training thread")
|
||||
@ -490,8 +559,17 @@ def test_signals(chart):
|
||||
# Add a test SELL signal
|
||||
chart.add_nn_signal("SELL", datetime.now(), 0.85)
|
||||
|
||||
# Add a test trade
|
||||
chart.add_trade("BUY", 50000.0, datetime.now(), 0.05)
|
||||
# Add a test trade if the method exists
|
||||
if hasattr(chart, 'add_trade'):
|
||||
chart.add_trade(
|
||||
price=83000.0,
|
||||
timestamp=datetime.now(),
|
||||
pnl=0.05,
|
||||
action="BUY",
|
||||
type="BUY" # Add explicit type
|
||||
)
|
||||
else:
|
||||
logger.warning("RealTimeChart has no add_trade method - skipping test trade")
|
||||
|
||||
async def main():
|
||||
"""Main function that coordinates the realtime chart and RL training"""
|
||||
@ -520,6 +598,18 @@ async def main():
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error: {str(e)}")
|
||||
finally:
|
||||
# Log final PnL summary
|
||||
if hasattr(integrator, 'session_pnl'):
|
||||
session_win_rate = integrator.session_wins / integrator.session_trades if integrator.session_trades > 0 else 0
|
||||
logger.info("=" * 50)
|
||||
logger.info("FINAL SESSION SUMMARY")
|
||||
logger.info("=" * 50)
|
||||
logger.info(f"Final Session Balance: ${integrator.session_balance:.2f}")
|
||||
logger.info(f"Total Session PnL: {integrator.session_pnl:.4f}")
|
||||
logger.info(f"Total Session Win Rate: {session_win_rate:.4f} ({integrator.session_wins}/{integrator.session_trades})")
|
||||
logger.info(f"Total Session Trades: {integrator.session_trades}")
|
||||
logger.info("=" * 50)
|
||||
|
||||
# Clean up
|
||||
if realtime_websocket_task:
|
||||
realtime_websocket_task.cancel()
|
||||
|
Loading…
x
Reference in New Issue
Block a user