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
|
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:
|
def calculate_metrics(self, paths: np.ndarray) -> Dict:
|
||||||
"""Calculate key metrics from simulation results"""
|
"""Calculate key metrics from simulation results"""
|
||||||
final_prices = paths[-1]
|
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.journal import get_latest_portfolio_value, get_open_trades_summary
|
||||||
from trading.position_calculator import PositionCalculator
|
from trading.position_calculator import PositionCalculator
|
||||||
from utils.data_utils import get_current_prices
|
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():
|
def trading_system_page():
|
||||||
st.header("Trading System")
|
st.header("Trading System")
|
||||||
@ -54,18 +57,44 @@ def trading_system_page():
|
|||||||
max_value=100.0,
|
max_value=100.0,
|
||||||
value=1.0,
|
value=1.0,
|
||||||
step=0.1)
|
step=0.1)
|
||||||
stop_loss_percentage = st.number_input("Stop Loss Percentage (%)",
|
use_monte_carlo = st.checkbox("Use Monte Carlo for Stop Loss", value=True)
|
||||||
min_value=0.1,
|
|
||||||
max_value=100.0,
|
|
||||||
value=7.0,
|
|
||||||
step=0.1)
|
|
||||||
|
|
||||||
with col2:
|
with col2:
|
||||||
|
ticker = st.text_input("Ticker Symbol", value="").upper()
|
||||||
entry_price = st.number_input("Entry Price ($)", min_value=0.01, step=0.01)
|
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)
|
target_price = st.number_input("Target Price ($)", min_value=0.01, step=0.01)
|
||||||
|
|
||||||
if st.button("Calculate Position"):
|
if st.button("Calculate Position"):
|
||||||
try:
|
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(
|
calculator = PositionCalculator(
|
||||||
account_size=account_size,
|
account_size=account_size,
|
||||||
risk_percentage=risk_percentage,
|
risk_percentage=risk_percentage,
|
||||||
@ -118,5 +147,16 @@ def trading_system_page():
|
|||||||
f"- {portfolio_usage:.1f}% of total portfolio"
|
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:
|
except Exception as e:
|
||||||
st.error(f"Error calculating position: {str(e)}")
|
st.error(f"Error calculating position: {str(e)}")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user