Source code for tradeexecutor.cli.commands.show_positions

"""show-positions command.

"""
import enum
from pathlib import Path
from typing import Optional

from tabulate import tabulate
from typer import Option

from .app import app
from .shared_options import PositionType
from ..bootstrap import prepare_executor_id, create_state_store
from ...analysis.position import display_positions, display_transactions
from ...state.state import State
from . import shared_options




[docs]class TransactionType(enum.Enum): """What transaction output we want from show-positions command.""" none = "none" #: Show only open positions failed = "failed" #: Show all positions all = "all"
[docs]@app.command() def show_positions( id: str = shared_options.id, state_file: Optional[Path] = shared_options.state_file, strategy_file: Optional[Path] = shared_options.optional_strategy_file, position_type: PositionType = shared_options.position_type, tx_type: TransactionType = Option("none", envvar="TX_TYPE", help="Which transactions to list"), ): """Display trading positions from a state file. - Dumps all open and historical positions from the state file for debug inspection - This command does not read any live chain state, but merely dumps the existing state file positions to the console. """ if not state_file: # Guess id from the strategy file id = prepare_executor_id(id, strategy_file) assert id, "Executor id must be given if not absolute state file path is given" state_file = Path(f"state/{id}.json") store = create_state_store(state_file) assert not store.is_pristine(), f"State file does not exists: {state_file}" state = State.read_json_file(state_file) print(f"Displaying positions and trades for state {state.name}") print(f"State last updated: {state.last_updated_at}") print(f"Position flags: F = frozen, R = contains repairs, UE = unexpected trades, SL = stop loss triggered, - = trade") print(f"Trade flags: T = trade, B = buy, S = sell, SL = stop loss, R1 = repaired, R2 = repairing") print("Open positions") df = display_positions(state.portfolio.open_positions.values()) # https://pypi.org/project/tabulate/ # https://stackoverflow.com/a/31885295/315168 if len(df) > 0: print(tabulate(df, headers='keys', tablefmt='rounded_outline')) else: print("No open positions") print() if position_type in (PositionType.all, PositionType.open_and_frozen): print("Frozen positions") df = display_positions(state.portfolio.frozen_positions.values()) if len(df) > 0: print(tabulate(df, headers='keys', tablefmt='rounded_outline')) else: print("No frozen positions") print() if position_type == PositionType.all: print("Closed positions") df = display_positions(state.portfolio.closed_positions.values()) print(tabulate(df, headers='keys', tablefmt='rounded_outline')) match tx_type: case TransactionType.failed: trades = (t for t in state.portfolio.get_all_trades() if t.is_failed()) case TransactionType.all: trades = (t for t in state.portfolio.get_all_trades()) case TransactionType.none: trades = None case _: raise NotImplementedError(f"{tx_type}") if trades: print("Transactions by trade") df = display_transactions(trades) # rounded_outline does not support newlines in cells print(tabulate(df, headers='keys', tablefmt="fancy_grid"))