- 전략 : 전종목대상 PBR( 0.3 이상 0.8 이하) + PER (3이상 8이하) 선택 후 

               시가총액 낮은 순으로 20종목 매수.




var account1, account2, account3;

var basket1, basket2, basket3;                // 주식 종목들을 담을 Basket



var STOCK_WEIGHT = 0.95;    // 주식 비율 현금 보유를 0%

var MAX_SIZE1 = 20;         // 바스켓1 사이즈




// 이 전략이 초기화되면 Initialize 함수가 호출됩니다.

function initialize() {

    IQEnvironment.simulationMethod = SimulationMethod.day;   

    IQEnvironment.stockCommission = 0.0015;   // commission for stocks 0.0015

  IQEnvironment.etfCommission = 0.0015;       // commission for ETFs 0.0015

    IQEnvironment.stockTax = 0.013;    // 주식 세금 1.3% (슬리피지 1%포함)

    

    

    var account_1 = IQAccount.addAccount('0000-0000-01', 'SSONG', IQEnvironment.aum);

     


basket1 = new Basket(account_1, MAX_SIZE1, IQEnvironment.aum * STOCK_WEIGHT);    

    

 

    basket1.setPortfolioBuilder(portfolioBuilder1);

 

}



// PCR역순 구하기

function cp(stock) { 

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return  (stock.getFundamentalOperatingCashFlow(0) +

           stock.getFundamentalOperatingCashFlow(1) +

           stock.getFundamentalOperatingCashFlow(2) +

           stock.getFundamentalOperatingCashFlow(3)) / stock.getMarketCapital(); }

// PBR역순 구하기

function PBR(stock) { 

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return  (stock.getFundamentalTotalEquity(0) +

           stock.getFundamentalTotalEquity(1) +

           stock.getFundamentalTotalEquity(2) +

           stock.getFundamentalTotalEquity(3)) / stock.getMarketCapital(); }

// PER역순 구하기

function PER(stock) { 

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return  (stock.getFundamentalNetProfit(0) +

           stock.getFundamentalNetProfit(1) +

           stock.getFundamentalNetProfit(2) +

           stock.getFundamentalNetProfit(3)) / stock.getMarketCapital(); }

// POR역순 구하기

function op(stock) { 

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return  (stock.getFundamentalOperatingIncome(0) +

           stock.getFundamentalOperatingIncome(1) +

           stock.getFundamentalOperatingIncome(2) +

           stock.getFundamentalOperatingIncome(3)) / stock.getMarketCapital(); }

// PSR역순 구하기

function sp(stock) { 

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return  (stock.getFundamentalRevenue(0) +

           stock.getFundamentalRevenue(1) +

           stock.getFundamentalRevenue(2) +

           stock.getFundamentalRevenue(3)) / stock.getMarketCapital(); }

// ev/ebitda역순 구하기

function eev(stock) {

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return  (stock. getFundamentalEBITDA(0) +

           stock. getFundamentalEBITDA(1) +

           stock. getFundamentalEBITDA(2) +

           stock. getFundamentalEBITDA(3)) / stock.getFundamentalEV(); }

// GPA 구하기

function gpa(stock) { return (stock.getFundamentalRevenue() - stock.getFundamentalSalesCost()) / stock.getFundamentalTotalAsset(); }

// GPA 구하기 

function gpa4(stock) {

stock.loadPrevData(2, 0, 0);

  return (stock.getFundamentalRevenue(0) + 

          stock.getFundamentalRevenue(1) + 

          stock.getFundamentalRevenue(2) + 

          stock.getFundamentalRevenue(3) - 

          stock.getFundamentalSalesCost(0) - 

          stock.getFundamentalSalesCost(1) - 

          stock.getFundamentalSalesCost(2) - 

          stock.getFundamentalSalesCost(3) ) / stock.getFundamentalTotalAsset(); }


// GPS 구하기

function gps(stock) { return (stock.getFundamentalRevenue() - stock.getFundamentalSalesCost()) / stock.getMarketCapital(); }

// GPS 구하기 

function gps4(stock) {

stock.loadPrevData(2, 0, 0);

  return (stock.getFundamentalRevenue(0) + 

          stock.getFundamentalRevenue(1) + 

          stock.getFundamentalRevenue(2) + 

          stock.getFundamentalRevenue(3) - 

          stock.getFundamentalSalesCost(0) - 

          stock.getFundamentalSalesCost(1) - 

          stock.getFundamentalSalesCost(2) - 

          stock.getFundamentalSalesCost(3) ) / stock.getMarketCapital(); }


//배당수익률 

function dvs(stock) {

    stock.loadPrevData(2, 0, 0); //이전 재무데이터 로드

  return (stock.getFundamentalDividend(0) +

          stock.getFundamentalDividend(1) +

          stock.getFundamentalDividend(2) +

          stock.getFundamentalDividend(3)) / stock.getMarketCapital(); }


//분기 자산성장률 역수

function AssetGrowth4(stock) {

  stock.loadPrevData(2,0,0); //이전 재무데이터 로드

    var AssetGrowth = 0;

    AssetGrowth =stock.getFundamentalTotalAsset(4)/(stock.getFundamentalTotalAsset(0) - stock.getFundamentalTotalAsset(4));

    return AssetGrowth;

}


//시가총액 역

function P(stock) {return 1/stock.getMarketCapital();}


///////////////////////////


