Finished Chap2 Deciphering the Market with Technical Analysis

master
Jason Zhu 2020-07-17 12:42:54 +10:00
parent 34cbbddc20
commit e7112671b6
30 changed files with 1495 additions and 0 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
.vscode
**.pdf

View File

@ -0,0 +1,280 @@
# Chap 2. Deciphering the Markets with Technical Analysis (使用技术分析来解密市场)
本章目标:
* 介绍流行的技术分析方法
* 展示如何用来分析市场数据
创造交易策略的基础:我们假设市场会不断重复自身。通过分析过往记录,市场数据的技术分析可分为两块:
* chart pattern (图表): 此类技术分析通过识别交易的模式并预测他们何时会重复。比较应用于算法交易
* technical indicator (技术指标): 使用数学来预测金融市场走向。指标有很多但可被归纳为
* trend (趋势)
* momentum (动量)
* volume (体量)
* volatility (波动)
* support and resistance (支撑与阻力)
## 1. Designing a trading strategy based on trend- and momentum-based indicator (设计一个基于趋势和动能的指标)
“趋势交易策略关注速度,动能交易策略关注加速度”
* 趋势交易:
* 在分析历史价格数据时,如果价格不断上涨一定时间(天),我们就开多头仓位
* 动能交易:
* 基于过往行为的强度来挂单
* price momentum 是一个价格动作的量
* 逻辑an asset price with a strong movement in a given direction will keep going in the same direction in the future.
### 1.1 Support and resistance indicators (支撑线、阻力线)
* 当价格下跌到一定程度时,会有集中的需求导致下跌停止。当价格上涨到一定程度时,会有集中性的供给导致价格无法上升
* Support line = 价格下跌的下限
* Resistance line = 价格上涨的上限
* 利用了买低卖高的市场心理
![](sources/sec2/supportresistanceline.png)
* 获取2015-07-01 至2018-01-01的GOOGLE的股票价格。
* 画出了 support line (红线), resistence line (绿线)
* 蓝线表示数据积累点 (200天)
基于这个简单的技术分析我们可以定出策略在200天的数据积累后蓝色虚线
* 股价高至 resistence line 后,挂空头仓位 (short the stock).
* 股价低至 support line 后,挂多头仓位 (long the stock).
实际效果:
* 2016-08 后GOOG 股价触发 resistance line, 算法开始持续做空 GOOGLE, 损失惨重。
分析:
* 即便 support & resistance indicator 有经济学逻辑,实际中需要对其进行矫正。例如:移动 support/resistance line.
改进(增加特性):
* 使用 rolling window 滚动窗口
* 数股价触及支撑线或阻力线的数量
* 加入 tolerance margin 从而把支撑/阻力线的空间缩小(如下图)
![](../img/2_1.jpg)
方案选择(增加两种参数):
* 价格触及 supporting/resistance line 的最少次数
* 定一个 tolorance margine
```
price sup_tolerance res_tolerance sup_count res_count sup res position signal
Date
2013-12-31 558.262512 NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-02 554.481689 NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-03 550.436829 NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-06 556.573853 NaN NaN NaN NaN NaN NaN NaN NaN
2014-01-07 567.303589 NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ...
2017-12-22 1060.119995 1014.371997 1061.44801 NaN NaN 998.679993 1077.140015 0.0 1.0
2017-12-26 1056.739990 1014.371997 1061.44801 NaN NaN 998.679993 1077.140015 0.0 1.0
2017-12-27 1049.369995 1014.371997 1061.44801 NaN NaN 998.679993 1077.140015 0.0 1.0
2017-12-28 1048.140015 1014.371997 1061.44801 NaN NaN 998.679993 1077.140015 0.0 1.0
2017-12-29 1046.400024 1014.371997 1061.44801 NaN NaN 998.679993 1077.140015 0.0 1.0
```
代码完成:
1. 在规定的滚动时间窗口内默认20天基于过去的数据计算支撑线、阻力线。
2. 基于支撑线、阻力线计算了20%的区域。
3. 用diff()计算了下单的时间
4. 当价格低于支撑线,到达支撑区间后(或者高于阻力线,到达阻力区间),我们会挂多头仓位(空头仓位)
![](sources/sec2/supportresistanceline_improved.png)
交易策略:
* 当价格进入支撑线区域后连续两天,就可以买多仓
* 价格进入阻力线区域后连续两天,买空仓
## 2. Creating trading signals based on fundamental technical analysis (基于基本技术分析的交易算法)
常用技术分析方法(指标):
* Simple Moving Average (SMA) 简单移动平均线
* Exponential Moving Average (EMA) 指数移动平均线
* Absolute Price Oscillator (APO) 绝对价格震荡器
* Moving Average Convergence Divergence (MACD) 指数平滑移动平均线
* Bollinger Bands (BBANDS) 布林线指标
* Relative Strength Indicator (RSI) 相对强弱和是
* EMA是非常常用的时间序列技术指标
* 类似于SMA,但是对价格的权重不是平均的
* 背后的概念:
* 若模型使用“时间约近,权重越高”:追求更新的信息
* 若模型使用“时间越远,权重越高”:认为 longer-term trends 含有更多信息
* 时间窗口:
* 越短EMA 对新数据的反映越大; i.e. **Fast EMA**
* 越长EMA 对新数据的反映月满; i.e. **Slow EMA**
#### 基于旧EMA计算新EMA
$$EMA = (P - EMA_{old})\times \mu + EMA_{old}$$
or
$$EMA = P \times \mu + (1-\mu) \times EMA_{old}$$
where:
* $P$ = 新的(当今)价格
* $/pu$ = **smoothing factor**; 新的价格数据的 weight factor (权重), 经常被设置为 $\frac{2}{(n+1)}$
* $N$ = 时间
* $EMA_{old}$ = 之前的EMA数值
![](sources/sec2/ema.png)
* EMA 和 SMA 一样具有平滑作用,因此减少了噪音
* EMA 中具有的 $\mu$ & $N$,可以让我们控制新进数据的权重。可以让我们通过不同的 $\mu$ & $N$ 建立不同的EMA
### 2.3 绝对价格震荡器 (APO)
* APO 为一种技术指标:通过价格的移动平均数值来捕捉价格在短期内的背离
* 计算方法:计算 Fast EMA 和 Slow EMA 时间的价差。
* 背后的逻辑:试图衡量 $EMA_{fast}$ 背离 $EMA_{slow}$ 多远。更大的背离标志着两种情况
* 金融资产价格开始出现趋势或者准备爆发
* 金融资产价格已经偏离平衡,要么是被低估或者高估
$$APO = EMA_{fast} - EMA_{slow}$$
下面案例使用了 $N=2/11$ 和 $N=2/41$ 的 APO
![](sources/sec2/apo.png)
* $EMA_{fast}$ 对新价格的的波动性更敏感,而 $SMA_{slow}$ 衰退得更加慢
* 当股价价格向上爆发的时候 APO 为正;而且爆发程度越强 APO 绝对值越高
这个信号可以用来做交易策略
### 2.4 指数平滑移动平均线 (MACD)
* MACD 是一种基于APO的指标
* 计算方法:
* 在计算 APO 后,我们对其再做一次 EMA从而得到一个MACD信号 ($MACD_{Signal}$)
* 或者,在$MACD_{Signal}$基础上生成histogram
$$MACD = EMA_{Fast} - EMA_{Slow}$$
$$MACD_{Signal} = EMA_{MACD}$$
$$MACD_{Histogram} = MACD-MACD_{Signal}$$
一个成功的 $MACD_{signal}$ 可以捕获金融产品的方向、趋势和时间长度
![](sources/sec2/macd.png)
* $EMA_{MACD}$ 在 MACD(APO)上在加了一层平滑。
* $MACD_{Histogram}$ 捕获了两个点:
* 趋势开始或者回归的时间
* 当$MACD_{Histogram}$值在反转正负以后,趋势持续的强度 (magnitude of lasting trends when $MACD_{Histogram}$ values stay positive or negative after reversing signs)
### 2.5 布林线指标 (BBANDS)
Bollinger Bands:
* 一种著名的技术分析指标,由 John Bollinger 发明
* 计算方式(类似 6-sigma
* 1. 使用一个时间窗口,计算 moving average (SMA, EMA 都可)
* 2. 计算这个时间窗口的 standard deviation
* 3. Upper Band = moving average 加上 standard deviation 的倍数
* 4. Lower Band = moving average 减去 standard deviation 的倍数
* BBAND 代表了对价格波动性的预估。若价格到了BBAND之外那就是一个交易信号。
$$BBAND_{Middle} = SMA_{n-periods}$$
* Lower Bollinger band $BBAND_{Middle}$ 是前n个时段的SMA (.e.g. 过去n天)
$$BBAND_{Upper} = BBAND_{Middle} + (\beta * \delta)$$
$$BBAND_{Lower} = BBAND_{Middle} - (\beta * \delta)$$
* $\delta$ 是standard deviation
* $\beta$ 是 standard deviation factor由我们选择; $\beta$ 越大BBAND越大
![](../bbands.png)
### 2.6 相对强弱指标 (RSI)
* RSI通过比较一段时期内的平均收盘涨数和平均收盘跌数来分析市场买沽盘的意向和实力从而作出未来市场的走势
* RSI在1978年6月由Wells Wider创制的一种通过特定时期内股价的变动情况计算市场买卖力量对比来判断股票价格内部本质强弱、推测价格未来的变动方向的技术指标。
> RSI[上升平均数÷(上升平均数+下跌平均数)]×100;
> 上升平均数是在某一段日子里升幅数的平均而下跌平均数则是在同一段日子里跌幅数的平均。
计算方法, 在lookback时间段内:
1. 计算magnitude of average of gains/losses over the period
$$AbsoluteGainOverPeriod = Price - PreviousPrice$$
$$AbsoluteLossOverPeriod = PreviousPrice - Price$$
$$RelativeStrength(RS) = \frac{\frac{\sum AbsoluteGainsOverLastNPeriods}{n}}{\frac{\sum AbsoluteLossesOverLastNPeriods}{n}}$$
可被简化为:
$$RelativeStrength(RS) = \frac{\sum AbsoluteGainsOverLastNPeriods}{\sum AbsoluteLossesOverLastNPeriods}$$
$$RelativeStrengthIndicator(RSI) = 100 - \frac{100}{(1+RS)}$$
![](sources/sec2/rsi.png)
* 上图使用了20天作为时间区域来计算上升平均数与下降平均数
* 上图说明了上升平均数基本上高于下降平均数这与GOOG成功的股价直接相关
### 2.7 标准差 (STDEV)
**Standard deviation** = **STDEV**, 是金融资产价格波动性的体现,可被用于结合其他的指标。
计算方法:
1. 先计算 variance:
$$\sigma ^2 = \frac{\sum^n_{i=1}(P_i - SMA)^2}{n}$$
SMA = simple moving average over n time periods
2. 计算标准差:
$$\sigma = \sqrt{\sigma^2}$$
![](sources/sec2/stdev.png)
### 2.8 动量指标 (MOM)
MOM 为一个对价格移动的速度和量的衡量指标。可用作 trend/breakout-based trading algorithms.
$$MOM = Price_i - Price_{t-n}$$
* $Price_t$ 为在t时间的价格
* $Price_{t-n}$ 在t时间之前n个时间片段的价格
MOM的含义
* 持续为正的MOM表示上升趋势
![](sources/sec2/momentum.png)
上图所示:
* MOM揭示了相比于20天前的股价股价何时会有大幅变动
## 3. Implementing advanced concepts in trading instruments
### 3.1 季节性
金融产品价格会有季节性(周期性):每周,每月,每个假期, 例如下图
![](sources/sec2/seasonality.png)
* GOOG的从2001到2018的每月平均股价在10月有明显偏高
### 3.2 Time Series analysis
时间序列分析因为较为advanced,因此这里暂时略过

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,75 @@
import os
import time
import statistics
from matplotlib.pyplot import legend, ylabel
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path+'/goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
""" Calculate APO """
num_periods_fast = 10 # time period for the fast EMA
K_fast = 2/(num_periods_fast + 1)
ema_fast = 0
num_periods_slow = 40
K_slow = 2/(num_periods_slow + 1)
ema_slow = 0
ema_fast_values = [] # Hold fast EMA values for visualization purposes
ema_slow_values = [] # Hold slow EMA values for visualization purposes
apo_values = []
for close_price in close:
if (ema_fast == 0):
ema_fast = close_price
ema_slow = close_price
else:
ema_fast = (close_price - ema_fast) * K_fast + ema_fast
ema_slow = (close_price - ema_slow) * K_slow + ema_slow
ema_fast_values.append(ema_fast)
ema_slow_values.append(ema_slow)
apo_values.append(ema_fast - ema_slow)
""" Visualizing """
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(FastExponential10DayMovingAverage=pd.Series(ema_fast_values, index=goog_data.index))
goog_data = goog_data.assign(SlowExponential140DayMovingAverage=pd.Series(ema_slow_values, index=goog_data.index))
goog_data = goog_data.assign(AbsolutePriceOscillator=pd.Series(apo_values, index=goog_data.index))
close_price = goog_data['ClosePrice']
ema_f = goog_data['FastExponential10DayMovingAverage']
ema_s = goog_data['SlowExponential140DayMovingAverage']
apo = goog_data['AbsolutePriceOscillator']
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(211, ylabel='Google price in $')
close_price.plot(ax=ax1, color='g', lw=2., legend=True)
ema_f.plot(ax=ax1, color='b', lw=2., legend=True)
ema_s.plot(ax=ax1, color='r', lw=2., legend=True)
ax2 = fig.add_subplot(212, ylabel='APO')
apo.plot(ax=ax2, color='black', lw=2., legend=True)
plt.savefig(dir_path + "/apo.png")
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -0,0 +1,73 @@
import os
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path + '/goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
import statistics as stats
import math as math
time_period = 20 # history length for Simple Moving Average for middle band
stdev_factor = 2 # Standard Deviation Scaling factor for the upper and lower bands
history = []
sma_values = []
upper_band = []
lower_band = []
""" Calculate BBAND """
for close_price in close:
history.append(close_price)
if len(history) > time_period:
del(history[0])
sma = stats.mean(history) # BBAND_Middle
sma_values.append(sma)
variance = 0
# Calculate variance using pure python
for hist_price in history:
variance = variance + ((hist_price - sma) ** 2)
stdev = math.sqrt(variance / len(history))
upper_band.append(sma + stdev_factor * stdev)
lower_band.append(sma - stdev_factor * stdev)
""" Draw Gragh """
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(MiddleBollingerBand20DaySMA=pd.Series(sma_values, index=goog_data.index))
goog_data = goog_data.assign(UpperBollingerBand20DaysSMA2StddevFactor=pd.Series(upper_band, index=goog_data.index))
goog_data = goog_data.assign(LowerBollingerBand20DaysSMA2StddevFactor=pd.Series(lower_band, index=goog_data.index))
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
goog_data['ClosePrice'].plot(ax=ax1, color='g', lw=2., legend=True)
goog_data['MiddleBollingerBand20DaySMA'].plot(ax=ax1, color='b', lw=2., legend=True)
goog_data['UpperBollingerBand20DaysSMA2StddevFactor'].plot(ax=ax1, color='y', lw=2., legend=True)
goog_data['LowerBollingerBand20DaysSMA2StddevFactor'].plot(ax=ax1, color='r', lw=2., legend=True)
plt.savefig(dir_path + '/bbands.png')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -0,0 +1,58 @@
import os
import time
import statistics
from matplotlib.pyplot import ylabel
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path + '/goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
""" Calculate EMA """
num_periods = 20 # number of days over which to average
K = 2/(num_periods + 1) # smoothing constant
ema_p = 0
ema_values = []
for close_price in close:
if (ema_p == 0):
# first observation, EMA = current price
ema_p = close_price
else:
ema_p = (close_price - ema_p) * K + ema_p
ema_values.append(ema_p)
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(Exponential120DayMovingAverage=pd.Series(ema_values, index=goog_data.index))
close_price = goog_data['ClosePrice']
ema = goog_data['Exponential120DayMovingAverage']
""" Draw plot """
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
close_price.plot(ax=ax1, color='g', lw=2., legend=True)
ema.plot(ax=ax1, color='b', lw=2., legend=True)
plt.savefig(dir_path + '/ema.png')
plt.show()

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,97 @@
import os
import time
import statistics
from matplotlib.pyplot import legend, ylabel
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path + '/goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
""" Calculate MACD """
num_periods_fast = 10 # fast EMA time period
K_fast = 2/(num_periods_fast+1)
ema_fast = 0
num_periods_slow = 40 # slow EMA time period
K_slow = 2/(num_periods_slow+1)
ema_slow = 0
num_periods_macd = 20 # MACD EMA time period
K_macd = 2/(num_periods_macd+1)
ema_macd=0
ema_fast_values = []
ema_slow_values = []
macd_values = []
macd_signal_values = []
macd_histogram_values = []
for close_price in close:
if (ema_fast == 0):
ema_fast = close_price
ema_slow = close_price
else:
ema_fast = (close_price - ema_fast) * K_fast + ema_fast
ema_slow = (close_price - ema_slow) * K_slow + ema_slow
ema_fast_values.append(ema_fast)
ema_slow_values.append(ema_slow)
macd = ema_fast - ema_slow # calculate MACD
# Based on APO(MACD), calculate EMA_MACD
if ema_macd == 0:
ema_macd = macd
else:
ema_macd = (macd - ema_macd) * K_slow + ema_macd
macd_values.append(macd)
macd_signal_values.append(ema_macd)
macd_histogram_values.append(macd - ema_macd)
""" Visualization """
# assign data back to goog_data to get index and aligned
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(Fast_EMA_110Days=pd.Series(ema_fast_values, index=goog_data.index))
goog_data = goog_data.assign(Slow_EMA_140Days=pd.Series(ema_slow_values, index=goog_data.index))
goog_data = goog_data.assign(MACD=pd.Series(macd_values, index=goog_data.index))
goog_data = goog_data.assign(EMA_of_MACD_120Days=pd.Series(macd_signal_values, index=goog_data.index))
goog_data = goog_data.assign(MACDHistogram=pd.Series(macd_histogram_values, index=goog_data.index))
print(goog_data['MACDHistogram'])
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(311, ylabel='Google price in $')
goog_data['ClosePrice'].plot(ax=ax1, color='g', lw=2., legend=True)
goog_data['Fast_EMA_110Days'].plot(ax=ax1, color='b', lw=2., legend=True)
goog_data['Slow_EMA_140Days'].plot(ax=ax1, color='r', lw=2., legend=True)
ax2 = fig.add_subplot(312, ylabel='MACD')
goog_data['MACD'].plot(ax=ax2, color='black', lw=2., legend=True)
goog_data['EMA_of_MACD_120Days'].plot(ax=ax2, color='g', lw=2., legend=True)
ax3 = fig.add_subplot(313, ylabel='MACD')
goog_data['MACDHistogram'].plot(ax=ax3, color='r', kind='bar', legend=True, use_index=False)
plt.savefig(dir_path + "/macd.png")
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1,54 @@
import os
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path + '/goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
""" Calculate momentum """
time_period = 20 # lookback period
history = [] # history of observed prices to use in momentum calculation
mom_values = [] # track momentum values for visualization purposes
for close_price in close:
history.append(close_price)
if len(history) > time_period:
del(history[0])
mom = close_price - history[0]
mom_values.append(mom)
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(MomentumFromPrice20DaysAgo=pd.Series(mom_values, index=goog_data.index))
""" Visualization """
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(211, ylabel='Google price in $')
goog_data['ClosePrice'].plot(ax=ax1, color='g', lw=2., legend=True)
ax2 = fig.add_subplot(212, ylabel='Momentum in $')
goog_data['MomentumFromPrice20DaysAgo'].plot(ax=ax2, color='b', lw=2., legend=True)
plt.savefig(dir_path + '/momentum.png')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -0,0 +1,81 @@
import os
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path + '/goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
import statistics as stats
time_period = 20 # look back period to compute gains & losses
gain_history = [] # history of gains over look back period (0 if no gain, magnitude of gain if gain)
loss_history = [] # history of losses over look back period (0 if no loss, magnitude of loss if loss)
avg_gain_values = [] # track avg gains for visualization purposes
avg_loss_values = []
rsi_values = [] # track computed RSI values
last_price = 0 # current_price - last_price > 0 => gain ; current_price - last_price < 0 => loss.
for close_price in close:
if last_price == 0:
last_price = close_price
gain_history.append(max(0, close_price - last_price))
loss_history.append(max(0, last_price - close_price))
last_price = close_price
if len(gain_history) > time_period:
del(gain_history[0])
del(loss_history[0])
avg_gain = stats.mean(gain_history) # average gain over lookback period
avg_loss = stats.mean(loss_history) # average loss over lookback period
avg_gain_values.append(avg_gain)
avg_loss_values.append(avg_loss)
rs = 0
if avg_loss > 0: # to avoid division by 0, which is undefined
rs = avg_gain /avg_loss
rsi = 100 - (100/(1+rs))
rsi_values.append(rsi)
""" Data Visualization """
goog_data = goog_data.assign(ClosePrice=pd.Series(close,index=goog_data.index))
goog_data = goog_data.assign(RelativeStrengthAvgGainOver20Days=pd.Series(avg_gain_values, index=goog_data.index))
goog_data = goog_data.assign(RelativeStrengthAvgLossOver20Days=pd.Series(avg_loss_values, index=goog_data.index))
goog_data = goog_data.assign(RelativeStrengthIndicatorOver20Days=pd.Series(rsi_values, index=goog_data.index))
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(311, ylabel='Google price in $')
goog_data['ClosePrice'].plot(ax=ax1, color='black', lw=2., legend=True)
ax2 = fig.add_subplot(312, ylabel='RS')
goog_data['RelativeStrengthAvgGainOver20Days'].plot(ax=ax2, color='g', lw=2., legend=True)
goog_data['RelativeStrengthAvgLossOver20Days'].plot(ax=ax2, color='r', lw=2., legend=True)
ax3 = fig.add_subplot(313, ylabel='RSI')
goog_data['RelativeStrengthIndicatorOver20Days'].plot(ax=ax3, color='b', lw=2., legend=True)
plt.savefig(dir_path + '/rsi.png')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,58 @@
import os
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2001-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = dir_path + '/goog_data_large.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
""" Calculate mean of each month's return """
goog_monthly_return = goog_data['Adj Close'].pct_change().groupby(
[goog_data['Adj Close'].index.year, goog_data['Adj Close'].index.month]).mean()
print(goog_monthly_return)
goog_monthly_return_list = []
for i in range(len(goog_monthly_return)):
goog_monthly_return_list.append({'month':goog_monthly_return.index[i][1],'monthly_return': goog_monthly_return[i]})
goog_monthly_return_list=pd.DataFrame(goog_monthly_return_list,\
columns=('month','monthly_return'))
print(goog_monthly_return_list)
goog_monthly_return_list.boxplot(column='monthly_return', by='month')
""" Visulization """
import matplotlib.pyplot as plt
ax = plt.gca()
labels = [item.get_text() for item in ax.get_xticklabels()]
print(labels)
labels = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
ax.set_xticklabels(labels)
ax.set_ylabel('GOOG return')
plt.tick_params(axis='both', which='major', labelsize=7)
plt.title("GOOG Monthly return 2001-2018")
plt.suptitle("")
plt.savefig(dir_path + '/seasonality.png')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1,64 @@
import os
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = 'goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
exe_start_time = time.time()
import statistics as stats
time_period = 20 # number of days over which to average
history = [] # to track a history of prices
sma_values = [] # to track simple moving average values
for close_price in goog_data_signal['price']:
history.append(close_price)
if len(history) > time_period:
# we remove oldest price because we only average over last 'time_period' prices
# i.e. keep the latest 20 day window
del(history[0])
sma_values.append(stats.mean(history))
# The first 20 sma of this data will not be mean of 20 values
print("--- algo1: %s seconds ---" % (time.time() - exe_start_time))
exe_start_time = time.time()
sma_values_improved = goog_data_signal.rolling(window=20, win_type='boxcar').mean()
print("--- algo2: %s seconds ---" % (time.time() - exe_start_time))
goog_data = goog_data.assign(ClosePrice=pd.Series(goog_data_signal['price'], index=goog_data.index))
goog_data = goog_data.assign(Simple20DayMovingAverage=pd.Series(sma_values, index=goog_data.index))
goog_data = goog_data.assign(Simple20DayMovingAverage_pd = sma_values_improved)
close_price = goog_data['ClosePrice']
sma = goog_data['Simple20DayMovingAverage']
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
close_price.plot(ax=ax1, color='g', lw=2., legend=True)
sma.plot(ax=ax1, color='r', lw=2., legend=True)
goog_data['Simple20DayMovingAverage_pd'].plot(ax=ax1, color='b', lw=1., legend=True)
plt.savefig(dir_path+'/sma.png')
plt.show()

View File

@ -0,0 +1,58 @@
# Same method as in sma.py, used pandas.DataFrame.rolling for faster calculation
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
exe_start_time = time.time()
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = 'goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
import statistics as stats
time_period = 20 # number of days over which to average
history = [] # to track a history of prices
sma_values = [] # to track simple moving average values
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(Simple20DayMovinigAverage=pd.Series(result, index=goog_data.index))
print(result)
# for close_price in close:
# history.append(close_price)
# if len(history) > time_period: # we remove oldest price because we only average over last 'time_period' prices
# del(history[0])
# sma_values.append(stats.mean(history))
# goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
# goog_data = goog_data.assign(Simple20DayMovingAverage=pd.Series(sma_values, index=goog_data.index))
# close_price = goog_data['ClosePrice']
# sma = goog_data['Simple20DayMovingAverage']
# print("--- %s seconds ---" % (time.time() - exe_start_time))
# import matplotlib.pyplot as plt
# fig = plt.figure()
# ax1 = fig.add_subplot(111, ylabel='Google price in $')
# close_price.plot(ax=ax1, color='g', lw=2., legend=True)
# sma.plot(ax=ax1, color='r', lw=2., legend=True)
# plt.savefig('sma.png')

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -0,0 +1,65 @@
import os
import time
import statistics
import pandas as pd
import numpy as np
from pandas_datareader import data
dir_path = os.path.dirname(os.path.realpath(__file__))
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = 'goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
close = goog_data_signal['price']
exe_start_time = time.time()
import statistics as stats
import math as math
time_period = 20
history = [] # history of prices
sma_values = [] # to tracking sma
stddev_values = [] # history of computed stdev values
for close_price in close:
history.append(close_price)
if len(history) > time_period: # track at most 20 prices
del(history[0])
sma = stats.mean(history)
sma_values.append(sma)
variance = 0
for hist_price in history:
variance = variance + ((hist_price - sma) ** 2)
stdev = math.sqrt(variance / len(history))
stddev_values.append(stdev)
goog_data = goog_data.assign(ClosePrice=pd.Series(close, index=goog_data.index))
goog_data = goog_data.assign(StandardDeviationOver20Days=pd.Series(stddev_values, index=goog_data.index))
""" Visualization """
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(211, ylabel='Google price in $')
goog_data['ClosePrice'].plot(ax=ax1, color='g', lw=2., legend=True)
ax2 = fig.add_subplot(212, ylabel='Stddev in $')
goog_data['StandardDeviationOver20Days'].plot(ax=ax2, color='b', lw=2., legend=True)
plt.savefig(dir_path + '/stdev.png')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,29 @@
import pandas as pd
from pandas_datareader import data
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = 'goog_data.pkl'
try:
goog_data2 = pd.read_pickle(SRC_DATA_FILENAME)
except FileNotFoundError:
goog_data2 = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data2.to_pickle(SRC_DATA_FILENAME)
goog_data = goog_data2.tail(620)
lows = goog_data['Low']
highs = goog_data['High']
print(goog_data)
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
highs.plot(ax=ax1, color='c', lw=2.)
lows.plot(ax=ax1, color='y', lw=2.)
# Return the first 200 rows using pandas.DataFrame.head(200)
plt.hlines(highs.head(200).max(), lows.index.values[0], lows.index.values[-1], linewidth=2, color='g')
plt.hlines(lows.head(200).min(), lows.index.values[0], lows.index.values[-1], linewidth=2, color='r')
plt.axvline(linewidth=2, color='b', x=lows.index.values[200], linestyle=':')
plt.savefig("supportresistanceline.png")

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -0,0 +1,94 @@
import pandas as pd
import numpy as np
from pandas_datareader import data
start_date = '2014-01-01'
end_date = '2018-01-01'
SRC_DATA_FILENAME = 'goog_data.pkl'
try:
goog_data = pd.read_pickle(SRC_DATA_FILENAME)
print('File data found...reading GOOG data')
except FileNotFoundError:
print('File not found...downloading the GOOG data')
goog_data = data.DataReader('GOOG', 'yahoo', start_date, end_date)
goog_data.to_pickle(SRC_DATA_FILENAME)
goog_data_signal = pd.DataFrame(index=goog_data.index)
goog_data_signal['price'] = goog_data['Adj Close']
import numpy as np
def trading_support_resistance(data, bin_width=20):
data['sup_tolerance'] = pd.Series(np.zeros(len(data))) # tolerance of support line
data['res_tolerance'] = pd.Series(np.zeros(len(data))) # tolerance of resistance line
data['sup_count'] = pd.Series(np.zeros(len(data))) # number of hitting support line
data['res_count'] = pd.Series(np.zeros(len(data)))
data['sup'] = pd.Series(np.zeros(len(data))) # support line value (constant)
data['res'] = pd.Series(np.zeros(len(data)))
data['position'] = pd.Series(np.zeros(len(data)))
data['signal'] = pd.Series(np.zeros(len(data)))
in_support = 0
in_resistance = 0
for x in range((bin_width-1) + bin_width, len(data)):
data_section = data[x-bin_width : x+1] # get data within rolling window
support_level = min(data_section['price'])
resistance_level = max(data_section['price'])
range_level = resistance_level - support_level
data['res'][x] = resistance_level
data['sup'][x] = support_level
data['sup_tolerance'][x] = support_level + 0.2*range_level # 20% tolorance
data['res_tolerance'][x] = resistance_level - 0.2*range_level
if (data['price'][x] >= data['res_tolerance'][x]) and (data['price'][x] <= data['res'][x]):
# if price is within resistance tolerance region
in_resistance += 1
data['res_count'][x] = in_resistance
elif (data['price'][x] <= data['sup_tolerance'][x]) and (data['price'][x] >= data['sup'][x]):
# price is within support tolerance region
in_support += 1
data['sup_count'][x] = in_support
else:
# if not within any region, clear count
in_support = 0
in_resistance = 0
if in_resistance > 2:
# If enter resistance region twice
data['signal'][x] = 1
elif in_support > 2:
data['signal'][x] = 0
else:
data['signal'][x] = data['signal'][x-1]
data['position'] = data['signal'].diff()
trading_support_resistance(goog_data_signal)
print(goog_data_signal)
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Google price in $')
goog_data_signal['sup'].plot(ax=ax1, color='g', lw=2.)
goog_data_signal['res'].plot(ax=ax1, color='b', lw=2.)
goog_data_signal['price'].plot(ax=ax1, color='r', lw=2.)
ax1.plot(goog_data_signal.loc[goog_data_signal.position == 1.0].index,
goog_data_signal.price[goog_data_signal.position == 1.0], '^', markersize=7, color='k', label='buy')
ax1.plot(goog_data_signal.loc[goog_data_signal.position == -1.0].index,
goog_data_signal.price[goog_data_signal.position == -1.0], 'v', markersize=7, color='k', label='sell')
plt.legend()
plt.savefig("supportresistanceline_improved")
plt.show()

BIN
img/2_1.jpg 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB