- 전략 : 전종목대상 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();
}
}