{"id":1883,"date":"2023-08-22T14:00:00","date_gmt":"2023-08-22T14:00:00","guid":{"rendered":"https:\/\/www.tejwin.com\/en\/insights\/%e3%80%90quant%e3%80%91aroon-up-down-strategy\/"},"modified":"2023-08-22T14:00:00","modified_gmt":"2023-08-22T14:00:00","slug":"%e3%80%90quant%e3%80%91aroon-up-down-strategy","status":"publish","type":"insight","link":"https:\/\/www.tejwin.com\/en\/insights\/%e3%80%90quant%e3%80%91aroon-up-down-strategy\/","title":{"rendered":"Aroon Up Down\u00a0Strategy"},"content":{"rendered":"<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"\u963f\u9686\u6307\u6a19\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/0KXwXM5W3Ts9ZnAKP.jpg\"\/><figcaption class=\"wp-element-caption\">Photo by <a href=\"https:\/\/unsplash.com\/@riddywankenobi?utm_source=medium&amp;utm_medium=referral\" rel=\"noreferrer noopener\" target=\"_blank\">R M<\/a> on\u00a0<a href=\"https:\/\/unsplash.com?utm_source=medium&amp;utm_medium=referral\" rel=\"noreferrer noopener\" target=\"_blank\">Unsplash<\/a><\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Highlight<\/h2>\n<ul class=\"wp-block-list\">\n<li>Difficulty\uff1a\u2605\u2605\u2605\u2605\u2605<\/li>\n<li>Automated trading via Aroon Up Down<\/li>\n<li>Assess the performance of portfolio<\/li>\n<li>Visualize the assessment of the performance<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Preface<\/h2>\n<p class=\"wp-block-paragraph\">Oscillator Technical Indicator is a technical indicator used in the financial market analysis for assessing the over-bought\/over-sold of a given asset in a given period. It can assist investors in identifying trends and potential trend reversals.<\/p>\n<p class=\"wp-block-paragraph\">Oscillator Technical Indicator processes and converts specific price indicators (e.g., opening, closing, highest, and lowest price) in a limited range. Some may include a negative range. Oscillator Technical Indicators are normally presented in a linear format.<\/p>\n<p class=\"wp-block-paragraph\">Today, we are going to introduce an Oscillator Technical Indicator\u200a\u2014\u200aAroon Up Down.<\/p>\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n<p class=\"wp-block-paragraph\">Aroon Indicator, developed by Tushar Chande in 1995, is typically for measuring market tendency. It consists of two lines\u200a-\u200aAroon Up and Aroon Down.<br \/>Aroon Up\uff1a((Number of periods\u200a-\u200aNumber of periods since highest high) \/ Number of periods) * 100<br \/>This indicator measures the periods since the highest price (high point) occurred within the selected period.<br \/>Aroon Down\uff1a((Number of periods\u200a-\u200aNumber of periods since lowest low) \/ Number of periods) * 100<br \/>This indicator measures the periods since the lowest price (low point) occurred within the selected period.<\/p>\n<p class=\"wp-block-paragraph\">The Aroon Up indicator measures the strength and time since the highest price within a given period (usually 25 periods). In contrast, the Aroon Down indicator measures the strength and time since the lowest price within the same period. These indicators are expressed as percentages and range from 0% to 100%.<\/p>\n<p class=\"wp-block-paragraph\">The crossover of the Aroon Up and Aroon Down lines can be used to signal potential changes in trend direction. For example, when Aroon Up crosses above Aroon Down, it might be seen as a bullish signal, indicating a potential shift towards an upward trend. Conversely, when Aroon Down crosses above Aroon Up, it could be interpreted as a bearish signal, suggesting a potential shift towards a downward trend.<\/p>\n<h2 class=\"wp-block-heading\">Programming environment and Module\u00a0required<\/h2>\n<p class=\"wp-block-paragraph\">MacOS and Jupyter Notebook is used as editor<\/p>\n<pre class=\"wp-block-preformatted\"><code>import pandas as pd \nimport re\nimport numpy as np \nimport tejapi\nimport plotly.express as px\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as mticker\nfrom matplotlib.pyplot import MultipleLocator\nfrom sklearn.linear_model import LinearRegression\nimport datetime<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Database<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/api.tej.com.tw\/columns.html?idCode=TWN\/APRCD\" rel=\"noreferrer noopener\" target=\"_blank\">Listed (OTC) unadjusted stock price (day) \uff1aTWN\/APRCD<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Import data<\/h2>\n<p class=\"wp-block-paragraph\">For the period from 2018\u201301\u201301 to 2020\u201312\u201331, we take Hon Hai Precision Industry Co., Ltd.(2317), Compal Electronics, Inc.(2324), YAGEO Corporation(2327), Taiwan Semiconductor Manufacturing Co., Ltd.(2330), Synnex Technology International Corp.(2347), Acer(2353), Foxconn Technology Co., Ltd.(2354), ASUS(2357), Realtek Semiconductor Corp.(2379), Quanta Computer, Inc.(2382), Advantech Co., Ltd.(2395) as instances, we will construct backtesting system with unadjusted price data, and compare the performance with the Market Return Index(Y9997).<\/p>\n<pre class=\"wp-block-preformatted\"><code>stock_id = [\"Y9997\", \"2317\", \"2324\", \"2327\", \"2330\", \"2347\", \"2353\", \"2354\",\n            \"2357\", \"2379\", \"2382\", \"2395\"]\ngte, lte = '2018-01-01', '2020-12-31'\nstock = tejapi.get('TWN\/APRCD',\n                   paginate = True,\n                   coid = stock_id,\n                   mdate = {'gte':gte, 'lte':lte},\n                   opts = {\n                       'columns':[ 'mdate', 'coid', 'open_d', 'high_d', 'low_d', 'close_d', 'volume']\n                   }\n                  )<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter is-resized caption-align-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"unadjusted stock price table\" height=\"642\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1wWeTnUDXD__JDLL1eVZUbg.png\" style=\"width:800px;height:642px\" width=\"800\"\/><figcaption class=\"wp-element-caption\">unadjusted stock price table<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">Next, we transfer the table to the pivot table by coid(company id) and exclude the market index.<\/p>\n<pre class=\"wp-block-preformatted\"><code>data_pivot = pd.pivot_table(stock[stock.coid != \"Y9997\"], columns=\"coid\", index=\"mdate\")<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"pivot table\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1WH7KC3tTOs9il2qyg02JJg.png\"\/><figcaption class=\"wp-element-caption\">pivot table<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Trading Strategy<\/h2>\n<p class=\"wp-block-paragraph\">First of all, we need to declare the following arguments:<\/p>\n<ul class=\"wp-block-list\">\n<li>principal: The capital initially invested.<\/li>\n<li>cash: The cash position that we currently hold.<\/li>\n<li>order_unit: The trading unit of each transaction.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">Because today\u2019s demo is a multi-target trading strategy, we will use for loop to create a dictionary to retain the following info:<\/p>\n<ul class=\"wp-block-list\">\n<li>position: The stock position that we currently hold.<\/li>\n<li>invested_principal: The amount of principal that we invested.<\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">We use a list type object aroon_record to record each target\u2019s \u201ccoid\u201d, \u201cmdate\u201d, \u201cAroon-up\u201d, \u201cAroon-down\u201d.<br \/>Besides, to measure the eventual performance of our portfolio, we create two list-type objects\u200a-\u200adaily_stock_value_record and daily_cash_value_record to store each transaction day\u2019s \u201cholding position,\u201d \u201cstock value,\u201d and \u201cremaining cash value.\u201d<br \/>Now, it\u2019s time to design our trading signals.<\/p>\n<p class=\"wp-block-paragraph\"><strong>When Aroon Up is greater than 80 and Aroon Down is lesser than 45, which represents a bullish trend. We consider it a buying signal and will acquire one unit at tomorrow\u2019s opening price.<br \/>When Aroon Up is lesser than 45, Aroon Down is greater than 55, and the gap of two indicators is greater than 15, we regard it as a selling signal and sell the holding position at tomorrow\u2019s opening price.<br \/>When Aroon Up is greater than 55, Aroon Down is lesser 45, the gap between the two indicators is greater than 15, our invested amount isn\u2019t greater than 20% principal, and we still have plentiful cash. We will acquire one more unit at tomorrow\u2019s opening price.<\/strong><\/p>\n<pre class=\"wp-block-preformatted\"><code>def Aroon_strategy_multi(data_pivot, principal, cash, order_unit, n):\n    trade_book = pd.DataFrame() \n    aroon = pd.DataFrame(columns=[\"coid\", \"mdate\", \"AroonUp\", \"AroonDown\"])\n\n    daily_stock_value_record = []\n    daily_cash_value_record = []\n    \n    coid_dict = {}\n    for i in list(data_pivot.high_d.columns):\n        coid_dict.update({i:{\"position\":0, \"invested_principal\":0}})\n    \n    for ind in range(len(data_pivot.index) - n -1):\n        for col in data_pivot.high_d.columns:\n            high_period = data_pivot.high_d[col].iloc[ ind : ind+n].reset_index()\n            AroonUp = round((high_period.idxmax()[1] + 1)\/n*100)\n\n            low_period = data_pivot.low_d[col].iloc[ ind : ind+n].reset_index()\n            AroonDown = round(((low_period.idxmin()[1] + 1)\/n*100))\n            \n            \n            aroon = aroon.append({\n                \"coid\":col,\n                \"mdate\":data_pivot.index[ind+n],\n                \"AroonUp\":AroonUp,\n                \"AroonDown\":AroonDown,\n            }, ignore_index=True)\n            \n            n_time = data_pivot.index[ind+n+1]\n            n_open = data_pivot.open_d[col].iloc[ind+n+1]\n\n\n            if coid_dict.get(col).get(\"position\") == 0: #\u9032\u5834\u689d\u4ef6\n                if (AroonDown &lt; 45) and (AroonUp &gt; 80):\n                    position = coid_dict.get(col).get(\"position\")\n                    \n                    order_time = n_time\n                    order_price = n_open\n                    order_unit = 1\n                    friction_cost = (20 if order_price*1000*0.001425 &lt; 20 else order_price*1000*0.001425)\n                    total_cost = -1 * order_price * 1000 - friction_cost\n                    cash += total_cost\n                    \n                    coid_dict.update({col:{\"position\":position+1, \"invested_principal\":order_price * 1000,}})                    \n                    \n                    trade_book = pd.concat([trade_book,\n                                           pd.DataFrame([col, 'Buy', order_time, 0,  total_cost, order_unit, coid_dict.get(col).get(\"position\"), cash, order_price])],\n                                           ignore_index = True, axis=1)\n\n            elif coid_dict.get(col).get(\"position\") &gt; 0:\n                if (AroonDown - AroonUp) &gt; 15 and AroonDown &gt; 55 and AroonUp &lt; 45: # \u51fa\u5834\u689d\u4ef6\n                    order_unit = coid_dict.get(col).get(\"position\")\n                    cover_time = n_time\n                    cover_price = n_open\n                    friction_cost = (20 if cover_price*order_unit*1000*0.001425 &lt; 20 else cover_price*order_unit*1000*0.001425) + cover_price*order_unit*1000*0.003\n                    total_cost = cover_price*order_unit*1000-friction_cost\n                    cash += total_cost\n                    \n                    coid_dict.update({col:{\"position\":0, \"invested_principal\":0}})                    \n\n                    trade_book = pd.concat([trade_book,\n                                           pd.DataFrame([col, 'Sell', 0, cover_time,  total_cost, -1*order_unit, coid_dict.get(col).get(\"position\"), cash, cover_price])],\n                                           ignore_index = True, axis=1)\n\n                elif (AroonUp - AroonDown) &gt; 15 and (AroonDown &lt; 45) and AroonUp &gt; 55 and (cash &gt;= n_open*1000) and (coid_dict.get(col).get(\"invested_principal\") &lt;= 0.2 * principal): #\u52a0\u78bc\u689d\u4ef6\n                    order_unit = 1\n                    order_time = n_time\n                    order_price = n_open\n\n                    position = coid_dict.get(col).get(\"position\")\n\n                    friction_cost = (20 if order_price*1000*0.001425 &lt; 20 else order_price*1000*0.001425) \n                    total_cost = -1 * order_price * 1000 - friction_cost\n                    cash += total_cost\n                    \n                    invested_principal = coid_dict.get(col).get(\"invested_principal\")\n                    coid_dict.update({col:{\"position\":position+1, \"invested_principal\": invested_principal + order_price*1000}})                    \n\n                    trade_book = pd.concat([trade_book,\n                                           pd.DataFrame([col, 'Buy', order_time, 0, total_cost, order_unit, coid_dict.get(col).get(\"position\"), cash, order_price])],\n                                           ignore_index = True, axis=1)\n                    \n            daily_stock_value_record.append({\n                \"mdate\": n_time,\n                \"coid\":col,\n                \"position\":coid_dict.get(col).get(\"position\"),\n                \"stock_value\":coid_dict.get(col).get(\"position\") * data_pivot.close_d[col].iloc[ind+n+1] * 1000,\n            })\n        daily_cash_value_record.append(cash)\n\n    for col in data_pivot.high_d.columns:# \u6700\u5f8c\u4e00\u5929\u5e73\u5009\n\n        if coid_dict.get(col).get(\"position\") &gt; 0: \n            \n            high_period = data_pivot.high_d[col].iloc[ -n : -1].reset_index()\n            AroonUp = round((high_period.idxmax()[1] + 1)\/n*100)\n            low_period = data_pivot.low_d[col].iloc[ -n : -1].reset_index()\n            AroonDown = round(((low_period.idxmin()[1] + 1)\/n*100))\n            \n            order_unit = coid_dict.get(col).get(\"position\")\n            cover_price = data_pivot.open_d[col].iloc[-1]\n            cover_time = data_pivot.index[-1]\n            friction_cost = (20 if cover_price*order_unit*1000*0.001425 &lt; 20 else cover_price*order_unit*1000*0.001425) + cover_price*order_unit*1000*0.003\n            cash += cover_price*order_unit*1000-friction_cost\n            \n            coid_dict.update({col:{\"position\":0, \"invested_principal\": 0,}})                    \n\n            trade_book = pd.concat([trade_book,\n                                   pd.DataFrame([col, 'Sell',0, cover_time, cover_price*order_unit*1000-friction_cost, -1*order_unit, 0, cash, cover_price])],\n                                   ignore_index=True, axis=1)\n            \n            daily_stock_value_record.append({\n                \"mdate\": data_pivot.index[-1]+datetime.timedelta(days = 1),\n                \"coid\":col,\n                \"position\":coid_dict.get(col).get(\"position\"),\n                \"stock_value\":0,\n            })\n        \n    daily_cash_value_record.append(cash)\n    value_book = pd.DataFrame(daily_stock_value_record).set_index(\"mdate\")\n    value_book = pd.pivot_table(value_book, columns = \"coid\", index = \"mdate\")\n    value_book[\"cash_value\"] = daily_cash_value_record\n\n            \n    trade_book = trade_book.T\n    trade_book.columns = ['coid', 'BuyOrSell', 'BuyTime', 'SellTime', 'CashFlow','TradeUnit', 'HoldingPosition', 'CashValue', 'DealPrice']\n    trade_book['mdate'] = [trade_book.BuyTime[i] if trade_book.BuyTime[i] != 0 else trade_book.SellTime[i] for i in trade_book.index]\n    trade_book = trade_book.loc[:, ['coid', 'BuyOrSell', 'DealPrice', 'CashFlow', 'TradeUnit', 'HoldingPosition', 'CashValue' ,'mdate']]\n        \n    return trade_book, aroon, value_book, order_unit, n)<\/code><\/pre>\n<p class=\"wp-block-paragraph\">After confirming the trading signals and setting down the function\u2019s input and output, we can pass parameters into the Aroon_strategy_multi() and execute it.<\/p>\n<pre class=\"wp-block-preformatted\"><code>principal = 10e6\ncash = principal\norder_unit = 0\nn = 25\n\ndf, aroon, value = Aroon_strategy_multi(data_pivot, principal, cash, order_unit, n)<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Transaction Records<\/h2>\n<p class=\"wp-block-paragraph\">Aroon_strategy_multi() will output three sheets:<\/p>\n<ul class=\"wp-block-list\">\n<li>Transaction Sheet: Records details of each transaction, including transaction behavior, deal price, deal unit, etc.<\/li>\n<li>Aroon Indicators Sheet: Records every target\u2019s daily Aroon-up and Aroon-down.<\/li>\n<li>Portfolio Value Sheet: Records every target\u2019s daily holding position, daily stock value, and the portfolio\u2019s remaining cash value.<\/li>\n<\/ul>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"Transaction Sheet\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1TOEuGk3xeAeMyMMUABPPUQ.png\"\/><figcaption class=\"wp-element-caption\">Transaction Sheet<\/figcaption><\/figure>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"Aroon Indicators Sheet\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1uCODhWeJeMwTpz5RUaXE1Q.png\"\/><figcaption class=\"wp-element-caption\">Aroon Indicators Sheet<\/figcaption><\/figure>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"Portfolio Value Sheet\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/15KZX3XG0vxkRviAzXGgI5Q.png\"\/><figcaption class=\"wp-element-caption\">Portfolio Value Sheet<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Performance Assessment<\/h2>\n<p class=\"wp-block-paragraph\">Today\u2019s demo will be via the portfolio\u2019s moving Alpha and Beta to assess the portfolio\u2019s performance. To materialize it, first, we need to calculate the daily returns of the portfolio and market and then, respectively, store them in the new columns of the Portfolio Value Sheet.<\/p>\n<pre class=\"wp-block-preformatted\"><code>value[\"total_value\"] = value.apply(lambda x : x.sum(), axis = 1)\nvalue[\"daily_return\"] = value[\"total_value\"].pct_change(periods=1)\nvalue[\"market_return\"] = list(stock[stock.coid == \"Y9997\"][\"close_d\"].pct_change(periods = 1)[25:])\nvalue<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"calculation of daily returns\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1oBOfY9Uhomi-m9HyCJPEew.png\"\/><figcaption class=\"wp-element-caption\">calculation of daily returns<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">Next step, we will use \u201cdaily_return\u201d and \u201cmarket_return\u201d as input variables to fit the Linear Regression model to get Alpha and Beta.<\/p>\n<pre class=\"wp-block-preformatted\"><code>X = np.array(value[\"daily_return\"].iloc[1:]).reshape(-1, 1)\ny = np.array(value[\"market_return\"].iloc[1:])\nregressor = LinearRegression()\nregressor.fit(X, y)\nw_0 = regressor.intercept_\nw_1 = regressor.coef_\n\nprint('alpha : ', w_0)\nprint('beta : ', w_1)<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"Portfolio's Alpha and Beta\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1dU3RgLZDqEgpku7v3HxmFA.png\"\/><figcaption class=\"wp-element-caption\">Portfolio\u2019s Alpha and Beta<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">Let\u2019s set our window as 60 days, calculate moving Alpha and Beta, and visualize the result.<\/p>\n<pre class=\"wp-block-preformatted\"><code>window = 60\nalpha = []\nbeta = []\nmdate = []\nfor i in range(len(value) - window - 1):\n    X = np.array(value[\"daily_return\"].iloc[i+1 : i+1+window]).reshape(-1, 1)\n    y = np.array(value[\"market_return\"].iloc[i+1 : i+1+window])\n    regressor = LinearRegression()\n    regressor.fit(X, y)\n    w_0 = regressor.intercept_\n    w_1 = regressor.coef_\n    alpha.append(round(w_0, 5))\n    beta.append(w_1)\n    mdate.append(value.index[i+1+window])<\/code>\n<\/pre>\n<pre class=\"wp-block-preformatted\"><code>fig, ax1 = plt.subplots(figsize=[16, 9], constrained_layout=True)\nax1.plot(mdate, alpha, label = \"Alpha\")\nax1_2 = ax1.twinx()\nax1_2.plot(mdate, beta, label = \"Beta\", color = \"orange\")\n\nAlpha_lines, Alpha_labels = ax1.get_legend_handles_labels()\nBeta_lines, Beta_labels = ax1_2.get_legend_handles_labels()\nax1.legend(Alpha_lines + Beta_lines,\n           Alpha_labels + Beta_labels, loc='upper right')\n\nax1.set_xlabel('mdate')\nax1.set_ylabel('Alpha')\nax1_2.set_ylabel('Beta')<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"Moving Alpha &amp; Bate\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1GaJPwW652vDjuHnWTx3K3A.png\"\/><figcaption class=\"wp-element-caption\">Moving Alpha &amp; Bate\u00a0<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">For the more profound analysis, we draw two line charts to compare the difference between each target\u2019s and market trends and the variation of Aroon indicators during the backtesting period.<\/p>\n<pre class=\"wp-block-preformatted\"><code>def make_plot(stock_df, aroon_dict, record_df, coid):\n    # stock[\"mdate\"] = stock[\"mdate\"].apply(lambda x:x.strftime('%Y-%m-%d'))\n    mdate = stock[stock.coid == \"Y9997\"].mdate\n\n    benchmark = stock[stock.coid == \"Y9997\"].close_d\n\n    AroonUp = aroon[aroon.coid == coid].AroonUp\n    AroonDown = aroon[aroon.coid == coid].AroonDown\n    aroon_date = aroon[aroon.coid == coid].mdate\n\n    fig, axes = plt.subplots(2,1, figsize=[16, 9], constrained_layout=True)\n\n    ax1 = axes[0]\n    stock[stock.coid == \"Y9997\"].set_index(\"mdate\").close_d.plot(ax = ax1, label = \"market return\")\n    ax1_2 = ax1.twinx()\n    stock[stock.coid == coid].set_index(\"mdate\").close_d.plot(ax = ax1_2, label=f'{coid}_close', color = \"lime\")\n    stock[stock.coid == coid].set_index(\"mdate\").open_d.plot(ax = ax1_2, label=f'{coid}_open', color = \"deeppink\", alpha = 0.5)\n    ax1_2.scatter(df[df.coid == coid].mdate, df[df.coid == coid].DealPrice, label = \"BuyOrSell\", color = [\"orange\" if i == \"Buy\" else \"purple\" for i in df[df.coid == coid].BuyOrSell])\n\n    benchmark_lines, benchmark_labels = ax1.get_legend_handles_labels()\n    target_lines, target_labels = ax1_2.get_legend_handles_labels()\n\n    ax1.legend(benchmark_lines + target_lines,\n               benchmark_labels + target_labels, loc='upper right')\n    ax1.set_xlabel('mdate')\n    ax1.set_ylabel('index')\n    ax1_2.set_ylabel(f'price')\n    ax1.set_title(f\"{coid}_Aroon\")\n\n    ax2 = axes[1]\n    aroon[aroon.coid == coid].set_index(\"mdate\").AroonUp.plot(ax = ax2, label = \"AroonUp\", color = \"red\")\n    ax2_2 = ax2.twinx()\n    aroon[aroon.coid == coid].set_index(\"mdate\").AroonDown.plot(ax = ax2_2, label = \"AroonDown\", color = \"green\")\n\n    up_lines, up_labels = ax2.get_legend_handles_labels()\n    down_lines, down_labels = ax2_2.get_legend_handles_labels()\n\n    ax2.legend(down_lines + down_lines,\n               up_labels + down_labels, loc='upper right')\n    ax2.set_xlabel('mdate')\n    ax2.set_ylabel('Aroon_indicator')\n\n    fig.tight_layout()\n\n    plt.show()<\/code><\/pre>\n<p class=\"wp-block-paragraph\">We can easily generate each target\u2019s charts by using for loop.<br \/>Please note that because the last item of stock.coid.unique() is the market\u2019s id \u201cY9997,\u201d our range of for loop would not contain the last item.<\/p>\n<pre class=\"wp-block-preformatted\"><code>for coid in stock.coid.unique()[:-1]:\n    make_plot(stock, aroon, value, coid)<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"2330 \u8996\u89ba\u5316\u5716\u8868\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/1xRcRoGZKIEWaUYu18vXybw.png\"\/><figcaption class=\"wp-element-caption\">2330 \u8996\u89ba\u5316\u5716\u8868<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">In the first chart, the blue line is the market index, the green line is the target\u2019s closing price, and the pink line is the opening price. And the yellow points are the buying points, and the purple points are the selling points.<br \/>In the second chart, the red line is the Aroon-up indicator, and the green line is the Aroon-down indicator.<\/p>\n<h2 class=\"wp-block-heading\">Compare the Portfolio Performance with Market Performance<\/h2>\n<p class=\"wp-block-paragraph\">While calculating the portfolio performance and market performance, we find out that the former\u2019s return transcends the latter\u2019s return about 17 percent.<\/p>\n<pre class=\"wp-block-preformatted\"><code>print(f'\u5927\u76e4\u7e3d\u7e3e\u6548\uff1a{stock[stock.coid == \"Y9997\"].close_d.iloc[-1]\/stock[stock.coid == \"Y9997\"].close_d.iloc[0] -1}')\nprint(f'\u6295\u8cc7\u7d44\u5408\u7e3d\u7e3e\u6548\uff1a{value[\"total_value\"].iloc[-1]\/value[\"total_value\"].iloc[0] -1}')<\/code><\/pre>\n<figure class=\"wp-block-image aligncenter caption-align-center\"><img decoding=\"async\" alt=\"Compare the Portfolio Performance with Market Performance\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/19dYDJWJTObmHus2E8o9Zmg.png\"\/><figcaption class=\"wp-element-caption\">Compare the Portfolio Performance with Market Performance<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n<p class=\"wp-block-paragraph\">Through the chart of Moving Alpha &amp; Beta, we can conclude that our strategy is arguably conservative. Its fluctuation of Alpha and Beta are both mild; On the other hand, each target\u2019s own buying and selling points are clearly seen by each target\u2019s first chart. So we can analyze which target in the portfolio is the backbone of profit. Furthermore, investors can freely adjust or customize the Aroon indicators trading strategy in accordance with their own stock-picking strategy to fulfill a one-stop system from stock picking and automated trading to performance assessing.<\/p>\n<p class=\"wp-block-paragraph\">Last but not least, please note that \u201cStocks this article mentions are just for the discussion, please do not consider it to be any recommendations or suggestions for investment or products.\u201d Hence, if you are interested in issues like Creating Trading Strategy\u00a0, Performance Backtesting\u00a0, Evidence-based research\u00a0, welcome to purchase the plans offered in TEJ E Shop and use the well-complete database to create your own optimal trading strategy.<\/p>\n<h2 class=\"wp-block-heading\">Source Code<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/gist.github.com\/tej87681088\/f9e30259b1f28d06422f9160fbbe1515\" rel=\"noopener\" target=\"_blank\">Click here to go  Github<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Extended Reading<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/www.tejwin.com\/wp-admin\/post.php?post=14364&amp;action=edit&amp;lang=en\">How to avoid common mistakes during trading \u2013 Loss Avoidance<\/a><\/li>\n<li><a href=\"https:\/\/www.tejwin.com\/wp-admin\/post.php?post=12869&amp;action=edit&amp;lang=en\">Options Pricing with Monte Carlo Simulation<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Related Link<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/medium.com\/r\/?url=https%3A%2F%2Fapi.tej.com.tw%2Findex.html\" rel=\"noopener\" target=\"_blank\">TEJ API<\/a><\/li>\n<li><a aria-label=\"TEJ E-Shop \u5b8c\u6574\u8cc7\u6599\u5eab\u8cfc\u8cb7 (opens in a new tab)\" class=\"ek-link\" href=\"https:\/\/eshop.tej.com.tw\/E-Shop\/Edata_intro\" rel=\"noreferrer noopener\" target=\"_blank\">TEJ E-Shop<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Oscillator Technical Indicator is a technical indicator used in the financial market analysis for assessing the over-bought\/over-sold of a given asset in a given period. It can assist investors in identifying trends and potential trend reversals.<br \/>\nOscillator Technical Indicator processes and converts specific price indicators (e.g., opening, closing, highest, and lowest price) in a limited range. Some may include a negative range. Oscillator Technical Indicators are normally presented in a linear format.<br \/>\nToday, we are going to introduce an Oscillator Technical Indicator\u200a\u2014\u200aAroon Up Down.<\/p>\n","protected":false},"featured_media":1872,"template":"","tags":[65,70,71,50],"insight_category":[13],"class_list":["post-1883","insight","type-insight","status-publish","has-post-thumbnail","hentry","tag-python","tag-tej-api","tag-quantitative-strategy","tag-market-data","insight_category-quant-research"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight\/1883","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\/1872"}],"wp:attachment":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/media?parent=1883"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/tags?post=1883"},{"taxonomy":"insight_category","embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight_category?post=1883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}