better sticks
This commit is contained in:
parent
73c5ecb0d2
commit
b9d2a36e50
1972
realtime.py
1972
realtime.py
File diff suppressed because it is too large
Load Diff
@ -107,6 +107,12 @@ class RLTrainingIntegrator:
|
|||||||
self.trade_count = 0
|
self.trade_count = 0
|
||||||
self.win_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
|
# Track current position state
|
||||||
self.in_position = False
|
self.in_position = False
|
||||||
self.entry_price = None
|
self.entry_price = None
|
||||||
@ -151,7 +157,28 @@ class RLTrainingIntegrator:
|
|||||||
# Calculate profit if we have entry data
|
# Calculate profit if we have entry data
|
||||||
pnl = None
|
pnl = None
|
||||||
if self.entry_price is not 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
|
# Log the complete trade on the chart
|
||||||
if self.chart:
|
if self.chart:
|
||||||
@ -162,10 +189,12 @@ class RLTrainingIntegrator:
|
|||||||
# Record the trade with PnL
|
# Record the trade with PnL
|
||||||
if hasattr(self.chart, 'add_trade'):
|
if hasattr(self.chart, 'add_trade'):
|
||||||
self.chart.add_trade(
|
self.chart.add_trade(
|
||||||
action=action_str,
|
|
||||||
price=price,
|
price=price,
|
||||||
timestamp=timestamp,
|
timestamp=timestamp,
|
||||||
pnl=pnl
|
pnl=pnl,
|
||||||
|
amount=0.1,
|
||||||
|
action=action_str,
|
||||||
|
type=action_str # Add explicit type
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update trade counts
|
# Update trade counts
|
||||||
@ -185,6 +214,21 @@ class RLTrainingIntegrator:
|
|||||||
'reward': reward,
|
'reward': reward,
|
||||||
'timestamp': timestamp.isoformat()
|
'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)
|
# Track reward for all actions (including hold)
|
||||||
self.reward_history.append(reward)
|
self.reward_history.append(reward)
|
||||||
@ -205,6 +249,23 @@ class RLTrainingIntegrator:
|
|||||||
logger.info(f" Win rate: {info['win_rate']:.4f}")
|
logger.info(f" Win rate: {info['win_rate']:.4f}")
|
||||||
logger.info(f" Trades: {info['trades']}")
|
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
|
# Reset position state for new episode
|
||||||
self.in_position = False
|
self.in_position = False
|
||||||
self.entry_price = None
|
self.entry_price = None
|
||||||
@ -441,8 +502,8 @@ async def start_realtime_chart(symbol="BTC/USDT", port=8050):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
logger.info(f"Initializing RealTimeChart for {symbol}")
|
logger.info(f"Initializing RealTimeChart for {symbol}")
|
||||||
# Create the chart
|
# Create the chart with sample data enabled and no-ticks warnings disabled
|
||||||
chart = RealTimeChart(symbol)
|
chart = RealTimeChart(symbol, use_sample_data=True, log_no_ticks_warning=False)
|
||||||
|
|
||||||
# Start the WebSocket connection in a separate thread
|
# Start the WebSocket connection in a separate thread
|
||||||
# The _start_websocket_thread method already handles this correctly
|
# 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())
|
logger.error(traceback.format_exc())
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def run_training_thread(chart, num_episodes=5000, max_steps=2000):
|
def run_training_thread(chart):
|
||||||
"""Run the RL training in a separate thread"""
|
"""Start the RL training in a separate thread"""
|
||||||
integrator = RLTrainingIntegrator(chart)
|
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.daemon = True
|
||||||
thread.start()
|
thread.start()
|
||||||
logger.info("Started RL training thread")
|
logger.info("Started RL training thread")
|
||||||
@ -490,8 +559,17 @@ def test_signals(chart):
|
|||||||
# Add a test SELL signal
|
# Add a test SELL signal
|
||||||
chart.add_nn_signal("SELL", datetime.now(), 0.85)
|
chart.add_nn_signal("SELL", datetime.now(), 0.85)
|
||||||
|
|
||||||
# Add a test trade
|
# Add a test trade if the method exists
|
||||||
chart.add_trade("BUY", 50000.0, datetime.now(), 0.05)
|
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():
|
async def main():
|
||||||
"""Main function that coordinates the realtime chart and RL training"""
|
"""Main function that coordinates the realtime chart and RL training"""
|
||||||
@ -520,6 +598,18 @@ async def main():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Unexpected error: {str(e)}")
|
logger.error(f"Unexpected error: {str(e)}")
|
||||||
finally:
|
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
|
# Clean up
|
||||||
if realtime_websocket_task:
|
if realtime_websocket_task:
|
||||||
realtime_websocket_task.cancel()
|
realtime_websocket_task.cancel()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user