Introduction

Alvin Tan created interesting Noteboook, which is partly used in this presentation. The Investopedia information source is also used. In addition, a Bookdown of Technical Analysis with R (second edition) from Ko Chiu Yu and ChatGPT were helpful with the coding in R.

Technical analysis is a method to predict price movement in the financial markets. Unlike the usual balance sheet analysis (fundamental investing), technical analysis estimates the value of a given stock using underlying trends of the price movement. The core assumption behind this method is that the fundamentals (information from financial statements) were factored into the price fluctuation, hence, detecting the patterns and signals from the fluctuation should provide sufficient indicator for future performance.

For this project, we are going to explore some of the common technical indicators using the TQQQ Exchange trade fund (ETF) stock. Among leveraged ETFs, ProShares UltraPro QQQ (TQQQ) is one of the largest with assets under management of \(\$18.56\) billion as of July 2022. TQQQ is also one of the more heavily traded leveraged ETFs in the U.S. with an average daily volume of \(\$5.29\) billion (compared with QQQ’s \(\$21\) billion).

TQQQ carries an expense ratio of 0.95%.

#install.packages("quantmod")
Warning messages:
1: In normalizePath(quartoSrcFile, winslash = "/") :
  path[1]="": No such file or directory
2: In normalizePath(quartoSrcFile, winslash = "/") :
  path[1]="": No such file or directory
3: In normalizePath(quartoSrcFile, winslash = "/") :
  path[1]="": No such file or directory
#install.packages("data.table")
#install.packages("ggplot2")
#install.packages("tidyquant")
library(quantmod)
library(data.table)
library(ggplot2)
library(tidyquant)  

Data Extraction & Manipulation, Data structure

TQQQ data is extracted using the getSymbols function from Yahoo Finance. Alternatively, the source can be replaced with FRED, MySQL, Google, or others. The data extracted should be in an ‘xts’ object - a format commonly used in time series analysis where observations are recorded in a matrix structure with an index of corresponding time.

Technically, analysis can be done in xts format alone, but for the sake of simplicity, data is converted into a standard dataframe and index column is renamed as “Date’. The end result is shown as below:

getSymbols('AAPL',src = 'yahoo')       ## change TQQQ ticker to Your ticker symbol
[1] "AAPL"

structure of the stock data

stock <<- as.data.table(AAPL)        ###### change TQQQ ticker to Your ticker symbol  #########
names(stock)[1] <- c('Date')

tail(stock)

I used Apple as the basis for my analysis, whose code was AAPL. In my analysis, I selected 2 different charts, one was “Interpretation of the HLCO graph” and the other was “Price - Moving Average”, the last graph.

Interpretation of the HLCO graph

In finance, HLCO graph is a type of financial chart that plots the high, low, close, and open prices for a given period of time. The HLCO chart is similar to a candlestick chart, but it includes the open price in addition to the high, low, and close prices.

The interpretation of an HLCO chart can provide insights into the price action of a security during a given period of time. Here is a brief explanation of how to interpret each component of an HLCO chart:

  1. High: The top of the vertical line represents the highest price reached during the given period. This shows the highest price that buyers were willing to pay for the security during the period.

  2. Low: The bottom of the vertical line represents the lowest price reached during the given period. This shows the lowest price that sellers were willing to accept for the security during the period.

  3. Close: The horizontal line to the right of the vertical line represents the closing price for the period. This shows the final price at which the security traded during the period.

  4. Open: The horizontal line to the left of the vertical line represents the opening price for the period. This shows the initial price at which the security traded during the period.

By looking at the patterns of the high, low, close, and open prices in an HLCO chart, traders and investors can gain insight into the overall trend and sentiment of the market for the given security. For example, a long green candlestick with a high close and low open may indicate bullish sentiment, while a long red candlestick with a low close and high open may indicate bearish sentiment.

# feel free to change "HLCO" to "candlestick" or to some other types ("lines", "auto"). 
chartSeries(stock, subset='2020-01-01::2020-09-23', type = "candlesticks", bar.type = "ohlc",theme=chartTheme('white'))

The trading session lasted from January 2 to September 23, 2020. After the opening, Apple’s stock was valued around $75 million, and in the following periods it began to rise slightly, reaching over $80 million in mid-to-late February. From the beginning of March, the price began to fluctuate continuously, as a result of which the share price fell to around 50 million by the end of March and reached its lowest point. After that, there is stagnation again, but at the same time a continuous rise can be seen until the end of July, where the exchange rate falters again and a slight decrease can be seen, but from mid-August it starts to rise again, reaching a high point of almost $ 140 million by the beginning of September. It then stagnates again and closes at around $110 million.

