-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimulation_engine.py
More file actions
155 lines (119 loc) · 5.53 KB
/
Copy pathsimulation_engine.py
File metadata and controls
155 lines (119 loc) · 5.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import time
from typing import Optional
from trading_components.data_loader import DataLoader
from trading_components.trading_algorithm import TradingAlgorithm
from trading_components.portfolio_manager import PortfolioManager
from trading_components.visualizer import TradingVisualizer
class TradingSimulation:
def __init__(self,
data_filepath:str,
initial_capital: float = 100000.0,
update_interval: float = 0.1,
max_iterations: Optional[int] = None):
self.data_filepath = data_filepath
self.initial_capital = initial_capital
self.update_interval = update_interval
self.max_iterations = max_iterations
# Initialize components
self.data_loader = DataLoader(data_filepath)
self.algorithm = TradingAlgorithm()
self.portfolio = PortfolioManager(initial_capital=initial_capital)
self.visualizer = TradingVisualizer()
# Simulation state
self.current_index = 0
self.is_running = False
def load_data(self):
"""
Load and prepare data for simulation.
"""
print("Loading silver price data...")
self.data_loader.load_data()
summary = self.data_loader.get_data_summary()
print(f"\nData Summary :")
print(f" Date Range : {summary['start_date']} to {summary['end_date']}")
print(f" Number of Days : {summary['num_days']}")
print(f" Price Range : ${summary['min_price']:.2f} - ${summary['max_price']:.2f}")
print(f" Mean Price : ${summary['mean_price']:.2f}")
print(f" Std Dev : ${summary['std_price']:.2f}\n")
def run_simulation(self, real_time: bool = False):
"""
Run the trading simulation.
Args:
real_time: If True, simulate with delays; if False, run quickly
"""
self.is_running = True
print("Starting trading simulation...")
# Setup visualization
self.visualizer.setup_plot()
# Get data
prices = self.data_loader.get_price_series()
dates = self.data_loader.get_date_series()
# Determine iteration count
max_iter = self.max_iterations if self.max_iterations else len(prices)
max_iter = min(max_iter, len(prices))
# Run simulation loop
for iteration_index in range(max_iter):
if not self.is_running:
break
self.current_index = iteration_index
current_date = dates.iloc[iteration_index]
current_price = prices.iloc[iteration_index]
# Generate trading signal
signal = self.algorithm.generate_combined_signal(prices, iteration_index)
# Get all indicator values
indicators = self.algorithm.get_all_indicators(prices, iteration_index)
# Execute trade if signal is generated
trade_action = self.portfolio.execute_trade(
signal, current_price, str(current_date.date()))
# Update portfolio value
self.portfolio.update_portfolio_history(current_price)
current_portfolio_value = self.portfolio.get_portfolio_value(current_price)
# Update visualization
self.visualizer.update_data(
current_date, current_price, indicators,
signal, current_portfolio_value)
# Print progress
trade_is_not_hold = trade_action != "Hold"
if trade_is_not_hold:
print(f"[{current_date.date()}] Price: ${current_price:.2f} | {trade_action}")
print(f" Portfolio Value : ${current_portfolio_value:,.2f}\n")
# Render frame periodically
should_render_frame = iteration_index % 10 == 0 or iteration_index == max_iter - 1
if should_render_frame:
self.visualizer.render_frame()
if real_time:
self.visualizer.fig.canvas.draw()
self.visualizer.fig.canvas.flush_events()
# Simulate real-time delay
if real_time:
time.sleep(self.update_interval)
self._print_final_summary()
def _print_final_summary(self):
# Print final performance summary
print("\n" + "="*60)
print("SIMULATION COMPLETE ")
print("="*60)
performance = self.portfolio.get_performance_summary()
print(f"\nPerformance Summary :")
print(f" Initial Capital : ${performance['initial_capital']:,.2f}")
print(f" Final Portfolio Value: ${performance['final_value']:,.2f}")
print(f" Total Return : {performance['total_return']:.2f}%")
print(f" Sharpe Ratio : {performance['sharpe_ratio']:.2f}")
print(f"\nTrading Statistics :")
print(f" Total Trades : {performance['total_trades']}")
print(f" Buy Trades : {performance['buy_trades']}")
print(f" Sell Trades : {performance['sell_trades']}")
print(f" Win Rate : {performance['win_rate']:.2f}%")
print(f" Total Profit from Trades: ${performance['total_profit']:,.2f}")
print(f" Current Position : {performance['current_position']:.2f} oz")
print("\n" + "="*60)
def save_results(self, output_path: str = "trading_simulation_results.png"):
"""
Save the final visualization.
"""
self.visualizer.save_final_plot(output_path)
def show_visualization(self):
self.visualizer.show()
def stop_simulation(self):
self.is_running = False
print("\nSimulation stopped by user.")