//portfolioBuilder 함수에서 사용할 필터링 함수를 정의합니다.

function stockFilter(stock) {

    if (stock.getMarketCapital() === 0) { return false; }

    if (stock.getClose() === 0) { return false; }                      // 가격 0인 종목 = 상폐종목 제외

    if (stock.getTradingVolume() === 0) { return false; }               // 거래량 0인 종목 = 거래정지 중인 종목 제외    

    if (stock.isETF) { return false; }            // ETF 제외

    if (stock.manage & 1 ) { return false; } // 관리종목 제외

    if (stock.name.substr(stock.name.length -3) === "ETN") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -4) === "투자신탁") { return true; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "스팩") { return false; } //스팩 제외

    if (stock.name.substr(stock.name.length -3) === "스팩2") { return false; } //스팩 제외    

    if (stock.name.substr(stock.name.length -2) === "우B") { return false; } //우선주 제외    

    if (stock.name.substr(stock.name.length -2) === "우C") { return false; } //우선주 제외  

    if (stock.name.substr(stock.name.length -1) === "우") {

        if (stock.name === "연우") { return true;} else { return false; }     }//우선주 제외     

    if (stock.name.substr(stock.name.length -3) === "우선주") { return false; } //우선주 제외          

    if (stock.name.substr(stock.name.length -1) === ")") { return false; } //우선주 제외  

    if (stock.name.substr(stock.name.length -2) === "1호") { return false; } //스팩 제외    

    if (stock.name.substr(stock.name.length -2) === "2호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "3호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "4호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "5호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "6호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "7호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "8호") { return false; } //스팩 제외  

    if (stock.name.substr(stock.name.length -2) === "9호") { return false; } //스팩 제외   

    if (stock.name.substr(stock.name.length -3) === "10호") { return false; } //스팩 제외 

    if (stock.name.substr(stock.name.length -3) === "개발1") { return false; } //스팩 제외     

    if (stock.name.substr(stock.name.length -4) === "SPAC") { return false; } //스팩 제외   

    if (stock.name.substr(0, 2) === "QV") { return false; } //ETN 제외  

    if (stock.name.substr(0, 4) === "TRUE") { return false; } //ETN 제외      

    if (stock.name.substr(0, 3) === "삼성 ") { return false; } //ETN 제외  

    if (stock.name.substr(0, 5) === "미래에셋 ") { return false; } //ETN 제외  

    if (stock.name.substr(0, 3) === "신한 ") { return false; } //ETN 제외  

    if (stock.name.substr(0, 3) === "대신 ") { return false; } //ETN 제외 

                      

    if (stock.getPBR() > 0.8 || stock.getPBR() < 0.3 || stock.getPER() > 8 || stock.getPER() < 3  ) { return false; }

   

    

    return true;

}

//////////////



function portfolioBuilder1(targetSize) {

    

    var universe = IQStock.filter(stockFilter); 

     

    

   // var sortedByPbr = universe.slice().sort( function(a, b) { return bp(b) - bp(a); });

   //  var sortedByper = universe.slice().sort( function(a, b) { return ep(b) - ep(a); });

   //  var sortedByPsr = universe.slice().sort( function(a, b) { return sp(b) - sp(a); });

   // var sortedByPcr = universe.slice().sort( function(a, b) { return cp(b) - cp(a); });

   // var sortedBygpa4 = universe.slice().sort( function(a, b) { return gpa4(b) - gpa4(a); });

    var sortedbyP    = universe.slice().sort( function(a, b) { return P(b) - P(a); });

    

    universe.forEach( function(stock) {// EBSCA4

        stock.setScore('rank_sum', //sortedByPER.indexOf(stock) + 

                     //  sortedByPbr.indexOf(stock) + 

                     //  sortedByper.indexOf(stock) +

                     //  sortedByPsr.indexOf(stock) +

                     //  sortedByPcr.indexOf(stock)

                      // sortedBygpa4.indexOf(stock)

                         sortedbyP.indexOf(stock)

                      ); 

    });

     

    //시총 하위20%

    var sortedByCap = universe.sort( function(a, b) { return a.getMarketCapital() - b.getMarketCapital(); });

    universe.forEach( function(stock) { stock.setScore('cap_rank', sortedByCap.indexOf(stock)); });

    

    var smallCap = universe.filter(function(stock) {

        if ( stock.getScore('cap_rank') > (0.999 * universe.length) ) { return false; }

        return true; } );

    

    var modelPortfolio = smallCap.slice().sort( function(a, b) {

        return a.getScore('rank_sum') - b.getScore('rank_sum');  });    

    

    var modelPortfolio2 =  modelPortfolio.slice(0, 20);    

    

    logger.debug(modelPortfolio2);

    return modelPortfolio2;

}




///////////////////////////

var lastRebalMonth = -1; 

var startDate = 3;


function onDayClose(now) {

    // 매달 초에 리밸런싱을 수행합니다.

if ((now.getMonth() != lastRebalMonth &&  now.getDate() >= startDate)) {

        

        var account_1 = IQAccount.getAccount('0000-0000-01');

        var Equity1 = account_1.getTotalEquity();

        basket1.setBudget(Equity1 * STOCK_WEIGHT);

        

        basket1.buildPortfolio();   

        basket1.reset();

basket1.targetSize = MAX_SIZE1;

        basket1.buildPortfolio();

        

        lastRebalMonth = now.getMonth();

}


}