Total Pageviews

2015/03/20

[Apache POI] org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents

Problem
I have a file upload function, which accept xlsx and xls file.




Here is the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
     // Get the workbook instance for Excel file
     Workbook workbook = new HSSFWorkbook(inputStream);
     // Get the specific sheet from the workbook
     Sheet sheet = workbook.getSheetAt(0);
     Iterator<Row> rowIterator = sheet.iterator();
     while (rowIterator.hasNext()) {
         Row row = rowIterator.next();
         log.debug("row = " + row.getCell(0));
     }
 } catch (IOException e) {
     throw e;
 }

But as I upload xlsx file, it throw this exception

1
2
3
4
5
6
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:131) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:104) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:128) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:342) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:323) ~[poi-3.10-FINAL.jar:3.10-FINAL]

Solution
To open an xlsx (Office Open XML) file, you should use XSSFWorkbook instead of HSSFWorkbook, which is used for xls (Excel 97-2003) files.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    // Get the workbook instance for Excel file
    Workbook xslxBook = new XSSFWorkbook(inputStream);
    // Get the specific sheet from the workbook
    Sheet sheet = xslxBook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0).toString());
    }
} catch (IOException e) {
    throw e;
}


Reference

[Apache POI] InvalidFormatException: Package should contain a content type part [M1.13]

Problem
I have a file upload function, which accept xlsx and xls file.


Here is the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    // Get the workbook instance for excel file
    Workbook xslxBook = new XSSFWorkbook(inputStream);
    // Get the specific sheet from the workbook
    Sheet sheet = xslxBook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0));
    }
} catch (IOException e) {
    throw e;
}


But as I upload xls file, it throw this exception
1
2
3
 org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
  at org.apache.poi.util.PackageHelper.open(PackageHelper.java:41) ~[poi-ooxml-3.9.jar:3.9]
  at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:204) ~[poi-ooxml-3.9.jar:3.9]

Solution
The error is telling you that POI couldn't find a core part of the OOXML file. Your file isn't a valid OOXML file, let alone a valid .xlsx file.  So you need to use HSSFWorkbook instead of XSSFWorkbook.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
     // Get the workbook instance for XLS file
     Workbook workbook = new HSSFWorkbook(inputStream);
     // Get the specific sheet from the workbook
     Sheet sheet = workbook.getSheetAt(0);
     Iterator<Row> rowIterator = sheet.iterator();
     while (rowIterator.hasNext()) {
         Row row = rowIterator.next();
         log.debug("row = " + row.getCell(0));
     }
 } catch (IOException e) {
     throw e;
 }



Reference
[1] http://stackoverflow.com/questions/6758364/getting-exceptionorg-apache-poi-openxml4j-exception-no-content-type-m1-13

2015/03/16

資本支出與營運成本

Graham於The Intelligent Investor有提到,資本支出是讓經營者讓企業成長的更大更好的基本工具。會計法允許經營者將營運成本轉換成資本支出,但一些不肖的公司會用此美化公司營收。

所謂的資本支出(Capital expenditure),是指為了獲得固定資產,或為了延長固定資產耐用年限而流出的費用。在會計記賬時,資本支出並不是在支出的當年全部計入費用,而是按照折舊的方式計入每一年的費用。


所謂的營運成本(Operation costs),包括行政開支、分行租金、廣告支出、利息支出、固定資產的折舊等。它們都不是直接成本,不會因為生意收入的増加而立即増加,也不會因為沒有生意收入而免得支出。


公司的毛利 - 營運成本 = 純利


所以,如果把營運成本(Operation costs)轉換成資本支出(Capital expenditure),就可以按折舊的方式來攤提,如此可以美化數字與提升純益


所謂的“資本化”(Capitalization)是指符合條件的相關費用支出不計入當期損益,而是計入相關資產成本,作為資產負債表的資產類專案管理。


簡單地說,資本化就是公司將支出歸類為資產(asset)的方式,因為這樣做對公司長期來說會有好處。費用化,是指此支出對於公司長期來說不具經濟效益,故將其視為費用


Intelligent investor 應該去了解公司的“資本化”(Capitalization)狀況,有那些東西資本化、為什麼資本化。

