本质上是一种基于统计与概率的计算机运算策略。通过对历史大量的数据进行不同组合的量化策略运算,寻找投资方向和确定买卖时机。随着大环境的改变,策略必然需要变动调整,但我们不变的目标便是执着地寻找出适合当下获利概率最大所对应的投资策略。
随机震荡指标STO(KD)
与MACD类似的是,STO同样地使用了两条曲线来表示,不同的是STO的曲线范围限制在0到100之间。在设计的过程当中,其不仅要研究其收市价,同时还要包括近期所出现过的最高价及最低价等。这样的设计可以综合了动量观念和RSI及移动平均线的各个优点。作为一款动量技术分析方法,其主要的目的是判断是否进入了超买或超买的状态,从而帮助投资者预知价格逆转的时机。STO计算公式(维基解释):
这里我们需要处理股票的历史数据,所以可以先下载到本地,方法可以参考前面所写的博文获取全球各大证券交易所的全部股票交易信息。为了更方便地使用数据,我们需要设计相关的函数,代码如下:
import numpy as np
import math
import random
import json
import matplotlib.pyplot as plt
import sys
sys.setrecursionlimit(10000)
#date|open|high|low|close|volume|adjsuted
def get_stock_hist(num):
s_his=np.genfromtxt('C:/Users/Haipeng/Desktop/python/Korea/Korea_{:03d}.csv'.format(num), delimiter=',')
s_hi=s_his[1:][:]
days=s_hi.shape[0]
this_stock = []
for i in range(1,days,1):
this_day = [i]
for k in range(1,7):
this_day.append(s_hi[i][k])
this_stock.append(this_day)
print 'Maximum date is ',len(this_stock)
return this_stock
def get_price(D, p_tpe):
if p_tpe=='close':
pos=4;
elif p_tpe=='open':
pos=1;
elif p_tpe=='high':
pos=2;
elif p_tpe=='low':
pos=3;
else:
pos=5
price=stock_hist[D-1][pos];
return price
def get_ma(D, N):
p_used=np.zeros(N);
for i in range(1,N+1,1):
p_used[i-1]=stock_hist[(D-1)-(i-1)][4];
ma=np.mean(p_used);
return ma
def get_mar(fro,to,N):
ma = []
for i in range(fro,to+1):
ma.append(get_ma(i,N))
return ma
#Date\Open\High\Low\Close
def get_tuples(fro,to):
res =[]
for d in range(fro,to+1):
tmp = []
tmp.append(d)
tmp.append(get_price(d,'open'))
tmp.append(get_price(d,'high'))
tmp.append(get_price(d,'low'))
tmp.append(get_price(d,'close'))
res.append(tmp)
return res
def get_volume(fro,to):
res = []
for d in range(fro,to+1):
num = 1
try:
if get_price(d,'close')1,'close'):
num = -1
except:
pass
res.append(num*get_price(d,'volume'))
return res
#STO实现
def get_STO(D,N):
a = 1.0/3
def get_H_L(D,N):
high = 0
low = 0
for i in range(N):
high = max(high,get_price(D-i,'high'))
low = min(low,get_price(D-i,'low'))
return [high,low]
def get_K(D,N):
high = get_H_L(D,N)[0]
low = get_H_L(D,N)[1]
RSV = 100*(get_price(D,'close')-low)/(high-low)
if D==N:
return a*RSV+(1-a)*50
else:
return a*RSV+(1-a)*get_K(D-1,N)
def get_D(D,N):
if D==N:
return a*get_K(D,N)+(1-a)*50
else:
return a*get_K(D,N)+(1-a)*get_D(D-1,N)
K = get_K(D,N)
D = get_D(D,N)
return [K,D]
def get_sto(fro,to):
res = [[],[]]
for d in range(fro,to+1):
res[0].append(get_STO(d,9)[0])
res[1].append(get_STO(d,9)[1])
return res
由以上按照定义实现的函数get_STO可以获取某一天的sto数据,再调用get_sto便可以获得一段日期内的数据列。可是由于get_STO中包含了多个递归函数,导致如果获取某段日期内的数据列时要重复多次递归调用,非常的低效率。故而整合以上两函数,可以以下面的函数get_STO_r来代替,将会大大提高计算速度:
def get_STO_r(fro,to,N):
a = 1.0/3
def get_H_L(D,N):
high = 0
low = 0
for i in range(N):
high = max(high,get_price(D-i,'high'))
low = min(low,get_price(D-i,'low'))
return [high,low]
def get_K(D,N):
if D<=N:
return 50
high = get_H_L(D,N)[0]
low = get_H_L(D,N)[1]
RSV = 100*(get_price(D,'close')-low)/(high-low)
return a*RSV+(1-a)*get_K(D-1,N)
K_res = []
for d in range(1,to+1):
K_res.append(get_K(d,N))
D_res = []
for i in range(to):
if i==0:
D_res.append(50)
else:
D_res.append(a*K_res[i]+(1.0-a)*D_res[-1])
K = K_res[fro-1:]
D = D_res[fro-1:]
return [K,D]
绘图代码:
def plot_STO(fro,to):
volume = get_volume(fro,to)
tmp = get_STO(fro,to,9)
K9 = tmp[0]
D9 = tmp[1]
ma5 = get_mar(fro,to,5)
ma10 = get_mar(fro,to,10)
ma20 = get_mar(fro,to,20)
tuples = get_tuples(fro,to)
date = [d for d in range(fro,to+1)]
fig = plt.figure(figsize=(8,5))
p1 = plt.subplot2grid((5,4),(0,0),rowspan=3,colspan=4,axisbg='k')
p1.set_title("Stochastic Oscillator(STO)")
p1.set_ylabel("Price")
p1.plot(date,ma5,'m')
p1.plot(date,ma10,'b')
p1.plot(date,ma20,'y')
p1.legend(('MA5','MA10','MA20'))
p1.grid(True,color='w')
candlestick_ohlc(p1, tuples, width=0.7,colorup='r',colordown="g")
p2 = plt.subplot2grid((5,4),(3,0),colspan=4,axisbg='c')
p2.set_ylabel("Volume")
colors = []
for i in range(len(volume)):
if volume[i]<0:
colors.append('green')
volume[i] = -volume[i]
else:
colors.append('red')
p2.bar(date,volume,color=colors)
p3 = plt.subplot2grid((5,4),(4,0),colspan=4,axisbg='m')
p3.set_ylabel("STO")
p3.set_xlabel("Dates")
p3.plot(date,K9, 'r-')
p3.plot(date,D9, 'g-')
p3.legend(('K9','D9'),loc='upper left')
plt.subplots_adjust(hspace=0)
plt.show()# show the plot on the screen
stock_hist = get_stock_hist(18)
plot_STO(200,800)
#例如,可得图2
plot_STO(420,520)
博文包含了获取数据、分析相关原理及技术指标STO的实现到图像的可视化。而股市上很多关于STO技术指标的操作指南,在这里并没有详述。原因是其实对于不一样的市场,不同的股票,不同的投资者可能得出完全不一样的策略。我们需要关注的事是如何让计算机通过高速运算帮我们找出某种隐含的规则,而STO可以作为其中的一个指标,来弥补人经验的缺陷。
量化交易——传统技术分析平滑异同移动平均线MACD的原理及实现
量化交易——传统技术分析能量潮指标OBV的原理及实现
量化交易——传统技术分析相对强弱指数RSI的原理及实现
量化交易——传统技术分析顺势指标CCI的原理及实现
量化交易——传统技术分析布林通道BollingerBands的原理及实现