Friday, October 8, 2021

Malaysia year 2022 national and state public holidays

The official 2022 national and state public holidays in Malaysia has been announced by Cabinet, Constitution and Inter-Government Relation Division (BKPP), Prime Minister Department.

There are 14 days of national holiday (12 national holidays, whereby Chinese New Year and Hari Raya Puasa have 2 days of holiday respectively, and all the rest are 1 day).

1 of them fall on Friday, 1 fall on Saturday, 5 fall on Sunday, and 2 fall on Monday. Most of the states will have around 4 state holidays in addition to the national holidays. 

Kelantan and Terengganu will have 1 additional holiday for Hari Raya Qurban.

Chinese New Year falls on Tuesday and Wednesday (1st and 2nd February 2022). I believe many people will take a few days leave during the period, namely Monday, Thursday and Friday, so that to enjoy a whole week holiday.

Hari Raya Puasa falls on Tuesday and Wednesday too (3rd and 4th May 2022). Good news is, Monday 2nd May 2022 is also a replacement holiday for Labour's Day which falls on Sunday 1st May. Therefore, you can have another whole week holiday by taking leave on Thursday and Friday.

Deepavali falls on Monday (24th October 2022), so you will have a long weekend.

Click here to download the table of Malaysia year 2021 gazetted national and state public holidays.


Thursday, October 7, 2021

PHP: Exporting data table array to Excel xlsx file with PhpSpreadsheet library

In many occasions when a data table is queried from database and/or displayed on the screen of web application, there is a need to enable the user to download the table, preferably as an MS Excel file.

Traditionally, the method of doing so is to export the table as CSV (comma-separated values) or TSV (tab-separated values) text file, and to use MS Excel to import the CSV or TSV into a worksheet.

There are a lot of shortcomings using this method, including but not limited to:

  • You need to open a new webpage in order to perform the file export, which looks weird to the user experience.
  • The separator character might be different for different users. Some uses comma (","), some uses semicolon (";"), some uses vertical bar pipe ("|"), and so on. Libre Calc in LibreOffice is more flexible in handling the separator character during data import, whereas in MS Excel, if the separator character in the file is not the same with your computer's regional format setting, you will probably get rows of long data in single column.
  • The CSV/TSV is in plain text, and no cell formatting can be made.
  • You need to properly escape and handle the data to be exported, to ensure your data export is successful without error.
  • Numeric fields will most probably be treated as number in the worksheet, although you might want to treat them as text string instead. Common occasions including handling of telephone numbers, batch numbers, serial numbers, etc.
Over the years, there is a trick to export a TSV as XLS (old Excel file format), by putting these 2 lines in the page header:

header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/vnd.ms-excel");

There is a matured sample source code by Chirp Internet (www.chirpinternet.eu) that includes a function to do data cleansing before the export. You can click here to look for the source code of that script.

However, the exported file is actually just a TSV instead of real XLS file. Newer version of MS Excel will actually prompt out warning message when you try to open such exported XLS file.

A much better and proper method is to use the PhpSpreadsheet library to generate the real MS Excel file in xlsx (Microsoft Open XML Spreadsheet) format.

By using this method, you can export the Excel file without the need of opening a new webpage that confuse the user. You can also perform many Excel file manipulation by using the functions, classes and methods provided by the PhpSpreadsheet library.

The PHP codes below are originally posted by billynoah in Stack Overflow forum.

Step 1: Install PhpSpreadsheet library using composer, if you haven't done so.

If you are using Laragon WAMP platform, you can install the library by opening the Terminal window (the 4th button in Laragon control panel) and type the following command:


composer require phpoffice/phpspreadsheet



Step 2: Add these 3 lines at the beginning of your PHP script.

require '/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

Step 3: Prepare your dataset in an array. Normally, this is queried from SQL database server using SELECT statement. Note that in order to use the writeXLSX function with source codes in Step 4 below, the dataset needs to be stored in an array instead of an object.

Below is a simple example of such codes, utilizing ezSQL library class:

$db = new ezSQL_mysqli(MY_USR, MY_PWD, MY_DB, MY_HOST);
$sql = "SELECT * FROM ".MY_TABLE;
$items =$db->get_results($sql, $output=ARRAY_A);
$keys = array_keys(current($items));

Step 4: Put the following function somewhere in your script.

