def get_asset_operations(portfolio_id, asset_name): managed_portfolio = portfolio_manager.get_portfolio(portfolio_id) managed_asset = asset_manager.get_asset(managed_portfolio, asset_name) asset_operations = asset_manager.get_operations(managed_asset) return flask.jsonify([ asset_operation.to_dict() for asset_operation in asset_operations.values() ])
def get_asset(portfolio_id, asset_name): managed_portfolio = portfolio_manager.get_portfolio(portfolio_id) managed_asset = asset_manager.get_asset(managed_portfolio, asset_name) asset_operations = asset_manager.get_operations(managed_asset) asset_position = position_manager.get_position(managed_asset) return flask.render_template( 'views/asset.jinja2', portfolio=managed_portfolio, asset=managed_asset, asset_operations=asset_operations, asset_position=asset_position, )
def _get_position_by_average(managed_asset: asset.Asset) -> position.Position: """Gets position of given asset applying average prices. Average prices does not take into consideration when buy/sell positions where done. As such, it is error prone. As assets bought at later time may distort the return on investment that were realized. However, it is the simplest method to calculate. Args: managed_asset: Asset for which to calculate positions. Returns: Position of the asset by average methodology. """ current_price = managed_asset.current_price asset_operations = list( asset_manager.get_operations(managed_asset).values()) operations_by_type = _get_operations_by_type(asset_operations) sold_units = operations_by_type[OperationType.SELL] buy_units_sold, buy_units_unsold = ( _get_average_buy_units_sold(operations_by_type)) rebought_units, sold_rebought_units, sold_not_rebought_units = ( _get_average_rebought_units_sold(operations_by_type)) remaining_quantity = _get_total_quantity(buy_units_unsold) market_value = remaining_quantity * current_price realized_pl, realized_roi = (_get_realized_pl_and_roi( buy_units_sold, sold_units)) unrealized_pl, unrealized_roi = _get_unrealized_pl_and_roi( buy_units_unsold, managed_asset.current_price) opportunity_pl, opportunity_roi = _get_opportunity_pl_and_roi( sold_not_rebought_units, sold_rebought_units, rebought_units, current_price) dividend_value, dividend_yield = ( _get_dividend_value_and_yield(operations_by_type)) return position.Position(managed_asset, remaining_quantity, market_value, realized_pl, realized_roi, unrealized_pl, unrealized_roi, opportunity_pl, opportunity_roi, dividend_value, dividend_yield)
def get_operations(managed_portfolio: portfolio.Portfolio ) -> Mapping[Text, operation.Operation]: """Gets all the position of all assets in the portfolio. Args: managed_portfolio: Portfolio from which to obtain operations. Returns: Map of portfolio operations to its ids. """ managed_assets = asset_manager.get_assets(managed_portfolio) portfolio_operations = {} for managed_asset in managed_assets.values(): asset_operations = asset_manager.get_operations(managed_asset) portfolio_operations.update(asset_operations) return portfolio_operations
def _get_position_by_fifo(managed_asset: asset.Asset) -> position.Position: """Gets position of given asset following Fist In, First Out method. First In, First Out(FIFO) methodology assumes that the sold assets are the first acquired ones. Args: managed_asset: Asset for which to calculate positions. Returns: Position of the asset by FIFO methodology. """ current_price = managed_asset.current_price asset_operations = list( asset_manager.get_operations(managed_asset).values()) asset_operations.sort(key=lambda op: op.timestamp) operations_by_type = _get_operations_by_type(asset_operations) sold_units = _get_fifo_sold_units(operations_by_type) buy_units_sold, buy_units_unsold = ( _get_fifo_buy_units_sold(operations_by_type)) rebought_units, sold_rebought_units, sold_not_rebought_units = ( _get_fifo_rebought_units_sold(operations_by_type)) remaining_quantity = _get_total_quantity(buy_units_unsold) market_value = remaining_quantity * current_price realized_pl, realized_roi = (_get_realized_pl_and_roi( buy_units_sold, sold_units)) unrealized_pl, unrealized_roi = _get_unrealized_pl_and_roi( buy_units_unsold, managed_asset.current_price) opportunity_pl, opportunity_roi = _get_opportunity_pl_and_roi( sold_not_rebought_units, sold_rebought_units, rebought_units, current_price) dividend_value, dividend_yield = ( _get_dividend_value_and_yield(operations_by_type)) return position.Position(managed_asset, remaining_quantity, market_value, realized_pl, realized_roi, unrealized_pl, unrealized_roi, opportunity_pl, opportunity_roi, dividend_value, dividend_yield)
def delete_operation(managed_portfolio: portfolio.Portfolio, operation_to_remove: operation.Operation): """Removes an operation from a portfolio. Args: managed_portfolio: Portfolio from which to remove operation. operation_to_remove: Operation to remove. Raises: ValueError: Operation not found in portfolio. """ managed_asset = operation_to_remove.managed_asset asset_operations = asset_manager.get_operations(managed_asset) if operation_to_remove not in asset_operations.values(): raise ValueError( f'{operation_to_remove} not found in {managed_asset}.') asset_manager.delete_operation(managed_asset, operation_to_remove) portfolio_manager.store_portfolio(managed_portfolio)
def get_position(managed_asset: asset.Asset) -> position.Position: """Gets position of given asset. Args: managed_asset: Asset for which to calculate position. Returns: Position of the given asset. """ buy_type = operation.OperationType.BUY sell_type = operation.OperationType.SELL dividend_type = operation.OperationType.DIVIDEND total_quantity = { buy_type: 0, sell_type: 0, dividend_type: 0, } total_value = { buy_type: 0, sell_type: 0, dividend_type: 0, } asset_operations = asset_manager.get_operations(managed_asset) for asset_operation in asset_operations.values(): # TODO: add currency conversion. total_quantity[asset_operation.operation_type] += asset_operation.quantity total_value[asset_operation.operation_type] += ( asset_operation.quantity * asset_operation.price_per_unit) # TODO: change average to FIFO methodology. average_price = { buy_type: ( total_value[buy_type] / total_quantity[buy_type] if total_quantity[buy_type] > 0 else 0 ), sell_type: ( total_value[sell_type] / total_quantity[sell_type] if total_quantity[sell_type] > 0 else 0 ), dividend_type: ( total_value[dividend_type] / total_quantity[dividend_type] if total_quantity[dividend_type] > 0 else 0 ), } cost_of_sold_units = total_quantity[sell_type] * average_price[buy_type] realized_pl = total_value[sell_type] - cost_of_sold_units realized_roi = (realized_pl / cost_of_sold_units if cost_of_sold_units > 0 else 0) remaining_quantity = total_quantity[buy_type] - total_quantity[sell_type] market_value = remaining_quantity * managed_asset.current_price cost_of_remaining_units = remaining_quantity * average_price[buy_type] unrealized_pl = market_value - cost_of_remaining_units unrealized_roi = (unrealized_pl / cost_of_remaining_units if cost_of_remaining_units > 0 else 0) current_value_of_sold_units = ( total_quantity[sell_type] * managed_asset.current_price) opportunity_pl = total_value[sell_type] - current_value_of_sold_units opportunity_roi = (opportunity_pl / total_value[sell_type] if total_value[sell_type] > 0 else 0) dividends = total_value[dividend_type] dividend_per_share = (dividends / total_quantity[dividend_type] if total_quantity[dividend_type] > 0 else 0) dividend_yield = (dividend_per_share / average_price[buy_type] if average_price[buy_type] > 0 else 0) return position.Position( managed_asset, remaining_quantity, market_value, realized_pl, realized_roi, unrealized_pl, unrealized_roi, opportunity_pl, opportunity_roi, dividends, dividend_yield)