{"id":2088,"date":"2023-04-17T09:10:00","date_gmt":"2023-04-17T09:10:00","guid":{"rendered":"https:\/\/www.tejwin.com\/en\/insights\/esg-investment-portfolio-part-2\/"},"modified":"2023-04-17T09:10:00","modified_gmt":"2023-04-17T09:10:00","slug":"esg-investment-portfolio-part-2","status":"publish","type":"insight","link":"https:\/\/www.tejwin.com\/en\/insights\/esg-investment-portfolio-part-2\/","title":{"rendered":"ESG Investment Portfolio (Part 2)"},"content":{"rendered":"<p class=\"wp-block-paragraph\" id=\"6dab\">Constructing a Custom ESG Investment Portfolio Using the TESG Database<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1YTvBkLj-2O9XLT06iir6Dg.png\"\/><figcaption class=\"wp-element-caption\">Photo by\u00a0<a href=\"https:\/\/unsplash.com\/photos\/JKUTrJ4vK00\" rel=\"noreferrer noopener\" target=\"_blank\">Luke Chesser<\/a>\u00a0on\u00a0<a href=\"https:\/\/unsplash.com\/s\/photos\/finance\" rel=\"noreferrer noopener\" target=\"_blank\">Unsplash<\/a><\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"a05c\">Summary of key points of this article<\/h2>\n<p class=\"wp-block-paragraph\" id=\"e370\">Article difficulty.\uff1a\u2605\u2605\u2606\u2606\u2606<\/p>\n<p class=\"wp-block-paragraph\" id=\"be25\">Reading Recommendation: This article is divided into two parts. The first part introduces the percentage of TEJ\u2019s TESG ratings in the components of popular ESG ETFs in the domestic market. The second part will further utilize TESG ratings to construct an investment portfolio with growth potential and sustainable operations. It is recommended that readers start by reading the article <a class=\"ek-link\" href=\"https:\/\/medium.com\/m\/signin\" rel=\"noopener\" target=\"_blank\">Practical Application: ESG Investment Portfolio (Part 1)<\/a>\u201d to gain a better understanding of this article.<\/p>\n<h2 class=\"wp-block-heading\" id=\"d114\">Introduction<\/h2>\n<p class=\"wp-block-paragraph\" id=\"137b\">In the previous article, we introduced TESG\u2019s scoring mechanism in detail and its proportion of constituent stocks on domestic popular ETFs. This article will teach readers how to further use the ESG rating provided by TESG, and use Python to construct a An investment portfolio that combines sustainable operations and financial growth. The screening criteria used in this paper are as follows:<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\" id=\"a8fa\">The company\u2019s TESG grades for the year were B-, B, B+, A, A+<\/p>\n<p class=\"wp-block-paragraph\">The CAGR of recurring after-tax net profit in the past year has reached more than 20% (inclusive).<\/p>\n<p class=\"wp-block-paragraph\">After-tax ROE for the quarter was greater than the industry ROE median for the quarter.<\/p>\n<p class=\"wp-block-paragraph\">The market value in the current quarter is at least greater than 1 billion yuan.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\">After screening, use the dividend yield rate in the past three years * 80% + the dividend yield rate in the past year * 20% to calculate the dividend score of the stock, and select the 20 stocks with the highest scores as constituent stocks, and allocate weights based on this score. Rebalancing is carried out on the annual financial report announcement day (end of March, May, August, and mid-November).<br \/>*Note: The word index in this article is just a synonym for investment group, please don\u2019t pay attention to it.<\/p>\n<p class=\"wp-block-paragraph\">Editing environment and module requirements<\/p>\n<p class=\"wp-block-paragraph\" id=\"d6da\">This article uses Windows OS and uses Jupyter as the editor.<\/p>\n<pre class=\"wp-block-preformatted\">import tejapi as tej<br\/>import pandas as pd<br\/>import numpy as np<br\/>import datetime<br\/>import matplotlib.pyplot as plt<br\/>import ffn <br\/><br\/>tej.ApiConfig.api_key = 'Your Key'<br\/><br\/>plt.rcParams['font.family'] = 'Noto Sans TC'<br\/><br\/>import warnings<br\/>warnings.filterwarnings(\"ignore\")<br\/><br\/>%matplotlib inline<\/pre>\n<h2 class=\"wp-block-heading\" id=\"d2d2\">Database Use<\/h2>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\" id=\"5236\">Securities Attribute Database(TWN\/ANPRCSTD)<\/p>\n<p class=\"wp-block-paragraph\" id=\"485c\">Listing (cabinet) adjusted stock price (day) \u2013 ex-dividend adjustment (TWN\/APRCD1)<\/p>\n<p class=\"wp-block-paragraph\" id=\"fa6b\">IFRS focuses on consolidation (single quarter) \u2013 All Industries\u2163(TWN\/AIFINQ)<\/p>\n<\/blockquote>\n<h2 class=\"wp-block-heading\" id=\"edda\">Data Loading<\/h2>\n<p class=\"wp-block-paragraph\" id=\"7a37\">Download the stock prices of all listed OTC (including unlisted OTC) stocks from January 2010 to November 2022. The fields include adjusted closing price, market value and dividend yield.<\/p>\n<pre class=\"wp-block-preformatted\">#Listed company code\ncode = tej.get('TWN\/ANPRCSTD', mdate={'lt':'2022-11-18'}, chinese_column_name=True, paginate=True)\nall_code = code[(code['\u8b49\u5238\u7a2e\u985e\u540d\u7a31'].isin(['\u666e\u901a\u80a1', '\u5916\u570b\u4f01\u696d\u4f86\u53f0\u639b\u724c', 'TDR'])) &amp; (code['\u4e0a\u5e02\u5225'].isin(['TSE', 'OTC', 'DIST']))]['\u8b49\u5238\u78bc'].to_list()  #Those that have been delisted also include\n\nm = pd.date_range('2010-01-01', '2022-11-18', freq='1M', inclusive='both').to_list()\n\nprice = pd.DataFrame()\n\nfor i in range(1, len(m)):\n    price = pd.concat([price, tej.get('TWN\/APRCD1', \n                                coid=all_code,\n                                mdate={'gt': m[i-1], 'lt':m[i]+pd.Timedelta(days=1)}, \n                                opts={'columns': ['coid', 'mdate', 'close_adj', 'mv', 'div_yid']},\n                                chinese_column_name=True, \n                                paginate=True)])\n    print(f'\u76ee\u524d\u9031\u671f:{m[i-1]}:{m[i]}')\n\nprice = price.reset_index(drop=True)\nprice = price.rename(columns={'\u8b49\u5238\u4ee3\u78bc':'\u516c\u53f8', '\u5e74\u6708\u65e5':'\u5e74\/\u6708'})\nprice['\u516c\u53f8'] = price['\u516c\u53f8'].astype(int)\nprice = price.astype({'\u5e74\/\u6708':'datetime64[ns]'})\nprice['y'] = price['\u5e74\/\u6708'].dt.year<\/pre>\n<p class=\"wp-block-paragraph\" id=\"a0c6\">For the ESG level of each company, please go to TEJ PRO \u2192 TESG Sustainability Solutions \u2192 TESG Sustainability Indicators \u2192 TESG Sustainability Indicators Master Table to download the latest version (2021) of information.<\/p>\n<pre class=\"wp-block-preformatted\">tesg = pd.read_csv('TESG_1118.csv')<br\/><br\/>tesg['\u8b49\u5238\u4ee3\u78bc'] = tesg['\u8b49\u5238\u4ee3\u78bc'].str.extract('(\\d+)').astype(int)<br\/><br\/>tesg['\u5e74'] = tesg['\u5e74\u6708'].map({201512:2015, 201612:2016, 201712:2017, 201812:2018, 201912:2019, 202012:2020, 202210:2021})<br\/><br\/>tesg = tesg[['\u8b49\u5238\u4ee3\u78bc', '\u5e74', 'TESG\u7b49\u7d1a']]<br\/><br\/>tesg = tesg[tesg['TESG\u7b49\u7d1a'].isin(['A', 'A+', 'B+', 'B', 'B-'])]<br\/><br\/>tesg_rank = tesg.pivot(index='\u8b49\u5238\u4ee3\u78bc', columns='\u5e74', values='TESG\u7b49\u7d1a').fillna(0)<\/pre>\n<p class=\"wp-block-paragraph\">The financial report data can also be downloaded through TEJ PRO or Python API, select the consolidated-based short form (single quarter)-full industry, and download the financial report of all columns from January 2010 to November 2022.<\/p>\n<p class=\"wp-block-paragraph\">In addition, it should be noted that, using the time of the financial report release date, the financial report release time of each stock is uniformly set at the end of March, May, August, and mid-November, so as to avoid using incorrect financial report time to screen individual stocks. The last day stipulated.<\/p>\n<h2 class=\"wp-block-heading\" id=\"2e8c\">Portfolio calculation<\/h2>\n<p class=\"wp-block-paragraph\" id=\"d3e2\">First, identify the stocks and time that meet the standards in each period, calculate the cumulative return rate of these stocks during this period, and then multiply it by np.dot and the corresponding individual equity weight to obtain the cumulative return rate of each period. , we use 1000 points as the initial value to observe its growth. The earliest batch of stocks are selected from 2015\/05\/15 and the cumulative returns are calculated.<\/p>\n<pre class=\"wp-block-preformatted\">def cul_index(price, df, init):\n    #Convert prices to array type\n    price_nd = price.pivot(columns='\u516c\u53f8', index='\u5e74\u6708', values='\u6536\u76e4\u50f9(\u5143)')\n    #Fetch all cycles\n    period = df['\u5e74\u6708'].drop_duplicates().to_list()\n    #Remove all companies\n    company = [list(df.groupby('\u5e74\u6708'))[i][1]['\u516c\u53f8'].to_list() for i in range(len(list(df.groupby(['\u5e74\u6708']))))]\n    #Remove all weight distributions\n    weights = [list(df.groupby('\u5e74\u6708'))[i][1]['\u6b0a\u91cd\u5206\u914d'].to_list() for i in range(len(list(df.groupby(['\u5e74\u6708']))))]\n\n    init = init\n    index = []\n\n    for i in range(1, len(weights)):\n        index.append((price_nd.loc[period[i-1]: period[i], company[i-1]].pct_change()+1).cumprod().dot(init * np.array(weights[i-1])))\n        init = index[-1][-1]\n        print(f'\u7b2c{i}\u6b21\u518d\u5e73\u8861:{init:8.2f}')\n    index.append((price_nd.loc[period[-1]: pd.Timestamp(2022, 11, 18), company[-1]].pct_change()+1).cumprod().dot(init * np.array(weights[-1]))) #\u6700\u5f8c\u4e00\u671f\n    #print(f'\u7b2c{i+1}\u6b21\u518d\u5e73\u8861:{init:8.2f}')\n\n    return pd.DataFrame(pd.concat(index).dropna(), columns=['\u6307\u6578'])<\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1s6Cr_L9Z7kDX9Lnp64SD5w.png\"\/><figcaption class=\"wp-element-caption\">The first phase of individual stocks<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\" id=\"eea3\">We integrate all screening criteria and calculation functions into the investment group formula in the table below. The parameter has an item year_2022, which assumes that the ESG scores of all stocks in 2022 are the same as those in 2021, so that we can observe the latest performance of the investment group.<\/p>\n<pre class=\"wp-block-preformatted\">def constr_index(n1, n2, n3, n4, init, tesg, year_2022=False):\n    #Assuming 2022 ESG scores are the same as 2021\n    tmp = tesg.loc[tesg['\u5e74'] == 2021].copy()\n    tmp['\u5e74'] = 2022\n    tesg = pd.concat([tesg, tmp]).reset_index(drop=True)\n    #--------------------------------------------------------Selective enable\n\n    fin_ind['\u5e38\u7e8c\u6027\u7a05\u5f8c\u6de8\u5229'].fillna(1)\n    fin_ind['\u6de8\u5229CAGR_3'] = fin_ind.groupby('\u516c\u53f8')['\u5e38\u7e8c\u6027\u7a05\u5f8c\u6de8\u5229'].transform(lambda x: (x.pct_change(n1) + 1)**(1\/n1)-1 )\n\n    fin_ind['\u7522\u696dROE\u4e2d\u4f4d\u6578'] = fin_ind.groupby(['\u5e74\u6708', 'TSE\u65b0\u7522\u696d\u540d'])['ROE(A)\uff0d\u7a05\u5f8c'].transform(lambda x: x.median())\n\n    filter1 = pd.merge_asof(fin_ind.sort_values('\u5e74\u6708'), price.sort_values('\u5e74\u6708'), on='\u5e74\u6708', by='\u516c\u53f8').sort_values(['\u5e74\u6708', '\u516c\u53f8'])\n\n    filter1['\u8fd1\u4e09\u5e74\u80a1\u5229\u6b96\u5229\u7387'] = filter1.groupby('\u516c\u53f8')['\u80a1\u5229\u6b96\u5229\u7387-TSE'].transform(lambda x: x.rolling(n2).mean())\n\n    filter1 = filter1.merge(tesg, left_on=['\u5e74', '\u516c\u53f8'], right_on=['\u5e74', '\u8b49\u5238\u4ee3\u78bc'])\n\n    filter1 = filter1[['\u516c\u53f8', '\u4ee3\u78bc', '\u5e74\u6708', '\u6de8\u5229CAGR_3', '\u7522\u696dROE\u4e2d\u4f4d\u6578', 'ROE(A)\uff0d\u7a05\u5f8c', '\u5e02\u503c(\u767e\u842c\u5143)', '\u80a1\u5229\u6b96\u5229\u7387-TSE', '\u5e74', 'TESG\u7b49\u7d1a', '\u8fd1\u4e09\u5e74\u80a1\u5229\u6b96\u5229\u7387', 'TSE\u65b0\u7522\u696d\u540d']]\n\n    #Multi-point ROE Filter\n    condition1 = filter1['\u6de8\u5229CAGR_3'] &gt;= n3\n    condition2 = filter1['ROE(A)\uff0d\u7a05\u5f8c'] &gt;= filter1['\u7522\u696dROE\u4e2d\u4f4d\u6578']\n    condition3 = filter1['\u5e02\u503c(\u767e\u842c\u5143)']\/100 &gt;= 10\n\n    filter1 = filter1[condition1 &amp; condition2 &amp; condition3]\n\n    filter1['\u80a1\u5229\u5206\u6578'] = filter1['\u8fd1\u4e09\u5e74\u80a1\u5229\u6b96\u5229\u7387']*0.8 + filter1['\u80a1\u5229\u6b96\u5229\u7387-TSE']*0.2\n\n    filter1 = filter1.dropna(subset=['\u80a1\u5229\u5206\u6578'])\n\n    div_30_Q = filter1.groupby('\u5e74\u6708').apply(lambda x: x.nlargest(n4, '\u80a1\u5229\u5206\u6578'))\n\n    div_30_Q = div_30_Q.drop(columns=['\u5e74\u6708']).reset_index().drop(columns='level_1')\n\n    div_30_Q['\u6b0a\u91cd\u5206\u914d'] = div_30_Q.reset_index().groupby('\u5e74\u6708')['\u80a1\u5229\u5206\u6578'].apply(lambda x: x\/x.sum())\n    #Adjustments are made in March and September every six months\n    if year_2022 == False:\n        div_30_Sem = div_30_Q[~(div_30_Q['\u5e74\u6708'].dt.year == 2022)].sort_values(['\u5e74\u6708', '\u516c\u53f8'])  #~(div_30_Q['\u5e74\u6708'].dt.month.isin([3, 8])) &amp; \n    else:\n        div_30_Sem = div_30_Q.sort_values(['\u5e74\u6708', '\u516c\u53f8'])\n\n    return cul_index(price, div_30_Sem, init), filter1, div_30_Sem\ndf, index_filter, div_30_Sem = constr_index(4, 12, 0.2, 20, 1000, tesg, year_2022=True)<\/pre>\n<p class=\"wp-block-paragraph\" id=\"9572\">The parameters are the recurring net profit after tax in the past four quarters, the dividend yield rate in the past three years, the recurring net profit after tax CAGR &gt;= 20%, 20 constituent stocks, a starting value of 1,000 points, and the assumption of starting the ESG score in 2022. As can be seen from the table below, a total of 30 rebalancings were carried out from May 2015 to November 2022, and the index grew from 1,000 points to 7,000 points.<\/p>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1YvuaD7dfU6Qtc_Y2pPRkVg.png\"\/><figcaption class=\"wp-element-caption\">2015~2022<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"8b79\">Achievement Statistics<\/h2>\n<p class=\"wp-block-paragraph\" id=\"943c\">We download the cumulative return index of the market during the same period \u2013 Y9997 as a control group to see if it can outperform the market. Obviously, compared with the 205% cumulative return of the broader market, our investment group outperformed the broader market with a cumulative return of 716%.<\/p>\n<pre class=\"wp-block-preformatted\">base_index = tej.get('TWN\/APRCD1', <br\/>            coid=['y9997'], <br\/>            mdate={'gt': '2015-03-01', 'lt':'2022-12-01'}, <br\/>            opts={'columns': ['coid', 'mdate', 'close_adj']},<br\/>            chinese_column_name=True, <br\/>            paginate=True)<br\/><br\/>base_index['\u5e74\u6708\u65e5'] = base_index['\u5e74\u6708\u65e5'].astype('datetime64[ns]')<br\/><br\/>base_index = base_index.pivot(columns='\u8b49\u5238\u4ee3\u78bc', index='\u5e74\u6708\u65e5', values='\u6536\u76e4\u50f9(\u5143)').rename_axis(None, axis=1).reset_index()<br\/><br\/>result = base_index.merge(df, left_on='\u5e74\u6708\u65e5', right_on='\u5e74\u6708')<br\/><br\/>result['997\u7d2f\u8a08\u5831\u916c'] = (result['Y9997'].pct_change()+1).cumprod()<br\/>result['\u6307\u6578\u7d2f\u8a08\u5831\u916c'] = (result['\u6307\u6578'].pct_change()+1).cumprod()<br\/>result<\/pre>\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/12QQInTyNVZkt54kFIxJqjA.png\"\/><\/figure>\n<p class=\"wp-block-paragraph\" id=\"37df\">From the chart below, it can be clearly seen that the investment group has gradually widened the gap with the market since 2016. The largest increase came from the V-shaped reversal of the epidemic in 2020. Basically, the accumulated return rate for the year was close to 100%.<\/p>\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1Ko7aWJLq4DKkmIvWIQq8bA.png\"\/><\/figure>\n<h2 class=\"wp-block-heading\" id=\"6979\">Performance Indicators<\/h2>\n<p class=\"wp-block-paragraph\" id=\"625e\">Calculate various common performance indicators such as rate of return, Sharpe value and MDD, etc.<\/p>\n<pre class=\"wp-block-preformatted\">stat = pd.DataFrame(index=['Y9997', '\u6307\u6578'],<br\/>                    columns=['\u5e74\u5316\u6a19\u6e96\u5dee', '\u5e74\u5316\u5831\u916c\u7387', '\u590f\u666e\u503c', 'MDD'],<br\/>                    data=[[cul_std(result['Y9997']), cul_ret(result['997\u7d2f\u8a08\u5831\u916c']), 0, mdd(result['997\u7d2f\u8a08\u5831\u916c'])],<br\/>                    [cul_std(result['\u6307\u6578']), cul_ret(result['\u6307\u6578\u7d2f\u8a08\u5831\u916c']), 0, mdd(result['\u6307\u6578\u7d2f\u8a08\u5831\u916c'])]])<br\/><br\/>stat['\u590f\u666e\u503c'] = stat['\u5e74\u5316\u5831\u916c\u7387'] \/ stat['\u5e74\u5316\u6a19\u6e96\u5dee']<br\/><br\/>stat['\u98a8\u5831\u6bd4'] = 0<br\/>stat['\u98a8\u5831\u6bd4'].iloc[0] = (result['997\u7d2f\u8a08\u5831\u916c'].iloc[-1]-1) \/ -stat['MDD'].iloc[0]<br\/>stat['\u98a8\u5831\u6bd4'].iloc[1] = (result['\u6307\u6578\u7d2f\u8a08\u5831\u916c'].iloc[-1]-1) \/ -stat['MDD'].iloc[1]<\/pre>\n<p class=\"wp-block-paragraph\" id=\"6fb2\">From the actual performance indicators, it can be seen that while far outperforming the market, the annualized standard deviation is only 0.18% higher than the market, and even the largest drawdown is only 26.45%, which is more stable than the market, and the wind report ratio is as high as 23.3.<\/p>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1CFtiIcY_1dNjJOEACsuigA.png\"\/><figcaption class=\"wp-element-caption\">Performance Indicators<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\" id=\"327c\">Retracement Range During The Period<\/h2>\n<p class=\"wp-block-paragraph\" id=\"6d75\">Graphically presents the periodic retracement range of investment groups and the market.<\/p>\n<pre class=\"wp-block-preformatted\">fig, ax = plt.subplots(figsize=(20, 6))<br\/><br\/>plt.rcParams['font.sans-serif'] = ['Taipei Sans TC Beta']<br\/><br\/>ax.plot(result['\u5e74\u6708\u65e5'], result['997\u7d2f\u8a08\u5831\u916c'].to_drawdown_series().to_list(), color='black', linewidth=1.5)<br\/><br\/>ax.fill_between(result['\u5e74\u6708\u65e5'], np.zeros(len(result['997\u7d2f\u8a08\u5831\u916c'])), result['997\u7d2f\u8a08\u5831\u916c'].to_drawdown_series().to_list(), label='\u5927\u76e4 DD', color='black', linewidth=1, alpha=0.5)<br\/><br\/>ax.plot(result['\u5e74\u6708\u65e5'], result['\u6307\u6578\u7d2f\u8a08\u5831\u916c'].to_drawdown_series().to_list(), color='blue', linewidth=1.5)<br\/><br\/>ax.fill_between(result['\u5e74\u6708\u65e5'], np.zeros(len(result['\u6307\u6578\u7d2f\u8a08\u5831\u916c'])), result['\u6307\u6578\u7d2f\u8a08\u5831\u916c'].to_drawdown_series().to_list(), label='\u7372\u5229ESG DD', color='c', linewidth=1, alpha=0.7)<br\/><br\/>ax.grid()<br\/><br\/>ax.legend(loc='best', fontsize=16)<br\/><br\/>plt.xlabel('\u6642\u9593', fontsize=16)<br\/>plt.ylabel('\u4e0b\u8dcc\u5e45\u5ea6', fontsize=16)<br\/><br\/>plt.title('\u5927\u76e4\u5831\u916c&amp;\u7372\u5229ESG \u56de\u64a4\u5e45\u5ea6', fontsize=20)<br\/><br\/>plt.show()<\/pre>\n<p class=\"wp-block-paragraph\" id=\"539f\">The table below shows the magnitude of the retracement compared with the broader market during the same period. It can be seen that although our blue investment group has been deeper than the broader market in the stock market declines in previous major events, it has been affected by the epidemic in 2020 and the big interest rate hike in the United States in 2022. The magnitude of the retracement is smaller than that of the market.<\/p>\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1lXY9Cw7hTI4iP9Gf69BKkQ.png\"\/><\/figure>\n<h2 class=\"wp-block-heading\" id=\"4a1e\"><strong>Reward Distribution<\/strong><\/h2>\n<p class=\"wp-block-paragraph\" id=\"e754\">Graphical presentation of monthly positive and negative return distribution and cumulative rate of return.<\/p>\n<pre class=\"wp-block-preformatted\">fig = plt.figure(figsize=(16, 12))<br\/><br\/>ax = fig.subplots()<br\/><br\/>ax2 = ax.twinx()<br\/><br\/>ax.bar(index_m.index, [i if i &gt;= 0 else 0 for i in index_m['\u55ae\u6708\u5831\u916c']], color='red', width=10, label='\u55ae\u6708\u6b63\u5831\u916c')<br\/><br\/>ax.bar(index_m.index, [i if i &lt; 0 else 0 for i in index_m['\u55ae\u6708\u5831\u916c']], color='blue', width=10, label='\u55ae\u6708\u8ca0\u5831\u916c')<br\/><br\/>ax2.plot(index_m.index, index_m['\u6307\u6578\u7d2f\u8a08\u5831\u916c']*100, label='\u7d2f\u8a08\u5831\u916c', linewidth=5)<br\/><br\/>ax.axhline(y = 0, color='black')<br\/><br\/>for i in range(2015, 2023):<br\/>    plt.axvline(x = [pd.Timestamp(i,12,31)], color='black', linestyle=\"--\", alpha=0.3)<br\/><br\/>ax.set_xlabel('\u6642\u9593', fontsize=16)<br\/><br\/>ax.set_ylabel('\u55ae\u6708\u5831\u916c\u7387(%)', fontsize=16)<br\/><br\/>ax2.set_ylabel('\u6307\u6578\u7d2f\u8a08\u5831\u916c(%)', fontsize=16)<br\/><br\/>plt.title('\u55ae\u6708\u5831\u916c vs. \u7d2f\u8a08\u5831\u916c', fontsize=16)<br\/><br\/>fig.legend(loc='upper left', bbox_to_anchor=(0,1), bbox_transform=ax.transAxes, fontsize=16)<\/pre>\n<p class=\"wp-block-paragraph\" id=\"9b20\">If we take a closer look at the distribution of positive and negative returns every month, we can see that except for the 2018 Sino-US trade war, 2020 new coronavirus pneumonia, 2021 Taiwan epidemic, and 2022 Ukraine-Russia war &amp; FED\u2019s big interest rate hike, the basic monthly returns are mostly positive. Overall The monthly winning rate came to 71.4%.<\/p>\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1SlxJW9DV2sc1C6TehQ5V3w.png\"\/><\/figure>\n<h2 class=\"wp-block-heading\" id=\"b868\">Latest Results<\/h2>\n<p class=\"wp-block-paragraph\" id=\"9646\">The most recent investment group screened the 20 constituent stocks in the table below. It can be seen that in the past month since November 14, at least 4 stocks with a return rate of more than 10% have been screened out, and the largest drop is only -1.35%. , the current rate of return came to 4.133%.<\/p>\n<figure class=\"wp-block-image aligncenter\"><img decoding=\"async\" alt=\"\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1yN5yUxFeFKRwY-l6rS9HjQ.png\"\/><\/figure>\n<h2 class=\"wp-block-heading\" id=\"a888\">Conclusion<\/h2>\n<p class=\"wp-block-paragraph\">We use the ESG ratings of individual stocks provided by TESG as the basis, combined with the more demanding profit growth indicators, hoping to find targets with both sustainable management and growth potential in the vast sea of \u200b\u200bstocks, and from the results we have successfully achieved To achieve this goal, it has earned a cumulative return rate that is more than 2 times that of the market while being more stable than the market, showing that even if the investment portfolio incorporates ESG indicators, it can still obtain significant excess returns. The investment code provided in the article is integrated in the form of a function, so that readers who want to further adjust the parameters can also refer to the method in the article to select other financial indicators to construct an exclusive ESG investment portfolio.<\/p>\n<p class=\"wp-block-paragraph\">Finally, we would like to remind you again that the objects mentioned in this article are for illustrative purposes only and do not represent recommendations or suggestions for any financial products. Therefore, if readers are interested in related topics such as construction strategies, performance backtesting, research evidence, etc., they are welcome to purchase the solutions in TEJ E Shop. With a complete database, various tests can be easily completed.<\/p>\n<h2 class=\"wp-block-heading\" id=\"a277\">Full Code<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/gist.github.com\/tej87681088\/303428b9a1794dcdc7d9acefcef3ef4b#file-tejapi_python_esg_port-ipynb\" rel=\"noopener\" target=\"_blank\">Click here to <\/a><a class=\"ek-link\" href=\"https:\/\/gist.github.com\/tej87681088\/303428b9a1794dcdc7d9acefcef3ef4b#file-tejapi_python_esg_port-ipynb\" rel=\"noopener\" target=\"_blank\">Github<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\" id=\"e59c\">Further Reading<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/medium.com\/m\/signin\" rel=\"noopener\" target=\"_blank\">ESG Investment Portfolio (Part 1)<\/a><\/li>\n<li><a class=\"ek-link\" href=\"https:\/\/www.tejwin.com\/insight\/tesg-%e6%b0%b8%e7%ba%8c%e7%99%bc%e5%b1%95%e6%8c%87%e6%a8%99%e6%b7%b1%e5%85%a5%e5%88%86%e6%9e%90%e8%88%87%e8%a9%95%e5%83%b9%e4%b9%98%e6%95%b8%e6%9c%89%e9%97%9c%e8%81%af\/\">In-Depth Analysis of TESG sustainable development indicators! Associated with the Evaluation Multiplier?<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\" id=\"69fb\">Related Link<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/api.tej.com.tw\/index.html\" rel=\"noopener\" target=\"_blank\">TEJ API\u00a0Database Home Page<\/a><\/li>\n<li><a class=\"ek-link\" href=\"https:\/\/eshop.tej.com.tw\/E-Shop\/Edata_intro\" rel=\"noopener\" target=\"_blank\">TEJ E-Shop Complete Database Purchase<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In the previous article, we introduced TESG\u2019s scoring mechanism in detail and its rating ratio among popular ETFs in China. This article will teach readers how to further use the ESG rating provided by TESG, and use Python to construct a concurrent An investment portfolio with sustainable operations and financial growth potential.<\/p>\n","protected":false},"featured_media":2087,"template":"","tags":[54,55],"insight_category":[87],"class_list":["post-2088","insight","type-insight","status-publish","has-post-thumbnail","hentry","tag-esg","tag-esg-investing","insight_category-event-alternative-signals"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight\/2088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight"}],"about":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/types\/insight"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/media\/2087"}],"wp:attachment":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/media?parent=2088"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/tags?post=2088"},{"taxonomy":"insight_category","embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight_category?post=2088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}