커뮤니티
내가 만든 전략들과 지식을 공유하고 토론합니다.

4. 주식 포트폴리오 구성을 위한 stockPortfolio() 함수

푸른주전자 2024.07.10 13:45 조회수  62 추천 1
//***********************************************************************
// 포트폴리오 구성(종목선택) : stockPortfolio
//***********************************************************************
function stockPortfolio(targetSize) {
    // 기본 필터
    var stockmarket = IQStock.filter(marketFilter);  
    
    // 시가총액 작은 순으로 정렬
    // a.getMarketCapital() - b.getMarketCapital();
    var sortedByMktCap = stockmarket.slice().sort(function(a,b){ return a.getMarketCapital() - b.getMarketCapital(); });
    var sortedBySize = sortedByMktCap.slice(0, Math.floor(sortedByMktCap.length * MkRate));
    
    // 유니버스 구성을 위한 필터
    var universe = sortedBySize.filter(stockFilter);

    //***********************************************************************
    // value
    var sortedByPsr = universe.slice().sort(function(a,b){return getPSR(a)-getPSR(b);});
    var sortedByPor = universe.slice().sort(function(a,b){return getPOR(a)-getPOR(b);});
    var sortedByPer = universe.slice().sort(function(a,b){return getPER(a)-getPER(b);});
    var sortedByPer_4 = universe.slice().sort(function(a,b){return getPER_4(a)-getPER_4(b);});
    var sortedByPer_Par = universe.slice().sort(function(a,b){return getPER_PAR(a)-getPER_PAR(b);});
    var sortedByPer_4Par = universe.slice().sort(function(a,b){return getPER_4PAR(a)-getPER_4PAR(b);});
    var sortedByEveb = universe.slice().sort(function(a,b){return getEVEB(a)-getEVEB(b);});
    var sortedByPbr = universe.slice().sort(function(a,b){return getPBR(a)-getPBR(b);});
    //***********************************************************************
    // quality
    var sortedByRoa = universe.slice().sort(function(a,b){return getROA(a)-getROA(b);});
    var sortedByRoe = universe.slice().sort(function(a,b){return getROE(a)-getROE(b);});
    var sortedByGpoa = universe.slice().sort(function(a,b){return getGPOA(a)-getGPOA(b);});
    //***********************************************************************
    // momentum
    var sortedByMom12 = universe.slice().sort(function(a,b){return getMom12(a)-getMom12(b);});
    

    // 지표별 가중치 지정
    var p10 = 0.0;      // PSR 가중치
    var p11 = 1.0;      // POR 가중치
    var p12 = 0.0;      // PER 가중치
    var p13 = 0.0;      // PER_4 가중치
    var p14 = 0.0;      // PER_Par 가중치
    var p15 = 0.0;      // PER_4Par 가중치
    var p16 = 1.0;      // EVEB 가중치
    var p19 = 1.0;      // PBR 가중치
    
    var p20 = 0.0;      // ROA 가중치
    var p21 = 0.0;      // ROE 가중치
    var p22 = 1.0;      // GPOA 가중치

    var p30 = 0.0;      // Mom12 가중치
    
    // 각 지표들의 순위 조합
    for (var i = 0; i < universe.length; i++) {
        var stock = universe[i];
        
        stock.setScore("combi_rank", 
                         p10*sortedByPsr.indexOf(stock)  
                       + p11*sortedByPor.indexOf(stock)  
                       + p12*sortedByPer.indexOf(stock)  
                       + p13*sortedByPer_4.indexOf(stock)
                       + p14*sortedByPer_Par.indexOf(stock)
                       + p15*sortedByPer_4Par.indexOf(stock)
                       + p16*sortedByEveb.indexOf(stock)  
                       + p19*sortedByPbr.indexOf(stock)  
                       
                       + p20*sortedByRoa.indexOf(stock) 
                       + p21*sortedByRoe.indexOf(stock) 
                       + p22*sortedByGpoa.indexOf(stock) 
                       
                       + p30*sortedByMom12.indexOf(stock) 
                       );
    }
    
    var sortedByTotalScore = universe.slice().sort(function(a,b){return b.getScore("combi_rank")-a.getScore("combi_rank");});
    var portfolio = sortedByTotalScore.slice(0, targetSize);

    return portfolio;                  
}


주식 포트폴리오 구성을 위한 stockPortfolio() 함수입니다.

initialize() 함수에서 포트폴리오 구성 함수를 등록합니다.(https://www.intelliquant.ai/article/1195?forum=0)
// stock_port.setPortfolioBuilder(stockPortfolio); 

이때 등록한 함수 stockPortfolio를 구현하는 것입니다.

먼저 기본 필터에서 종가/시총이 0인 종목을 제외하고 주식 종목을 가지고 와서
// var stockmarket = IQStock.filter(marketFilter);

시가총액이 작은 순으로 정렬하고 하위 25% 종목을 선택합니다.
// var sortedByMktCap = stockmarket.slice().sort(function(a,b){ return a.getMarketCapital() - b.getMarketCapital(); });
// var sortedBySize = sortedByMktCap.slice(0, Math.floor(sortedByMktCap.length * MkRate));

하위 25% 종목 중에서 stockFilter로 유니버스를 구성합니다.
// var universe = sortedBySize.filter(stockFilter);


유니버스 종목들의 각 지표 별 정확한 계산 값이 아니라 순서의 조합이므로
앞시간에 만든 각 지표 함수들을 작은 순으로 각각 정렬을 합니다.
// var sortedByPsr = universe.slice().sort(function(a,b){return getPSR(a)-getPSR(b);});
// var sortedByPor = universe.slice().sort(function(a,b){return getPOR(a)-getPOR(b);});
......

이렇게 나열한 지표들에 가중치를 주어서 
// var p10 = 0.0;      // PSR 가중치
// var p11 = 1.0;      // POR 가중치
......

각 지표들의 순위 조합으로 퀀트 전략을 수립합니다. (코드 붉은색 부분)


다음은 리밸런싱을 위한 onDayClose() 함수를 작성해 보겠습니다.

감사합니다. ^^
댓글 0
댓글 등록을 위해서 로그인해주세요.
 
최신 게시글