Skip to content

Commit

Permalink
adding first draft of the func
Browse files Browse the repository at this point in the history
  • Loading branch information
LVG77 committed Sep 17, 2024
1 parent a1e8977 commit f9cab5f
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 15 deletions.
Empty file added build/lib/stocksim/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions build/lib/stocksim/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .cli import cli

if __name__ == "__main__":
cli()
50 changes: 50 additions & 0 deletions build/lib/stocksim/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import click
import yfinance as yf
import numpy as np
import pandas as pd
from datetime import datetime, timedelta

@click.command()
@click.option('--ticker', required=True, help='Stock ticker symbol')
@click.option('--days', default=30, help='Number of days for simulation')
@click.option('--target-price', required=True, type=float, help='Target price for probability calculation')
@click.option('--simulations', default=1000, help='Number of Monte Carlo simulations')
def monte_carlo_simulation(ticker, days, target_price, simulations):
# Download historical data
end_date = datetime.now()
start_date = end_date - timedelta(days=5*365) # 5 years ago
data = yf.download(ticker, start=start_date, end=end_date)

# Calculate daily returns
returns = data['Close'].pct_change().dropna()

# Calculate mean and variance of daily returns
mu = returns.mean()
var = returns.var()

# Simulate future stock prices
last_price = data['Close'].iloc[-1]
simulation_df = pd.DataFrame()

for i in range(simulations):
prices = [last_price]
for _ in range(days):
price = prices[-1] * (1 + np.random.normal(mu, var**0.5))
prices.append(price)
simulation_df[i] = prices

# Calculate probability of exceeding target price
final_prices = simulation_df.iloc[-1]
prob_above_target = (final_prices > target_price).mean()

# Output results
click.echo(f"Monte Carlo simulation results for {ticker}:")
click.echo(f"Number of simulations: {simulations}")
click.echo(f"Number of days: {days}")
click.echo(f"Target price: ${target_price:.2f}")
click.echo(f"Probability of price above target: {prob_above_target:.2%}")
click.echo(f"Current price: ${last_price:.2f}")
click.echo(f"Simulated price range: ${final_prices.min():.2f} - ${final_prices.max():.2f}")

if __name__ == '__main__':
monte_carlo_simulation()
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ description = "Simulate stock price over a future period"
readme = "README.md"
authors = [{name = "Lyubomir Georgiev"}]
license = {text = "Apache-2.0"}
requires-python = ">=3.8"
requires-python = ">=3.10"
classifiers = [
"License :: OSI Approved :: Apache Software License"
]
dependencies = [
"click"
"click",
"pandas",
"numpy",
"yfinance"
]

[project.urls]
Expand Down
64 changes: 51 additions & 13 deletions stocksim/cli.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@
import click

import yfinance as yf
import numpy as np
import pandas as pd
from datetime import datetime, timedelta

@click.group()
@click.version_option()
def cli():
"Simulate stock price over a future period"

@click.command()
@click.option('--ticker', required=True, help='Stock ticker symbol')
@click.option('--days', default=30, help='Number of days for simulation')
@click.option('--target-price', required=True, type=float, help='Target price for probability calculation')
@click.option('--simulations', default=1000, help='Number of Monte Carlo simulations')
def cli(ticker, days, target_price, simulations):
# Download historical data
end_date = datetime.now()
start_date = end_date - timedelta(days=5*365) # 5 years ago
data = yf.download(ticker, start=start_date, end=end_date)

# Calculate daily returns
returns = data['Close'].pct_change().dropna()

# Calculate mean and variance of daily returns
mu = returns.mean()
var = returns.var()

# Simulate future stock prices
last_price = data['Close'].iloc[-1]

# Create a matrix of random returns
random_returns = np.random.normal(mu, var**0.5, size=(days, simulations))

# Calculate price paths
price_paths = last_price * np.exp(np.cumsum(random_returns, axis=0))

# Insert the initial price at the beginning of each path
price_paths = np.insert(price_paths, 0, last_price, axis=0)

# Convert to DataFrame
simulation_df = pd.DataFrame(price_paths, columns=[f'Sim_{i}' for i in range(simulations)])

# Calculate probability of exceeding target price
final_prices = simulation_df.iloc[-1]
prob_above_target = (final_prices > target_price).mean()

# Output results
click.echo(f"Monte Carlo simulation results for {ticker}:")
click.echo(f"Number of simulations: {simulations}")
click.echo(f"Number of days: {days}")
click.echo(f"Target price: ${target_price:.2f}")
click.echo(f"Probability of price above target: {prob_above_target:.2%}")
click.echo(f"Current price: ${last_price:.2f}")
click.echo(f"Simulated price range: ${final_prices.min():.2f} - ${final_prices.max():.2f}")

@cli.command(name="command")
@click.argument(
"example"
)
@click.option(
"-o",
"--option",
help="An example option",
)
def first_command(example, option):
"Command description goes here"
click.echo("Here is some output")
if __name__ == '__main__':
cli()

0 comments on commit f9cab5f

Please sign in to comment.