Volume

One of the most common basic indicators traders examine is the trading volume. Trading volume is an indication for the ‘activeness’ of a financial instrument. Depending on the financial instruments, trading volume can be measured either using the number of stocks traded or number of contracts with changed ownerships. To put this in practice, if an increase in volume is observed with a steady increase in price, the instrument can be viewed as steady and strong. However, if volume and price are changing in different directions, a reversal might be happened.

You can analyze it in the previous picture.

Price - Moving Average

chartSeries(stock,
            subset='2020-01-01::2020-09-23', type = "candlestick",
            theme=chartTheme('white'))

addSMA(n = 12, on = 1, with.col = Cl, overlay = TRUE, col = "brown")

addSMA(n = 24, on = 1, with.col = Cl, overlay = TRUE, col = "blue")

NA
NA

My other analysis is Moving Average. This is a stock indicator that is often used in technical analysis. This trading session also runs from January 2nd to August 23rd, 2020. After opening, stagnation can be seen in the market. Towards mid-February, the blue line crosses the red line and trading clearly enters a bear market. This lasts until April, when the negative moving average also crosses with the positive and enters the bull market for trading. After that, the market stagnates and starts to rise to the end of July. Here it peaks, and by the end of September the bear market re-enters and start to decline. Here we can optionally see a backtest or a further decrease, but this is no visible from the graph. However, I looked it up on the tradingview.com site, I already see that this was a backtesting and there is further growth.

Moving Average Convergence Divergence (MACD)

chartSeries(stock,
            subset='2020-01-01::2020-09-23', type = "bars",
            theme=chartTheme('white'))

addMACD(fast=12,slow=26,signal=9,type="EMA")

Bollinger Band

chartSeries(stock,
            subset='2020-01-01::2020-09-23', type = "bars",
            theme=chartTheme('white'))

addBBands(n = 20, sd = 2, maType = "SMA", draw = 'bands', on = -1)

Relative Strength Index (RSI)

chartSeries(stock,
            subset='2020-01-01::2020-09-23', type = "bars",
            theme=chartTheme('white'))

addRSI(n = 14, maType = "EMA", wilder = TRUE)

Parabolic stop and reversal

chartSeries(stock,
            subset='2020-01-01::2020-09-23', type = "bars",
            theme=chartTheme('white'))

addSAR(accel = c(0.02, 0.2), col = "blue")

NA
NA

Summary graphs

Apart from the few that was mentioned above, other indicators include rate of change, money flow index (MFI), MACD and etc.

Chart Series

ChartSeries provides an alternative way to summarise the plot. Instead of one plot for each indicator, all of them can now be compiled into a single figure, where indicators can be added to the bottom of the existing plot.

chartSeries(stock,
            subset='2020-01-01::2020-09-23', type = "bars",
            theme=chartTheme('white'))

addBBands(n=20,sd=2)

addRSI(n=14,maType="EMA")

addMACD(fast=12,slow=26,signal=9,type="EMA")

My analyses may not be accurate, but I tried to solve this task based on my previous knowledge, and I really enjoyed this assignment.

