Commit ·
e9dd307
1
Parent(s): 45ac00a
feat: sensible defaults for cli
Browse filesfocli simulate
focli portfolio
- src/focli/README.md +6 -6
- src/focli/commands/help.py +13 -7
- src/focli/commands/portfolio.py +2 -5
- src/focli/commands/simulate.py +17 -16
src/focli/README.md
CHANGED
|
@@ -33,9 +33,9 @@ portfolio load <path>
|
|
| 33 |
Load your portfolio data from a CSV file. This is typically the first command you'll run to begin your analysis session.
|
| 34 |
|
| 35 |
```
|
| 36 |
-
portfolio
|
| 37 |
```
|
| 38 |
-
Get a high-level overview of your portfolio, including total value, exposure breakdown, and key risk metrics. This helps you understand your overall positioning at a glance.
|
| 39 |
|
| 40 |
```
|
| 41 |
portfolio list [options]
|
|
@@ -50,7 +50,7 @@ View all positions in your portfolio with filtering and sorting options:
|
|
| 50 |
### Simulation
|
| 51 |
|
| 52 |
```
|
| 53 |
-
simulate
|
| 54 |
```
|
| 55 |
See how your portfolio might perform across different market scenarios:
|
| 56 |
- `--range 20` - Set the range of market movement to analyze (±20%)
|
|
@@ -96,14 +96,14 @@ Exit the application.
|
|
| 96 |
|
| 97 |
```
|
| 98 |
folio> portfolio load private-data/portfolio-private.csv
|
| 99 |
-
folio> portfolio
|
| 100 |
-
folio> simulate
|
| 101 |
folio> position SPY risk
|
| 102 |
folio> position AAPL simulate --range 20
|
| 103 |
folio> portfolio list --options --sort value
|
| 104 |
```
|
| 105 |
|
| 106 |
-
This workflow gives you a complete picture of your portfolio's risk profile and behavior in different market conditions, focusing on the positions that matter most.
|
| 107 |
|
| 108 |
## Getting Help
|
| 109 |
|
|
|
|
| 33 |
Load your portfolio data from a CSV file. This is typically the first command you'll run to begin your analysis session.
|
| 34 |
|
| 35 |
```
|
| 36 |
+
portfolio
|
| 37 |
```
|
| 38 |
+
Get a high-level overview of your portfolio, including total value, exposure breakdown, and key risk metrics. This helps you understand your overall positioning at a glance. (Same as `portfolio summary`)
|
| 39 |
|
| 40 |
```
|
| 41 |
portfolio list [options]
|
|
|
|
| 50 |
### Simulation
|
| 51 |
|
| 52 |
```
|
| 53 |
+
simulate [options]
|
| 54 |
```
|
| 55 |
See how your portfolio might perform across different market scenarios:
|
| 56 |
- `--range 20` - Set the range of market movement to analyze (±20%)
|
|
|
|
| 96 |
|
| 97 |
```
|
| 98 |
folio> portfolio load private-data/portfolio-private.csv
|
| 99 |
+
folio> portfolio
|
| 100 |
+
folio> simulate --range 15 --steps 11
|
| 101 |
folio> position SPY risk
|
| 102 |
folio> position AAPL simulate --range 20
|
| 103 |
folio> portfolio list --options --sort value
|
| 104 |
```
|
| 105 |
|
| 106 |
+
This workflow gives you a complete picture of your portfolio's risk profile and behavior in different market conditions, focusing on the positions that matter most. Notice how commands use sensible defaults, making the interface more intuitive and requiring fewer keystrokes for common operations.
|
| 107 |
|
| 108 |
## Getting Help
|
| 109 |
|
src/focli/commands/help.py
CHANGED
|
@@ -43,25 +43,28 @@ def help_command(args: list[str], state: dict[str, Any], console): # noqa: ARG0
|
|
| 43 |
|
| 44 |
if command == "simulate":
|
| 45 |
console.print(
|
| 46 |
-
" [green]simulate
|
| 47 |
)
|
| 48 |
console.print(
|
| 49 |
-
" [green]simulate
|
| 50 |
)
|
| 51 |
console.print(
|
| 52 |
-
" [green]simulate
|
| 53 |
)
|
| 54 |
console.print(
|
| 55 |
-
" [green]simulate
|
| 56 |
)
|
| 57 |
console.print(
|
| 58 |
-
" [green]simulate
|
| 59 |
)
|
| 60 |
console.print(
|
| 61 |
-
" [green]simulate
|
| 62 |
)
|
| 63 |
console.print(
|
| 64 |
-
" [green]simulate
|
|
|
|
|
|
|
|
|
|
| 65 |
)
|
| 66 |
|
| 67 |
elif command == "position":
|
|
@@ -82,6 +85,9 @@ def help_command(args: list[str], state: dict[str, Any], console): # noqa: ARG0
|
|
| 82 |
)
|
| 83 |
|
| 84 |
elif command == "portfolio":
|
|
|
|
|
|
|
|
|
|
| 85 |
console.print(
|
| 86 |
" [green]portfolio summary[/green] - Show a summary of the portfolio"
|
| 87 |
)
|
|
|
|
| 43 |
|
| 44 |
if command == "simulate":
|
| 45 |
console.print(
|
| 46 |
+
" [green]simulate[/green] - Run a simulation with default parameters (SPY benchmark)"
|
| 47 |
)
|
| 48 |
console.print(
|
| 49 |
+
" [green]simulate --range 10 --steps 21[/green] - Run a simulation with ±10% range and 21 steps"
|
| 50 |
)
|
| 51 |
console.print(
|
| 52 |
+
" [green]simulate --focus SPY,AAPL[/green] - Run a simulation focusing on specific tickers"
|
| 53 |
)
|
| 54 |
console.print(
|
| 55 |
+
" [green]simulate --detailed[/green] - Run a simulation with detailed position analysis"
|
| 56 |
)
|
| 57 |
console.print(
|
| 58 |
+
" [green]simulate --preset detailed[/green] - Run a simulation using a saved preset"
|
| 59 |
)
|
| 60 |
console.print(
|
| 61 |
+
" [green]simulate --save-preset my_preset[/green] - Save current parameters as a preset"
|
| 62 |
)
|
| 63 |
console.print(
|
| 64 |
+
" [green]simulate --filter options[/green] - Run a simulation only on positions with options"
|
| 65 |
+
)
|
| 66 |
+
console.print(
|
| 67 |
+
" [green]simulate spy[/green] - Explicitly specify SPY benchmark (same as 'simulate')"
|
| 68 |
)
|
| 69 |
|
| 70 |
elif command == "position":
|
|
|
|
| 85 |
)
|
| 86 |
|
| 87 |
elif command == "portfolio":
|
| 88 |
+
console.print(
|
| 89 |
+
" [green]portfolio[/green] - Show a summary of the portfolio (same as 'portfolio summary')"
|
| 90 |
+
)
|
| 91 |
console.print(
|
| 92 |
" [green]portfolio summary[/green] - Show a summary of the portfolio"
|
| 93 |
)
|
src/focli/commands/portfolio.py
CHANGED
|
@@ -23,11 +23,8 @@ def portfolio_command(args: list[str], state: dict[str, Any], console):
|
|
| 23 |
"""
|
| 24 |
# Check if we have a subcommand
|
| 25 |
if not args:
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
)
|
| 29 |
-
console.print("Available subcommands: list, summary, load")
|
| 30 |
-
console.print("Type 'help portfolio' for more information.")
|
| 31 |
return
|
| 32 |
|
| 33 |
subcommand = args[0].lower()
|
|
|
|
| 23 |
"""
|
| 24 |
# Check if we have a subcommand
|
| 25 |
if not args:
|
| 26 |
+
# Default to summary if no subcommand is specified
|
| 27 |
+
portfolio_summary([], state, console)
|
|
|
|
|
|
|
|
|
|
| 28 |
return
|
| 29 |
|
| 30 |
subcommand = args[0].lower()
|
src/focli/commands/simulate.py
CHANGED
|
@@ -26,27 +26,28 @@ def simulate_command(args: list[str], state: dict[str, Any], console):
|
|
| 26 |
console.print("Use 'portfolio load <path>' to load a portfolio.")
|
| 27 |
return
|
| 28 |
|
| 29 |
-
# Check if we have a subcommand
|
| 30 |
if not args:
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
)
|
| 34 |
-
console.print("Available subcommands: spy, scenario")
|
| 35 |
-
console.print("Type 'help simulate' for more information.")
|
| 36 |
return
|
| 37 |
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
else:
|
| 48 |
-
|
| 49 |
-
|
| 50 |
|
| 51 |
|
| 52 |
def simulate_spy(args: list[str], state: dict[str, Any], console):
|
|
|
|
| 26 |
console.print("Use 'portfolio load <path>' to load a portfolio.")
|
| 27 |
return
|
| 28 |
|
| 29 |
+
# Check if we have a subcommand or arguments
|
| 30 |
if not args:
|
| 31 |
+
# Default to SPY simulation with default parameters
|
| 32 |
+
simulate_spy([], state, console)
|
|
|
|
|
|
|
|
|
|
| 33 |
return
|
| 34 |
|
| 35 |
+
# Check if the first argument is a subcommand
|
| 36 |
+
first_arg = args[0].lower()
|
| 37 |
+
if first_arg in ["spy", "scenario"]:
|
| 38 |
+
# It's a subcommand
|
| 39 |
+
subcommand = first_arg
|
| 40 |
+
subcommand_args = args[1:]
|
| 41 |
|
| 42 |
+
if subcommand == "spy":
|
| 43 |
+
simulate_spy(subcommand_args, state, console)
|
| 44 |
+
elif subcommand == "scenario":
|
| 45 |
+
console.print(
|
| 46 |
+
"[bold yellow]Note:[/bold yellow] Scenario simulation is not yet implemented."
|
| 47 |
+
)
|
| 48 |
else:
|
| 49 |
+
# No subcommand specified, assume SPY simulation with the provided arguments
|
| 50 |
+
simulate_spy(args, state, console)
|
| 51 |
|
| 52 |
|
| 53 |
def simulate_spy(args: list[str], state: dict[str, Any], console):
|