function writeXLSX($filename, $rows, $keys = [], $formats = []) {
// instantiate the class
$doc = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $doc->getActiveSheet();

// $keys are for the header row.  If they are supplied we start writing at row 2
if ($keys) {
$offset = 2;
} else {
$offset = 1;
}

// write the rows
$i = 0;
foreach($rows as $row) {
$doc->getActiveSheet()->fromArray($row, null, 'A' . ($i++ + $offset));
}

// write the header row from the $keys
if ($keys) {
$doc->setActiveSheetIndex(0);
$doc->getActiveSheet()->fromArray($keys, null, 'A1');
}

// get last row and column for formatting
$last_column = $doc->getActiveSheet()->getHighestColumn();
$last_row = $doc->getActiveSheet()->getHighestRow();

// if $keys, freeze the header row and make it bold
if ($keys) {
$doc->getActiveSheet()->freezePane('A2');
$doc->getActiveSheet()->getStyle('A1:' . $last_column . '1')->getFont()->setBold(true);
}
// format all columns as text
$doc->getActiveSheet()->getStyle('A2:' . $last_column . $last_row)->getNumberFormat()->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_TEXT);
if ($formats) {
foreach ($formats as $col => $format) {
$doc->getActiveSheet()->getStyle($col . $offset . ':' . $col . $last_row)->getNumberFormat()->setFormatCode($format);
}
}

// enable autofilter
$doc->getActiveSheet()->setAutoFilter($doc->getActiveSheet()->calculateWorksheetDimension());

// autosize all columns to content width
for ($i = 'A'; $i <= $last_column; $i++) {
$doc->getActiveSheet()->getColumnDimension($i)->setAutoSize(TRUE);
}

// write and save the file
$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($doc);
$writer->save($filename);
}

Step 5: Call the writeXLSX function to generate your MS Excel file.

writeXLSX(EXCELFILE, $items, $keys);

That's all about it. Pretty easy and straightforward, isn't it?


Sunday, October 3, 2021

Online stock filtering and screening by ROE and ROA

In fundamental analysis, Return of Equity (ROE) and Return of Assets (ROA) are among the most important indicators used to evaluate the investability of targetted stock counters.

There are generally 4 components that make up the shareholders' equity:

  • The shares that are sold out to the shareholders, and tradable in the market.
  • The shares that are repurchased by the company and kept as treasury shares.
  • Company's profit that is reinvested into the business as retained earnings.
  • Additional paid-in capital pumped into the company by its shareholders.
In short, shareholders' equity is the money that the company's shareholder had invested into its business, together with the retained earnings from the company's business profit.

ROE is therefore a measurement to evaluate how effective is the company's management team in managing the business and bringing in annual profit to the company.

ROE = Net Profit / Shareholder Equity

The main different between ROE and ROA is that, ROE does not take into account the financial leverage or debt of the company, whereas ROA includes it.

As you might have aware of the basic financial equation as illustrated in the diagram below:


Total Assets = Shareholders' Equity + Total Liabilities

The company needs assets to run its business. The assets can be funded either from shareholders' equity, or from 3rd parties (non-shareholders) as liabilities, for example, in the form of financing loans.

ROA is a measurement to evaluate how effective is the company's management team in utilizing the company's assets to make profit.

ROA = Net Profit / Total Assets

ROA = Net Profit / (Shareholder Equity + Liabilities)

For those companies that are in net cash position (without any debts), its ROE = ROA.

For those companies with liabilities, its ROE is normally higher than ROA, as assets are increased by taking debt.

As a benchmark, if the ROA is lower than bond return rate or even fixed deposit return rate, the shareholders might as well put their money (and borrowed money) in those low-risk money-generating financial instruments, rather than in the business, which is more risky.

When picking target stocks for investment from thousands of counters in the stock market, one of the initial fundamental shortlisting methods is to filter the target stocks to those that meeting the criteria of ROE > 20% and ROA > 15%.

In Rakuten Trade, you can easily do your shortlisting with just a few mouse clicks.

You just need to login to Rakuten Trade online trading website, select the Stock Screener menu, add a new filtering criterion, and select ROE (%).


After that, do the same to select another filtering criterion ROA (%).

Set the minimum of ROE to 20%, and the minimum of ROA to 15%.



You will instantly get the list of matching stocks on your screen, which is around 30 to 40 counters at the time being.

If you don't have a Rakuten Trade account to access to the Stock Screener above, you can use this link to open a new Rakuten Trade account for free, including no charge for opening new CDS account. By opening account with the link, you can get 500 RT Points within 30 days upon your account activation. Beside that, if you start your trading within the first 10 business days after account activation, your first online trading brokerage fee will be rebated as additional RT Points as well.


Hint: Click on the "Older Posts" link to continue reading, or click here for a listing of all my past 3 months articles.