Stata:Finance Topics

Stata:Finance Topics

This articles is my notes for learning two three articles which introduce some technical analysis methods in Stata.

Bollinger Bands

Bollinger bands were developed by John bollinger in the 1980s and consist of an upper and lower band, defining an envelope of usual trading. A stock price moving outside this envelope triggers an investment decision. The upper band is calculated as K standard deviations above the stock’s moving average. The lower band is calculated as K standard deviations below the moving average. bollinger bands mimic the idea that random variables tend to stay within plus or minus two standard deviations from their mean. To this insight, Bollinger bands add that the financial data might be not stationary, so the means and standard deviations are updated continually.

The usual trading system using Bollinger bands is to sell when the price reached it upper band, because a reversion to the mean is expected. A contrarian Bollinger trading system reverses this logic: buy when the price crosses its upper band.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* two deviations */
clear all
freduse SP500
drop date
ren daten date
gen obs = _n
tsset obs
tftools bollingerbands if year(date) > 2015, ///
symbol(SP500) generate(SP500_BB)
tw ///
line SP500 date || ///
line SP500_BB_upper_band date, lw(thick) || ///
line SP500_BB_lower_band date, lw(thick) || ///
if year(date) > 2015
gr export tftools1.png, replace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* four deviations */
clear all
freduse SP500
drop date
ren daten date
gen obs = _n
tsset obs
tftools bollingerbands if year(date) > 2015, ///
symbol(SP500) generate(SP500_BB) sdevs(4)
tw ///
line SP500 date || ///
line SP500_BB_upper_band date, lw(thick) || ///
line SP500_BB_lower_band date, lw(thick) || ///
if year(date) > 2015
gr export tftools2.png, replace

MACD

The MACD (“Mack-D”) is a momentum indicator commonly used by technical analysis. The MACD is equal to the difference between 2 EMAs of different lengths: (1) a long-term EMA of usually 26 days and (2) a short-term EMA of usually 12 days. The MACD is defined as the short-term EMA minus the long-term EMA. A third component is the so-called signal lines, which is usually a nine-day EMA of the MACD.

The convention is to plot the signal line over the MACD. A “bullish” indicator is when the signal line crosses above the MACD. A “bearish” indicator is when the signal line crosses below the MACD.

The MACD histogram is equal to the MACD less the signal line. As such, it oscillates above and below zero. A bullish signal is when the histogram becomes positive. A bearish signal is when the histogram becomes negative. The histogram is used as an indicator of momentum. When the histogram is positive ans increasing, the stock price is said to have increasing positive momentum. A negative and decreasing histogram implies steeper downside momentum.

It is often viewd as signaling the end of a current trend when the actual stock price diverges significantly from the MACD. Finally, the MACD rises steeply when the short-term EMA (usually 12 days) is rising faster than the long-term EMA (usually 26 days). That is, price have moved dramatically upward recently. Analysts sometimes infer that the current price has moved away from its equilibrium value, and they expect a downward correction.

1
2
3
4
5
6
7
8
9
10
11
12
13
clear all
freduse SP500, clear
drop if SP500 == .
drop date
ren daten date
gen obs = _n
tsset obs
tftools macd if year(date) > 2015, symbol(SP500) generate(SP500)
tw ///
line SP500_MACD_line date, lp(dash) || ///
line SP500_signal_line date || ///
if year(date) > 2015
gr export tftools3.png, replace

Moving Average

1
2
3
4
5
6
7
8
9
10
11
12
13
clear all
freduse SP500, clear
drop if SP500 == .
drop date
ren daten date
gen obs = _n
tsset obs
tftools movingaverage if year(date) > 2015, symbol(SP500) generate(SP500) period(100) ma_type(sma)
tw ///
line SP500 date || ///
line SP500_sma_100 date || ///
if year(date) > 2015
gr export tftools4.png, replace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
clear all
freduse SP500, clear
drop if SP500 == .
drop date
ren daten date
gen obs = _n
tsset obs
tftools movingaverage if year(date) > 2010, symbol(SP500) generate(SP500) period(50) ma_type(sma)
tftools movingaverage if year(date) > 2010, symbol(SP500) generate(SP500) period(200) ma_type(sma)
tw ///
line SP500 date || ///
line SP500_sma_50 date || ///
line SP500_sma_200 date || ///
if year(date) > 2010
gr export tftools5.png, replace

RSI

$$RSI = 100 - \frac{100}{1 + RS}$$

where:

$$RS = \frac{average of upward returns over x days}{average of downward returns over x days}$$

