feat: Add Monte Carlo stop loss calculation to trading system
This commit is contained in:
parent
7910da0430
commit
cd9b6f7969
@ -47,6 +47,31 @@ class MonteCarloSimulator:
|
||||
|
||||
return price_paths
|
||||
|
||||
def calculate_stop_loss(self, risk_percentage: float) -> float:
|
||||
"""
|
||||
Calculate stop loss price based on Monte Carlo simulation and desired risk percentage
|
||||
|
||||
Args:
|
||||
risk_percentage (float): Maximum risk percentage willing to take
|
||||
|
||||
Returns:
|
||||
float: Recommended stop loss price
|
||||
"""
|
||||
# Run a quick simulation
|
||||
paths = self.run_simulation()
|
||||
|
||||
# Get the first day's simulated prices
|
||||
first_day_prices = paths[1] # Using day 1 instead of day 0 to see immediate movement
|
||||
|
||||
# Calculate the price that represents the risk percentage loss
|
||||
potential_losses = (first_day_prices - self.last_price) / self.last_price * 100
|
||||
|
||||
# Find the price level that corresponds to our risk percentage
|
||||
stop_loss_percentile = np.percentile(potential_losses, risk_percentage)
|
||||
stop_loss_price = self.last_price * (1 + stop_loss_percentile / 100)
|
||||
|
||||
return stop_loss_price
|
||||
|
||||
def calculate_metrics(self, paths: np.ndarray) -> Dict:
|
||||
"""Calculate key metrics from simulation results"""
|
||||
final_prices = paths[-1]
|
||||
|
||||
@ -2,6 +2,9 @@ import streamlit as st
|
||||
from trading.journal import get_latest_portfolio_value, get_open_trades_summary
|
||||
from trading.position_calculator import PositionCalculator
|
||||
from utils.data_utils import get_current_prices
|
||||
from pages.analysis.monte_carlo_page import MonteCarloSimulator
|
||||
from datetime import datetime, timedelta
|
||||
from utils.common_utils import get_stock_data
|
||||
|
||||
def trading_system_page():
|
||||
st.header("Trading System")
|
||||
@ -54,18 +57,44 @@ def trading_system_page():
|
||||
max_value=100.0,
|
||||
value=1.0,
|
||||
step=0.1)
|
||||
stop_loss_percentage = st.number_input("Stop Loss Percentage (%)",
|
||||
min_value=0.1,
|
||||
max_value=100.0,
|
||||
value=7.0,
|
||||
step=0.1)
|
||||
use_monte_carlo = st.checkbox("Use Monte Carlo for Stop Loss", value=True)
|
||||
|
||||
with col2:
|
||||
ticker = st.text_input("Ticker Symbol", value="").upper()
|
||||
entry_price = st.number_input("Entry Price ($)", min_value=0.01, step=0.01)
|
||||
target_price = st.number_input("Target Price ($)", min_value=0.01, step=0.01)
|
||||
|
||||
if st.button("Calculate Position"):
|
||||
try:
|
||||
if not ticker:
|
||||
st.error("Please enter a ticker symbol")
|
||||
return
|
||||
|
||||
# Get historical data for Monte Carlo simulation
|
||||
if use_monte_carlo:
|
||||
with st.spinner("Calculating optimal stop loss..."):
|
||||
df = get_stock_data(
|
||||
ticker,
|
||||
datetime.now() - timedelta(days=30), # Last 30 days of data
|
||||
datetime.now(),
|
||||
'1m' # Minute data for more accurate simulation
|
||||
)
|
||||
|
||||
if df.empty:
|
||||
st.error("No data available for the selected ticker")
|
||||
return
|
||||
|
||||
# Initialize Monte Carlo simulator
|
||||
simulator = MonteCarloSimulator(df, num_simulations=1000, time_horizon=5)
|
||||
|
||||
# Calculate stop loss price
|
||||
stop_loss_price = simulator.calculate_stop_loss(risk_percentage)
|
||||
|
||||
# Calculate stop loss percentage
|
||||
stop_loss_percentage = abs((stop_loss_price - entry_price) / entry_price * 100)
|
||||
else:
|
||||
stop_loss_percentage = 7.0 # Default value if not using Monte Carlo
|
||||
|
||||
calculator = PositionCalculator(
|
||||
account_size=account_size,
|
||||
risk_percentage=risk_percentage,
|
||||
@ -118,5 +147,16 @@ def trading_system_page():
|
||||
f"- {portfolio_usage:.1f}% of total portfolio"
|
||||
)
|
||||
|
||||
# Add Monte Carlo metrics if used
|
||||
if use_monte_carlo:
|
||||
st.subheader("Monte Carlo Analysis")
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.metric("Calculated Stop Loss Price", f"${stop_loss_price:.2f}")
|
||||
st.metric("Stop Loss Percentage", f"{stop_loss_percentage:.2f}%")
|
||||
with col2:
|
||||
st.metric("Based on Simulations", "1,000")
|
||||
st.metric("Simulation Timeframe", "5 days")
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error calculating position: {str(e)}")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user