//*********************************************************************** // 포트폴리오 구성(종목선택) : 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() 함수를 작성해 보겠습니다.
감사합니다. ^^