1
2
3
4
5
6
7
8
9
10
clear all
freduse SP500, clear
drop if SP500 == .
drop date
ren daten date
gen obs = _n
tsset obs
tftools rsi if year(date) > 2015, symbol(SP500) generate(SP500)
tw line SP500_RSI date if year(date) > 2015
gr export tftools6.png, replace

Candle Chart

1
2
3
4
5
6
7
8
9
10
11
12
13
* net install gr0076.pkg, from("http://www.stata-journal.com/software/sj19-1")
cntrade2 1, start(20190101) end(20191018)
foreach i of varlist _all{
if !inlist("`i'", "code", "date", "name"){
ren `i' `i'_pingan
}
}
save pingan, replace

/* Draw Basic Candle Chart */
use pingan, clear
candlechart pingan
gr export candlechart1.png, replace

1
2
3
4
5
/* Draw Basic Candle Chart and Transaction Volume */
use pingan, clear
replace volume_pingan = volume_pingan / 10000000
candlechart pingan, price volume
gr export candlechart2.png, replace

1
2
3
4
5
6
7
8
/* Add Bollinger bands, MACD, and RSI */
use pingan, clear
replace volume_pingan = volume_pingan / 10000000
gen adjclose_pingan = close_pingan + 1
gen obs = _n
tsset obs
candlechart pingan, price volume macd rsi bollinger
gr export candlechart3.png, replace

1
2
3
4
5
6
7
8
9
10
11
/* Chart Options */
use pingan, clear
replace volume_pingan = volume_pingan / 10000000
gen adjclose_pingan = close_pingan
gen obs = _n
tsset obs
candlechart pingan, price volume macd rsi bollinger ///
chart_options(yla(, ang(horizontal) format(%5.0fc)) ///
xla(, ang(20) format(%td)) scale(0.50)) ///
combined_chart_options(title("Technical analysis charts for Pingan Bank", size(3)))
gr export candlechart4.png, replace

Stata for finance students

Download Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* Financial statements */
* net install http://researchata.com/stata/048/fetch_statements.pkg, force
* The following example will download the annual balance sheets for AAPL.
fetch_statements AAPL, freq(A) st(BS)

/* Economic data */
ssc install freduse
freduse DEXUSEU, clear
tw line DEXUSEU daten
gr export DEXUSEU.png, replace

/* Daily gold fixing */
* net install http://researchata.com/stata/029/fetchgold.pkg, force
fetchgold, year(2013 2014 2015 2016 2017 2018 2019) metal(gold)
tw line usd_am date, scale(0.5)
gr export fetchgold.png, replace

1
2
3
/* Earnings per share */
* net install http://researchata.com/stata/041/fetch_EPS.pkg, force
fetch_EPS AAPL

Econometric Analysis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* Econometric Analysis */
/* CAPM */
/* Ping An Bank */
cntrade2 000001
keep close date
ren close pingan
save pingan2, replace
/* Shenzhen Stock Index */
cntrade2 399001, index
keep close date
ren close zzcz
merge 1:1 date using pingan2
drop _m
replace pingan = ln(pingan)
replace zzcz = ln(zzcz)
reg pingan zzcz

*> Source | SS df MS Number of obs = 6,758
*> -------------+---------------------------------- F(1, 6756) = 9.95
*> Model | 2.33604384 1 2.33604384 Prob > F = 0.0016
*> Residual | 1585.56523 6,756 .234689939 R-squared = 0.0015
*> -------------+---------------------------------- Adj R-squared = 0.0013
*> Total | 1587.90127 6,757 .235000928 Root MSE = .48445
*> ------------------------------------------------------------------------------
*> pingan | Coef. Std. Err. t P>|t| [95% Conf. Interval]
*> -------------+----------------------------------------------------------------
*> zzcz | .0235385 .0074608 3.15 0.002 .008913 .038164
*> _cons | 2.49601 .063581 39.26 0.000 2.371371 2.620648
*> ------------------------------------------------------------------------------

/* GARCH(1, 1) */
/*
CAPM is estimated using GARCH which controls risk.
*/
tsset date
arch pingan zzcz, arch(1) garch(1)

Day-of-the-week effect

Day-of-the-week effect is one of most common return anomalies tested in the literature. It stems from the hypothesis that if securities compensate investors for risk for any holding period then a weekend return should be higher than a daily return. Thus, based on this hypothesis, it would be expected that returns for Fridays to Mondays should be higher than any other mid-week daily return. However, if investors expect higher returns for the weekend they would trade such expectation to take advantage of it. This would eliminate the higher weekend returns. Based on the efficient market hypothesis, such profitable pattern trading should not exist. In fact, if it exists, it would be akin to investors not taking advantage of a profitable trading strategy. Thus, existence of day-of-the-week is considered to be an anomaly: why would investors leave money on the table?