Reference
[1] http://zh.wikipedia.org/wiki/%E8%B3%87%E6%9C%AC%E6%94%AF%E5%87%BA
[2] http://zh.wikipedia.org/wiki/%E7%87%9F%E9%81%8B%E6%88%90%E6%9C%AC
[3] http://hsmiyu20.pixnet.net/blog/post/251513978-%E6%94%AF%E5%87%BA%E7%9A%84-%E8%B3%87%E6%9C%AC%E5%8C%96-%E8%88%87-%E8%B2%BB%E7%94%A8%E5%8C%96-%3F

2015/03/13

[AngularJS] $scope.$watch

Problem
I have a data grid which implement by ng-grid.
As I click "利率明細", it will pop up a modal dialog and pass parameters into modal dialog. The parameters include "預算別", "債務別", and so on.



預算別 and 債務別 are dynamic and cascading drop down list, it will start to generate these two dynamic and cascading drop down list as it popup modal dialog.


Code snippet in JavaScript (this approach in Line 60 cannot set value correctly, because the dropdown list is dynamic, it set value but the dropdown list is not ready)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//grid definition
$scope.dbm100eFormGrid2 = {
        data : 'dbm100eFormGrid2Data',
        selectedItems: $scope.grid2SelectedRow,
        columnDefs : [
                      { field : 'budgetCode',  displayName : '預算別', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'diversityAmount',  displayName : '溢(折)價金額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'issueCostAmount',  displayName : '發行成本額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'budgetName',  displayName : '預算別', 
                        width: 150, cellClass: 'text-left'},
                      { field : 'debtCode',    displayName : '債務別', 
                        width: 0, cellClass: 'text-left'}, 
                      { field : 'debtCodeDesc',    displayName : '債務別', 
                            width: 150, cellClass: 'text-left'}, 
                      { field : 'issueAmount', displayName : '發行額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'}, 
                      { field : 'realAmount',  displayName : '實收額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'},
                      { field : 'rateDtl',    displayName : '利率%',  
                        width: 170, cellClass: 'text-left',
   //popup modal dialog
                        cellTemplate: '<div class="ngCellText" ng-click="showRateDtl(row);"><a>利率明細</a></div>'}],
        enableColumnResize :true,
        i18n:'zh-tw',
        multiSelect : false
};

$scope.showRateDtl = function(row){
    openDialogForTab2(row);
};

