PM (Portfolio Model)

Create a portfolio by combining alphas created by yourself or others

Importing Libraries

Here, necessary libraries are imported for the operation of the portfolio model.

import numpy as np
from finter import BasePortfolio

Define Model Information

# Model information configuration
model_info = {
    "exchange": "krx",             # Exchange name, e.g., Korean Exchange (KRX)
    "universe": "krx",             # Universe for the model
    "instrument_type": "stock",    # Type of instrument, e.g., stock
    "freq": "1d",                  # Frequency of data, e.g., daily (1d)
    "position_type": "target",     # Type of position, e.g., target
    "type": "portfolio"            # Model type, e.g., alpha
}

Alpha Set Definition

A set of alphas for the portfolio is defined. These alphas are specific financial models or strategies to be used within the portfolio.

alpha_set = {
  "krx.krx.stock.ldh0127_qt.sample_univ_1",
  "krx.krx.stock.soobeom33_qt.low_vol_factor_simple"
}

Portfolio Class Definition

A Portfolio class is defined, inheriting from BasePortfolio. It includes methods for loading alpha positions for a given period and fetching alpha positions to construct the portfolio.

class Portfolio(BasePortfolio):
  alpha_set = alpha_set
  
  def alpha_loader(self, start, end):
      return self.get_alpha_position_loader(
          start, end,
          model_info["exchange"],
          model_info["universe"],
          model_info["instrument_type"],
          model_info["freq"],
          model_info["position_type"],
      )
      
  def get(self, start, end):
      alpha_loader = self.alpha_loader(start, end)
      alpha_dict = {}
      for i in self.alpha_set:
          alpha_dict[i] = alpha_loader.get_alpha(i)
          alpha_dict[i] = alpha_dict[i][alpha_dict[i] > 0]
      pf = sum(map(lambda x: x.fillna(0), alpha_dict.values()))
      pf = pf.div(pf.sum(axis=1), axis=0) * 1e8
      return pf.fillna(0)

Initializing Portfolio and Fetching Data

The portfolio is initialized, and data for a specified period is fetched.

start, end = (20190929, 20201230)
self = Portfolio()
pf = self.get(start, end)

Simulation

Constraints of portfolio

model_info['type'] == portfolio
return_calc_method == 'geometric'
volcap_pct == 1
from finter.framework_model.simulation import adj_stat_container_helper

# Generating model statistics
model_stat = adj_stat_container_helper(
    position=pf,                            # Portfolio position data
    model_info=model_info,                  # Model information defined above
    start=start,                            # Start date for the simulation
    end=end,                                # End date for the simulation
    volcap_pct=1,                           # Volume cap percentage
    decay=1,                                # Decay factor for volume limit
    cost_list=["hi_low", "fee_tax"],        # Costs to include (price limits, transaction tax)
    slippage=10,                            # Slippage applied (10 basis points)
    return_calc_method="geometric",         # Method for return calculation (geometric)
    turnover_calc_method="diff",            # Method for turnover calculation (diff)
    booksize=1e8,                           # Size of the book (100 million)
    close=True,                             # Whether to use closing prices
    adj_dividend=False                      # Apply dividend adjustments
)

import pandas as pd
df = pd.read_json(model_stat['cum_ret'], orient='records').set_index('index')['data']
df.index = pd.to_datetime(df.index).to_series().apply(lambda x: x.date())
df.plot()

Last updated