Dicle and Levendis (2014) argue that investors and academic study indexes as well as popular stocks. This leads to less popular stocks to be left not studied. They find no evidence of day-of-the-week effect for indexes. However, based on evaluation of 51 markets in 33 countries, approximately 8% of 37631 stocks present day-of-the-week effect.

The day-of-the-week effect test is quite simple. It basically evaluates returns for each day of the week to be statistically different from each other. For this purposes, a binary variable is assigned to each week day. However, in order to avoid binary variable trap (a.k.a. dummy trap) in the regression, one of the weekdays is left out(usually Wednesday). This allows each week day’s return to compared to the returns on Wednesdays.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cntrade2 1
gen Monday = 0
replace Monday = 1 if dow(date) == 1

gen Tuesday = 0
replace Tuesday = 1 if dow(date) == 2

gen Thursday = 0
replace Thursday = 1 if dow(date) == 4

gen Friday = 0
replace Friday = 1 if dow(date) == 5

replace close = ln(close)
reg close Monday Tuesday Thursday Friday

*> Source | SS df MS Number of obs = 6,806
*> -------------+---------------------------------- F(4, 6801) = 0.05
*> Model | .04941502 4 .012353755 Prob > F = 0.9953
*> Residual | 1681.47724 6,801 .247239706 R-squared = 0.0000
*> -------------+---------------------------------- Adj R-squared = -0.0006
*> Total | 1681.52666 6,805 .24710164 Root MSE = .49723
*> ------------------------------------------------------------------------------
*> close | Coef. Std. Err. t P>|t| [95% Conf. Interval]
*> -------------+----------------------------------------------------------------
*> Monday | -.0060295 .0190734 -0.32 0.752 -.0434194 .0313604
*> Tuesday | -.006021 .0189777 -0.32 0.751 -.0432232 .0311812
*> Thursday | -.0054165 .0189917 -0.29 0.775 -.0426461 .031813
*> Friday | -.0079601 .0190128 -0.42 0.675 -.045231 .0293109
*> _cons | 2.710606 .0133899 202.44 0.000 2.684357 2.736854
*> ------------------------------------------------------------------------------

It seems no day-of-the-week effect exists. Also it would be best to estimate this model using GARCH(1, 1) model instead of OLS to control for risk.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
tsset date
arch close Monday Tuesday Thursday Friday, arch(1) garch(1)
*> ARCH family regression
*> Sample: 1991-01-02 - 2019-10-17, but with gaps Number of obs = 6,806
*> Distribution: Gaussian Wald chi2(4) = 6.37
*> Log likelihood = -1541.701 Prob > chi2 = 0.1729
*> ------------------------------------------------------------------------------
*> | OPG
*> close | Coef. Std. Err. z P>|z| [95% Conf. Interval]
*> -------------+----------------------------------------------------------------
*> close |
*> Monday | -.0023443 .002306 -1.02 0.309 -.0068639 .0021754
*> Tuesday | -.0018581 .0023177 -0.80 0.423 -.0064008 .0026845
*> Thursday | -.0056006 .0023971 -2.34 0.019 -.0102988 -.0009023
*> Friday | -.0062451 .0029979 -2.08 0.037 -.0121209 -.0003693
*> _cons | 2.750632 .001823 1508.81 0.000 2.747059 2.754205
*> -------------+----------------------------------------------------------------
*> ARCH |
*> arch |
*> L1. | 1.00639 .0339583 29.64 0.000 .9398327 1.072947
*> |
*> garch |
*> L1. | -.0007083 .0002863 -2.47 0.013 -.0012695 -.0001471
*> |
*> _cons | .0004455 .0000435 10.25 0.000 .0003603 .0005307
*> ------------------------------------------------------------------------------

Still no day-of-the-week effect was founded.

References

Dicle, M. F., & Levendis, J. D. (2017). Technical Financial Analysis Tools for Stata. The Stata Journal: Promoting Communications on Statistics and Stata, 17(3), 736–747. doi:10.1177/1536867x1701700312
Dicle, Mehmet F., Stata for Finance Students (October 28, 2018). Available at SSRN: https://ssrn.com/abstract=2318687 or http://dx.doi.org/10.2139/ssrn.2318687
Dicle, M. F. (2019). Candle charts for financial technical analysis. The Stata Journal: Promoting Communications on Statistics and Stata, 19(1), 200–209. doi:10.1177/1536867x19830918

unsplash-logoM. B. M.

# Stata

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×