File size: 6,556 Bytes
f56729d 45ac00a 5a20d88 f56729d 45ac00a f56729d 45ac00a f56729d 45ac00a f56729d 45ac00a f56729d 45ac00a f56729d |
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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
"""
Position analysis commands for the Folio CLI.
This module provides commands for analyzing specific position groups.
"""
from typing import Any
from src.focli.formatters import (
display_position_details,
display_position_risk_analysis,
display_position_simulation,
)
from src.focli.utils import find_position_group, parse_args
from src.folio.simulator import generate_spy_changes, simulate_position_with_spy_changes
def position_command(args: list[str], state: dict[str, Any], console):
"""Analyze a specific position group.
Args:
args: Command arguments
state: Application state
console: Rich console for output
"""
# Check if a portfolio is loaded
if not state.get("portfolio_groups"):
console.print("[bold red]Error:[/bold red] No portfolio loaded.")
console.print("Use 'portfolio load <path>' to load a portfolio.")
return
# Check if we have a ticker
if not args:
console.print("[bold yellow]Usage:[/bold yellow] position <ticker> [options]")
console.print("Type 'help position' for more information.")
return
# Get the ticker
ticker = args[0].upper()
# Check if we have a subcommand
if len(args) > 1 and args[1] in ["details", "risk", "simulate"]:
subcommand = args[1]
position_args = args[2:]
if subcommand == "details":
position_details(ticker, position_args, state, console)
elif subcommand == "risk":
position_risk(ticker, position_args, state, console)
elif subcommand == "simulate":
position_simulate(ticker, position_args, state, console)
else:
# Default to details
position_args = args[1:]
position_details(ticker, position_args, state, console)
def position_details(ticker: str, args: list[str], state: dict[str, Any], console):
"""Show detailed information about a position.
Args:
ticker: Ticker symbol
args: Command arguments
state: Application state
console: Rich console for output
"""
# Define argument specifications
arg_specs = {
"detailed": {
"type": bool,
"default": True,
"help": "Show detailed information",
"aliases": ["-d", "--detailed", "--no-detailed"],
}
}
try:
# Parse arguments
parsed_args = parse_args(args, arg_specs)
detailed = parsed_args["detailed"]
# Find the position group
group = find_position_group(ticker, state["portfolio_groups"])
if not group:
console.print(f"[bold red]Position not found:[/bold red] {ticker}")
return
# Display detailed position information
display_position_details(group, detailed, console)
# Store the last viewed position in state
state["last_position"] = group
except ValueError as e:
console.print(f"[bold red]Error:[/bold red] {e!s}")
except Exception as e:
console.print(f"[bold red]Error analyzing position:[/bold red] {e!s}")
import traceback
console.print(traceback.format_exc())
def position_risk(ticker: str, args: list[str], state: dict[str, Any], console):
"""Show risk analysis for a position.
Args:
ticker: Ticker symbol
args: Command arguments
state: Application state
console: Rich console for output
"""
# Define argument specifications
arg_specs = {
"detailed": {
"type": bool,
"default": False,
"help": "Show detailed information",
"aliases": ["-d", "--detailed"],
}
}
try:
# Parse arguments
parsed_args = parse_args(args, arg_specs)
detailed = parsed_args["detailed"]
# Find the position group
group = find_position_group(ticker, state["portfolio_groups"])
if not group:
console.print(f"[bold red]Position not found:[/bold red] {ticker}")
return
# Display risk analysis
display_position_risk_analysis(group, detailed, console)
# Store the last viewed position in state
state["last_position"] = group
except ValueError as e:
console.print(f"[bold red]Error:[/bold red] {e!s}")
except Exception as e:
console.print(f"[bold red]Error analyzing position risk:[/bold red] {e!s}")
import traceback
console.print(traceback.format_exc())
def position_simulate(ticker: str, args: list[str], state: dict[str, Any], console):
"""Simulate a position with SPY changes.
Args:
ticker: Ticker symbol
args: Command arguments
state: Application state
console: Rich console for output
"""
# Define argument specifications
arg_specs = {
"range": {
"type": float,
"default": 20.0,
"help": "SPY change range in percent",
"aliases": ["-r", "--range"],
},
"steps": {
"type": int,
"default": 13,
"help": "Number of steps in the simulation",
"aliases": ["-s", "--steps"],
},
}
try:
# Parse arguments
parsed_args = parse_args(args, arg_specs)
range_pct = parsed_args["range"]
steps = parsed_args["steps"]
# Find the position group
group = find_position_group(ticker, state["portfolio_groups"])
if not group:
console.print(f"[bold red]Position not found:[/bold red] {ticker}")
return
# Generate SPY changes
spy_changes = generate_spy_changes(range_pct, steps)
# Run the simulation
console.print(
f"[bold]Simulating {ticker} with SPY range ±{range_pct}% and {steps} steps...[/bold]"
)
# Simulate the position
results = simulate_position_with_spy_changes(group, spy_changes)
# Store results in state
if "position_simulations" not in state:
state["position_simulations"] = {}
state["position_simulations"][ticker] = results
state["last_position"] = group
# Display the results
display_position_simulation(results, console)
except ValueError as e:
console.print(f"[bold red]Error:[/bold red] {e!s}")
except Exception as e:
console.print(f"[bold red]Error simulating position:[/bold red] {e!s}")
import traceback
console.print(traceback.format_exc())
|