position ======== .. py:module:: position Attributes ---------- .. autoapisummary:: position.portfolio_schema position.positions_schema Classes ------- .. autoapisummary:: position.PortfolioStats position.PositionType position.PositionEncoder position.Position position.PositionManager position.LivePositionManager Functions --------- .. autoapisummary:: position.PositionDecoder Module Contents --------------- .. py:data:: portfolio_schema .. py:class:: PortfolioStats(/, **data) Bases: :py:obj:`pydantic.BaseModel` !!! abstract "Usage Documentation" [Models](../concepts/models.md) A base class for creating Pydantic models. .. attribute:: __class_vars__ The names of the class variables defined on the model. .. attribute:: __private_attributes__ Metadata about the private attributes of the model. .. attribute:: __signature__ The synthesized `__init__` [`Signature`][inspect.Signature] of the model. .. attribute:: __pydantic_complete__ Whether model building is completed, or if there are still undefined fields. .. attribute:: __pydantic_core_schema__ The core schema of the model. .. attribute:: __pydantic_custom_init__ Whether the model has a custom `__init__` function. .. attribute:: __pydantic_decorators__ Metadata containing the decorators defined on the model. This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1. .. attribute:: __pydantic_generic_metadata__ Metadata for generic models; contains data used for a similar purpose to __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these. .. attribute:: __pydantic_parent_namespace__ Parent namespace of the model, used for automatic rebuilding of models. .. attribute:: __pydantic_post_init__ The name of the post-init method for the model, if defined. .. attribute:: __pydantic_root_model__ Whether the model is a [`RootModel`][pydantic.root_model.RootModel]. .. attribute:: __pydantic_serializer__ The `pydantic-core` `SchemaSerializer` used to dump instances of the model. .. attribute:: __pydantic_validator__ The `pydantic-core` `SchemaValidator` used to validate instances of the model. .. attribute:: __pydantic_fields__ A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects. .. attribute:: __pydantic_computed_fields__ A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects. .. attribute:: __pydantic_extra__ A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra] is set to `'allow'`. .. attribute:: __pydantic_fields_set__ The names of fields explicitly set during instantiation. .. attribute:: __pydantic_private__ Values of private attributes set on the model instance. .. py:attribute:: COLS :type: ClassVar[list[str]] :value: ['net_value', 'cash', 'pnl', 'pnl_pct', 'date', 'rolling_pnl', 'rolling_pnl_pct'] .. py:attribute:: net_value :type: float :value: 0.0 .. py:attribute:: cash :type: float :value: 0.0 .. py:attribute:: pnl :type: float :value: 0.0 .. py:attribute:: pnl_pct :type: float :value: 0.0 .. py:attribute:: rolling_pnl :type: float :value: 0.0 .. py:attribute:: rolling_pnl_pct :type: float :value: 0.0 .. py:attribute:: date :type: datetime.datetime .. py:method:: __iter__() So `dict(model)` works. .. py:method:: to_row() .. py:class:: PositionType Bases: :py:obj:`str`, :py:obj:`enum.Enum` str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'. .. py:attribute:: LONG :value: 'long' .. py:attribute:: SHORT :value: 'short' .. py:class:: PositionEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None) Bases: :py:obj:`json.JSONEncoder` Extensible JSON encoder for Python data structures. Supports the following objects and types by default: +-------------------+---------------+ | Python | JSON | +===================+===============+ | dict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str | string | +-------------------+---------------+ | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ | False | false | +-------------------+---------------+ | None | null | +-------------------+---------------+ To extend this to recognize other objects, subclass and implement a ``.default()`` method with another method that returns a serializable object for ``o`` if possible, otherwise it should call the superclass implementation (to raise ``TypeError``). .. py:method:: default(obj) Implement this method in a subclass such that it returns a serializable object for ``o``, or calls the base implementation (to raise a ``TypeError``). For example, to support arbitrary iterators, you could implement default like this:: def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return super().default(o) .. py:function:: PositionDecoder(dct) .. py:data:: positions_schema .. py:class:: Position(shape, dtype=float, buffer=None, offset=0, strides=None, order=None) Bases: :py:obj:`numpy.ndarray` Represents a position in the portfolio, backed by a numpy array. TODO swap out in favor of alpacas Position type, if possible, however speed of np.ndarray is preferred. .. py:attribute:: COLS :value: ['symbol', 'lot_size', 'enter_date', 'enter_price', 'exit_date', 'exit_price', 'exit_size',... .. py:attribute:: IDX_SYMBOL :value: 0 .. py:attribute:: IDX_LOT_SIZE :value: 1 .. py:attribute:: IDX_ENTER_DATE :value: 2 .. py:attribute:: IDX_ENTER_PRICE :value: 3 .. py:attribute:: IDX_EXIT_DATE :value: 4 .. py:attribute:: IDX_EXIT_PRICE :value: 5 .. py:attribute:: IDX_EXIT_SIZE :value: 6 .. py:attribute:: IDX_POSITION_TYPE :value: 7 .. py:method:: to_row() This method is for completeness and consistency, as it derives from np.ndarray, it is alread a list-like object. :param self: Description :return: Description :rtype: list[Any] .. py:method:: from_alpaca_position(alpaca_position) :classmethod: .. py:property:: symbol :type: str .. py:property:: lot_size :type: float .. py:property:: enter_price :type: float .. py:property:: exit_price :type: float | None .. py:property:: enter_date :type: pandas.Timestamp | None .. py:property:: exit_date :type: pandas.Timestamp | None .. py:property:: exit_size :type: float | None .. py:property:: position_type :type: PositionType .. py:method:: exit(exit_date, price, exit_size = None) .. py:method:: profit() .. py:method:: __iter__() .. py:method:: __str__() .. py:method:: __repr__() .. py:class:: PositionManager(symbols, max_lots = None, maintain_history = True, initial_cash = 0.0, df = None, positions = None, cash = None) .. py:attribute:: symbols .. py:attribute:: max_lots :type: int | None :value: None .. py:attribute:: _initial_cash .. py:attribute:: _cash .. py:attribute:: closed_positions :type: list[Position] :value: [] .. py:attribute:: maintain_history :value: True .. py:method:: __getitem__(key) Allow access to the internal DataFrame using the [] accessor. .. py:method:: to_csv(path) Save the positions to a CSV file. .. py:method:: reset() Reset the position manager. .. py:method:: from_client(trading_client, symbols, max_lots = None, maintain_history = True, initial_cash = 0.0, initial_prices = None) :classmethod: .. py:method:: to_df(client_positions, df) Populate this PositionManager from a mapping of positions (e.g. from a TradingClient). .. py:method:: _append(df) .. py:method:: _exit_positions(df) Exit positions based on the provided DataFrame. ! Removing the whole lots thing would reduce complexity and speed. AKA single "position" per symbol with size attribute. .. py:method:: step(df) Step through the position manager. Return a set indicating if a position was exited and the profit from that position. .. py:method:: available_cash() Return the available cash of the portfolio. .. py:method:: initial_cash() Return the initial cash of the portfolio. .. py:method:: nav(prices = None) Calculate the net asset value (NAV) of the portfolio. .. py:method:: net_value(prices = None) .. py:class:: LivePositionManager(trading_client, symbols, max_lots = None, maintain_history = True, initial_cash = 0, initial_prices = None) Bases: :py:obj:`PositionManager` Position Manager derived class for implementing wrapper functionality to the underlying logic of the PositionManager. Additional logic to convert actual live portfolio positions into the PositionManager format, and thus perform that logic on the live data. Additionally Position Manager can be derived to perform other wrapper functionality on the underlying actions taken by the Position Manager logic. .. py:attribute:: pf_history :type: list[PortfolioStats] :value: [] .. py:attribute:: trading_client .. py:method:: __del__() .. py:method:: reset() Reset the position manager. .. py:method:: step(df) Step through the position manager. Return a set indicating if a position was exited and the profit from that position.