{"id":1527,"date":"2024-05-10T13:00:00","date_gmt":"2024-05-10T13:00:00","guid":{"rendered":"https:\/\/www.tejwin.com\/en\/insights\/williams-r-2\/"},"modified":"2024-05-10T13:00:00","modified_gmt":"2024-05-10T13:00:00","slug":"williams-r-2","status":"publish","type":"insight","link":"https:\/\/www.tejwin.com\/en\/insights\/williams-r-2\/","title":{"rendered":"TQuant Lab Williams %R, \u00a0looking for stock price turning points"},"content":{"rendered":"<figure class=\"wp-block-image aligncenter size-full caption-align-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"Williams %R\" class=\"wp-image-23217\" height=\"980\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/image-425.png\" style=\"aspect-ratio:1.5;object-fit:cover\" width=\"1470\"\/><figcaption class=\"wp-element-caption\">Photo by <a class=\"ek-link\" href=\"https:\/\/unsplash.com\/@m_____me?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash\" rel=\"noopener\" target=\"_blank\">m.<\/a> on <a class=\"ek-link\" href=\"https:\/\/unsplash.com\/photos\/selective-focus-photography-of-graph-ZzOa5G8hSPI?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash\" rel=\"noopener\" target=\"_blank\">Unsplash<\/a><\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\"><strong>Highlight<\/strong><\/h2>\n<ul class=\"wp-block-list\">\n<li>Difficulty\uff1a\u2605\u2605\u2606\u2606\u2606<\/li>\n<li>Introduce Williams %R and indicator entry timing.<\/li>\n<li>Use the TQuant Lab backtesting platform to write Williams %R strategies and backtest risk and performance.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\"><strong>Introduction<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">The Williams %R is also called the Williams index, wmsr, or W%R. It was created by the famous American trader Larry Williams in 1973. It is a standard indicator in technical analysis.<\/p>\n<p class=\"wp-block-paragraph\">The William indicator is the earliest indicator to judge whether the market price is overbought or oversold. The KD line and other indicators commonly used by investors to judge overbought or oversold are developed based on the William indicator.<\/p>\n<p class=\"wp-block-paragraph\">The Williams %R is calculated as follows:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>(Highest price on N days \u2013 closing price) \u00f7 (Highest price on N days \u2013 lowest price on N days) \u00d7 100% \u00d7 (-1)<\/strong><\/li>\n<\/ul>\n<p class=\"wp-block-paragraph\">According to the above formula, it can be known that the value of the Williams %R ranges from 0 to -100. When the indicator\u2019s value is between 0 and -50, the stock price is in a strong stage; when the indicator\u2019s value falls between -51 and -100, the stock price is in a weak stage. In addition, when the indicator value is less than -80, it means that the stock price may be in an oversold state, which is a good time to buy; and when the indicator value is greater than -20, it means that the stock price may be in an overbought state, and it is a good time to sell.<\/p>\n<p class=\"wp-block-paragraph\">In addition, the time parameters of the Williams %R have a considerable impact on it, so investors need to set parameters that suit them according to their habits.<\/p>\n<h2 class=\"wp-block-heading\">Williams %R strategy<\/h2>\n<p class=\"wp-block-paragraph\">This article uses the Williams %R to determine the timing of overbought and oversold stocks. It uses the following entry and exit rules to establish a trading strategy and perform backtesting:<\/p>\n<p class=\"wp-block-paragraph\">Buy the stock when the Williams %R \u2264 -80 because the market is too cold and the stock is in the oversold stage.<\/p>\n<p class=\"wp-block-paragraph\">When the Williams %R \u2265 -20, sell the stock because the market is overheated and the stock is in the overbought stage.<\/p>\n<p class=\"wp-block-paragraph\">In addition, this article sets the N value to 100 days instead of the more common pane used in calculating the Williams %R. Finally, the 14 days often used in the industry will be used for backtest comparison.<\/p>\n<h2 class=\"wp-block-heading\"><strong>Editing Environment and Module Requirements<\/strong>\u00a0<\/h2>\n<p class=\"wp-block-paragraph\">This article uses Windows 11 and Jupyter Notebook as the editor.<\/p>\n<h2 class=\"wp-block-heading\">Data Import<\/h2>\n<p class=\"wp-block-paragraph\">This strategy lasts for three years, from 2021-01-01 to 2023-12-31, focusing on electronics stocks: Hon Hai Precision (2317), Yageo (2327), TSMC (2330), Acer (2353), Asus (2357), and Quanta (2382) are used as examples, and the return index (IR0001) is used as the broader market for performance comparison.<\/p>\n<pre class=\"wp-block-code\"><code>import os\nos.environ['TEJAPI_KEY'] = \"your key\" \nos.environ['TEJAPI_BASE'] = \"https:\/\/api.tej.com.tw\"\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom zipline.data import bundles\nfrom zipline.utils.calendar_utils import get_calendar\nfrom zipline.sources.TEJ_Api_Data import get_Benchmark_Return\n\nstart = '2021-01-01'\nend = '2023-12-31'\n\nos.environ['ticker'] = 'IR0001 2317 2327 2330 2353 2357 2382'\nos.environ['mdate'] = start+' '+end\n!zipline ingest -b tquant<\/code><\/pre>\n<h2 class=\"wp-block-heading\"><strong>Creating Pipeline Function<\/strong><\/h2>\n<h3 class=\"wp-block-heading\"><strong>Creating Custom Factor<\/strong><\/h3>\n<p class=\"wp-block-paragraph\">CustomFactor allows users to design the required customization factors. In this case, we use it to handle:<\/p>\n<ul class=\"wp-block-list\">\n<li>Williams %R (Wmsr)<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>from zipline.data import bundles\nfrom zipline.sources.TEJ_Api_Data import get_Benchmark_Return\nfrom zipline.pipeline.mixins import SingleInputMixin\nfrom zipline.pipeline.data import TWEquityPricing\nfrom zipline.pipeline.factors import CustomFactor\nfrom zipline.pipeline import Pipeline\nfrom zipline.TQresearch.tej_pipeline import run_pipeline\nfrom zipline.pipeline.filters import StaticAssets\nfrom zipline.utils.math_utils import nanmax, nanmin\n\nclass Wmsr(CustomFactor):\n    inputs = [TWEquityPricing.close, TWEquityPricing.high, TWEquityPricing.low]\n    window_length = 100\n    \n    def compute(self, today, assets, out, close, high, low):\n        highest_highs = nanmax(high, axis=0)\n        lowest_lows = nanmin(low, axis=0)\n        williams_index = ((highest_highs - close[-1]) \/ (highest_highs - lowest_lows)) * 100 * -1\n        \n        out[:] = williams_index<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Pipeline() provides users with the function of quickly processing multiple targets\u2019 quantitative indicators and price and volume data. In this case, we use it to process:<\/p>\n<p class=\"wp-block-paragraph\">The current stock price of the stock (curr_price)<\/p>\n<pre class=\"wp-block-code\"><code>start_dt, end_dt = pd.Timestamp(start, tz='utc'), pd.Timestamp(end, tz='utc')\nbundle = bundles.load('tquant')\nbenchmark_asset = bundle.asset_finder.lookup_symbol('IR0001',as_of_date = None)\n\ndef make_pipeline():\n    wmsr = Wmsr()\n    curr_price = TWEquityPricing.close.latest\n    \n    return Pipeline(\n        columns = {\n            'curr_price':curr_price,\n            'Williams_index' : wmsr,\n        },\n        screen = ~StaticAssets([benchmark_asset])\n    )\nmy_pipeline = run_pipeline(make_pipeline(),start_dt, end_dt)\nmy_pipeline.tail(20)<\/code><\/pre>\n<figure class=\"wp-block-image size-full caption-align-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"Williams %R\" class=\"wp-image-23200\" height=\"720\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/E7B0A1E5A0B11.jpg\" width=\"1280\"\/><figcaption class=\"wp-element-caption\">Pipeline partial data<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\"><strong>Creating Initialize Function<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">The initialize() function is used to define the daily trading environment before the start of trading. In this example, we set:<\/p>\n<ul class=\"wp-block-list\">\n<li>Slippage costs<\/li>\n<li>Transaction costs model for the Taiwan stock market<\/li>\n<li>Weighted return index (<em>IR0001<\/em>) as the benchmark<\/li>\n<li>Import the Williams %R designed by Pipeline into the trading process<\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>from zipline.finance import slippage, commission\nfrom zipline.api import *\nfrom zipline.api import set_slippage, set_commission, set_benchmark, attach_pipeline, order, order_target, symbol, pipeline_output, record\n\ndef initialize(context):\n    set_slippage(slippage.VolumeShareSlippage(volume_limit = 0.025, price_impact = 0.1))\n    set_commission(commission.Custom_TW_Commission(min_trade_cost = 20, discount = 1.0, tax = 0.003))\n    attach_pipeline(make_pipeline(), 'mystrats')\n    set_benchmark(symbol('IR0001'))<\/code><\/pre>\n<h2 class=\"wp-block-heading\"><strong>Creating Handle_data Function<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">The <strong><code>handle_data()<\/code><\/strong> function is important for constructing the Williams %R strategy. It is called every day after the start of backtesting, and its main tasks include setting trading strategies, placing orders, and recording trading information.<\/p>\n<ul class=\"wp-block-list\">\n<li><span data-preserver-spaces=\"true\" style=\"font-size: revert; color: initial;\">When Williams %R \u2264 -80 and current funds \u2265 current\u00a0price of the stock\u00a0* 1000, buy the stock.<\/span><\/li>\n<li><span data-preserver-spaces=\"true\" style=\"font-size: revert; color: initial;\">When Williams %R \u2265 -20, sell holdings.<\/span><\/li>\n<\/ul>\n<pre class=\"wp-block-code\"><code>def handle_data(context, data):\n    out_dir = pipeline_output('mystrats')\n    \n    for i in out_dir.index:\n        curr_price = out_dir.loc[i, 'curr_price']\n        w_value = out_dir.loc[i, 'Williams_index']\n        stock_position = context.portfolio.positions[i].amount\n        cash_position = context.portfolio.cash\n\n        if stock_position == 0 and cash_position &gt;= curr_price * 1000:\n            if w_value &lt;= -80:\n                order(i, 1000)\n        elif stock_position &gt; 0:\n            if w_value &lt;= -80 and cash_position &gt;= curr_price * 1000:\n                order(i, 1000)\n                \n            elif w_value &gt;= -20:\n                order_target(i, 0)<\/code><\/pre>\n<h2 class=\"wp-block-heading\"><strong>Executing Trading Strategy<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">Use the <code><strong>run_algorithm()<\/strong><\/code> function to execute the Williams %R strategy as defined above. Set the trading period from start_dt (2021-01-01) to end_dt (2023-12-31), using the dataset tquant, with an initial capital of 20 million dollars. The output results represent the daily performance and trade details.<\/p>\n<pre class=\"wp-block-code\"><code>from zipline import run_algorithm\n\nstart_date = pd.Timestamp('2021-01-01',tz='utc')\nend_date = pd.Timestamp('2023-12-31',tz='utc')\n\nresults = run_algorithm(start = start_date,  \n                        end = end_date,\n                        initialize = initialize,                      \n                        capital_base = 1e7,                      \n                        handle_data = handle_data,\n                        data_frequency = 'daily',\n                        bundle = 'tquant'\n                        )\nresults<\/code><\/pre>\n<figure class=\"wp-block-image size-full caption-align-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"Williams %R\" class=\"wp-image-23202\" height=\"720\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/E7B0A1E5A0B12.jpg\" width=\"1280\"\/><figcaption class=\"wp-element-caption\">Backtest Details<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Evaluating performance using\u00a0Pyfolio<\/h2>\n<pre class=\"wp-block-code\"><code>import pyfolio as pf\nfrom pyfolio.utils import extract_rets_pos_txn_from_zipline\n\nreturns, positions, transactions = pf.utils.extract_rets_pos_txn_from_zipline(results)\nbenchmark_rets = results.benchmark_return\n\n# Creating a Full Tear Sheet\npf.create_full_tear_sheet(returns, positions = positions, transactions = transactions,\n                          benchmark_rets = benchmark_rets,\n                          round_trips=False)<\/code><\/pre>\n<figure class=\"wp-block-image size-full caption-align-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"Williams %R\" class=\"wp-image-23204\" height=\"720\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/E7B0A1E5A0B13.jpg\" style=\"object-fit:cover\" width=\"1280\"\/><figcaption class=\"wp-element-caption\">Backtest Performance &amp; Benchmark Comparison Chart \uff08100 days\uff09<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">In these 34 months, the Williams %R strategy obtained an annualized return of 11.696%, with a cumulative return of 37.708%. The profit performance was generally slightly better than the market; however, the annualized volatility and maximum drawdown were 18.221% and -34.638% respectively, showing that the risk of market fluctuations using the Williams %R strategy is more significant. When used, because the fluctuations are too large, it is impossible to rely solely on the Williams %R for quantitative trading. It can be combined with the <a class=\"ek-link\" href=\"\/en\/insight\/tquant-lab-ichimoku-kinko-hyo\/\">TQuant Lab Ichimoku Kinko Hyo Strategy, A Self-contained Technical Analysis Indicator<\/a> in the previous article, a set of self-contained technical analysis indicators such as the moving index loss or the moving average. The method matches the Williams %R to increase the stability of investment.<\/p>\n<figure class=\"wp-block-image size-full caption-align-center\"><img loading=\"lazy\" decoding=\"async\" alt=\"Williams %R\" class=\"wp-image-23214\" height=\"720\" src=\"https:\/\/www.tejwin.com\/en\/wp-content\/uploads\/2026\/08\/E7B0A1E5A0B14-2.jpg\" width=\"1280\"\/><figcaption class=\"wp-element-caption\">Backtest Performance &amp; Benchmark Comparison Chart\uff0814 days\uff09<\/figcaption><\/figure>\n<p class=\"wp-block-paragraph\">This chart only changes the time parameter and shows that the Williams %R time parameter has a huge impact. Since the Williams %R is more sensitive to price than other technical indicators, if you only follow the fast-line (short-day) Williams %R, buying and selling may be performed too frequently, leading to misjudgments.<\/p>\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n<p class=\"wp-block-paragraph\">This strategy uses the Williams %R to conduct backtest simulations, using the indicator to enter the market when it is oversold and exit when it is overbought. The backtest results show that investors sometimes get more rewards compared to the broader market, but investors will bear the excessive market pressure. Fluctuation risk and time parameters have a huge impact on indicators. Therefore, investors must pay attention to their habits and adjust them to suitable parameters when investing. Also, note that the Williams %R is only a technical indicator and should be combined with other auxiliary judgments when investing to increase the stability and reliability of the investment.<\/p>\n<p class=\"wp-block-paragraph\">In the future, I will continue to introduce various indicators constructed using the TEJ database and backtest their performance. Therefore, readers interested in trading backtests are encouraged to explore <a class=\"ek-link\" href=\"https:\/\/tquant.tejwin.com\/\" rel=\"noopener\" target=\"_blank\"><strong>TQuant Lab<\/strong><\/a>\u2018s related solutions, utilizing high-quality databases to build their trading strategies.<\/p>\n<p class=\"wp-block-paragraph\"><strong>A friendly reminder:<\/strong>\u00a0This strategy is for reference only and does not constitute any recommendation for commodities or investments.<\/p>\n<div style=\"border: 1px black; border-style: solid none; text-align: center; border-color: #296580; padding: 24px; margin-top: 24px; margin-bottom: 24px;\">\n<p style=\"margin: 0px; font-size: 24px; font-weight: bold; line-height: 1.5;\">[TQuant Lab] Solving Your Quantitative Finance Pain Points<\/p>\n<p style=\"margin: 0px; font-size: 24px; font-weight: bold; line-height: 1.5;\">Comprehensively providing all the tools needed for trading backtesting.<\/p>\n<div style=\"margin-top: 32px;\"><a href=\"https:\/\/tquant.tejwin.com\/\" rel=\"noopener\" style=\"border: none; border-radius: 4px; background-color: #296580; color: white; font-size: 20px; width: fit-content; text-decoration: none; padding: 12px 30px 12px 30px;\" target=\"_blank\">Register and Start Your Trial<\/a><\/div>\n<\/div>\n<h2 class=\"wp-block-heading\">Source Code<\/h2>\n<p class=\"wp-block-paragraph\"><a class=\"ek-link\" href=\"https:\/\/github.com\/tejtw\/TEJAPI_Python_Medium_Application\/blob\/1738f739afc13449042dfa55ee58587d159f9fd4\/%E5%A8%81%E5%BB%89%E6%8C%87%E6%A8%99.ipynb\" rel=\"noopener\" target=\"_blank\"><\/a><a class=\"ek-link\" href=\"https:\/\/github.com\/tejtw\/TEJAPI_Python_Medium_Application\/blob\/1738f739afc13449042dfa55ee58587d159f9fd4\/%E5%A8%81%E5%BB%89%E6%8C%87%E6%A8%99.ipynb\" rel=\"noopener\" target=\"_blank\">Click here to Github<\/a><\/p>\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\/insight\/esg-etf\/\"><\/a><a class=\"ek-link\" href=\"https:\/\/www.tejwin.com\/wp-admin\/post.php?post=22962&amp;action=edit&amp;lang=en&amp;update_needed=1&amp;trid=328125&amp;language_code=en\"><\/a><a class=\"ek-link\" href=\"\/en\/insight\/tquant-lab-ichimoku-kinko-hyo\/\">TQuant Lab Ichimoku Kinko Hyo Strategy, A Self-contained Technical Analysis Indicator<\/a><\/li>\n<li><a class=\"ek-link\" href=\"https:\/\/www.tejwin.com\/insight\/tquant-lab-kd-%e6%8c%87%e6%a8%99%e7%ad%96%e7%95%a5\/\"><\/a><a class=\"ek-link\" href=\"https:\/\/www.tejwin.com\/wp-admin\/post.php?post=22519&amp;action=edit&amp;lang=en&amp;update_needed=1&amp;trid=328047&amp;language_code=en\">TQuant Lab KD Indicator Strategy: Exploring Stock Price Reversal Timing?<\/a><\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">About<\/h2>\n<ul class=\"wp-block-list\">\n<li><a class=\"ek-link\" href=\"https:\/\/github.com\/tejtw\/TQuant-Lab\" rel=\"noreferrer noopener\" target=\"_blank\">TQuant Lab Github<\/a><\/li>\n<li><a class=\"ek-link\" href=\"https:\/\/tquant.tejwin.com\/\" rel=\"noopener\" target=\"_blank\">TQuant Lab Home Page<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This time, the Williams %R  strategy was used for backtesting. The Williams indicator is also called the Williams index, wmsr, or W%R. Its English name is The Williams Percent Range. It was created by the famous American trader Larry Williams in 1973. It is a standard indicator in technical analysis. One. The KD line and other indicators commonly used by investors to judge overbought or oversold are developed based on the William indicator.<\/p>\n","protected":false},"featured_media":1522,"template":"","tags":[59,65,100],"insight_category":[16],"class_list":["post-1527","insight","type-insight","status-publish","has-post-thumbnail","hentry","tag-backtesting","tag-python","tag-quantitative-trading","insight_category-quant-data-science"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight\/1527","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\/1522"}],"wp:attachment":[{"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/media?parent=1527"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/tags?post=1527"},{"taxonomy":"insight_category","embeddable":true,"href":"https:\/\/www.tejwin.com\/en\/wp-json\/wp\/v2\/insight_category?post=1527"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}