var openDialogForTab2 = function(row){
    var options = {
            templateUrl: 'dbm100eTab4.html',
            controller: ModalInstanceCtrl,
            windowClass: 'app-modal-window',
            backdrop: true,
            keyboard: true,
            backdropClick: true,
            resolve: {
                model: function(){
                    return row.entity;
                }
            }
    };

    var modalInstance = $modal.open(options);
    
    modalInstance.result.then(function (model) {
       // ...
    
};

var ModalInstanceCtrl = function($scope, $modalInstance, model) {
    $scope.dbm100eTab4FormBean = {};
    //set grid data into modal dialog
    $scope.dbm100eTab4FormBean = angular.copy(model);
 //...
};

Solution
Use watch to set value until dropdown lists are ready.
Here is the updated code (check line 59 ~ 64)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//grid definition
$scope.dbm100eFormGrid2 = {
        data : 'dbm100eFormGrid2Data',
        selectedItems: $scope.grid2SelectedRow,
        columnDefs : [
                      { field : 'budgetCode',  displayName : '預算別', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'diversityAmount',  displayName : '溢(折)價金額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'issueCostAmount',  displayName : '發行成本額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'budgetName',  displayName : '預算別', 
                        width: 150, cellClass: 'text-left'},
                      { field : 'debtCode',    displayName : '債務別', 
                        width: 0, cellClass: 'text-left'}, 
                      { field : 'debtCodeDesc',    displayName : '債務別', 
                            width: 150, cellClass: 'text-left'}, 
                      { field : 'issueAmount', displayName : '發行額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'}, 
                      { field : 'realAmount',  displayName : '實收額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'},
                      { field : 'rateDtl',    displayName : '利率%',  
                        width: 170, cellClass: 'text-left',
      //popup modal dialog
                        cellTemplate: '<div class="ngCellText" ng-click="showRateDtl(row);"><a>利率明細</a></div>'}],
        enableColumnResize :true,
        i18n:'zh-tw',
        multiSelect : false
};

$scope.showRateDtl = function(row){
    openDialogForTab2(row);
};

var openDialogForTab2 = function(row){
    var options = {
            templateUrl: 'dbm100eTab4.html',
            controller: ModalInstanceCtrl,
            windowClass: 'app-modal-window',
            backdrop: true,
            keyboard: true,
            backdropClick: true,
            resolve: {
                model: function(){
                    return row.entity;
                }
            }
    };

    var modalInstance = $modal.open(options);
    
    modalInstance.result.then(function (model) {
       // ...
    
};

var ModalInstanceCtrl = function($scope, $modalInstance, model) {
    $scope.dbm100eTab4FormBean = {}; 
    //dbm100eTab4FormBean.debtCode is the name of dropdown list
    //use $scope.$watch means as the dropdown list is ready, then set value
    $scope.$watch("dbm100eTab4FormBean.debtCode", function(newValue, oldValue) {
    //set grid data into modal dialog
        $scope.dbm100eTab4FormBean = angular.copy(model);
    },true);
 //...
};


Reference
[1] http://blog-it.hypoport.de/2013/10/28/angularjs-ordered-init-async-promise/
[2] http://ithelp.ithome.com.tw/question/10139851

2015/03/12

如何計算 Intrinsic Value (股票內在價值)

The Intelligent Investor的作者,有提到一個公式來計算股票的Intrinsic Value內在價值

Intrinsic Value = Current (Normal) Earnings x (8.5 + (2 x Expected Annual Growth Rate)
  • Current (Normal) Earnings = Trailing Twelve Months Earnings Per Share
  • 8.5 = P/E base for a no-growth company
  • Expected Annual Growth Rate = reasonably expected 7 to 10 year growth rate


以下是1210 大成 為例
以下是從2003到2013年這10年的稅後EPS (Column B) 與 EPS成長 (Column C),如C3 = B3 - B4 = 3.42 - 1.43 = 1.99

EPS成長率 = 每年度成長除以上一年度的稅後EPS,如D3 = C4 / B4 = 1.99 / 1.43 = 1.39 X 100 = 139%,過去10年EPS成長率 (Column D) 如下:

過去十年的平均成長 = SUM(C3 : C12) / 10 = 0.49
 Intrinsic Value (股票內在價值) = 最近一年的EPS X (8.5 + 2 X 平均成長率) = B2 X (8.5 + 2 X D14) = 3.42 X (8.5 + 2 X 0.49 ) = 32.42

但是,Graham還是強調,公式所算出的結果僅供參考,因為還有太多的因素會影響到未來的成長率、EPS與股價,如利率的高低會影響到股價,由於股票市場是不保本的,你的投資有可能會賠錢。當利率提高時,投資人就會開始躊躇,在風險與投資報酬的考量下,最後可能會決定把股票部分或全部賣掉,改放到銀行定存,這時候就會造成股價下跌。

Reference
[1] http://www.grahaminvestor.com/articles/how-to/finding-undervalued-stocks-3-using-intrinsic-value/
[2] http://en.wikipedia.org/wiki/Benjamin_Graham_formula
[3] http://goodinfo.tw/stockinfo/StockBzPerformance.asp?STOCK_ID=1210
[4] https://happyeric1120.wordpress.com/2007/06/12/%E5%88%A9%E7%8E%87%E3%80%81%E5%82%B5%E5%88%B8%E3%80%81%E8%88%87%E8%82%A1%E7%A5%A8%E4%B8%89%E8%80%85%E7%9A%84%E9%97%9C%E4%BF%82/

[AngularJS] How to popup modal dialog as I click row in ng-grid

Requirement
I am using ng-grid to implement data grid.
If user click "利率明細" in each row in ng-grid


it should open a modal dialog.

Solution
The code should be like this:  
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 $scope.dbm100eFormGrid2 = {
         data : 'dbm100eFormGrid2Data',
         selectedItems: $scope.grid2SelectedRow,
         columnDefs : [
                       { field : 'budgetCode',  displayName : '預算別', 
                         width: 0, cellClass: 'text-left', visible:false},
                       { field : 'diversityAmount',  displayName : '溢(折)價金額', 
                         width: 0, cellClass: 'text-left', visible:false},
                       { field : 'issueCostAmount',  displayName : '發行成本額', 
                         width: 0, cellClass: 'text-left', visible:false},
                       { field : 'budgetName',  displayName : '預算別', 
                         width: 150, cellClass: 'text-left'},
                       { field : 'debtCode',    displayName : '債務別', 
                         width: 0, cellClass: 'text-left'}, 
                       { field : 'debtName',    displayName : '債務別', 
                             width: 150, cellClass: 'text-left'}, 
                       { field : 'issueAmount', displayName : '發行額', 
                         width: 180, cellClass: 'text-right', cellFilter: 'number'}, 
                       { field : 'realAmount',  displayName : '實收額', 
                         width: 180, cellClass: 'text-right', cellFilter: 'number'},
                       { field : 'rateDtl',    displayName : '利率%',  
                         width: 170, cellClass: 'text-left',
                         cellTemplate: '<div class="ngCellText" ng-click="showRateDtl(row);"><a>利率明細</a></div>'}],
         enableColumnResize :true,
         i18n:'zh-tw',
         multiSelect : false,
         afterSelectionChange: function (row, event) {
             if(!angular.isUndefined($scope.grid2SelectedRow[0])){
                //...
             }
         }
 };
 $scope.showRateDtl = function(row){
     openDialogForTab2(row);
 };
 
 var openDialogForTab2 = function(row){
     var options = {
             templateUrl: 'dbm100eTab4.html',
             controller: ModalInstanceCtrl,
             windowClass: 'app-modal-window',
             backdrop: true,
             keyboard: true,
             backdropClick: true,
             resolve: {
                 model: function(){
                     return row.entity;
                 }
             }
     };

     var modalInstance = $modal.open(options);
     
     modalInstance.result.then(function (model) {
         //...
       });
     
 };
 
 var ModalInstanceCtrl = function($scope, $modalInstance, model) {
     $scope.dbm100eTab4FormBean = angular.copy(model);
     
     //...
     
     $scope.dbm100eFormGrid4 = {
             data : 'dbm100eFormGrid4Data',
             selectedItems: $scope.grid4SelectedRow,
             columnDefs : [
                           { field : 'effcDateB', displayName : '實施日期起', width: 283, cellClass: 'text-left'},
                           { field : 'effcDateE', displayName : '實施日期迄', width: 283, cellClass: 'text-left'},
                           { field : 'debtRate',  displayName : '利率%', width: 283, cellClass: 'text-left'}],
             enableColumnResize :true,
             i18n:'zh-tw',
             multiSelect : false
     };
 };
        

Reference
[1] http://stackoverflow.com/questions/28201723/angular-ui-grid-double-click-row-to-open-pop-up-for-editing-a-row

[AngularJS] TypeError: Cannot set property 'gridDim' of undefined

Problem
I have a data grid which implement by ng-grid.
As I click "利率明細", it should popup a modal dialog. 

The popup modal dialog will have a data grid in the modal dialog. But as I popup the modal dialog, the data grid does not show properly.

Chrome console have error message:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
TypeError: Cannot set property 'gridDim' of undefined
    at ngGridDirectives.directive.ngGridDirective.compile.pre (http://localhost:8080/dbm/assets/ng-grid/2.0.11/ng-grid.js?v=14b4202a:3213:37)
    at nodeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:6559:13)
    at compositeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5986:15)
    at compositeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5989:13)
    at compositeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5989:13)
    at compositeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5989:13)
    at nodeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:6573:24)
    at compositeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5986:15)
    at compositeLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5989:13)
    at publicLinkFn (http://localhost:8080/dbm/assets/angularjs/1.2.16-cht-2/angular.js?v=14b4202a:5891:30) <div class="grid-style ng-scope" data-ng-grid="dbm100eFormGrid4" style="display: inline-block; height: 100px; width: 80%;">

Here is code snippet, ng-grid part, for the modal dialog in HTML:
1
2
3
4
5
6
7
      <div class="row text-center">
        <div class="col-sm-12">
          <div class="grid-style" data-ng-grid="dbm100eFormGrid4"
               style="display: inline-block; height: 100px; width: 80%;">
          </div>
        </div>
      </div>


Here is code snippet in JavaScript (including how to open modal dialog and define ng-grid in modal dialog):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 // click "利率明細", it should popup a modal dialog
 $scope.showRateDtl = function(row){
     openDialogForTab2(row);
 };
 
 //open modal dialog
 var openDialogForTab2 = function(row){
     var options = {
             templateUrl: 'dbm100eTab4.html',
             controller: ModalInstanceCtrl,
             windowClass: 'app-modal-window',
             backdrop: true,
             keyboard: true,
             backdropClick: true,
             resolve: {
                 model: function(){
                     return row.entity;
                 }
             }
     };

     var modalInstance = $modal.open(options);
   //...
 };
 
 var ModalInstanceCtrl = function($scope, $modalInstance, model) {
     //.....
 };
 
 //declare ng-grid in modal dialog
 $scope.dbm100eFormGrid4 = {
         data : 'dbm100eFormGrid4Data',
         selectedItems: $scope.grid4SelectedRow,
         columnDefs : [
                       { field : 'effcDateB', displayName : '實施日期起', width: 283, cellClass: 'text-left'},
                       { field : 'effcDateE', displayName : '實施日期迄', width: 283, cellClass: 'text-left'},
                       { field : 'debtRate',  displayName : '利率%', width: 283, cellClass: 'text-left'}],
         enableColumnResize :true,
         i18n:'zh-tw',
         multiSelect : false
 };


Solution
The modal has it's own scope not inheriting from the scope where you defined the gridOptions, this error occurs if it can't find the gridOptions to set the gridDim on it.

Hence, you need to move line31~41 in to ModalInstanceCtrl as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var ModalInstanceCtrl = function($scope, $modalInstance, model) {
    //...
    $scope.dbm100eFormGrid4 = {
            data : 'dbm100eFormGrid4Data',
            selectedItems: $scope.grid4SelectedRow,
            columnDefs : [
                          { field : 'effcDateB', displayName : '實施日期起', width: 283, cellClass: 'text-left'},
                          { field : 'effcDateE', displayName : '實施日期迄', width: 283, cellClass: 'text-left'},
                          { field : 'debtRate',  displayName : '利率%', width: 283, cellClass: 'text-left'}],
            enableColumnResize :true,
            i18n:'zh-tw',
            multiSelect : false
    };
};

After updated, the data grid can show properly in modal dialog


Reference
[1] http://stackoverflow.com/questions/22802986/combining-ng-grid-and-ui-bootstrap-modal

2015/03/11

[AngularJS] How to set 1000 separator in ng-grid

Problem
I am using AngularJS to implement data grid as bellows:

Here has the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$scope.dbm100eFormGrid2 = {
        data : 'dbm100eFormGrid2Data',
        selectedItems: $scope.grid2SelectedRow,
        columnDefs : [
                      { field : 'budgetCode',  displayName : '預算別', 
                        width: 150, cellClass: 'text-left'},
                      { field : 'debtCode',    displayName : '債務別', 
                        width: 150, cellClass: 'text-left'}, 
                      { field : 'issueAmount', displayName : '發行額', 
                        width: 170, cellClass: 'text-right'}, 
                      { field : 'realAmount',  displayName : '實收額', 
                        width: 170, cellClass: 'text-right'},
                      { field : 'debtName',    displayName : '利率%',  
                        width: 170, cellClass: 'text-left'}],
        enableColumnResize :true,
        i18n:'zh-tw',
        multiSelect : false
};

If I would like to add 1000 separator to issueAmount(發行額) and realAmount(實收額) column, how to do it?


Solution
Just add cellFilter:'number' to issueAmount(發行額) and realAmount(實收額) column definition.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 $scope.dbm100eFormGrid2 = {
         data : 'dbm100eFormGrid2Data',
         selectedItems: $scope.grid2SelectedRow,
         columnDefs : [
                       { field : 'budgetCode',  displayName : '預算別', 
                         width: 170, cellClass: 'text-left'},
                       { field : 'debtCode',    displayName : '債務別', 
                         width: 170, cellClass: 'text-left'}, 
                       { field : 'issueAmount', displayName : '發行額', 
                         width: 170, cellClass: 'text-right', cellFilter: 'number'}, 
                       { field : 'realAmount',  displayName : '實收額', 
                         width: 170, cellClass: 'text-right', cellFilter: 'number'},
                       { field : 'debtName',    displayName : '利率%',  
                         width: 170, cellClass: 'text-left'}],
         enableColumnResize :true,
         i18n:'zh-tw',
         multiSelect : false
 };
  
  

Check the result :


Reference
[1] https://github.com/angular-ui/ng-grid/wiki/Defining-columns

2015/03/06

基金賣出法則

The intelligent investor有提到幾個可以把此檔基金賣出的信號:
  • 投資策略大改變 (如價值型基金突然買進科技股、成長型基金突然買進保險股)
  • 突然增加基金費用
  • 基金公司突然頻繁的交易
  • 突然的不穩定的收益(如突然的巨額收益或損失)
但是其實有些資訊,一般投資大眾並不是很容易取得,只能自己去搜尋

例如如果要看該筆資金的投資策略的話,有幾個步驟 (但是還是不知道如何判斷此家基金公司是否有頻繁的交易)
  1. 境外基金觀測站 尋找 ISIN CODE
  2. 根據所查詢到的ISIN CODE 貼到 http://funds.ft.com/uk/ 查詢 
  3. 找出該筆基金後,scroll down到下方查詢Top 10 holdings,就可以看到Top 10 holdings近一年來的持股增減

如果是定期定額買進基金的話,觀察交易費用則相對簡單,只要看每個月被扣的手續費即可


基金收益的部分,各家銀行或者是一些理財網站都有提供各檔基金淨值的走勢圖

如果覺得收集以上資訊很麻煩的話,可以採納Graham的觀點:
  • 如果你的投資週期可以持續至少25或30年,唯一的投資方式是:每個月定期定額買進。投資標的最好的選擇就是買入指數型基金(total stock-market index fund),只有在你需要現金的時候才賣出
  • 每月定期定額買進index funds,經過二十年,你會發現你的績效打敗大部分的理財專家。
  • 不要想預測未來股市,你應該做的是定期定額投資,讓你的投資變成autopilot mode,你該專注的是你的long-term financial goals,而不是預測未來股市。

2015/03/04

基金挑選法則

The intelligent investor此本書有提到幾個挑選基金的概念

  • 根據研究證明,基金收取的費用越高,其未來的收益會越低。High returns只會是暫時的,但是high expenses卻是固定的
  • 在挑選基金的時候,記得把fund expenses當作第一優先的過濾條件。未來的收益無法預測,但是fund expenses則是唯一可以預測的,故若兩個表現差不多的基金,挑選fund expenses較低的那檔基金 
  • 不要只單看過去的績效來預測未來的績效,過去的贏家常常是未來的輸家,但是過去的輸家未必會是未來的贏家。所以,挑選基金時,避免挑選績效一直表現不好,且fund expenses高於平均的基金

基金的費用可以到晨星網站查詢。舉個例子來說,假設這是一份基金的排名,且我對安本環球 - 世界股票基金A2天達環球策略基金 - 環球策略股票基金 A 累積股份這兩檔基金有興趣

我們可以點選進去這兩檔基金的費用,檢視其費用的差異,圖中總開支比率就是這檔基金一整年會收取的費用,包含 與基金管理及運作相關的支出相對基金資產總值的總開支比例,一般計入管理費及其他所有開支包括交易費、法例相關費用及其他運作及行政費用。



按照Graham的挑選基金的原則,就會挑選安本環球 - 世界股票基金A2此檔基金,因為其fund expenses較低

Reference
[1] http://www.amazon.com/The-Intelligent-Investor-Definitive-Investing/dp/0060555661
[2] http://tw.morningstar.com/ap/main/default.aspx