LS0tCnRpdGxlOiAiVGVjaG5pY2FsIGFuYWx5c2lzIGluIFIiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KCiMjIEludHJvZHVjdGlvbgoKQWx2aW4gVGFuIGNyZWF0ZWQgaW50ZXJlc3RpbmcgW05vdGVib29va10oaHR0cDovL3JwdWJzLmNvbS96aGVzaHVlbi82NjU2MTYpLCB3aGljaCBpcyBwYXJ0bHkgdXNlZCBpbiB0aGlzIHByZXNlbnRhdGlvbi4gVGhlIFtJbnZlc3RvcGVkaWFdKGh0dHBzOi8vd3d3LmludmVzdG9wZWRpYS5jb20vKSBpbmZvcm1hdGlvbiBzb3VyY2UgaXMgYWxzbyB1c2VkLiBJbiBhZGRpdGlvbiwgYSBCb29rZG93biBvZiBbVGVjaG5pY2FsIEFuYWx5c2lzIHdpdGggUiAoc2Vjb25kIGVkaXRpb24pIGZyb20gS28gQ2hpdSBZdV0oaHR0cHM6Ly9ib29rZG93bi5vcmcva29jaGl1eXUvdGVjaG5pY2FsLWFuYWx5c2lzLXdpdGgtci1zZWNvbmQtZWRpdGlvbjIvKSAgYW5kIENoYXRHUFQgd2VyZSBoZWxwZnVsIHdpdGggdGhlIGNvZGluZyBpbiBSLgoKVGVjaG5pY2FsIGFuYWx5c2lzIGlzIGEgbWV0aG9kIHRvIHByZWRpY3QgcHJpY2UgbW92ZW1lbnQgaW4gdGhlIGZpbmFuY2lhbCBtYXJrZXRzLiBVbmxpa2UgdGhlIHVzdWFsIGJhbGFuY2Ugc2hlZXQgYW5hbHlzaXMgKGZ1bmRhbWVudGFsIGludmVzdGluZyksIHRlY2huaWNhbCBhbmFseXNpcyBlc3RpbWF0ZXMgdGhlIHZhbHVlIG9mIGEgZ2l2ZW4gc3RvY2sgdXNpbmcgdW5kZXJseWluZyB0cmVuZHMgb2YgdGhlIHByaWNlIG1vdmVtZW50LiBUaGUgY29yZSBhc3N1bXB0aW9uIGJlaGluZCB0aGlzIG1ldGhvZCBpcyB0aGF0IHRoZSBmdW5kYW1lbnRhbHMgKGluZm9ybWF0aW9uIGZyb20gZmluYW5jaWFsIHN0YXRlbWVudHMpIHdlcmUgZmFjdG9yZWQgaW50byB0aGUgcHJpY2UgZmx1Y3R1YXRpb24sIGhlbmNlLCBkZXRlY3RpbmcgdGhlIHBhdHRlcm5zIGFuZCBzaWduYWxzIGZyb20gdGhlIGZsdWN0dWF0aW9uIHNob3VsZCBwcm92aWRlIHN1ZmZpY2llbnQgaW5kaWNhdG9yIGZvciBmdXR1cmUgcGVyZm9ybWFuY2UuCgpGb3IgdGhpcyBwcm9qZWN0LCB3ZSBhcmUgZ29pbmcgdG8gZXhwbG9yZSBzb21lIG9mIHRoZSBjb21tb24gdGVjaG5pY2FsIGluZGljYXRvcnMgdXNpbmcgdGhlIFRRUVEgRXhjaGFuZ2UgdHJhZGUgZnVuZCAoRVRGKSBzdG9jay4gQW1vbmcgbGV2ZXJhZ2VkIEVURnMsIFByb1NoYXJlcyBVbHRyYVBybyBRUVEgKFRRUVEpIGlzIG9uZSBvZiB0aGUgbGFyZ2VzdCB3aXRoIGFzc2V0cyB1bmRlciBtYW5hZ2VtZW50IG9mICRcJDE4LjU2JCBiaWxsaW9uIGFzIG9mIEp1bHkgMjAyMi4gVFFRUSBpcyBhbHNvIG9uZSBvZiB0aGUgbW9yZSBoZWF2aWx5IHRyYWRlZCBsZXZlcmFnZWQgRVRGcyBpbiB0aGUgVS5TLiB3aXRoIGFuIGF2ZXJhZ2UgZGFpbHkgdm9sdW1lIG9mICRcJDUuMjkkIGJpbGxpb24gKGNvbXBhcmVkIHdpdGggUVFRJ3MgJFwkMjEkIGJpbGxpb24pLgoKVFFRUSBjYXJyaWVzIGFuIFtleHBlbnNlIHJhdGlvXShodHRwczovL3d3dy5pbnZlc3RvcGVkaWEuY29tL3Rlcm1zL2UvZXhwZW5zZXJhdGlvLmFzcCkgb2YgMC45NSUuCgpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoInF1YW50bW9kIikKI2luc3RhbGwucGFja2FnZXMoImRhdGEudGFibGUiKQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCiNpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5cXVhbnQiKQpsaWJyYXJ5KHF1YW50bW9kKQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5cXVhbnQpICAKYGBgCgojIyBEYXRhIEV4dHJhY3Rpb24gJiBNYW5pcHVsYXRpb24sIERhdGEgc3RydWN0dXJlCgpUUVFRIGRhdGEgaXMgZXh0cmFjdGVkIHVzaW5nIHRoZSBnZXRTeW1ib2xzIGZ1bmN0aW9uIGZyb20gWWFob28gRmluYW5jZS4gQWx0ZXJuYXRpdmVseSwgdGhlIHNvdXJjZSBjYW4gYmUgcmVwbGFjZWQgd2l0aCBGUkVELCBNeVNRTCwgR29vZ2xlLCBvciBvdGhlcnMuIFRoZSBkYXRhIGV4dHJhY3RlZCBzaG91bGQgYmUgaW4gYW4g4oCYeHRz4oCZIG9iamVjdCAtIGEgZm9ybWF0IGNvbW1vbmx5IHVzZWQgaW4gdGltZSBzZXJpZXMgYW5hbHlzaXMgd2hlcmUgb2JzZXJ2YXRpb25zIGFyZSByZWNvcmRlZCBpbiBhIG1hdHJpeCBzdHJ1Y3R1cmUgd2l0aCBhbiBpbmRleCBvZiBjb3JyZXNwb25kaW5nIHRpbWUuCgpUZWNobmljYWxseSwgYW5hbHlzaXMgY2FuIGJlIGRvbmUgaW4geHRzIGZvcm1hdCBhbG9uZSwgYnV0IGZvciB0aGUgc2FrZSBvZiBzaW1wbGljaXR5LCBkYXRhIGlzIGNvbnZlcnRlZCBpbnRvIGEgc3RhbmRhcmQgZGF0YWZyYW1lIGFuZCBpbmRleCBjb2x1bW4gaXMgcmVuYW1lZCBhcyAiRGF0ZeKAmS4gVGhlIGVuZCByZXN1bHQgaXMgc2hvd24gYXMgYmVsb3c6CgpgYGB7ciBkb3dubG9hZF9zdG9ja19oaXN0b3J5fQpnZXRTeW1ib2xzKCdBQVBMJyxzcmMgPSAneWFob28nKSAgICAgICAjIyBjaGFuZ2UgVFFRUSB0aWNrZXIgdG8gWW91ciB0aWNrZXIgc3ltYm9sCmBgYAoKIyMgc3RydWN0dXJlIG9mIHRoZSAqc3RvY2sqIGRhdGEKCmBgYHtyfQpzdG9jayA8PC0gYXMuZGF0YS50YWJsZShBQVBMKSAgICAgICAgIyMjIyMjIGNoYW5nZSBUUVFRIHRpY2tlciB0byBZb3VyIHRpY2tlciBzeW1ib2wgICMjIyMjIyMjIwpuYW1lcyhzdG9jaylbMV0gPC0gYygnRGF0ZScpCgp0YWlsKHN0b2NrKQpgYGAKCkkgdXNlZCBBcHBsZSBhcyB0aGUgYmFzaXMgZm9yIG15IGFuYWx5c2lzLCB3aG9zZSBjb2RlIHdhcyBBQVBMLiBJbiBteSBhbmFseXNpcywgSSBzZWxlY3RlZCAyIGRpZmZlcmVudCBjaGFydHMsIG9uZSB3YXMgIkludGVycHJldGF0aW9uIG9mIHRoZSBITENPIGdyYXBoIiBhbmQgdGhlIG90aGVyIHdhcyAiUHJpY2UgLSBNb3ZpbmcgQXZlcmFnZSIsIHRoZSBsYXN0IGdyYXBoLiAKCiMjIEludGVycHJldGF0aW9uIG9mIHRoZSBITENPIGdyYXBoCgpJbiBmaW5hbmNlLCBITENPIGdyYXBoIGlzIGEgdHlwZSBvZiBmaW5hbmNpYWwgY2hhcnQgdGhhdCBwbG90cyB0aGUgaGlnaCwgbG93LCBjbG9zZSwgYW5kIG9wZW4gcHJpY2VzIGZvciBhIGdpdmVuIHBlcmlvZCBvZiB0aW1lLiBUaGUgSExDTyBjaGFydCBpcyBzaW1pbGFyIHRvIGEgY2FuZGxlc3RpY2sgY2hhcnQsIGJ1dCBpdCBpbmNsdWRlcyB0aGUgb3BlbiBwcmljZSBpbiBhZGRpdGlvbiB0byB0aGUgaGlnaCwgbG93LCBhbmQgY2xvc2UgcHJpY2VzLgoKVGhlIGludGVycHJldGF0aW9uIG9mIGFuIEhMQ08gY2hhcnQgY2FuIHByb3ZpZGUgaW5zaWdodHMgaW50byB0aGUgcHJpY2UgYWN0aW9uIG9mIGEgc2VjdXJpdHkgZHVyaW5nIGEgZ2l2ZW4gcGVyaW9kIG9mIHRpbWUuIEhlcmUgaXMgYSBicmllZiBleHBsYW5hdGlvbiBvZiBob3cgdG8gaW50ZXJwcmV0IGVhY2ggY29tcG9uZW50IG9mIGFuIEhMQ08gY2hhcnQ6CgoxLiBIaWdoOiBUaGUgdG9wIG9mIHRoZSB2ZXJ0aWNhbCBsaW5lIHJlcHJlc2VudHMgdGhlIGhpZ2hlc3QgcHJpY2UgcmVhY2hlZCBkdXJpbmcgdGhlIGdpdmVuIHBlcmlvZC4gVGhpcyBzaG93cyB0aGUgaGlnaGVzdCBwcmljZSB0aGF0IGJ1eWVycyB3ZXJlIHdpbGxpbmcgdG8gcGF5IGZvciB0aGUgc2VjdXJpdHkgZHVyaW5nIHRoZSBwZXJpb2QuCgoyLiBMb3c6IFRoZSBib3R0b20gb2YgdGhlIHZlcnRpY2FsIGxpbmUgcmVwcmVzZW50cyB0aGUgbG93ZXN0IHByaWNlIHJlYWNoZWQgZHVyaW5nIHRoZSBnaXZlbiBwZXJpb2QuIFRoaXMgc2hvd3MgdGhlIGxvd2VzdCBwcmljZSB0aGF0IHNlbGxlcnMgd2VyZSB3aWxsaW5nIHRvIGFjY2VwdCBmb3IgdGhlIHNlY3VyaXR5IGR1cmluZyB0aGUgcGVyaW9kLgoKMy4gQ2xvc2U6IFRoZSBob3Jpem9udGFsIGxpbmUgdG8gdGhlIHJpZ2h0IG9mIHRoZSB2ZXJ0aWNhbCBsaW5lIHJlcHJlc2VudHMgdGhlIGNsb3NpbmcgcHJpY2UgZm9yIHRoZSBwZXJpb2QuIFRoaXMgc2hvd3MgdGhlIGZpbmFsIHByaWNlIGF0IHdoaWNoIHRoZSBzZWN1cml0eSB0cmFkZWQgZHVyaW5nIHRoZSBwZXJpb2QuCgo0LiBPcGVuOiBUaGUgaG9yaXpvbnRhbCBsaW5lIHRvIHRoZSBsZWZ0IG9mIHRoZSB2ZXJ0aWNhbCBsaW5lIHJlcHJlc2VudHMgdGhlIG9wZW5pbmcgcHJpY2UgZm9yIHRoZSBwZXJpb2QuIFRoaXMgc2hvd3MgdGhlIGluaXRpYWwgcHJpY2UgYXQgd2hpY2ggdGhlIHNlY3VyaXR5IHRyYWRlZCBkdXJpbmcgdGhlIHBlcmlvZC4KCkJ5IGxvb2tpbmcgYXQgdGhlIHBhdHRlcm5zIG9mIHRoZSBoaWdoLCBsb3csIGNsb3NlLCBhbmQgb3BlbiBwcmljZXMgaW4gYW4gSExDTyBjaGFydCwgdHJhZGVycyBhbmQgaW52ZXN0b3JzIGNhbiBnYWluIGluc2lnaHQgaW50byB0aGUgb3ZlcmFsbCB0cmVuZCBhbmQgc2VudGltZW50IG9mIHRoZSBtYXJrZXQgZm9yIHRoZSBnaXZlbiBzZWN1cml0eS4gRm9yIGV4YW1wbGUsIGEgbG9uZyBncmVlbiBjYW5kbGVzdGljayB3aXRoIGEgaGlnaCBjbG9zZSBhbmQgbG93IG9wZW4gbWF5IGluZGljYXRlIGJ1bGxpc2ggc2VudGltZW50LCB3aGlsZSBhIGxvbmcgcmVkIGNhbmRsZXN0aWNrIHdpdGggYSBsb3cgY2xvc2UgYW5kIGhpZ2ggb3BlbiBtYXkgaW5kaWNhdGUgYmVhcmlzaCBzZW50aW1lbnQuCgpgYGB7cn0KIyBmZWVsIGZyZWUgdG8gY2hhbmdlICJITENPIiB0byAiY2FuZGxlc3RpY2siIG9yIHRvIHNvbWUgb3RoZXIgdHlwZXMgKCJsaW5lcyIsICJhdXRvIikuIApjaGFydFNlcmllcyhzdG9jaywgc3Vic2V0PScyMDIwLTAxLTAxOjoyMDIwLTA5LTIzJywgdHlwZSA9ICJjYW5kbGVzdGlja3MiLCBiYXIudHlwZSA9ICJvaGxjIix0aGVtZT1jaGFydFRoZW1lKCd3aGl0ZScpKQpgYGAKClRoZSB0cmFkaW5nIHNlc3Npb24gbGFzdGVkIGZyb20gSmFudWFyeSAyIHRvIFNlcHRlbWJlciAyMywgMjAyMC4gQWZ0ZXIgdGhlIG9wZW5pbmcsIEFwcGxlJ3Mgc3RvY2sgd2FzIHZhbHVlZCBhcm91bmQgJDc1IG1pbGxpb24sIGFuZCBpbiB0aGUgZm9sbG93aW5nIHBlcmlvZHMgaXQgYmVnYW4gdG8gcmlzZSBzbGlnaHRseSwgcmVhY2hpbmcgb3ZlciAkODAgbWlsbGlvbiBpbiBtaWQtdG8tbGF0ZSBGZWJydWFyeS4gRnJvbSB0aGUgYmVnaW5uaW5nIG9mIE1hcmNoLCB0aGUgcHJpY2UgYmVnYW4gdG8gZmx1Y3R1YXRlIGNvbnRpbnVvdXNseSwgYXMgYSByZXN1bHQgb2Ygd2hpY2ggdGhlIHNoYXJlIHByaWNlIGZlbGwgdG8gYXJvdW5kIDUwIG1pbGxpb24gYnkgdGhlIGVuZCBvZiBNYXJjaCBhbmQgcmVhY2hlZCBpdHMgbG93ZXN0IHBvaW50LiBBZnRlciB0aGF0LCB0aGVyZSBpcyBzdGFnbmF0aW9uIGFnYWluLCBidXQgYXQgdGhlIHNhbWUgdGltZSBhIGNvbnRpbnVvdXMgcmlzZSBjYW4gYmUgc2VlbiB1bnRpbCB0aGUgZW5kIG9mIEp1bHksIHdoZXJlIHRoZSBleGNoYW5nZSByYXRlIGZhbHRlcnMgYWdhaW4gYW5kIGEgc2xpZ2h0IGRlY3JlYXNlIGNhbiBiZSBzZWVuLCBidXQgZnJvbSBtaWQtQXVndXN0IGl0IHN0YXJ0cyB0byByaXNlIGFnYWluLCByZWFjaGluZyBhIGhpZ2ggcG9pbnQgb2YgYWxtb3N0ICQgMTQwIG1pbGxpb24gYnkgdGhlIGJlZ2lubmluZyBvZiBTZXB0ZW1iZXIuIEl0IHRoZW4gc3RhZ25hdGVzIGFnYWluIGFuZCBjbG9zZXMgYXQgYXJvdW5kICQxMTAgbWlsbGlvbi4KCgojIyBWb2x1bWUgCgpPbmUgb2YgdGhlIG1vc3QgY29tbW9uIGJhc2ljIGluZGljYXRvcnMgdHJhZGVycyBleGFtaW5lIGlzIHRoZSB0cmFkaW5nIHZvbHVtZS4gVHJhZGluZyB2b2x1bWUgaXMgYW4gaW5kaWNhdGlvbiBmb3IgdGhlIOKAmGFjdGl2ZW5lc3PigJkgb2YgYSBmaW5hbmNpYWwgaW5zdHJ1bWVudC4gRGVwZW5kaW5nIG9uIHRoZSBmaW5hbmNpYWwgaW5zdHJ1bWVudHMsIHRyYWRpbmcgdm9sdW1lIGNhbiBiZSBtZWFzdXJlZCBlaXRoZXIgdXNpbmcgdGhlIG51bWJlciBvZiBzdG9ja3MgdHJhZGVkIG9yIG51bWJlciBvZiBjb250cmFjdHMgd2l0aCBjaGFuZ2VkIG93bmVyc2hpcHMuIFRvIHB1dCB0aGlzIGluIHByYWN0aWNlLCBpZiBhbiBpbmNyZWFzZSBpbiB2b2x1bWUgaXMgb2JzZXJ2ZWQgd2l0aCBhIHN0ZWFkeSBpbmNyZWFzZSBpbiBwcmljZSwgdGhlIGluc3RydW1lbnQgY2FuIGJlIHZpZXdlZCBhcyBzdGVhZHkgYW5kIHN0cm9uZy4gSG93ZXZlciwgaWYgdm9sdW1lIGFuZCBwcmljZSBhcmUgY2hhbmdpbmcgaW4gZGlmZmVyZW50IGRpcmVjdGlvbnMsIGEgcmV2ZXJzYWwgbWlnaHQgYmUgaGFwcGVuZWQuCgpZb3UgY2FuIGFuYWx5emUgaXQgaW4gdGhlIHByZXZpb3VzIHBpY3R1cmUuCgoKIyMgUHJpY2UgLSBNb3ZpbmcgQXZlcmFnZQoKCgpgYGB7cn0KY2hhcnRTZXJpZXMoc3RvY2ssCiAgICAgICAgICAgIHN1YnNldD0nMjAyMC0wMS0wMTo6MjAyMC0wOS0yMycsIHR5cGUgPSAiY2FuZGxlc3RpY2siLAogICAgICAgICAgICB0aGVtZT1jaGFydFRoZW1lKCd3aGl0ZScpKQphZGRTTUEobiA9IDEyLCBvbiA9IDEsIHdpdGguY29sID0gQ2wsIG92ZXJsYXkgPSBUUlVFLCBjb2wgPSAiYnJvd24iKQphZGRTTUEobiA9IDI0LCBvbiA9IDEsIHdpdGguY29sID0gQ2wsIG92ZXJsYXkgPSBUUlVFLCBjb2wgPSAiYmx1ZSIpCgoKYGBgCk15IG90aGVyIGFuYWx5c2lzIGlzIE1vdmluZyBBdmVyYWdlLiBUaGlzIGlzIGEgc3RvY2sgaW5kaWNhdG9yIHRoYXQgaXMgb2Z0ZW4gdXNlZCBpbiB0ZWNobmljYWwgYW5hbHlzaXMuClRoaXMgdHJhZGluZyBzZXNzaW9uIGFsc28gcnVucyBmcm9tIEphbnVhcnkgMm5kIHRvIEF1Z3VzdCAyM3JkLCAyMDIwLiBBZnRlciBvcGVuaW5nLCBzdGFnbmF0aW9uIGNhbiBiZSBzZWVuIGluIHRoZSBtYXJrZXQuIFRvd2FyZHMgbWlkLUZlYnJ1YXJ5LCB0aGUgYmx1ZSBsaW5lIGNyb3NzZXMgdGhlIHJlZCBsaW5lIGFuZCB0cmFkaW5nIGNsZWFybHkgZW50ZXJzIGEgYmVhciBtYXJrZXQuIFRoaXMgbGFzdHMgdW50aWwgQXByaWwsIHdoZW4gdGhlIG5lZ2F0aXZlIG1vdmluZyBhdmVyYWdlIGFsc28gY3Jvc3NlcyB3aXRoIHRoZSBwb3NpdGl2ZSBhbmQgZW50ZXJzIHRoZSBidWxsIG1hcmtldCBmb3IgdHJhZGluZy4gQWZ0ZXIgdGhhdCwgdGhlIG1hcmtldCBzdGFnbmF0ZXMgYW5kIHN0YXJ0cyB0byByaXNlIHRvIHRoZSBlbmQgb2YgSnVseS4gSGVyZSBpdCBwZWFrcywgYW5kIGJ5IHRoZSBlbmQgb2YgU2VwdGVtYmVyIHRoZSBiZWFyIG1hcmtldCByZS1lbnRlcnMgYW5kIHN0YXJ0IHRvIGRlY2xpbmUuIEhlcmUgd2UgY2FuIG9wdGlvbmFsbHkgc2VlIGEgYmFja3Rlc3Qgb3IgYSBmdXJ0aGVyIGRlY3JlYXNlLCBidXQgdGhpcyBpcyBubyB2aXNpYmxlIGZyb20gdGhlIGdyYXBoLiBIb3dldmVyLCBJIGxvb2tlZCBpdCB1cCBvbiB0aGUgdHJhZGluZ3ZpZXcuY29tIHNpdGUsIEkgYWxyZWFkeSBzZWUgdGhhdCB0aGlzIHdhcyBhIGJhY2t0ZXN0aW5nIGFuZCB0aGVyZSBpcyBmdXJ0aGVyIGdyb3d0aC4KCiMjIE1vdmluZyBBdmVyYWdlIENvbnZlcmdlbmNlIERpdmVyZ2VuY2UgKE1BQ0QpCgoKYGBge3J9CmNoYXJ0U2VyaWVzKHN0b2NrLAogICAgICAgICAgICBzdWJzZXQ9JzIwMjAtMDEtMDE6OjIwMjAtMDktMjMnLCB0eXBlID0gImJhcnMiLAogICAgICAgICAgICB0aGVtZT1jaGFydFRoZW1lKCd3aGl0ZScpKQphZGRNQUNEKGZhc3Q9MTIsc2xvdz0yNixzaWduYWw9OSx0eXBlPSJFTUEiKQoKYGBgCgoKIyMgQm9sbGluZ2VyIEJhbmQKCgpgYGB7cn0KY2hhcnRTZXJpZXMoc3RvY2ssCiAgICAgICAgICAgIHN1YnNldD0nMjAyMC0wMS0wMTo6MjAyMC0wOS0yMycsIHR5cGUgPSAiYmFycyIsCiAgICAgICAgICAgIHRoZW1lPWNoYXJ0VGhlbWUoJ3doaXRlJykpCmFkZEJCYW5kcyhuID0gMjAsIHNkID0gMiwgbWFUeXBlID0gIlNNQSIsIGRyYXcgPSAnYmFuZHMnLCBvbiA9IC0xKQpgYGAKCgojIyBSZWxhdGl2ZSBTdHJlbmd0aCBJbmRleCAoUlNJKQoKCmBgYHtyfQpjaGFydFNlcmllcyhzdG9jaywKICAgICAgICAgICAgc3Vic2V0PScyMDIwLTAxLTAxOjoyMDIwLTA5LTIzJywgdHlwZSA9ICJiYXJzIiwKICAgICAgICAgICAgdGhlbWU9Y2hhcnRUaGVtZSgnd2hpdGUnKSkKYWRkUlNJKG4gPSAxNCwgbWFUeXBlID0gIkVNQSIsIHdpbGRlciA9IFRSVUUpCgpgYGAKCgoKCgojIyBQYXJhYm9saWMgc3RvcCBhbmQgcmV2ZXJzYWwKCgoKYGBge3J9CmNoYXJ0U2VyaWVzKHN0b2NrLAogICAgICAgICAgICBzdWJzZXQ9JzIwMjAtMDEtMDE6OjIwMjAtMDktMjMnLCB0eXBlID0gImJhcnMiLAogICAgICAgICAgICB0aGVtZT1jaGFydFRoZW1lKCd3aGl0ZScpKQphZGRTQVIoYWNjZWwgPSBjKDAuMDIsIDAuMiksIGNvbCA9ICJibHVlIikKCgpgYGAKCgoKCiMjIFN1bW1hcnkgZ3JhcGhzCgpBcGFydCBmcm9tIHRoZSBmZXcgdGhhdCB3YXMgbWVudGlvbmVkIGFib3ZlLCBvdGhlciBpbmRpY2F0b3JzIGluY2x1ZGUgcmF0ZSBvZiBjaGFuZ2UsIG1vbmV5IGZsb3cgaW5kZXggKE1GSSksIE1BQ0QgYW5kIGV0Yy4KCiMjIENoYXJ0IFNlcmllcwoKQ2hhcnRTZXJpZXMgcHJvdmlkZXMgYW4gYWx0ZXJuYXRpdmUgd2F5IHRvIHN1bW1hcmlzZSB0aGUgcGxvdC4gSW5zdGVhZCBvZiBvbmUgcGxvdCBmb3IgZWFjaCBpbmRpY2F0b3IsIGFsbCBvZiB0aGVtIGNhbiBub3cgYmUgY29tcGlsZWQgaW50byBhIHNpbmdsZSBmaWd1cmUsIHdoZXJlIGluZGljYXRvcnMgY2FuIGJlIGFkZGVkIHRvIHRoZSBib3R0b20gb2YgdGhlIGV4aXN0aW5nIHBsb3QuCgpgYGB7cn0KY2hhcnRTZXJpZXMoc3RvY2ssCiAgICAgICAgICAgIHN1YnNldD0nMjAyMC0wMS0wMTo6MjAyMC0wOS0yMycsIHR5cGUgPSAiYmFycyIsCiAgICAgICAgICAgIHRoZW1lPWNoYXJ0VGhlbWUoJ3doaXRlJykpCmFkZEJCYW5kcyhuPTIwLHNkPTIpCmFkZFJTSShuPTE0LG1hVHlwZT0iRU1BIikKYWRkTUFDRChmYXN0PTEyLHNsb3c9MjYsc2lnbmFsPTksdHlwZT0iRU1BIikKCmBgYApNeSBhbmFseXNlcyBtYXkgbm90IGJlIGFjY3VyYXRlLCBidXQgSSB0cmllZCB0byBzb2x2ZSB0aGlzIHRhc2sgYmFzZWQgb24gbXkgcHJldmlvdXMga25vd2xlZGdlLCBhbmQgSSByZWFsbHkgZW5qb3llZCB0aGlzIGFzc2lnbm1lbnQuCgo=