核心提示:investor_main.js(function(investor) {use strict;var controller = investor.controller;controller.disp...
investor_main.js
(function(investor) {
"use strict";
var controller = investor.controller;
controller.displayTable();
controller.displayWords();
}(window._investor = window._investor || {}));
investor_controller.js
(function(investor) {
"use strict";
investor.controller = investor.controller || (function(){
var headerProperties;
var model = investor.model;
function _displayTable(){
var tableElement = document.querySelector('#table');
var header = model.header;
headerProperties = _getHeaderProperties(header);
tableElement.appendChild(_createRow(header));
var market = investor.market;
market.retrieve().then(function(){}).catch(function(){}).then(function(){
var tableData = model.tableData;
tableData.forEach(
function(rowData){
var newRowElement = _createRow(rowData);
_addOnClickEventTo(newRowElement);
tableElement.appendChild(newRowElement);
}
);
_addFreezeClassToColumn(0);
});
_addScrollEvent();
}
function _createRow(rowData){
var newRowElement = document.createElement('p');
newRowElement.className = 'row';
headerProperties.forEach(
function(headerProperty){
newRowElement.appendChild(_createCell(rowData[headerProperty]));
}
);
return newRowElement;
}
function _createCell(cellData){
var newCellElement = document.createElement('p');
newCellElement.innerHTML = cellData;
newCellElement.className = typeof cellData;
return newCellElement;
}
function _getHeaderProperties(header){
var properties = [];
for(var property in header){
if(header.hasOwnProperty(property)){
properties.push(property);
}
}
return properties;
}
function _displayWords(){
var words = model.words;
var wordsElement = document.querySelector('#words');
words.forEach(
function(word){
var wordElement = document.createElement('p');
wordElement.innerHTML = word;
wordsElement.appendChild(wordElement);
}
);
}
function _addFreezeClassToColumn(index){
var rowElements = document.querySelectorAll('#table .row');
Array.prototype.forEach.call(rowElements,
function(rowElement){
var cellElements = rowElement.querySelectorAll('p');
cellElements[index].classList.add('freezeX');
}
);
}
function _addScrollEvent(){
var freezeXStyle = document.styleSheets[0].rules[0].style;
window.addEventListener('scroll', function(e){
freezeXStyle.left = window.scrollX.toString() + 'px';
//console.log(window.scrollX);
});
}
function _addOnClickEventTo(currentRowElement){
currentRowElement.onclick = _rowOnClickHandler;
}
function _rowOnClickHandler(){
var selectedRowElements = document.querySelectorAll('#table .row.selected');
Array.prototype.forEach.call(selectedRowElements,
function(selectedRowElement){
selectedRowElement.classList.remove('selected');
}
);
this.classList.add('selected');
}
return {
displayTable: _displayTable,
displayWords: _displayWords
};
}());
}(window._investor = window._investor || {}));
investor_model.js
(function(investor) {
"use strict";
investor.model = investor.model || (function(){
// EPS earning per share
// PER price earning ratio
// NAV net asset value
var model = {};
var Stock = (function(){
var Stock = function(){};
Object.defineProperty(Stock.prototype, 'PER_avg_7', {
get: function(){
return (this.latest_price/this.EPS_avg_7).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'PER_2015', {
get: function(){
return (this.latest_price/this.EPS_2015).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'price_to_pidend_ratio_2015', {
get: function(){
return (this.pident_per_share_2015/this.latest_price*100).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'book_to_price_ratio', {
get: function(){
return (this.NAV_per_share_2015/this.latest_price).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'EPS25_avg_7_minus_price', {
get: function(){
return (this.EPS_avg_7*25 - this.latest_price).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'PER20_2015_minus_price', {
get: function(){
return (this.EPS_2015*20 - this.latest_price).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'safe_price', {
get: function(){
return Math.min((this.EPS_avg_7*25).toFixed(1), (this.EPS_2015*20).toFixed(1));
}
});
Object.defineProperty(Stock.prototype, 'price_diff', {
get: function(){
return (this.safe_price - this.latest_price).toFixed(1);
}
});
Object.defineProperty(Stock.prototype, 'price_diff_ratio', {
get: function(){
return (this.price_diff/this.safe_price*100).toFixed(1);
}
});
return Stock;
}());
Object.defineProperty(model, 'stockCodes', {
get: function(){
var rawData = investor.data.stocks;
return rawData.map(function(data){
return data.code;
});
}
});
Object.defineProperty(model, 'header', {
get: function(){
return {
name: '名称',
code: '代码',
price_20151231: '价格 2015.12.31',
price_change_percent_in_one_year: '价格变动自2014.12 (%)',
latest_price: '最近价格',
pay_margin_since: '每年股利支付自',
EPS_avg_7: '每股市场收益 2009-2015 (7年平均收益)',
EPS_2015: '每股收益 2015',
pident_per_share_2015: '每股股利 2015',
NAV_per_share_2015: '每股净资产价值 2015',
PER_avg_7: '2009-2015市场与收益(7年平均)',
PER_2015: '市场与收益 2015',
price_to_pidend_ratio_2015: '股利率 2015',
book_to_price_ratio: '净有形资产比市价比率',
EPS25_avg_7_minus_price: '25倍(7年平均收益)-价格',
PER20_2015_minus_price: '20倍(2015年收益)-价格',
safe_price: '安全边际价格',
price_diff: '价差',
price_diff_ratio:'价差比率',
};
}
});
Object.defineProperty(model, 'words', {
get: function(){
return [
'每一个公司应该是大的、突出的、谨慎投资的。',
'每个公司应该具有一个长期的连续的红利支付记录。',
'联系到过去7年的平均收益,投资者应表明他愿意为一个证券所支付的价格的界限。(平均收益的25倍,并且不多于最近12月的20倍)',
'应该有适当的但不是长度的多样化,就也许意味着有最少10种和最多大约30种不同的证券。',
'',
'发现廉价的普通股有两种方法:',
'1。',
'2。把更多的注意力放在实际资产价值上,特别强调流动资产或流动资本。',
'',
'影响资本化率的因素',
'管理:',
'公平地说,一个杰出的公司会有显著的良好的管理,它显示在以往的记录中,还会显示在下一个5年的预测中,并更多的作为影响长期前景的因素出现。在另一个时间,它会带着乐观的考虑估计它的趋势,并易导致价值的高估。',
'财力和资本结构',
'大量公积金,银行贷款。债券 (偶尔地,资本过大的结构--普通股相对债券和优先股太少--也许在顺利的状态下给普通股造成巨大的“投机”利润,这就是所谓的“杠杆作用”因素)。',
'',
'股利记录',
'',
'当期股利率(p176)',
'幸运的是,大部分公司有所谓的标准股利政策。它意味着它们平均收益约2/3用于分配,除非近期高利润和通货膨胀要求更多的资本,使这个比率相对趋于降低。',
'',
];
}
});
Object.defineProperty(model, 'tableData', {
get: function(){
var stocks = investor.data.stocks;
var tableData = [];
stocks.forEach(function(item){
var stock = new Stock();
for(var attr in item){
if(item.hasOwnProperty(attr)){
stock[attr] = item[attr];
}
}
//Object.assign(stock, item); //too new
var live_market_data = window['hq_str_'+stock.code];
if(live_market_data){
stock.latest_price = live_market_data.split(',')[3];
}
tableData.push(stock);
});
return tableData;
}
});
return model;
}());
}(window._investor = window._investor || {}));
investor_market.js
(function(investor) {
"use strict";
investor.market = investor.market || (function(){
function _retrieve(){
var model = investor.model;
var promise = new Promise(function(resolve, reject){
var script = document.createElement("script");
script.onload = function() {
script.onload = null;
resolve();
}
script.onerror = function() {
script.onerror = null;
reject();
}
script.src = "https://hq.sinajs.cn/list=" + model.stockCodes.toString();
document.head.appendChild( script );
});
return promise;
}
return {
retrieve: _retrieve
}
}());
}(window._investor = window._investor || {}));
investor_data.js
(function(investor) {
"use strict";
investor.data = investor.data || (function(){
var data = {};
Object.defineProperty(data, 'stocks', {
get: function(){
return [
{
name: '中国建筑',
code: 'sh601668',
price_20151231: 6.34,
price_change_percent_in_one_year: '',
//latest_price: undefined,
pay_margin_since: '2009',
EPS_avg_7: .5,
EPS_2015: .84,
pident_per_share_2015: .2,
NAV_per_share_2015: 5.3,
},
{
name: '中国神华',
code: 'sh601088',
price_20151231: 14.97,
price_change_percent_in_one_year: '',
pay_margin_since: '2007',
EPS_avg_7: 1.8,
EPS_2015: .81,
pident_per_share_2015: .32,
NAV_per_share_2015: 12.9,
},
{
name: '中国石化',
code: 'sh600028',
price_20151231: 4.96,
price_change_percent_in_one_year: '',
pay_margin_since: '2001',
EPS_avg_7: .6,
EPS_2015: .27,
pident_per_share_2015: .15,
NAV_per_share_2015: 4.9,
},
{
name: '中集集团',
code: 'sz000039',
price_20151231: 21,
price_change_percent_in_one_year: '',
pay_margin_since: '2007',
EPS_avg_7: .8,
EPS_2015: .72,
pident_per_share_2015: .22,
NAV_per_share_2015: 7.9,
},
{
name: '建设银行',
code: 'sh601939',
price_20151231: 4.78,
price_change_percent_in_one_year: '',
pay_margin_since: '2007',
EPS_avg_7: .7,
EPS_2015: .91,
pident_per_share_2015: .274,
NAV_per_share_2015: 5.6,
},
{
name: '中国人寿',
code: 'sh601628',
price_20151231: 28.31,
price_change_percent_in_one_year: '',
pay_margin_since: '2006',
EPS_avg_7: .9,
EPS_2015: 1.22,
pident_per_share_2015: .42,
NAV_per_share_2015: 11.1,
},
{
name: '中国平安',
code: 'sh601318',
price_20151231: 36,
price_change_percent_in_one_year: '',
pay_margin_since: '2006',
EPS_avg_7: 2.9,
EPS_2015: 2.98,
pident_per_share_2015: .53,
NAV_per_share_2015: 16.6,
},
];
}
});
return data;
}());
}(window._investor = window._investor || {}));
investor_view.html
<html>
<head>
<style>
.freezeX{
left: 0; /* value changed when scrollX */
position: relative;
}
.row{
display: flex;
}
.row p{
border-right: 1px solid gray;
border-bottom: 1px solid gray;
flex: 0 0 100px;
word-wrap: break-word;
background-color: white;
}
.row:first-child p{
border-top: 1px solid gray;
}
.row p:first-child{
border-left: 1px solid gray;
}
.row:nth-child(even) p{
background-color: whitesmoke;
}
.row.selected p{
background-color: lightcyan;
}
</style>
</head>
<body>
<p id="table"></p>
<p id="words"></p>
<script src="investor_model.js" charset="utf-8"></script>
<script src="investor_data.js" charset="utf-8"></script>
<script src="investor_market.js" charset="utf-8"></script>
<script src="investor_controller.js" charset="utf-8"></script>
<script src="investor_main.js" charset="utf-8"></script>
</body>
</html>


