TA-Lib 量化交易代码实例 <二> 获取布林线的上轨,中轨,下轨的数据

李魔佛 发表了文章 • 0 个评论 • 7251 次浏览 • 2017-05-28 23:08 • 来自相关话题

BOLL指标的原理
BOLL指标是美国股市分析家约翰·布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标。一般而言,股价的运动总是围绕某一价值中枢(如均线、成本线等)在一定的范围内变动,布林线指标指标正是在上述条件的基础上,引进了“股价通道”的概念,其认为股价通道的宽窄随着股价波动幅度的大小而变化,而且股价通道又具有变异性,它会随着股价的变化而自动调整。正是由于它具有灵活性、直观性和趋势性的特点,BOLL指标渐渐成为投资者广为应用的市场上热门指标。
在众多技术分析指标中,BOLL指标属于比较特殊的一类指标。绝大多数技术分析指标都是通过数量的方法构造出来的,它们本身不依赖趋势分析和形态分析,而BOLL指标却股价的形态和趋势有着密不可分的联系。BOLL指标中的“股价通道”概念正是股价趋势理论的直观表现形式。BOLL是利用“股价通道”来显示股价的各种价位,当股价波动很小,处于盘整时,股价通道就会变窄,这可能预示着股价的波动处于暂时的平静期;当股价波动超出狭窄的股价通道的上轨时,预示着股价的异常激烈的向上波动即将开始;当股价波动超出狭窄的股价通道的下轨时,同样也预示着股价的异常激烈的向下波动将开始。
投资者常常会遇到两种最常见的交易陷阱,一是买低陷阱,投资者在所谓的低位买进之后,股价不仅没有止跌反而不断下跌;二是卖高陷阱,股票在所谓的高点卖出后,股价却一路上涨。布林线特别运用了爱因斯坦的相对论,认为各类市场间都是互动的,市场内和市场间的各种变化都是相对性的,是不存在绝对性的,股价的高低是相对的,股价在上轨线以上或在下轨线以下只反映该股股价相对较高或较低,投资者作出投资判断前还须综合参考其他技术指标,包括价量配合,心理类指标,类比类指标,市场间的关联数据等。
总之,BOLL指标中的股价通道对预测未来行情的走势起着重要的参考作用,它也是布林线指标所特有的分析手段。
[编辑]
BOLL指标的计算方法
在所有的指标计算中,BOLL指标的计算方法是最复杂的之一,其中引进了统计学中的标准差概念,涉及到中轨线(MB)、上轨线(UP)和下轨线(DN)的计算。另外,和其他指标的计算一样,由于选用的计算周期的不同,BOLL指标也包括日BOLL指标、周BOLL指标、月BOLL指标年BOLL指标以及分钟BOLL指标等各种类型。经常被用于股市研判的是日BOLL指标和周BOLL指标。虽然它们的计算时的取值有所不同,但基本的计算方法一样。以日BOLL指标计算为例,其计算方法如下:
1、日BOLL指标的计算公式
中轨线=N日的移动平均线
上轨线=中轨线+两倍的标准差
下轨线=中轨线-两倍的标准差
2、日BOLL指标的计算过程
1)计算MA
MA=N日内的收盘价之和÷N2)计算标准差MD
MD=平方根N日的(C-MA)的两次方之和除以N3)计算MB、UP、DN线
MB=(N-1)日的MA
UP=MB+2×MD
DN=MB-2×MD在股市分析软件中,BOLL指标一共由四条线组成,即上轨线UP 、中轨线MB、下轨线DN和价格线。其中上轨线UP是UP数值的连线,用黄色线表示;中轨线MB是MB数值的连线,用白色线表示;下轨线DN是DN数值的连线,用紫色线表示;价格线是以美国线表示,颜色为浅蓝色。和其他技术指标一样,在实战中,投资者不需要进行BOLL指标的计算,主要是了解BOLL的计算方法和过程,以便更加深入地掌握BOLL指标的实质,为运用指标打下基础。
 
#通过tushare获取股票信息
df=ts.get_k_data('300580',start='2017-01-12',end='2017-05-26')
#提取收盘价
closed=df['close'].values

upper,middle,lower=talib.BBANDS(closed,matype=talib.MA_Type.T3)

print upper,middle,lower
plt.plot(upper)
plt.plot(middle)
plt.plot(lower)
plt.grid()
plt.show()
diff1=upper-middle
diff2=middle-lower
print diff1
print diff2





 
最后那里可以看到diff1和diff2是一样的。 验证了布林线的定义ma+2d,m-2d。 查看全部

BOLL指标的原理
BOLL指标是美国股市分析家约翰·布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标。一般而言,股价的运动总是围绕某一价值中枢(如均线、成本线等)在一定的范围内变动,布林线指标指标正是在上述条件的基础上,引进了“股价通道”的概念,其认为股价通道的宽窄随着股价波动幅度的大小而变化,而且股价通道又具有变异性,它会随着股价的变化而自动调整。正是由于它具有灵活性、直观性和趋势性的特点,BOLL指标渐渐成为投资者广为应用的市场上热门指标。
在众多技术分析指标中,BOLL指标属于比较特殊的一类指标。绝大多数技术分析指标都是通过数量的方法构造出来的,它们本身不依赖趋势分析和形态分析,而BOLL指标却股价的形态和趋势有着密不可分的联系。BOLL指标中的“股价通道”概念正是股价趋势理论的直观表现形式。BOLL是利用“股价通道”来显示股价的各种价位,当股价波动很小,处于盘整时,股价通道就会变窄,这可能预示着股价的波动处于暂时的平静期;当股价波动超出狭窄的股价通道的上轨时,预示着股价的异常激烈的向上波动即将开始;当股价波动超出狭窄的股价通道的下轨时,同样也预示着股价的异常激烈的向下波动将开始。
投资者常常会遇到两种最常见的交易陷阱,一是买低陷阱,投资者在所谓的低位买进之后,股价不仅没有止跌反而不断下跌;二是卖高陷阱,股票在所谓的高点卖出后,股价却一路上涨。布林线特别运用了爱因斯坦的相对论,认为各类市场间都是互动的,市场内和市场间的各种变化都是相对性的,是不存在绝对性的,股价的高低是相对的,股价在上轨线以上或在下轨线以下只反映该股股价相对较高或较低,投资者作出投资判断前还须综合参考其他技术指标,包括价量配合,心理类指标,类比类指标,市场间的关联数据等。
总之,BOLL指标中的股价通道对预测未来行情的走势起着重要的参考作用,它也是布林线指标所特有的分析手段。
[编辑]
BOLL指标的计算方法
在所有的指标计算中,BOLL指标的计算方法是最复杂的之一,其中引进了统计学中的标准差概念,涉及到中轨线(MB)、上轨线(UP)和下轨线(DN)的计算。另外,和其他指标的计算一样,由于选用的计算周期的不同,BOLL指标也包括日BOLL指标、周BOLL指标、月BOLL指标年BOLL指标以及分钟BOLL指标等各种类型。经常被用于股市研判的是日BOLL指标和周BOLL指标。虽然它们的计算时的取值有所不同,但基本的计算方法一样。以日BOLL指标计算为例,其计算方法如下:
1、日BOLL指标的计算公式
中轨线=N日的移动平均线
上轨线=中轨线+两倍的标准差
下轨线=中轨线-两倍的标准差
2、日BOLL指标的计算过程
1)计算MA
MA=N日内的收盘价之和÷N2)计算标准差MD
MD=平方根N日的(C-MA)的两次方之和除以N3)计算MB、UP、DN线
MB=(N-1)日的MA
UP=MB+2×MD
DN=MB-2×MD在股市分析软件中,BOLL指标一共由四条线组成,即上轨线UP 、中轨线MB、下轨线DN和价格线。其中上轨线UP是UP数值的连线,用黄色线表示;中轨线MB是MB数值的连线,用白色线表示;下轨线DN是DN数值的连线,用紫色线表示;价格线是以美国线表示,颜色为浅蓝色。和其他技术指标一样,在实战中,投资者不需要进行BOLL指标的计算,主要是了解BOLL的计算方法和过程,以便更加深入地掌握BOLL指标的实质,为运用指标打下基础。
 
    #通过tushare获取股票信息
df=ts.get_k_data('300580',start='2017-01-12',end='2017-05-26')
#提取收盘价
closed=df['close'].values

upper,middle,lower=talib.BBANDS(closed,matype=talib.MA_Type.T3)

print upper,middle,lower
plt.plot(upper)
plt.plot(middle)
plt.plot(lower)
plt.grid()
plt.show()
diff1=upper-middle
diff2=middle-lower
print diff1
print diff2


布林线.PNG

 
最后那里可以看到diff1和diff2是一样的。 验证了布林线的定义ma+2d,m-2d。

quantdigger 量化交易入门 代码示例

李魔佛 发表了文章 • 1 个评论 • 1734 次浏览 • 2017-05-28 21:39 • 来自相关话题

第五天
 
《》
待更新
第五天
 
《》
待更新

TA-Lib 量化交易代码实例 <一> 获取5日,10日,20日均线数据

李魔佛 发表了文章 • 0 个评论 • 7969 次浏览 • 2017-05-28 21:37 • 来自相关话题

第一节
 
安装教程在前面内容已经介绍过了,对于新手也是有点障碍,可以参照前面的文章进行一步一步操作。 http://30daydo.com/article/195 #通过tushare获取股票信息
df=ts.get_k_data('300580',start='2017-01-12',end='2017-05-26')
#提取收盘价
closed=df['close'].values
#获取均线的数据,通过timeperiod参数来分别获取 5,10,20 日均线的数据。
ma5=talib.SMA(closed,timeperiod=5)
ma10=talib.SMA(closed,timeperiod=10)
ma20=talib.SMA(closed,timeperiod=20)

#打印出来每一个数据
print closed
print ma5
print ma10
print ma20

#通过plog函数可以很方便的绘制出每一条均线
plt.plot(closed)
plt.plot(ma5)
plt.plot(ma10)
plt.plot(ma20)
#添加网格,可有可无,只是让图像好看点
plt.grid()
#记得加这一句,不然不会显示图像
plt.show()
上面第一句使用tushare获取股票的数据,如果不知道怎么操作的,可以在这里参考,同样是入门的教程。
http://30daydo.com/article/13
 
 
运行上面的代码后,可以得到下面的曲线:
 





 
你们可以去对比一下贝斯特的收盘价,5日,10日,20日均线。是不是一样的?
就这样我们就完成了均线的获取。 是不是很简单?
 
 
  查看全部
第一节
 
安装教程在前面内容已经介绍过了,对于新手也是有点障碍,可以参照前面的文章进行一步一步操作。 http://30daydo.com/article/195
    #通过tushare获取股票信息
df=ts.get_k_data('300580',start='2017-01-12',end='2017-05-26')
#提取收盘价
closed=df['close'].values
#获取均线的数据,通过timeperiod参数来分别获取 5,10,20 日均线的数据。
ma5=talib.SMA(closed,timeperiod=5)
ma10=talib.SMA(closed,timeperiod=10)
ma20=talib.SMA(closed,timeperiod=20)

#打印出来每一个数据
print closed
print ma5
print ma10
print ma20

#通过plog函数可以很方便的绘制出每一条均线
plt.plot(closed)
plt.plot(ma5)
plt.plot(ma10)
plt.plot(ma20)
#添加网格,可有可无,只是让图像好看点
plt.grid()
#记得加这一句,不然不会显示图像
plt.show()

上面第一句使用tushare获取股票的数据,如果不知道怎么操作的,可以在这里参考,同样是入门的教程。
http://30daydo.com/article/13
 
 
运行上面的代码后,可以得到下面的曲线:
 

贝斯特曲线.PNG

 
你们可以去对比一下贝斯特的收盘价,5日,10日,20日均线。是不是一样的?
就这样我们就完成了均线的获取。 是不是很简单?
 
 
 

量化工具TA-Lib 使用例子

李魔佛 发表了文章 • 0 个评论 • 5586 次浏览 • 2017-05-26 23:51 • 来自相关话题

http://30daydo.com/article/196
 TA-Lib主要用来计算一些股市中常见的指标。
比如MACD,BOLL,均线等参数。
 #-*-coding=utf-8-*-
import Tkinter as tk
from Tkinter import *
import ttk
import matplotlib.pyplot as plt

import numpy as np
import talib as ta

series = np.random.choice([1, -1], size=200)
close = np.cumsum(series).astype(float)

# 重叠指标
def overlap_process(event):
print(event.widget.get())
overlap = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(overlap, fontproperties="SimHei")

if overlap == '布林线':
pass
elif overlap == '双指数移动平均线':
real = ta.DEMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '指数移动平均线 ':
real = ta.EMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '希尔伯特变换——瞬时趋势线':
real = ta.HT_TRENDLINE(close)
axes[1].plot(real, '')
elif overlap == '考夫曼自适应移动平均线':
real = ta.KAMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '移动平均线':
real = ta.MA(close, timeperiod=30, matype=0)
axes[1].plot(real, '')
elif overlap == 'MESA自适应移动平均':
mama, fama = ta.MAMA(close, fastlimit=0, slowlimit=0)
axes[1].plot(mama, '')
axes[1].plot(fama, '')
elif overlap == '变周期移动平均线':
real = ta.MAVP(close, periods, minperiod=2, maxperiod=30, matype=0)
axes[1].plot(real, '')
elif overlap == '简单移动平均线':
real = ta.SMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '三指数移动平均线(T3)':
real = ta.T3(close, timeperiod=5, vfactor=0)
axes[1].plot(real, '')
elif overlap == '三指数移动平均线':
real = ta.TEMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '三角形加权法 ':
real = ta.TRIMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '加权移动平均数':
real = ta.WMA(close, timeperiod=30)
axes[1].plot(real, '')
plt.show()

# 动量指标
def momentum_process(event):
print(event.widget.get())
momentum = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(momentum, fontproperties="SimHei")

if momentum == '绝对价格振荡器':
real = ta.APO(close, fastperiod=12, slowperiod=26, matype=0)
axes[1].plot(real, '')
elif momentum == '钱德动量摆动指标':
real = ta.CMO(close, timeperiod=14)
axes[1].plot(real, '')
elif momentum == '移动平均收敛/散度':
macd, macdsignal, macdhist = ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
axes[1].plot(macd, '')
axes[1].plot(macdsignal, '')
axes[1].plot(macdhist, '')
elif momentum == '带可控MA类型的MACD':
macd, macdsignal, macdhist = ta.MACDEXT(close, fastperiod=12, fastmatype=0, slowperiod=26, slowmatype=0, signalperiod=9, signalmatype=0)
axes[1].plot(macd, '')
axes[1].plot(macdsignal, '')
axes[1].plot(macdhist, '')
elif momentum == '移动平均收敛/散度 固定 12/26':
macd, macdsignal, macdhist = ta.MACDFIX(close, signalperiod=9)
axes[1].plot(macd, '')
axes[1].plot(macdsignal, '')
axes[1].plot(macdhist, '')
elif momentum == '动量':
real = ta.MOM(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '比例价格振荡器':
real = ta.PPO(close, fastperiod=12, slowperiod=26, matype=0)
axes[1].plot(real, '')
elif momentum == '变化率':
real = ta.ROC(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '变化率百分比':
real = ta.ROCP(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '变化率的比率':
real = ta.ROCR(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '变化率的比率100倍':
real = ta.ROCR100(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '相对强弱指数':
real = ta.RSI(close, timeperiod=14)
axes[1].plot(real, '')
elif momentum == '随机相对强弱指标':
fastk, fastd = ta.STOCHRSI(close, timeperiod=14, fastk_period=5, fastd_period=3, fastd_matype=0)
axes[1].plot(fastk, '')
axes[1].plot(fastd, '')
elif momentum == '三重光滑EMA的日变化率':
real = ta.TRIX(close, timeperiod=30)
axes[1].plot(real, '')

plt.show()

# 周期指标
def cycle_process(event):
print(event.widget.get())
cycle = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(cycle, fontproperties="SimHei")

if cycle == '希尔伯特变换——主要的循环周期':
real = ta.HT_DCPERIOD(close)
axes[1].plot(real, '')
elif cycle == '希尔伯特变换,占主导地位的周期阶段':
real = ta.HT_DCPHASE(close)
axes[1].plot(real, '')
elif cycle == '希尔伯特变换——相量组件':
inphase, quadrature = ta.HT_PHASOR(close)
axes[1].plot(inphase, '')
axes[1].plot(quadrature, '')
elif cycle == '希尔伯特变换——正弦曲线':
sine, leadsine = ta.HT_SINE(close)
axes[1].plot(sine, '')
axes[1].plot(leadsine, '')
elif cycle == '希尔伯特变换——趋势和周期模式':
integer = ta.HT_TRENDMODE(close)
axes[1].plot(integer, '')

plt.show()


# 统计功能
def statistic_process(event):
print(event.widget.get())
statistic = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(statistic, fontproperties="SimHei")

if statistic == '线性回归':
real = ta.LINEARREG(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '线性回归角度':
real = ta.LINEARREG_ANGLE(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '线性回归截距':
real = ta.LINEARREG_INTERCEPT(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '线性回归斜率':
real = ta.LINEARREG_SLOPE(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '标准差':
real = ta.STDDEV(close, timeperiod=5, nbdev=1)
axes[1].plot(real, '')
elif statistic == '时间序列预测':
real = ta.TSF(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '方差':
real = ta.VAR(close, timeperiod=5, nbdev=1)
axes[1].plot(real, '')

plt.show()


# 数学变换
def math_transform_process(event):
print(event.widget.get())
math_transform = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(math_transform, fontproperties="SimHei")


if math_transform == '反余弦':
real = ta.ACOS(close)
axes[1].plot(real, '')
elif math_transform == '反正弦':
real = ta.ASIN(close)
axes[1].plot(real, '')
elif math_transform == '反正切':
real = ta.ATAN(close)
axes[1].plot(real, '')
elif math_transform == '向上取整':
real = ta.CEIL(close)
axes[1].plot(real, '')
elif math_transform == '余弦':
real = ta.COS(close)
axes[1].plot(real, '')
elif math_transform == '双曲余弦':
real = ta.COSH(close)
axes[1].plot(real, '')
elif math_transform == '指数':
real = ta.EXP(close)
axes[1].plot(real, '')
elif math_transform == '向下取整':
real = ta.FLOOR(close)
axes[1].plot(real, '')
elif math_transform == '自然对数':
real = ta.LN(close)
axes[1].plot(real, '')
elif math_transform == '常用对数':
real = ta.LOG10(close)
axes[1].plot(real, '')
elif math_transform == '正弦':
real = ta.SIN(close)
axes[1].plot(real, '')
elif math_transform == '双曲正弦':
real = ta.SINH(close)
axes[1].plot(real, '')
elif math_transform == '平方根':
real = ta.SQRT(close)
axes[1].plot(real, '')
elif math_transform == '正切':
real = ta.TAN(close)
axes[1].plot(real, '')
elif math_transform == '双曲正切':
real = ta.TANH(close)
axes[1].plot(real, '')

plt.show()


# 数学操作
def math_operator_process(event):
print(event.widget.get())
math_operator = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(math_operator, fontproperties="SimHei")


if math_operator == '指定的期间的最大值':
real = ta.MAX(close, timeperiod=30)
axes[1].plot(real, '')
elif math_operator == '指定的期间的最大值的索引':
integer = ta.MAXINDEX(close, timeperiod=30)
axes[1].plot(integer, '')
elif math_operator == '指定的期间的最小值':
real = ta.MIN(close, timeperiod=30)
axes[1].plot(real, '')
elif math_operator == '指定的期间的最小值的索引':
integer = ta.MININDEX(close, timeperiod=30)
axes[1].plot(integer, '')
elif math_operator == '指定的期间的最小和最大值':
min, max = ta.MINMAX(close, timeperiod=30)
axes[1].plot(min, '')
axes[1].plot(max, '')
elif math_operator == '指定的期间的最小和最大值的索引':
minidx, maxidx = ta.MINMAXINDEX(close, timeperiod=30)
axes[1].plot(minidx, '')
axes[1].plot(maxidx, '')
elif math_operator == '合计':
real = ta.SUM(close, timeperiod=30)
axes[1].plot(real, '')

plt.show()


root = tk.Tk()

# 第一行:重叠指标
rowframe1 = tk.Frame(root)
rowframe1.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe1, text="重叠指标").pack(side=tk.LEFT)

overlap_indicator = tk.StringVar() # 重叠指标
combobox1 = ttk.Combobox(rowframe1, textvariable=overlap_indicator)
combobox1['values'] = ['布林线','双指数移动平均线','指数移动平均线 ','希尔伯特变换——瞬时趋势线',
'考夫曼自适应移动平均线','移动平均线','MESA自适应移动平均','变周期移动平均线',
'简单移动平均线','三指数移动平均线(T3)','三指数移动平均线','三角形加权法 ','加权移动平均数']
combobox1.current(0)
combobox1.pack(side=tk.LEFT)

combobox1.bind('<<ComboboxSelected>>', overlap_process)


# 第二行:动量指标
rowframe2 = tk.Frame(root)
rowframe2.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe2, text="动量指标").pack(side=tk.LEFT)

momentum_indicator = tk.StringVar() # 动量指标
combobox2 = ttk.Combobox(rowframe2, textvariable=momentum_indicator)
combobox2['values'] = ['绝对价格振荡器','钱德动量摆动指标','移动平均收敛/散度','带可控MA类型的MACD',
'移动平均收敛/散度 固定 12/26','动量','比例价格振荡器','变化率','变化率百分比',
'变化率的比率','变化率的比率100倍','相对强弱指数','随机相对强弱指标','三重光滑EMA的日变化率']

combobox2.current(0)
combobox2.pack(side=tk.LEFT)

combobox2.bind('<<ComboboxSelected>>', momentum_process)



# 第三行:周期指标
rowframe3 = tk.Frame(root)
rowframe3.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe3, text="周期指标").pack(side=tk.LEFT)

cycle_indicator = tk.StringVar() # 周期指标
combobox3 = ttk.Combobox(rowframe3, textvariable=cycle_indicator)
combobox3['values'] = ['希尔伯特变换——主要的循环周期','希尔伯特变换——主要的周期阶段','希尔伯特变换——相量组件',
'希尔伯特变换——正弦曲线','希尔伯特变换——趋势和周期模式']

combobox3.current(0)
combobox3.pack(side=tk.LEFT)

combobox3.bind('<<ComboboxSelected>>', cycle_process)


# 第四行:统计功能
rowframe4 = tk.Frame(root)
rowframe4.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe4, text="统计功能").pack(side=tk.LEFT)

statistic_indicator = tk.StringVar() # 统计功能
combobox4 = ttk.Combobox(rowframe4, textvariable=statistic_indicator)
combobox4['values'] = ['贝塔系数;投资风险与股市风险系数','皮尔逊相关系数','线性回归','线性回归角度',
'线性回归截距','线性回归斜率','标准差','时间序列预测','方差']

combobox4.current(0)
combobox4.pack(side=tk.LEFT)

combobox4.bind('<<ComboboxSelected>>', statistic_process)


# 第五行:数学变换
rowframe5 = tk.Frame(root)
rowframe5.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe5, text="数学变换").pack(side=tk.LEFT)

math_transform = tk.StringVar() # 数学变换
combobox5 = ttk.Combobox(rowframe5, textvariable=math_transform_process)
combobox5['values'] = ['反余弦','反正弦','反正切','向上取整','余弦','双曲余弦','指数','向下取整',
'自然对数','常用对数','正弦','双曲正弦','平方根','正切','双曲正切']

combobox5.current(0)
combobox5.pack(side=tk.LEFT)

combobox5.bind('<<ComboboxSelected>>', math_transform_process)


# 第六行:数学操作
rowframe6 = tk.Frame(root)
rowframe6.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe6, text="数学操作").pack(side=tk.LEFT)

math_operator = tk.StringVar() # 数学操作
combobox6 = ttk.Combobox(rowframe6, textvariable=math_operator_process)
combobox6['values'] = ['指定期间的最大值','指定期间的最大值的索引','指定期间的最小值','指定期间的最小值的索引',
'指定期间的最小和最大值','指定期间的最小和最大值的索引','合计']

combobox6.current(0)
combobox6.pack(side=tk.LEFT)

combobox6.bind('<<ComboboxSelected>>', math_operator_process)




root.mainloop() 查看全部
http://30daydo.com/article/196
 TA-Lib主要用来计算一些股市中常见的指标。
比如MACD,BOLL,均线等参数。
 
#-*-coding=utf-8-*-
import Tkinter as tk
from Tkinter import *
import ttk
import matplotlib.pyplot as plt

import numpy as np
import talib as ta

series = np.random.choice([1, -1], size=200)
close = np.cumsum(series).astype(float)

# 重叠指标
def overlap_process(event):
print(event.widget.get())
overlap = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(overlap, fontproperties="SimHei")

if overlap == '布林线':
pass
elif overlap == '双指数移动平均线':
real = ta.DEMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '指数移动平均线 ':
real = ta.EMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '希尔伯特变换——瞬时趋势线':
real = ta.HT_TRENDLINE(close)
axes[1].plot(real, '')
elif overlap == '考夫曼自适应移动平均线':
real = ta.KAMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '移动平均线':
real = ta.MA(close, timeperiod=30, matype=0)
axes[1].plot(real, '')
elif overlap == 'MESA自适应移动平均':
mama, fama = ta.MAMA(close, fastlimit=0, slowlimit=0)
axes[1].plot(mama, '')
axes[1].plot(fama, '')
elif overlap == '变周期移动平均线':
real = ta.MAVP(close, periods, minperiod=2, maxperiod=30, matype=0)
axes[1].plot(real, '')
elif overlap == '简单移动平均线':
real = ta.SMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '三指数移动平均线(T3)':
real = ta.T3(close, timeperiod=5, vfactor=0)
axes[1].plot(real, '')
elif overlap == '三指数移动平均线':
real = ta.TEMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '三角形加权法 ':
real = ta.TRIMA(close, timeperiod=30)
axes[1].plot(real, '')
elif overlap == '加权移动平均数':
real = ta.WMA(close, timeperiod=30)
axes[1].plot(real, '')
plt.show()

# 动量指标
def momentum_process(event):
print(event.widget.get())
momentum = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(momentum, fontproperties="SimHei")

if momentum == '绝对价格振荡器':
real = ta.APO(close, fastperiod=12, slowperiod=26, matype=0)
axes[1].plot(real, '')
elif momentum == '钱德动量摆动指标':
real = ta.CMO(close, timeperiod=14)
axes[1].plot(real, '')
elif momentum == '移动平均收敛/散度':
macd, macdsignal, macdhist = ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
axes[1].plot(macd, '')
axes[1].plot(macdsignal, '')
axes[1].plot(macdhist, '')
elif momentum == '带可控MA类型的MACD':
macd, macdsignal, macdhist = ta.MACDEXT(close, fastperiod=12, fastmatype=0, slowperiod=26, slowmatype=0, signalperiod=9, signalmatype=0)
axes[1].plot(macd, '')
axes[1].plot(macdsignal, '')
axes[1].plot(macdhist, '')
elif momentum == '移动平均收敛/散度 固定 12/26':
macd, macdsignal, macdhist = ta.MACDFIX(close, signalperiod=9)
axes[1].plot(macd, '')
axes[1].plot(macdsignal, '')
axes[1].plot(macdhist, '')
elif momentum == '动量':
real = ta.MOM(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '比例价格振荡器':
real = ta.PPO(close, fastperiod=12, slowperiod=26, matype=0)
axes[1].plot(real, '')
elif momentum == '变化率':
real = ta.ROC(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '变化率百分比':
real = ta.ROCP(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '变化率的比率':
real = ta.ROCR(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '变化率的比率100倍':
real = ta.ROCR100(close, timeperiod=10)
axes[1].plot(real, '')
elif momentum == '相对强弱指数':
real = ta.RSI(close, timeperiod=14)
axes[1].plot(real, '')
elif momentum == '随机相对强弱指标':
fastk, fastd = ta.STOCHRSI(close, timeperiod=14, fastk_period=5, fastd_period=3, fastd_matype=0)
axes[1].plot(fastk, '')
axes[1].plot(fastd, '')
elif momentum == '三重光滑EMA的日变化率':
real = ta.TRIX(close, timeperiod=30)
axes[1].plot(real, '')

plt.show()

# 周期指标
def cycle_process(event):
print(event.widget.get())
cycle = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(cycle, fontproperties="SimHei")

if cycle == '希尔伯特变换——主要的循环周期':
real = ta.HT_DCPERIOD(close)
axes[1].plot(real, '')
elif cycle == '希尔伯特变换,占主导地位的周期阶段':
real = ta.HT_DCPHASE(close)
axes[1].plot(real, '')
elif cycle == '希尔伯特变换——相量组件':
inphase, quadrature = ta.HT_PHASOR(close)
axes[1].plot(inphase, '')
axes[1].plot(quadrature, '')
elif cycle == '希尔伯特变换——正弦曲线':
sine, leadsine = ta.HT_SINE(close)
axes[1].plot(sine, '')
axes[1].plot(leadsine, '')
elif cycle == '希尔伯特变换——趋势和周期模式':
integer = ta.HT_TRENDMODE(close)
axes[1].plot(integer, '')

plt.show()


# 统计功能
def statistic_process(event):
print(event.widget.get())
statistic = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(statistic, fontproperties="SimHei")

if statistic == '线性回归':
real = ta.LINEARREG(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '线性回归角度':
real = ta.LINEARREG_ANGLE(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '线性回归截距':
real = ta.LINEARREG_INTERCEPT(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '线性回归斜率':
real = ta.LINEARREG_SLOPE(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '标准差':
real = ta.STDDEV(close, timeperiod=5, nbdev=1)
axes[1].plot(real, '')
elif statistic == '时间序列预测':
real = ta.TSF(close, timeperiod=14)
axes[1].plot(real, '')
elif statistic == '方差':
real = ta.VAR(close, timeperiod=5, nbdev=1)
axes[1].plot(real, '')

plt.show()


# 数学变换
def math_transform_process(event):
print(event.widget.get())
math_transform = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(math_transform, fontproperties="SimHei")


if math_transform == '反余弦':
real = ta.ACOS(close)
axes[1].plot(real, '')
elif math_transform == '反正弦':
real = ta.ASIN(close)
axes[1].plot(real, '')
elif math_transform == '反正切':
real = ta.ATAN(close)
axes[1].plot(real, '')
elif math_transform == '向上取整':
real = ta.CEIL(close)
axes[1].plot(real, '')
elif math_transform == '余弦':
real = ta.COS(close)
axes[1].plot(real, '')
elif math_transform == '双曲余弦':
real = ta.COSH(close)
axes[1].plot(real, '')
elif math_transform == '指数':
real = ta.EXP(close)
axes[1].plot(real, '')
elif math_transform == '向下取整':
real = ta.FLOOR(close)
axes[1].plot(real, '')
elif math_transform == '自然对数':
real = ta.LN(close)
axes[1].plot(real, '')
elif math_transform == '常用对数':
real = ta.LOG10(close)
axes[1].plot(real, '')
elif math_transform == '正弦':
real = ta.SIN(close)
axes[1].plot(real, '')
elif math_transform == '双曲正弦':
real = ta.SINH(close)
axes[1].plot(real, '')
elif math_transform == '平方根':
real = ta.SQRT(close)
axes[1].plot(real, '')
elif math_transform == '正切':
real = ta.TAN(close)
axes[1].plot(real, '')
elif math_transform == '双曲正切':
real = ta.TANH(close)
axes[1].plot(real, '')

plt.show()


# 数学操作
def math_operator_process(event):
print(event.widget.get())
math_operator = event.widget.get()

upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
fig, axes = plt.subplots(2, 1, sharex=True)
ax1, ax2 = axes[0], axes[1]
axes[0].plot(close, '', markersize=3)
axes[0].plot(upperband, '')
axes[0].plot(middleband, '')
axes[0].plot(lowerband, '')
axes[0].set_title(math_operator, fontproperties="SimHei")


if math_operator == '指定的期间的最大值':
real = ta.MAX(close, timeperiod=30)
axes[1].plot(real, '')
elif math_operator == '指定的期间的最大值的索引':
integer = ta.MAXINDEX(close, timeperiod=30)
axes[1].plot(integer, '')
elif math_operator == '指定的期间的最小值':
real = ta.MIN(close, timeperiod=30)
axes[1].plot(real, '')
elif math_operator == '指定的期间的最小值的索引':
integer = ta.MININDEX(close, timeperiod=30)
axes[1].plot(integer, '')
elif math_operator == '指定的期间的最小和最大值':
min, max = ta.MINMAX(close, timeperiod=30)
axes[1].plot(min, '')
axes[1].plot(max, '')
elif math_operator == '指定的期间的最小和最大值的索引':
minidx, maxidx = ta.MINMAXINDEX(close, timeperiod=30)
axes[1].plot(minidx, '')
axes[1].plot(maxidx, '')
elif math_operator == '合计':
real = ta.SUM(close, timeperiod=30)
axes[1].plot(real, '')

plt.show()


root = tk.Tk()

# 第一行:重叠指标
rowframe1 = tk.Frame(root)
rowframe1.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe1, text="重叠指标").pack(side=tk.LEFT)

overlap_indicator = tk.StringVar() # 重叠指标
combobox1 = ttk.Combobox(rowframe1, textvariable=overlap_indicator)
combobox1['values'] = ['布林线','双指数移动平均线','指数移动平均线 ','希尔伯特变换——瞬时趋势线',
'考夫曼自适应移动平均线','移动平均线','MESA自适应移动平均','变周期移动平均线',
'简单移动平均线','三指数移动平均线(T3)','三指数移动平均线','三角形加权法 ','加权移动平均数']
combobox1.current(0)
combobox1.pack(side=tk.LEFT)

combobox1.bind('<<ComboboxSelected>>', overlap_process)


# 第二行:动量指标
rowframe2 = tk.Frame(root)
rowframe2.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe2, text="动量指标").pack(side=tk.LEFT)

momentum_indicator = tk.StringVar() # 动量指标
combobox2 = ttk.Combobox(rowframe2, textvariable=momentum_indicator)
combobox2['values'] = ['绝对价格振荡器','钱德动量摆动指标','移动平均收敛/散度','带可控MA类型的MACD',
'移动平均收敛/散度 固定 12/26','动量','比例价格振荡器','变化率','变化率百分比',
'变化率的比率','变化率的比率100倍','相对强弱指数','随机相对强弱指标','三重光滑EMA的日变化率']

combobox2.current(0)
combobox2.pack(side=tk.LEFT)

combobox2.bind('<<ComboboxSelected>>', momentum_process)



# 第三行:周期指标
rowframe3 = tk.Frame(root)
rowframe3.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe3, text="周期指标").pack(side=tk.LEFT)

cycle_indicator = tk.StringVar() # 周期指标
combobox3 = ttk.Combobox(rowframe3, textvariable=cycle_indicator)
combobox3['values'] = ['希尔伯特变换——主要的循环周期','希尔伯特变换——主要的周期阶段','希尔伯特变换——相量组件',
'希尔伯特变换——正弦曲线','希尔伯特变换——趋势和周期模式']

combobox3.current(0)
combobox3.pack(side=tk.LEFT)

combobox3.bind('<<ComboboxSelected>>', cycle_process)


# 第四行:统计功能
rowframe4 = tk.Frame(root)
rowframe4.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe4, text="统计功能").pack(side=tk.LEFT)

statistic_indicator = tk.StringVar() # 统计功能
combobox4 = ttk.Combobox(rowframe4, textvariable=statistic_indicator)
combobox4['values'] = ['贝塔系数;投资风险与股市风险系数','皮尔逊相关系数','线性回归','线性回归角度',
'线性回归截距','线性回归斜率','标准差','时间序列预测','方差']

combobox4.current(0)
combobox4.pack(side=tk.LEFT)

combobox4.bind('<<ComboboxSelected>>', statistic_process)


# 第五行:数学变换
rowframe5 = tk.Frame(root)
rowframe5.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe5, text="数学变换").pack(side=tk.LEFT)

math_transform = tk.StringVar() # 数学变换
combobox5 = ttk.Combobox(rowframe5, textvariable=math_transform_process)
combobox5['values'] = ['反余弦','反正弦','反正切','向上取整','余弦','双曲余弦','指数','向下取整',
'自然对数','常用对数','正弦','双曲正弦','平方根','正切','双曲正切']

combobox5.current(0)
combobox5.pack(side=tk.LEFT)

combobox5.bind('<<ComboboxSelected>>', math_transform_process)


# 第六行:数学操作
rowframe6 = tk.Frame(root)
rowframe6.pack(side=tk.TOP, ipadx=3, ipady=3)
tk.Label(rowframe6, text="数学操作").pack(side=tk.LEFT)

math_operator = tk.StringVar() # 数学操作
combobox6 = ttk.Combobox(rowframe6, textvariable=math_operator_process)
combobox6['values'] = ['指定期间的最大值','指定期间的最大值的索引','指定期间的最小值','指定期间的最小值的索引',
'指定期间的最小和最大值','指定期间的最小和最大值的索引','合计']

combobox6.current(0)
combobox6.pack(side=tk.LEFT)

combobox6.bind('<<ComboboxSelected>>', math_operator_process)




root.mainloop()

quantdigger 安装教程 & 安装出现的问题解决

李魔佛 发表了文章 • 2 个评论 • 2266 次浏览 • 2017-05-25 22:00 • 来自相关话题

http://30daydo.com/publish/article/195
 
 win7
可以下载https://github.com/Rockyzsu/quantdigger 然后解压, 运行以下python命令: 
python setupscripts/install.py 或者 pip install quantdigger
 
如果出现一些库文件的依赖关系导致出错
fatal error C1083: Cannot open include file: 'ta_libc.
 
那么说明你的TA-Lib的这个库没有安装好。
 
先尝试 pip install TA-Lib 看能否安装成功。如果失败了,继续下面的: 
下载http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip 然后解压放在c盘根目录下 (如: C:\ta-lib)。
 
再运行pip install TA-Lib
 
然后重新运行 python setupscripts/install.py 查看全部
http://30daydo.com/publish/article/195
 
 win7
可以下载https://github.com/Rockyzsu/quantdigger 然后解压, 运行以下python命令: 
python setupscripts/install.py 或者 pip install quantdigger
 
如果出现一些库文件的依赖关系导致出错
fatal error C1083: Cannot open include file: 'ta_libc.
 
那么说明你的TA-Lib的这个库没有安装好。
 
先尝试 pip install TA-Lib 看能否安装成功。如果失败了,继续下面的: 
下载http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip 然后解压放在c盘根目录下 (如: C:\ta-lib)。
 
再运行pip install TA-Lib
 
然后重新运行 python setupscripts/install.py

量化交易 获取获取上市公司年报

李魔佛 发表了文章 • 0 个评论 • 1528 次浏览 • 2017-05-22 11:37 • 来自相关话题

http://30daydo.com/article/192
 
 tushare有一个函数, ts.get_report_data(年份,季度), 可以获取每一年的季度的业绩。

如果想要获取上市公司的年报,只要吧季度参数改为4即可 

例如 要获取 中国银行的2016年的年报

df=ts.get_report_data(2016,4)

print df[df['code']=='601988']


输出的结果如下:
 
In [4]: print df[df['code']=='601988']
        code  name   eps  eps_yoy  bvps    roe  epcf  net_profits  \
1826  601988  中国银行  0.54    -3.57  4.46  12.58   NaN   16457800.0

      profits_yoy  distrib report_date
1826        -3.67  10派1.68       04-01
 
 
  查看全部
http://30daydo.com/article/192
 
 tushare有一个函数, ts.get_report_data(年份,季度), 可以获取每一年的季度的业绩。

如果想要获取上市公司的年报,只要吧季度参数改为4即可 

例如 要获取 中国银行的2016年的年报

df=ts.get_report_data(2016,4)

print df[df['code']=='601988']


输出的结果如下:
 
In [4]: print df[df['code']=='601988']
        code  name   eps  eps_yoy  bvps    roe  epcf  net_profits  \
1826  601988  中国银行  0.54    -3.57  4.46  12.58   NaN   16457800.0

      profits_yoy  distrib report_date
1826        -3.67  10派1.68       04-01
 
 
 

python 多线程监测股票涨停板打开 并通知用户

李魔佛 发表了文章 • 0 个评论 • 3538 次浏览 • 2017-05-17 12:27 • 来自相关话题

相信打板一族一个习惯就是需要盯盘,这个一件很累的事情。 需要时刻盯着分时走势,委托单的数目,涨停打开,回封。
 
下面写了一个用python监测准备要打开涨停板的股票。 用多线程实现,可以支持同时监测多个股票,如果遇到撤单或者托单数少于某个临界值,说明涨停很快就要被打开。
 
# -*-coding=utf-8-*-
__author__ = 'Rocky'
'''
http://30daydo.com
Contact: weigesysu@qq.com
'''
import smtplib, time, os, datetime
from email.mime.text import MIMEText
from email.header import Header
from toolkit import Toolkit
from email.mime.multipart import MIMEMultipart
from email import Encoders, Utils
from toolkit import Toolkit
import tushare as ts
from pandas import Series
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import threading

#监测涨停板开板监测
class break_monitor():
def __init__(self,send=True):
self.send=send
if self.send==True:
cfg = Toolkit.getUserData('data.cfg')
from_mail = cfg['from_mail']
password = cfg['password']
to_mail = cfg['to_mail']
smtp_server = 'smtp.qq.com'

self.server = smtp_server
self.username = from_mail.split("@")[0]
self.from_mail = from_mail
self.password = password
self.to_mail = to_mail
# 初始化邮箱设置读取需要股票信息
# 这样子只登陆一次
try:
self.smtp = smtplib.SMTP_SSL(port=465)
self.smtp.connect(self.server)
self.smtp.login(self.username, self.password)
except smtplib.SMTPException, e:
print e
return 0
self.bases = pd.read_csv('bases.csv', dtype={'code': np.str})
self.stocklist = Toolkit.read_stock('monitor_list.log')



def send_txt(self, name, content):

subject = '%s' % name
self.msg = MIMEText(content, 'plain', 'utf-8')
self.msg['to'] = self.to_mail
self.msg['from'] = self.from_mail
self.msg['Subject'] = subject
self.msg['Date'] = Utils.formatdate(localtime=1)
try:
self.smtp.sendmail(self.msg['from'], self.msg['to'], self.msg.as_string())
self.smtp.quit()
print "sent"
except smtplib.SMTPException, e:
print e
return 0

#开板提示
def break_ceil(self, code):
print threading.current_thread().name
while 1:
#print code
time.sleep(2)
try:
df = ts.get_realtime_quotes(code)
except:
time.sleep(5)
continue
v = long(df['b1_v'].values[0])

if v <= 1000:
print datetime.datetime.now().strftime("%H:%M:%S")
print u"小于万手,小心!跑"
if self.send==True:
self.push_msg('break', 10, 10, 'down')
#这里可以优化,不必每次都登陆。


def monitor_break(self,send=True):
thread_num = len(self.stocklist)
thread_list = []
join_list = []
for i in range(thread_num):
t = threading.Thread(target=self.break_ceil, args=(self.stocklist[i],))
thread_list.append(t)

for j in thread_list:
j.start()

for k in thread_list:
k.join()


if __name__ == '__main__':
path = os.path.join(os.getcwd(), 'data')
if os.path.exists(path) == False:
os.mkdir(path)
os.chdir(path)
obj = break_monitor(send=False)
obj.monitor_break()

用法: 创建一个data文件夹,里面存放一个bases.csv文件,这个文件保存了A股的所有股票基本信息。 至于如何获取。请参看连接:
 
然后创建一个monitor_list.log的文件,把你要监测的股票代码写进去,一个代码写一行。
 
如果你需要程序发信息到你的手机或者邮箱,那么在data文件夹下创建一个data.cfg的文件,里面的内容格式为:
 
from_mail=从这个邮箱发出,我测试的是QQ邮箱
password=发出邮箱的密码
to_mail=需要发送到的通知邮箱,推荐139邮箱,这个会推送到短信手机,等同于发一个短信给你。
 
然后直接运行就可以了。 查看全部
相信打板一族一个习惯就是需要盯盘,这个一件很累的事情。 需要时刻盯着分时走势,委托单的数目,涨停打开,回封。
 
下面写了一个用python监测准备要打开涨停板的股票。 用多线程实现,可以支持同时监测多个股票,如果遇到撤单或者托单数少于某个临界值,说明涨停很快就要被打开。
 
# -*-coding=utf-8-*-
__author__ = 'Rocky'
'''
http://30daydo.com
Contact: weigesysu@qq.com
'''
import smtplib, time, os, datetime
from email.mime.text import MIMEText
from email.header import Header
from toolkit import Toolkit
from email.mime.multipart import MIMEMultipart
from email import Encoders, Utils
from toolkit import Toolkit
import tushare as ts
from pandas import Series
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import threading

#监测涨停板开板监测
class break_monitor():
def __init__(self,send=True):
self.send=send
if self.send==True:
cfg = Toolkit.getUserData('data.cfg')
from_mail = cfg['from_mail']
password = cfg['password']
to_mail = cfg['to_mail']
smtp_server = 'smtp.qq.com'

self.server = smtp_server
self.username = from_mail.split("@")[0]
self.from_mail = from_mail
self.password = password
self.to_mail = to_mail
# 初始化邮箱设置读取需要股票信息
# 这样子只登陆一次
try:
self.smtp = smtplib.SMTP_SSL(port=465)
self.smtp.connect(self.server)
self.smtp.login(self.username, self.password)
except smtplib.SMTPException, e:
print e
return 0
self.bases = pd.read_csv('bases.csv', dtype={'code': np.str})
self.stocklist = Toolkit.read_stock('monitor_list.log')



def send_txt(self, name, content):

subject = '%s' % name
self.msg = MIMEText(content, 'plain', 'utf-8')
self.msg['to'] = self.to_mail
self.msg['from'] = self.from_mail
self.msg['Subject'] = subject
self.msg['Date'] = Utils.formatdate(localtime=1)
try:
self.smtp.sendmail(self.msg['from'], self.msg['to'], self.msg.as_string())
self.smtp.quit()
print "sent"
except smtplib.SMTPException, e:
print e
return 0

#开板提示
def break_ceil(self, code):
print threading.current_thread().name
while 1:
#print code
time.sleep(2)
try:
df = ts.get_realtime_quotes(code)
except:
time.sleep(5)
continue
v = long(df['b1_v'].values[0])

if v <= 1000:
print datetime.datetime.now().strftime("%H:%M:%S")
print u"小于万手,小心!跑"
if self.send==True:
self.push_msg('break', 10, 10, 'down')
#这里可以优化,不必每次都登陆。


def monitor_break(self,send=True):
thread_num = len(self.stocklist)
thread_list = []
join_list = []
for i in range(thread_num):
t = threading.Thread(target=self.break_ceil, args=(self.stocklist[i],))
thread_list.append(t)

for j in thread_list:
j.start()

for k in thread_list:
k.join()


if __name__ == '__main__':
path = os.path.join(os.getcwd(), 'data')
if os.path.exists(path) == False:
os.mkdir(path)
os.chdir(path)
obj = break_monitor(send=False)
obj.monitor_break()

用法: 创建一个data文件夹,里面存放一个bases.csv文件,这个文件保存了A股的所有股票基本信息。 至于如何获取。请参看连接:
 
然后创建一个monitor_list.log的文件,把你要监测的股票代码写进去,一个代码写一行。
 
如果你需要程序发信息到你的手机或者邮箱,那么在data文件夹下创建一个data.cfg的文件,里面的内容格式为:
 
from_mail=从这个邮箱发出,我测试的是QQ邮箱
password=发出邮箱的密码
to_mail=需要发送到的通知邮箱,推荐139邮箱,这个会推送到短信手机,等同于发一个短信给你。
 
然后直接运行就可以了。

统计新股的连板天数,通过累计换手率预测开板时机

李魔佛 发表了文章 • 0 个评论 • 1229 次浏览 • 2017-05-11 17:12 • 来自相关话题

http://30daydo.com/article/182
 
对于一只新股,不少人会盯着它什么时候开板。 不过对于一般散户,如果换手率低于5%的一字涨停,也很难挤进去。 
那么今天我们来试一下计算新股的开板前的连板天数。# -*-coding=utf-8-*-
__author__ = 'Rocky'
'''
http://30daydo.com
Contact: weigesysu@qq.com
'''
#分析新股的开板时机
import tushare as ts
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
class New_Stock_Break():
def __init__(self):
#为了文件整齐,新建一个文件夹data用来专门存放数据
current = os.getcwd()
folder = os.path.join(current, 'data')
if os.path.exists(folder) == False:
os.mkdir(folder)
os.chdir(folder)
#调用tushare接口,获取A股信息
df0=ts.get_stock_basics()
#df0=pd.read_csv('bases.csv',dtype={'code':np.str})
self.bases=df0.sort_values('timeToMarket',ascending=False)

#获取样本, 获取最近一个年的新股情况

self.cxg=self.bases[(self.bases['timeToMarket']>20160101) & (self.bases['timeToMarket']<20170101)]
self.codes= self.cxg['code'].values

def calc_open_by_percent(self,code):
cont=100000000
#total_vol=self.bases[self.bases['code']==code]['totals'].values[0]
acutal_vol=self.bases[self.bases['code']==code]['outstanding'].values[0]
all_vol= acutal_vol*cont
df1=ts.get_k_data(code)
i=1
while 1:
s=df1.ix[1]
if s['high']!=s['low']:
#date=s['date']
break
i=i+1

j=i-1
date_end=df1.ix[j]['date']
date_start=df1.ix[0]['date']
df3=df1[(df1['date']>=date_start) & (df1['date']<=date_end)]
v_total_break=df3['volume'].sum()
l=len(df3)
print l
print v_total_break
rate=v_total_break*100*100.00/all_vol #手和股 注意
print round(rate,6)
return rate,l


def getData(self):
result=
max_line=
k=
for i in self.codes:
print i
name=self.bases[self.bases['code']==i]['name'].values[0]
rate,l=self.calc_open_by_percent(i)
if rate is not None:
result.append(rate)
max_line.append([name,l,rate])
k.append(l)
#写入文件
f=open('2016-2017-cixin.csv','w')
for x in max_line:
#f.write(';'.join(x))
f.write(x[0])
f.write('-')
f.write(str(x[1]))
f.write('-')
f.write(str(x[2]))
f.write('\n')

f.close()

def main():
obj=New_Stock_Break()
obj.testcase2()

main() 
运行后得到的数据如下:





 
你可以修改部分参数,可以获取每一年,或者每一个月的新股情况。
 
从上面的数据可以获取得到,最多的连班是海天精工的29板, 海天精工-29-12.8248076923 
累计的换手率达到了12.8。
 
当然上面的是在2016年IPO速度还没那么快的时候,2017年平均不到10个板就开了。 
 
附上抓取的数据文件
 
 链接: https://pan.baidu.com/s/1c1LpOZ2 密码: r3yk 查看全部
http://30daydo.com/article/182
 
对于一只新股,不少人会盯着它什么时候开板。 不过对于一般散户,如果换手率低于5%的一字涨停,也很难挤进去。 
那么今天我们来试一下计算新股的开板前的连板天数。
# -*-coding=utf-8-*-
__author__ = 'Rocky'
'''
http://30daydo.com
Contact: weigesysu@qq.com
'''
#分析新股的开板时机
import tushare as ts
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
class New_Stock_Break():
def __init__(self):
#为了文件整齐,新建一个文件夹data用来专门存放数据
current = os.getcwd()
folder = os.path.join(current, 'data')
if os.path.exists(folder) == False:
os.mkdir(folder)
os.chdir(folder)
#调用tushare接口,获取A股信息
df0=ts.get_stock_basics()
#df0=pd.read_csv('bases.csv',dtype={'code':np.str})
self.bases=df0.sort_values('timeToMarket',ascending=False)

#获取样本, 获取最近一个年的新股情况

self.cxg=self.bases[(self.bases['timeToMarket']>20160101) & (self.bases['timeToMarket']<20170101)]
self.codes= self.cxg['code'].values

def calc_open_by_percent(self,code):
cont=100000000
#total_vol=self.bases[self.bases['code']==code]['totals'].values[0]
acutal_vol=self.bases[self.bases['code']==code]['outstanding'].values[0]
all_vol= acutal_vol*cont
df1=ts.get_k_data(code)
i=1
while 1:
s=df1.ix[1]
if s['high']!=s['low']:
#date=s['date']
break
i=i+1

j=i-1
date_end=df1.ix[j]['date']
date_start=df1.ix[0]['date']
df3=df1[(df1['date']>=date_start) & (df1['date']<=date_end)]
v_total_break=df3['volume'].sum()
l=len(df3)
print l
print v_total_break
rate=v_total_break*100*100.00/all_vol #手和股 注意
print round(rate,6)
return rate,l


def getData(self):
result=
max_line=
k=
for i in self.codes:
print i
name=self.bases[self.bases['code']==i]['name'].values[0]
rate,l=self.calc_open_by_percent(i)
if rate is not None:
result.append(rate)
max_line.append([name,l,rate])
k.append(l)
#写入文件
f=open('2016-2017-cixin.csv','w')
for x in max_line:
#f.write(';'.join(x))
f.write(x[0])
f.write('-')
f.write(str(x[1]))
f.write('-')
f.write(str(x[2]))
f.write('\n')

f.close()

def main():
obj=New_Stock_Break()
obj.testcase2()

main()
 
运行后得到的数据如下:

开板.PNG

 

你可以修改部分参数,可以获取每一年,或者每一个月的新股情况。
 
从上面的数据可以获取得到,最多的连班是海天精工的29板, 海天精工-29-12.8248076923 
累计的换手率达到了12.8。
 
当然上面的是在2016年IPO速度还没那么快的时候,2017年平均不到10个板就开了。 
 
附上抓取的数据文件
 
 链接: https://pan.baidu.com/s/1c1LpOZ2 密码: r3yk

聚币网/coinegg API使用教程 附demo代码

李魔佛 发表了文章 • 56 个评论 • 11762 次浏览 • 2017-05-11 09:05 • 来自相关话题

******* 2018.14 更新 ***********
现在聚币网已经被关闭了,但是所有的币都可以转移到CoinEgg网了,币种和以前一模一样,只是用户参与度减少了很多,市场不是一个有效的市场,但是这对于操盘手来说,更加是一个收益大的地方。
使用下面链接注册后,用户可以返30%的佣金。 其实也无所谓,佣金不会很多,一次也就几分钱到几毛钱,自己去官网注册也可以。看个人心情啦。
 
http://www.coinegg.com/user/register?inv=7d91a
 
 后续会就coinegg写一个自动交易的系统出来
 

******* 8.28 更新 ***********
不少人反应签名不通过,经过调试,发现是加密前的字符拼接的顺序问题,这个拼接顺序要和你post上去的顺序要一致,才能通过。如果出现104的返回代码,说明是你的顺序问题,说明你的签名没有成功。
 
贴代码说明下: 使用字典循环,就可以知道正确的拼接顺序。 下面的代码是获取成交订单的。 def Trade_list(self, coin):
'''
Trade_list(挂单查询)
您指定时间后的挂单,可以根据类型查询,比如查看正在挂单和全部挂单
Path:/api/v1/trade_list/
Request类型:POST
参数
key - API key
signature - signature
nonce - nonce
since - unix timestamp(utc timezone) default == 0, i.e. 返回所有
coin - 币种简称,例如btc、ltc、xas
type - 挂单类型[open:正在挂单, all:所有挂单]

返回JSON dictionary
id - 挂单ID
datetime - date and time
type - "buy" or "sell"
price - price
amount_original - 下单时数量
amount_outstanding - 当前剩余数量
'''
url = self.host + '/api/v1/trade_list/'
time.sleep(random.random())
nonce = self.get_nonce_time()
types = 'all'
since = 0
parameters = {'key': self.public_key, 'nonce': str(nonce), 'type': types, 'coin': coin, 'signature': ''}
# print parameters
post_data = ''
for k, v in parameters.items():
if not isinstance(v, str):
#if type(v) is not types.StringType:
v = str(v)
post_data = post_data + k
post_data = post_data + '=' + v + '&'

#print 'post-data:\n',post_data
post_data = post_data[:-1]
post_data = post_data.replace('&signature=', '')
#print post_data

signature = hmac.new(self.md5, post_data, digestmod=hashlib.sha256).digest()
sig = self.toHex(signature)
parameters['signature'] = sig
#print parameters
r = requests.post(url=url, data=parameters)
s = r.json()
#print s
return s
 
如果还是没有解决的话就网站内私信我看看问题所在。

******************************************* 原文内容 ***************************************************
 

 官方有API的文档,可是这个文档就像一个草稿一样,两个基本例子都没有。 所以自己摸索一下,自己写一个现成的例子给大家,可以有个参考。 下面的例子亲测成功。 
 
首先看一下官方的API文档:

一、API使用说明

1、请求过程说明

1.1 构造请求数据,用户数据按照Jubi提供的接口规则,通过程序生成签名和要传输给Jubi的数据集合;

1.2 发送请求数据,把构造完成的数据集合通过POST/GET提交的方式传递给Jubi;

1.3 Jubi对请求数据进行处理,服务器在接收到请求后,会首先进行安全校验,验证通过后便会处理该次发送过来的请求;

1.4 返回响应结果数据,Jubi把响应结果以JSON的格式反馈给用户,具体的响应格式,错误代码参见接口部分;

1.5 对获取的返回结果数据进行处理;

2、安全认证

所有的private API都需要经过认证

Api的申请可以到财务中心 -> API,申请得到私钥和公钥,私钥Jubi将不做储存,一旦丢失将无法找回

注意:请勿向任何人泄露这两个参数,这像您的密码一样重要

2.签名机制

每次请求private api 都需要验证签名,发送的参数示例:

$param = array(

amount => 1,

price => 10000,

type => 'buy',

nonce => 141377098123

key => 5zi7w-4mnes-swmc4-egg9b-f2iqw-396z4-g541b

signature => 459c69d25c496765191582d9611028b9974830e9dfafd762854669809290ed82

);

nonce 可以理解为一个递增的整数:http://zh.wikipedia.org/wiki/Nonce

key 是申请到的公钥

signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.

 

 
 
  
首先聚币的行情是使用网络爬虫获取的,而说明中给出了一系列的参数,你需要做的就是把这些参数填充上去。
 
如果你只是想要获取行情,那么事情容易很多。 def real_time_ticker(coin):
url = 'https://www.jubi.com/api/v1/ticker/'
try:
data = requests.post(url, data={'coin': coin}).json()

except Exception ,e:
print e
return data
上面代码展示的时候获取实时的行情。委一和买一的价格,数量,和当前成交的数量,价格。
 按照上面的格式,把参数coin填上去,比如要获取泽塔币, real_time_ticker('zet') 就会返回获取的数据。{u'sell': u'0.179000', u'volume': 21828245.102822, u'buy': u'0.175010', u'last': u'0.179000', u'vol': 108290769.9171, u'high': u'0.289000', u'low': u'0.119141'}
 
 
所有的private API都需要经过认证, 就是说如果你要进行交易,委托,下单,你就需要使用私钥和公钥,并进行一系列的加密。

每次请求private api 都需要验证签名,发送的参数示例:

$param = array(

amount => 1,

price => 10000,

type => 'buy',

nonce => 141377098123

key => 5zi7w-4mnes-swmc4-egg9b-f2iqw-396z4-g541b

signature => 459c69d25c496765191582d9611028b9974830e9dfafd762854669809290ed82

);

nonce 可以理解为一个递增的整数:http://zh.wikipedia.org/wiki/Nonce

key 是申请到的公钥

signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.

 
 
比如下单:

Trade_add(下单)
Path:/api/v1/trade_add/
Request类型:POST
 
参数
key - API key
signature - signature
nonce - nonce
amount - 购买数量
price - 购买价格
type - 买单或者卖单
coin - 币种简称,例如btc、ltc、xas
id - 挂单ID
result - true(成功), false(失败)
{"result":true, "id":"11"}
 
返回JSON dictionary
id - 挂单ID
result - true(成功), false(失败)
 
返回结果示例:
{"result":true, "id":"11"}
 


首先解决nonce。
 
在维基百科中
在安全工程中,Nonce是一个在加密通信只能使用一次的数字。在认证协议中,它往往是一个随机或伪随机数,以避免重放攻击。Nonce也用于流密码以确保安全。如果需要使用相同的密钥加密一个以上的消息,就需要Nonce来确保不同的消息与该密钥加密的密钥流不同。
 
结合stackoverflow, nonce只是一个12位的随机数。
可以用以下方法获得这个随机数 def get_nonce(self):
lens=12
return ''.join([str(random.randint(0, 9)) for i in range(lens)])
 聚币中的nonce的位数是12位,所以lens定义为12
 
或者可以直接用时间函数生成: def get_nonce_time(self):
lens = 12
curr_stamp = time.time()*100
nonece=int(curr_stamp)
return nonece
 
然后是signature。
signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.

先把私钥进行md5处理 def getHash(self,s):
m=hashlib.md5()
m.update(s)
return m.hexdigest()
只要把私钥传入函数getHash就可以得到一个md5处理过的字符串。
 
私钥是聚币网给每个用户分配的字符串,是唯一的,这里假设为private_key=123456789吧,具体是多少,在你的聚币网设置里面可以找到。
sha_256key=self.getHash(private_key)
 
按照要求吧 你要post的数据字符串连起来nonce=self.get_nonce_time
type='buy'
amount='10000'
key='xxxxxxxxxxx‘ #这个是聚币网给你的公钥,同样在设置里头可以找到
price='10' #你要设置的价格为10
coin='zet'
message = "amount=“+amount+”&nonce="+str(nonce)+"&type="+type+"&key="+key+'&price="+price+"&coin"+coin

signature = hmac.new(sha_256key, message, digestmod=hashlib.sha256).digest()

这样获得signature之后,就可以通过签名来进行post操作。

data_wrap={'nonce':nonce,'key':key_value,'signature':signature}

js=requests.post(url,data=data_wrap).json()
 
如果直接按照上面的代码去获取账户相关信息或者去挂单的话,会返回104的签名错误。 经过不断的排查,发现是signature的字符格式的问题。
 
构造一个str转换格式的函数: def toHex(self,str):
lst =
for ch in str:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)这个函数的作用就是把原来十六进制格式的字符完全转化成十六进制,把前面的0x去掉,不足2位的补全为2位。
把经过处理的signature进行格式转换后,几次提交,终于发现可以获取到用户的账户信息,进行下单,撤单,等操作。
 
 
 
下面是一个获取账户信息的代码段: def getAccount(self):
url='https://www.jubi.com/api/v1/balance/'

nonce_value=self.get_nonce_time()
print nonce_value
key_value=self.public_key
private_key=self.private_key

s='nonce='+str(nonce_value)+'&'+'key='+key_value

print s

#signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.
md5=self.getHash(private_key)
print md5
print type(md5)

msg=bytes(s).encode('utf-8')
key=bytes(md5).encode('utf-8')
signature =hmac.new(key,msg,digestmod=hashlib.sha256).digest()
print signature
print type(signature)
sig=self.toHex(signature)

print sig
data_wrap={'nonce':nonce_value,'key':key_value,'signature':sig}

print data_wrap

data_en=urllib.urlencode(data_wrap)
req=urllib2.Request(url,data=data_en)
resp=urllib2.urlopen(req).read()
print resp


def toHex(self,str):
lst =
for ch in str:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)
 
以上的代码运行后返回一下账户信息:{"uid":123456,"nameauth":1,"moflag":1,"asset":,"btc_balance":0,"btc_lock":0,"drk_balance":0,"drk_lock":0,"blk_balance":0,"blk_lock":0,"vrc_balance":0,"vrc_lock":0,"tfc_balance":0,"tfc_lock":0,"jbc_balance":0,"jbc_lock":0,"ltc_balance":0,"ltc_lock":0,"doge_balance":0,"doge_lock":0,"xpm_balance":0,"xpm_lock":0,"ppc_balance":0,"ppc_lock":0,"wdc_balance":0,"wdc_lock":0,"vtc_balance":0,"vtc_lock":0,"max_balance":0,"max_lock":0,"ifc_balance":0,"ifc_lock":0,"zcc_balance":0,"zcc_lock":0,"zet_balance":0,"zet_lock":0,"eac_balance":0,"eac_lock":0,"fz_balance":0,"fz_lock":0,"skt_balance":0,"skt_lock":0,"plc_balance":0,"plc_lock":0,"mtc_balance":0,"mtc_lock":0,"qec_balance":0,"qec_lock":0,"lkc_balance":10,"lkc_lock":0,"met_balance":0,"met_lock":0,"ytc_balance":0,"ytc_lock":0,"hlb_balance":0,"hlb_lock":0,"game_balance":0,"game_lock":0,"rss_balance":0,"rss_lock":0,"rio_balance":0,"rio_lock":0,"ktc_balance":0,"ktc_lock":0,"pgc_balance":0,"pgc_lock":0,"mryc_balance":0,"mryc_lock":0,"eth_balance":0,"eth_lock":0,"etc_balance":0,"etc_lock":0,"dnc_balance":0,"dnc_lock":0,"gooc_balance":0,"gooc_lock":0,"xrp_balance":0,"xrp_lock":0,"nxt_balance":0,"nxt_lock":0,"lsk_balance":0,"lsk_lock":0,"xas_balance":0,"xas_lock":0,"peb_balance":0,"peb_lock":0,"nhgh_balance":0,"nhgh_lock":0,"xsgs_balance":0,"xsgs_lock":0,"ans_balance":0,"ans_lock":0,"bts_balance":0,"bts_lock":0,"cny_balance":0,"cny_lock":0}











 
聚币网个人邀请码:
514330
 
还没注册可以拿去用,对于我而言可以拿到你们交易费用的50%,不过一般交易费除非是超级大户,一般散户都很少。千分之一的交易手续费。
 
欢迎一起讨论:
Email:weigesysu@qq.com

 原创内容,转载请注明出处
http://30daydo.com/article/181 
  查看全部
******* 2018.14 更新 ***********
现在聚币网已经被关闭了,但是所有的币都可以转移到CoinEgg网了,币种和以前一模一样,只是用户参与度减少了很多,市场不是一个有效的市场,但是这对于操盘手来说,更加是一个收益大的地方。
使用下面链接注册后,用户可以返30%的佣金。 其实也无所谓,佣金不会很多,一次也就几分钱到几毛钱,自己去官网注册也可以。看个人心情啦。
 
http://www.coinegg.com/user/register?inv=7d91a
 
 后续会就coinegg写一个自动交易的系统出来
 

******* 8.28 更新 ***********
不少人反应签名不通过,经过调试,发现是加密前的字符拼接的顺序问题,这个拼接顺序要和你post上去的顺序要一致,才能通过。如果出现104的返回代码,说明是你的顺序问题,说明你的签名没有成功。
 
贴代码说明下: 使用字典循环,就可以知道正确的拼接顺序。 下面的代码是获取成交订单的。
    def Trade_list(self, coin):
'''
Trade_list(挂单查询)
您指定时间后的挂单,可以根据类型查询,比如查看正在挂单和全部挂单
Path:/api/v1/trade_list/
Request类型:POST
参数
key - API key
signature - signature
nonce - nonce
since - unix timestamp(utc timezone) default == 0, i.e. 返回所有
coin - 币种简称,例如btc、ltc、xas
type - 挂单类型[open:正在挂单, all:所有挂单]

返回JSON dictionary
id - 挂单ID
datetime - date and time
type - "buy" or "sell"
price - price
amount_original - 下单时数量
amount_outstanding - 当前剩余数量
'''
url = self.host + '/api/v1/trade_list/'
time.sleep(random.random())
nonce = self.get_nonce_time()
types = 'all'
since = 0
parameters = {'key': self.public_key, 'nonce': str(nonce), 'type': types, 'coin': coin, 'signature': ''}
# print parameters
post_data = ''
for k, v in parameters.items():
if not isinstance(v, str):
#if type(v) is not types.StringType:
v = str(v)
post_data = post_data + k
post_data = post_data + '=' + v + '&'

#print 'post-data:\n',post_data
post_data = post_data[:-1]
post_data = post_data.replace('&signature=', '')
#print post_data

signature = hmac.new(self.md5, post_data, digestmod=hashlib.sha256).digest()
sig = self.toHex(signature)
parameters['signature'] = sig
#print parameters
r = requests.post(url=url, data=parameters)
s = r.json()
#print s
return s

 
如果还是没有解决的话就网站内私信我看看问题所在。

******************************************* 原文内容 ***************************************************
 

 官方有API的文档,可是这个文档就像一个草稿一样,两个基本例子都没有。 所以自己摸索一下,自己写一个现成的例子给大家,可以有个参考。 下面的例子亲测成功。 
 
首先看一下官方的API文档:


一、API使用说明

1、请求过程说明

1.1 构造请求数据,用户数据按照Jubi提供的接口规则,通过程序生成签名和要传输给Jubi的数据集合;

1.2 发送请求数据,把构造完成的数据集合通过POST/GET提交的方式传递给Jubi;

1.3 Jubi对请求数据进行处理,服务器在接收到请求后,会首先进行安全校验,验证通过后便会处理该次发送过来的请求;

1.4 返回响应结果数据,Jubi把响应结果以JSON的格式反馈给用户,具体的响应格式,错误代码参见接口部分;

1.5 对获取的返回结果数据进行处理;

2、安全认证

所有的private API都需要经过认证

Api的申请可以到财务中心 -> API,申请得到私钥和公钥,私钥Jubi将不做储存,一旦丢失将无法找回

注意:请勿向任何人泄露这两个参数,这像您的密码一样重要

2.签名机制

每次请求private api 都需要验证签名,发送的参数示例:

$param = array(

amount => 1,

price => 10000,

type => 'buy',

nonce => 141377098123

key => 5zi7w-4mnes-swmc4-egg9b-f2iqw-396z4-g541b

signature => 459c69d25c496765191582d9611028b9974830e9dfafd762854669809290ed82

);

nonce 可以理解为一个递增的整数:http://zh.wikipedia.org/wiki/Nonce

key 是申请到的公钥

signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.

 


 
 
  
首先聚币的行情是使用网络爬虫获取的,而说明中给出了一系列的参数,你需要做的就是把这些参数填充上去。
 
如果你只是想要获取行情,那么事情容易很多。
    def real_time_ticker(coin):
url = 'https://www.jubi.com/api/v1/ticker/'
try:
data = requests.post(url, data={'coin': coin}).json()

except Exception ,e:
print e
return data

上面代码展示的时候获取实时的行情。委一和买一的价格,数量,和当前成交的数量,价格。
 按照上面的格式,把参数coin填上去,比如要获取泽塔币, real_time_ticker('zet') 就会返回获取的数据。
{u'sell': u'0.179000', u'volume': 21828245.102822, u'buy': u'0.175010', u'last': u'0.179000', u'vol': 108290769.9171, u'high': u'0.289000', u'low': u'0.119141'}

 
 
所有的private API都需要经过认证, 就是说如果你要进行交易,委托,下单,你就需要使用私钥和公钥,并进行一系列的加密。


每次请求private api 都需要验证签名,发送的参数示例:

$param = array(

amount => 1,

price => 10000,

type => 'buy',

nonce => 141377098123

key => 5zi7w-4mnes-swmc4-egg9b-f2iqw-396z4-g541b

signature => 459c69d25c496765191582d9611028b9974830e9dfafd762854669809290ed82

);

nonce 可以理解为一个递增的整数:http://zh.wikipedia.org/wiki/Nonce

key 是申请到的公钥

signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.


 
 
比如下单:


Trade_add(下单)
Path:/api/v1/trade_add/
Request类型:POST
 
参数
key - API key
signature - signature
nonce - nonce
amount - 购买数量
price - 购买价格
type - 买单或者卖单
coin - 币种简称,例如btc、ltc、xas
id - 挂单ID
result - true(成功), false(失败)
{"result":true, "id":"11"}
 
返回JSON dictionary
id - 挂单ID
result - true(成功), false(失败)
 
返回结果示例:
{"result":true, "id":"11"}
 



首先解决nonce。
 
在维基百科中
在安全工程中,Nonce是一个在加密通信只能使用一次的数字。在认证协议中,它往往是一个随机或伪随机数,以避免重放攻击。Nonce也用于流密码以确保安全。如果需要使用相同的密钥加密一个以上的消息,就需要Nonce来确保不同的消息与该密钥加密的密钥流不同。
 
结合stackoverflow, nonce只是一个12位的随机数。
可以用以下方法获得这个随机数
    def get_nonce(self):
lens=12
return ''.join([str(random.randint(0, 9)) for i in range(lens)])

 聚币中的nonce的位数是12位,所以lens定义为12
 
或者可以直接用时间函数生成:
    def get_nonce_time(self):
lens = 12
curr_stamp = time.time()*100
nonece=int(curr_stamp)
return nonece

 
然后是signature。
signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.

先把私钥进行md5处理
    def getHash(self,s):
m=hashlib.md5()
m.update(s)
return m.hexdigest()

只要把私钥传入函数getHash就可以得到一个md5处理过的字符串。
 
私钥是聚币网给每个用户分配的字符串,是唯一的,这里假设为private_key=123456789吧,具体是多少,在你的聚币网设置里面可以找到。
sha_256key=self.getHash(private_key)
 
按照要求吧 你要post的数据字符串连起来
nonce=self.get_nonce_time
type='buy'
amount='10000'
key='xxxxxxxxxxx‘ #这个是聚币网给你的公钥,同样在设置里头可以找到
price='10' #你要设置的价格为10
coin='zet'
message = "amount=“+amount+”&nonce="+str(nonce)+"&type="+type+"&key="+key+'&price="+price+"&coin"+coin

signature = hmac.new(sha_256key, message, digestmod=hashlib.sha256).digest()

这样获得signature之后,就可以通过签名来进行post操作。

data_wrap={'nonce':nonce,'key':key_value,'signature':signature}

js=requests.post(url,data=data_wrap).json()

 
如果直接按照上面的代码去获取账户相关信息或者去挂单的话,会返回104的签名错误。 经过不断的排查,发现是signature的字符格式的问题。
 
构造一个str转换格式的函数:
    def toHex(self,str):
lst =
for ch in str:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)
这个函数的作用就是把原来十六进制格式的字符完全转化成十六进制,把前面的0x去掉,不足2位的补全为2位。
把经过处理的signature进行格式转换后,几次提交,终于发现可以获取到用户的账户信息,进行下单,撤单,等操作。
 
 
 
下面是一个获取账户信息的代码段:
    def getAccount(self):
url='https://www.jubi.com/api/v1/balance/'

nonce_value=self.get_nonce_time()
print nonce_value
key_value=self.public_key
private_key=self.private_key

s='nonce='+str(nonce_value)+'&'+'key='+key_value

print s

#signature是签名,是将amount price type nonce key等参数通过'&'字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.
md5=self.getHash(private_key)
print md5
print type(md5)

msg=bytes(s).encode('utf-8')
key=bytes(md5).encode('utf-8')
signature =hmac.new(key,msg,digestmod=hashlib.sha256).digest()
print signature
print type(signature)
sig=self.toHex(signature)

print sig
data_wrap={'nonce':nonce_value,'key':key_value,'signature':sig}

print data_wrap

data_en=urllib.urlencode(data_wrap)
req=urllib2.Request(url,data=data_en)
resp=urllib2.urlopen(req).read()
print resp


def toHex(self,str):
lst =
for ch in str:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0' + hv
lst.append(hv)
return reduce(lambda x, y: x + y, lst)

 
以上的代码运行后返回一下账户信息:
{"uid":123456,"nameauth":1,"moflag":1,"asset":,"btc_balance":0,"btc_lock":0,"drk_balance":0,"drk_lock":0,"blk_balance":0,"blk_lock":0,"vrc_balance":0,"vrc_lock":0,"tfc_balance":0,"tfc_lock":0,"jbc_balance":0,"jbc_lock":0,"ltc_balance":0,"ltc_lock":0,"doge_balance":0,"doge_lock":0,"xpm_balance":0,"xpm_lock":0,"ppc_balance":0,"ppc_lock":0,"wdc_balance":0,"wdc_lock":0,"vtc_balance":0,"vtc_lock":0,"max_balance":0,"max_lock":0,"ifc_balance":0,"ifc_lock":0,"zcc_balance":0,"zcc_lock":0,"zet_balance":0,"zet_lock":0,"eac_balance":0,"eac_lock":0,"fz_balance":0,"fz_lock":0,"skt_balance":0,"skt_lock":0,"plc_balance":0,"plc_lock":0,"mtc_balance":0,"mtc_lock":0,"qec_balance":0,"qec_lock":0,"lkc_balance":10,"lkc_lock":0,"met_balance":0,"met_lock":0,"ytc_balance":0,"ytc_lock":0,"hlb_balance":0,"hlb_lock":0,"game_balance":0,"game_lock":0,"rss_balance":0,"rss_lock":0,"rio_balance":0,"rio_lock":0,"ktc_balance":0,"ktc_lock":0,"pgc_balance":0,"pgc_lock":0,"mryc_balance":0,"mryc_lock":0,"eth_balance":0,"eth_lock":0,"etc_balance":0,"etc_lock":0,"dnc_balance":0,"dnc_lock":0,"gooc_balance":0,"gooc_lock":0,"xrp_balance":0,"xrp_lock":0,"nxt_balance":0,"nxt_lock":0,"lsk_balance":0,"lsk_lock":0,"xas_balance":0,"xas_lock":0,"peb_balance":0,"peb_lock":0,"nhgh_balance":0,"nhgh_lock":0,"xsgs_balance":0,"xsgs_lock":0,"ans_balance":0,"ans_lock":0,"bts_balance":0,"bts_lock":0,"cny_balance":0,"cny_lock":0}











 
聚币网个人邀请码:
514330
 
还没注册可以拿去用,对于我而言可以拿到你们交易费用的50%,不过一般交易费除非是超级大户,一般散户都很少。千分之一的交易手续费。
 
欢迎一起讨论:
Email:weigesysu@qq.com

 原创内容,转载请注明出处
http://30daydo.com/article/181 
 

python 计算当天指定某个时段的成交量

李魔佛 发表了文章 • 0 个评论 • 1305 次浏览 • 2017-05-08 23:32 • 来自相关话题

计算当天指定某个时段的成交量
 
为什么需要这个功能? 因为平时复盘的时候,会切换当天的分时图,一般喜欢切换成5分钟图,这样子就对每个时刻的成交量有比较直观的认识。比如今天(2017-05-08)的无锡银行。
 






很无耻是吧? 我就像看看尾盘的20分钟内,主力动用了多少资金把股价从水下直接拉到涨停。 用程序处理,比用手工计算,要节省多时间了(前阵子的确是每笔粗略的相加)。
 
只要在main()中修改股票代码和你要获取成交量的时间,就可以获取你想要的数据。 还有一个数据就是该成交量占当天成交量的比例。# -*-coding=utf-8-*-
__author__ = 'Rocky'
#计算某个股票的某个时间段的成交量
import tushare as ts
import pandas as pd
import datetime
pd.set_option('display.max_rows',None)
class amount_calculation():
def __init__(self,code):
self.df=ts.get_today_ticks(code)

#转换str为时间格式,便于下面用来比较时间的大小
self.df['time']=self.df['time'].map(lambda x:datetime.datetime.strptime(str(x),'%H:%M:%S'))
print '\n'
self.total= self.df['volume'].sum()

def calc(self,start,end):
s0=datetime.datetime.strptime(start,'%H:%M:%S')
e0=datetime.datetime.strptime(end,'%H:%M:%S')
new_df=self.df[(self.df['time']>=s0) & (self.df['time']<e0) ]
part=new_df['volume'].sum()
print part
rate=round(part*1.00/self.total*100,2)
print rate
return rate




def main():
obj=amount_calculation('600908')
#s1=obj.calc('09:24:00','10:30:00')
#s2=obj.calc('10:30:00','11:30:00')
#s3=obj.calc('13:00:00','14:00:00')
s4=obj.calc('14:35:00','15:05:00')
#print s1+s2+s3+s4

main()
 
运行上面代码,得到
 
114046
34.16
成交量为11.4万手,大概占当天成交量的34.16%, 半小时的时间。(1/8的时间,涨了1/3的成交量)
算出这个有什么用呢?
 
对于庄股,可以便于你计算出主力当天吸了多少货,或者出了多少货。 数据不会完全精确,但是能够知道交易的量级。 像上面的例子,大概就10w-12w手的样子。
 
更多文章
30天学会量化交易模型 Day01 查看全部
计算当天指定某个时段的成交量
 
为什么需要这个功能? 因为平时复盘的时候,会切换当天的分时图,一般喜欢切换成5分钟图,这样子就对每个时刻的成交量有比较直观的认识。比如今天(2017-05-08)的无锡银行。
 

无锡银行.PNG


很无耻是吧? 我就像看看尾盘的20分钟内,主力动用了多少资金把股价从水下直接拉到涨停。 用程序处理,比用手工计算,要节省多时间了(前阵子的确是每笔粗略的相加)。
 
只要在main()中修改股票代码和你要获取成交量的时间,就可以获取你想要的数据。 还有一个数据就是该成交量占当天成交量的比例。
# -*-coding=utf-8-*-
__author__ = 'Rocky'
#计算某个股票的某个时间段的成交量
import tushare as ts
import pandas as pd
import datetime
pd.set_option('display.max_rows',None)
class amount_calculation():
def __init__(self,code):
self.df=ts.get_today_ticks(code)

#转换str为时间格式,便于下面用来比较时间的大小
self.df['time']=self.df['time'].map(lambda x:datetime.datetime.strptime(str(x),'%H:%M:%S'))
print '\n'
self.total= self.df['volume'].sum()

def calc(self,start,end):
s0=datetime.datetime.strptime(start,'%H:%M:%S')
e0=datetime.datetime.strptime(end,'%H:%M:%S')
new_df=self.df[(self.df['time']>=s0) & (self.df['time']<e0) ]
part=new_df['volume'].sum()
print part
rate=round(part*1.00/self.total*100,2)
print rate
return rate




def main():
obj=amount_calculation('600908')
#s1=obj.calc('09:24:00','10:30:00')
#s2=obj.calc('10:30:00','11:30:00')
#s3=obj.calc('13:00:00','14:00:00')
s4=obj.calc('14:35:00','15:05:00')
#print s1+s2+s3+s4

main()

 
运行上面代码,得到
 
114046
34.16
成交量为11.4万手,大概占当天成交量的34.16%, 半小时的时间。(1/8的时间,涨了1/3的成交量)
算出这个有什么用呢?
 
对于庄股,可以便于你计算出主力当天吸了多少货,或者出了多少货。 数据不会完全精确,但是能够知道交易的量级。 像上面的例子,大概就10w-12w手的样子。
 
更多文章
30天学会量化交易模型 Day01

ts.get_stock_basics() to_excel("base.xls") 保存dataframe 编码错误

李魔佛 发表了文章 • 0 个评论 • 1408 次浏览 • 2017-04-21 18:36 • 来自相关话题

 
基本代码片:
base=ts.get_stock_basics()
base.to_csv('2.xls')
 出现的错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 1: ordinal not in range(128) 
然后替换几种编码方式:
base.to_excel('base.xls',encoding='GBK')
base.to_excel('111.xls',encoding='utf8')
base.to_excel('111.xls‘)
不过问题还在。
 
而保存为csv文件却没有这个编码问题:
 
base.to_csv('base.csv)
 
 
于是采取了迂回战术, 先把数据保存为csv, 然后读取这个文件,然后 再保存为exel文件。
 
居然给我弄成功了!!
 
  查看全部
 
基本代码片:
    base=ts.get_stock_basics()
base.to_csv('2.xls')

 出现的错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 1: ordinal not in range(128) 
然后替换几种编码方式:
    base.to_excel('base.xls',encoding='GBK')
base.to_excel('111.xls',encoding='utf8')
base.to_excel('111.xls‘)

不过问题还在。
 
而保存为csv文件却没有这个编码问题:
 
base.to_csv('base.csv)
 
 
于是采取了迂回战术, 先把数据保存为csv, 然后读取这个文件,然后 再保存为exel文件。
 
居然给我弄成功了!!
 
 

JoinQuant 遇到的问题总结 --定期更新

李魔佛 发表了文章 • 0 个评论 • 709 次浏览 • 2017-04-20 23:51 • 来自相关话题

1. 一些涨停一字板的个股或者新股,你是无法买入的。 经过测试,会发现没有买入任何的个股。
1. 一些涨停一字板的个股或者新股,你是无法买入的。 经过测试,会发现没有买入任何的个股。

pandas dataframe 读取csv文件 数据类型转化 字符变成了数字

李魔佛 发表了文章 • 0 个评论 • 13657 次浏览 • 2017-04-17 22:43 • 来自相关话题

因为csv中包含了大量的股票代码,如果是002开头的股票,比如002111, 使用pd.read_csv('text.csv') 则会让所有的002xxx,变成了2xxx,前面2个0不见了,当然你可以收工操作,填充那2个0。 不过对于pandas大法,何须这么麻烦?
 
直接在参数一栏设置一下即可:
df=pd.read_csv('text.csv', dtype={'code':str}
 
这样,把你要转换的列的名字设定好, “code”列中的数据读取为str
 
这样,读取到的数据就是按照我们的要求的了。 查看全部
因为csv中包含了大量的股票代码,如果是002开头的股票,比如002111, 使用pd.read_csv('text.csv') 则会让所有的002xxx,变成了2xxx,前面2个0不见了,当然你可以收工操作,填充那2个0。 不过对于pandas大法,何须这么麻烦?
 
直接在参数一栏设置一下即可:
df=pd.read_csv('text.csv', dtype={'code':str}
 
这样,把你要转换的列的名字设定好, “code”列中的数据读取为str
 
这样,读取到的数据就是按照我们的要求的了。

tushare 中的ts.get_stock_basics() 函数总是超时 返回不到结果的原因

李魔佛 发表了文章 • 0 个评论 • 5792 次浏览 • 2017-04-17 18:30 • 来自相关话题

调用的方法:import tushare as ts

ts.get_stock_basics()
不过经常会出现: self.base=ts.get_stock_basics()
File "C:\Python27\lib\site-packages\tushare\stock\fundamental.py", line 44, in get_stock_basics
text = urlopen(request, timeout=10).read()
File "C:\Python27\lib\socket.py", line 351, in read
data = self._sock.recv(rbufsize)
File "C:\Python27\lib\httplib.py", line 567, in read
s = self.fp.read(amt)
File "C:\Python27\lib\socket.py", line 380, in read
data = self._sock.recv(left)
socket.timeout: timed out这样的问题。
 
这个是因为tushare的作者把get_stock_basics()的信息文件保存在他自己的服务器。
这一点可以翻看源码就知道。 地址为: http://218.244.146.57/static/all.csv 
估计作者用的一般的服务器,所以一旦数据请求多了,你的IP也被服务器当做是DDOS攻击,屏蔽掉你的请求了。
 
所以如果你平时需要频繁调用这个函数,不如把这个文件下载到本地,然后使用函数 df=pd.read_csv('all.csv')
来得到你想要数据,这样一来,程序不会因为经常超时而中断,而且本地读取文件的数据很快。 这样会节约不少的时间。
 
 
 在最新的tushare这个问题得到了解决。已经换一个数据源了。
 
PS:好多小问题都可以通过更新最新的tushare版本来得到解决。

升级命令:pip install tushare --upgrade
  查看全部
调用的方法:
import tushare as ts

ts.get_stock_basics()

不过经常会出现:
    self.base=ts.get_stock_basics()
File "C:\Python27\lib\site-packages\tushare\stock\fundamental.py", line 44, in get_stock_basics
text = urlopen(request, timeout=10).read()
File "C:\Python27\lib\socket.py", line 351, in read
data = self._sock.recv(rbufsize)
File "C:\Python27\lib\httplib.py", line 567, in read
s = self.fp.read(amt)
File "C:\Python27\lib\socket.py", line 380, in read
data = self._sock.recv(left)
socket.timeout: timed out
这样的问题。
 
这个是因为tushare的作者把get_stock_basics()的信息文件保存在他自己的服务器。
这一点可以翻看源码就知道。 地址为: http://218.244.146.57/static/all.csv 
估计作者用的一般的服务器,所以一旦数据请求多了,你的IP也被服务器当做是DDOS攻击,屏蔽掉你的请求了。
 
所以如果你平时需要频繁调用这个函数,不如把这个文件下载到本地,然后使用函数 df=pd.read_csv('all.csv')
来得到你想要数据,这样一来,程序不会因为经常超时而中断,而且本地读取文件的数据很快。 这样会节约不少的时间。
 
 
 在最新的tushare这个问题得到了解决。已经换一个数据源了。
 
PS:好多小问题都可以通过更新最新的tushare版本来得到解决。

升级命令:
pip install tushare --upgrade

 

中国各个省份/直辖市拥有的上市公司数目 附python代码

李魔佛 发表了文章 • 0 个评论 • 1413 次浏览 • 2017-04-16 02:25 • 来自相关话题

一个省份地区的上市公司的数目,可以很直接地反应这个地区的发达程度。
下面通过代码来统计这个数据, 其实很简单,用python只需几行代码就能够实现
  def count_area():
base=ts.get_stock_basics()
count=base['area'].value_counts()
#这一句的意思,就是获取所有股票的上市地区的数据,然后计算出现的次数
print count
print type(count)
得出的是以下的数据:
浙江     360
江苏     337
北京     289
广东     267
上海     251
深圳     242
山东     176
福建     116
四川     110
安徽      98
湖北      95
湖南      91
河南      76
辽宁      75
河北      54
新疆      50
天津      46
陕西      46
重庆      45
吉林      42
山西      38
江西      37
广西      36
黑龙江     35
云南      32
甘肃      31
海南      29
内蒙      25
贵州      23
西藏      14
宁夏      12
青海      11
 
从数据来看,数量最多的是江浙一带(因为深圳从广东省的数据中分离出去了)。
这个也从正面反映每个地方的经济繁荣程度。 查看全部
一个省份地区的上市公司的数目,可以很直接地反应这个地区的发达程度。
下面通过代码来统计这个数据, 其实很简单,用python只需几行代码就能够实现
 
    def count_area():
base=ts.get_stock_basics()
count=base['area'].value_counts()
#这一句的意思,就是获取所有股票的上市地区的数据,然后计算出现的次数
print count
print type(count)

得出的是以下的数据:
浙江     360
江苏     337
北京     289
广东     267
上海     251
深圳     242
山东     176
福建     116
四川     110
安徽      98
湖北      95
湖南      91
河南      76
辽宁      75
河北      54
新疆      50
天津      46
陕西      46
重庆      45
吉林      42
山西      38
江西      37
广西      36
黑龙江     35
云南      32
甘肃      31
海南      29
内蒙      25
贵州      23
西藏      14
宁夏      12
青海      11
 
从数据来看,数量最多的是江浙一带(因为深圳从广东省的数据中分离出去了)。
这个也从正面反映每个地方的经济繁荣程度。

mac os x python安装matplotlib 库 出错: Operation not permitted

低调的哥哥 发表了文章 • 0 个评论 • 3794 次浏览 • 2017-04-15 23:19 • 来自相关话题

使用pip安装: sudo pip install matplotlibPassword:
The directory '/Users/rocky/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/Users/rocky/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Requirement already satisfied: matplotlib in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python
Requirement already satisfied: numpy>=1.5 in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from matplotlib)
Requirement already satisfied: python-dateutil in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from matplotlib)
Collecting tornado (from matplotlib)
Downloading tornado-4.4.3.tar.gz (463kB)
100% |████████████████████████████████| 471kB 84kB/s
Requirement already satisfied: pyparsing>=1.5.6 in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from matplotlib)
Collecting nose (from matplotlib)
Downloading nose-1.3.7-py2-none-any.whl (154kB)
100% |████████████████████████████████| 163kB 75kB/s
Collecting singledispatch (from tornado->matplotlib)
Downloading singledispatch-3.4.0.3-py2.py3-none-any.whl
Collecting certifi (from tornado->matplotlib)
Downloading certifi-2017.1.23-py2.py3-none-any.whl (382kB)
100% |████████████████████████████████| 389kB 105kB/s
Collecting backports_abc>=0.4 (from tornado->matplotlib)
Downloading backports_abc-0.5-py2.py3-none-any.whl
Requirement already satisfied: six in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from singledispatch->tornado->matplotlib)
Installing collected packages: singledispatch, certifi, backports-abc, tornado, nose
Running setup.py install for tornado ... done
Exception:
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/Library/Python/2.7/site-packages/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/Library/Python/2.7/site-packages/pip/req/req_set.py", line 784, in install
**kwargs
File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 851, in install
self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 1064, in move_wheel_files
isolated=self.isolated,
File "/Library/Python/2.7/site-packages/pip/wheel.py", line 377, in move_wheel_files
clobber(source, dest, False, fixer=fixer, filter=filter)
File "/Library/Python/2.7/site-packages/pip/wheel.py", line 316, in clobber
ensure_dir(destdir)
File "/Library/Python/2.7/site-packages/pip/utils/__init__.py", line 83, in ensure_dir
os.makedirs(path)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 150, in makedirs
makedirs(head, mode)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 157, in makedirs
mkdir(name, mode)
OSError: [Errno 1] Operation not permitted: '/System/Library/Frameworks/Python.framework/Versions/2.7/man' 
分析了原因后,以为权限不够,所以就把这个目录:
/Users/rocky/Library/Caches/pip/
做了提权: sudo /Users/rocky/Library/Caches/pip/
然后重新运行sudo pip install matplotlib
然后没有上面提示的错误。 然后在主程序中继续运行,结果还是出现:matplotlib模块没找到。
 
删除后重装,问题依然存在。
 
于是尝试用easy_install 安装, sudo easy_install matplotlib
 
等待了大概10多分钟,居然安装成功了。 因为下载的服务器比较慢,所以等待的时间就有点长了。
  查看全部
使用pip安装: sudo pip install matplotlib
Password:
The directory '/Users/rocky/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/Users/rocky/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Requirement already satisfied: matplotlib in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python
Requirement already satisfied: numpy>=1.5 in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from matplotlib)
Requirement already satisfied: python-dateutil in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from matplotlib)
Collecting tornado (from matplotlib)
Downloading tornado-4.4.3.tar.gz (463kB)
100% |████████████████████████████████| 471kB 84kB/s
Requirement already satisfied: pyparsing>=1.5.6 in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from matplotlib)
Collecting nose (from matplotlib)
Downloading nose-1.3.7-py2-none-any.whl (154kB)
100% |████████████████████████████████| 163kB 75kB/s
Collecting singledispatch (from tornado->matplotlib)
Downloading singledispatch-3.4.0.3-py2.py3-none-any.whl
Collecting certifi (from tornado->matplotlib)
Downloading certifi-2017.1.23-py2.py3-none-any.whl (382kB)
100% |████████████████████████████████| 389kB 105kB/s
Collecting backports_abc>=0.4 (from tornado->matplotlib)
Downloading backports_abc-0.5-py2.py3-none-any.whl
Requirement already satisfied: six in /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python (from singledispatch->tornado->matplotlib)
Installing collected packages: singledispatch, certifi, backports-abc, tornado, nose
Running setup.py install for tornado ... done
Exception:
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/Library/Python/2.7/site-packages/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/Library/Python/2.7/site-packages/pip/req/req_set.py", line 784, in install
**kwargs
File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 851, in install
self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 1064, in move_wheel_files
isolated=self.isolated,
File "/Library/Python/2.7/site-packages/pip/wheel.py", line 377, in move_wheel_files
clobber(source, dest, False, fixer=fixer, filter=filter)
File "/Library/Python/2.7/site-packages/pip/wheel.py", line 316, in clobber
ensure_dir(destdir)
File "/Library/Python/2.7/site-packages/pip/utils/__init__.py", line 83, in ensure_dir
os.makedirs(path)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 150, in makedirs
makedirs(head, mode)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 157, in makedirs
mkdir(name, mode)
OSError: [Errno 1] Operation not permitted: '/System/Library/Frameworks/Python.framework/Versions/2.7/man'
 
分析了原因后,以为权限不够,所以就把这个目录:
/Users/rocky/Library/Caches/pip/
做了提权: sudo /Users/rocky/Library/Caches/pip/
然后重新运行sudo pip install matplotlib
然后没有上面提示的错误。 然后在主程序中继续运行,结果还是出现:matplotlib模块没找到。
 
删除后重装,问题依然存在。
 
于是尝试用easy_install 安装, sudo easy_install matplotlib
 
等待了大概10多分钟,居然安装成功了。 因为下载的服务器比较慢,所以等待的时间就有点长了。
 

sqlite 删除数据库中重复的行

李魔佛 发表了文章 • 0 个评论 • 583 次浏览 • 2017-03-21 18:34 • 来自相关话题

经常在爬取网络的信息后,会发现有重复的行。 如何使用sqlite删除那些重复的行?
 





 
本人SQL连入门都算不上,只能用到就去查相关的函数。
经过2个小时的不懈尝试,终于结合网上各种版本的删除数据重复行(网上太多坑呀 )
写出满足自己需求的sql语句
 
cmd='delete from STRATEGY where rowid not in (select max(rowid) from STRATEGY group by 代码);'
 
就是上面的这一句语句。
 
下面来简单说明一下,如果是DBA大牛请忽略。
 
首先表名字是STRATEGY,里面记录了一些股票,买入的原因,买入时间,股票名字和代码,当前股票的价格。当前的盈亏状态。
 
如果一天爬取同样的数据几次,机会自动追加到db数据中。 会造成大量的重复数据。 
首先从后面往前递推
 
select max(rowid) from STRATEGY group by 代码
 
这个语句 选择出来一些rowid, rowid是你创建数据库的时候默认就生产了,因为我在前面生成这个数据库的时候没有设置ID,或者index。 suo所以数据库默认用的是rowid,类似于行号。从第一行开始 rowid=1
 
上面就是 STRATEGY按照“代码”列进行排序, 因为有相同的,max(rowid) 
  查看全部
经常在爬取网络的信息后,会发现有重复的行。 如何使用sqlite删除那些重复的行?
 

重复.PNG

 
本人SQL连入门都算不上,只能用到就去查相关的函数。
经过2个小时的不懈尝试,终于结合网上各种版本的删除数据重复行(网上太多坑呀 )
写出满足自己需求的sql语句
 
cmd='delete from STRATEGY where rowid not in (select max(rowid) from STRATEGY group by 代码);'
 
就是上面的这一句语句。
 
下面来简单说明一下,如果是DBA大牛请忽略。
 
首先表名字是STRATEGY,里面记录了一些股票,买入的原因,买入时间,股票名字和代码,当前股票的价格。当前的盈亏状态。
 
如果一天爬取同样的数据几次,机会自动追加到db数据中。 会造成大量的重复数据。 
首先从后面往前递推
 
select max(rowid) from STRATEGY group by 代码
 
这个语句 选择出来一些rowid, rowid是你创建数据库的时候默认就生产了,因为我在前面生成这个数据库的时候没有设置ID,或者index。 suo所以数据库默认用的是rowid,类似于行号。从第一行开始 rowid=1
 
上面就是 STRATEGY按照“代码”列进行排序, 因为有相同的,max(rowid) 
 

《利用python进行数据分析》 学习笔记

李魔佛 发表了文章 • 0 个评论 • 1486 次浏览 • 2017-01-09 00:31 • 来自相关话题

Series
pandas的数组是没有逗号的 ['a' 'b' 'c' 'd' 'e']

r=Series([1,3,5,7,9],index=['A','B','C','D','E'])
print r
print r.index
r.reindex(['B','C''D','E','A'])

重新按照index进行排序
print r[['A','D']] #需要用两个中括号 才能正确地引用你说需要的值
 
字典操作:
print ‘A' in r
返回的是True或者False
可以用字典直接生成 Series
dict={"Username":"Rocky","Sex":"Male","Country":"China","Langauge":"Chinese"}
t=Series(dict)
print t
t.isnull()
判断是否为空
Series 的index可以随时就修改
t.index = ["AAA","DDD","DD","DE"]


DataFrame
默认会给你0,1,2,3,4 的index和columns
创建方法:
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002],'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
df=pd.DataFrame(data)
print df
访问一整列的方法:
print df['year']
print df.year
修改整列 df[’year‘]= 2017
或者使用 Series 来赋值
为不存在的列赋值会创建出一个新列。关 键字del用于删除列
根据列 重新索引
col=["year','states','pop']
df.reindex(colunms=col)
这时会重新按照列进行索引。
当然也可以同时进行索引。

df[df>5]=0
将df中大于5的元素清零
用于行操作时,需要用ix,这也是一种重新索引的方法。
获取某一行:
df.irow(x)
获取某一列:
df.icol(x)
上面的x都是整数,按照实际的行列进行获取
修改某一个值:
df.ix[3, 'a'] = 88
排序:
sort_index() 按照字母表排序,或者 数字大小, 日期
如果想要按照列进行排列, sort_index(axis=1) 默认按照index 也就是行标进行排序。
按照某一列排序 sort_values(by="a"), 如果需要按照多列 就 使用 sort_values(by=['a','b']

文件读取与存储/数据库
pd.read_table(文件名,sep=",") 以,为分隔符读取数据。 如果文件没有标题栏,可以使用header=None来制定,就是columns的值为空。 或者手动制定一个 names=xxx
如果要制定index为某列,可以index_col=“xx”
skiprow 可以帮助跳过第几行。

合并操作:

合并列
pd.merge(df1,df2)
merge重复的的值。 默认做的是交集: inner, 并集是outer, pd.merge(df1,df2,how=outer)
df1.join(df2)
行合并:
df.append(df2[:2]) index 不会变,df的值也不变,返回的值才是append之后的值
pd.concat( [ df1, df2 ] )
index重新排序。 注意格式


排序 df.groupby("Weather") #按照某一列进行排序
weather_group=df.groupby("Weather")
返回一个列表元组: for name, group in weather_group:
weather_group.first() 返回每一组分组中第一行
weather_group.last() 返回第一组分组中的最后一行
多行排序: df.groupby(['A','B'])
记住数据是Series还是DataFrame的 !

从csv文件读入,设置index 用 pd.read_csv(filename, index_col="XXXXX")
或者new_df= df.set_index('XXXX')



利用python进行数据分析
PDF电子书完整版 百度网盘下载
http://pan.baidu.com/s/1pLm7hAb 
密码:pvi4



  查看全部
Series
pandas的数组是没有逗号的 ['a' 'b' 'c' 'd' 'e']

r=Series([1,3,5,7,9],index=['A','B','C','D','E'])
print r
print r.index
r.reindex(['B','C''D','E','A'])

重新按照index进行排序
print r[['A','D']] #需要用两个中括号 才能正确地引用你说需要的值
 
字典操作:
print ‘A' in r
返回的是True或者False
可以用字典直接生成 Series
dict={"Username":"Rocky","Sex":"Male","Country":"China","Langauge":"Chinese"}
t=Series(dict)
print t
t.isnull()
判断是否为空
Series 的index可以随时就修改
t.index = ["AAA","DDD","DD","DE"]


DataFrame
默认会给你0,1,2,3,4 的index和columns
创建方法:
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002],'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
df=pd.DataFrame(data)
print df
访问一整列的方法:
print df['year']
print df.year
修改整列 df[’year‘]= 2017
或者使用 Series 来赋值
为不存在的列赋值会创建出一个新列。关 键字del用于删除列
根据列 重新索引
col=["year','states','pop']
df.reindex(colunms=col)
这时会重新按照列进行索引。
当然也可以同时进行索引。

df[df>5]=0
将df中大于5的元素清零
用于行操作时,需要用ix,这也是一种重新索引的方法。
获取某一行:
df.irow(x)
获取某一列:
df.icol(x)
上面的x都是整数,按照实际的行列进行获取
修改某一个值:
df.ix[3, 'a'] = 88
排序:
sort_index() 按照字母表排序,或者 数字大小, 日期
如果想要按照列进行排列, sort_index(axis=1) 默认按照index 也就是行标进行排序。
按照某一列排序 sort_values(by="a"), 如果需要按照多列 就 使用 sort_values(by=['a','b']

文件读取与存储/数据库
pd.read_table(文件名,sep=",") 以,为分隔符读取数据。 如果文件没有标题栏,可以使用header=None来制定,就是columns的值为空。 或者手动制定一个 names=xxx
如果要制定index为某列,可以index_col=“xx”
skiprow 可以帮助跳过第几行。

合并操作:

合并列
pd.merge(df1,df2)
merge重复的的值。 默认做的是交集: inner, 并集是outer, pd.merge(df1,df2,how=outer)
df1.join(df2)
行合并:
df.append(df2[:2]) index 不会变,df的值也不变,返回的值才是append之后的值
pd.concat( [ df1, df2 ] )
index重新排序。 注意格式


排序 df.groupby("Weather") #按照某一列进行排序
weather_group=df.groupby("Weather")
返回一个列表元组: for name, group in weather_group:
weather_group.first() 返回每一组分组中第一行
weather_group.last() 返回第一组分组中的最后一行
多行排序: df.groupby(['A','B'])
记住数据是Series还是DataFrame的 !

从csv文件读入,设置index 用 pd.read_csv(filename, index_col="XXXXX")
或者new_df= df.set_index('XXXX')



利用python进行数据分析
PDF电子书完整版 百度网盘下载
http://pan.baidu.com/s/1pLm7hAb 
密码:pvi4



 

dataframe按照条件删除行

李魔佛 发表了文章 • 0 个评论 • 2040 次浏览 • 2016-09-22 01:51 • 来自相关话题

#存储每天 涨幅排行榜,避免每次读取耗时过长
        filename=self.today+'.xls'
        filename=os.path.join(os.getcwd(),filename)
        if not os.path.exists(filename):
            self.df_today_all=ts.get_today_all()
            #过滤停牌的
            self.df_today_all.drop(self.df_today_all[self.df_today_all['turnoverratio']==0].index,inplace=True)
            #实测可用,删除的方法
            #n1=self.df_today_all[self.df_today_all['turnoverratio']==0]
            #n2=self.df_today_all.drop(n1.index)
            #print n2
            print self.df_today_all
            self.df_today_all.to_excel(filename)
        else:
            self.df_today_all=pd.read_excel(filename)
            print self.df_today_all 查看全部
#存储每天 涨幅排行榜,避免每次读取耗时过长
        filename=self.today+'.xls'
        filename=os.path.join(os.getcwd(),filename)
        if not os.path.exists(filename):
            self.df_today_all=ts.get_today_all()
            #过滤停牌的
            self.df_today_all.drop(self.df_today_all[self.df_today_all['turnoverratio']==0].index,inplace=True)
            #实测可用,删除的方法
            #n1=self.df_today_all[self.df_today_all['turnoverratio']==0]
            #n2=self.df_today_all.drop(n1.index)
            #print n2
            print self.df_today_all
            self.df_today_all.to_excel(filename)
        else:
            self.df_today_all=pd.read_excel(filename)
            print self.df_today_all

说实话,没觉得德州扑克有什么好玩的

回复

李魔佛 发起了问题 • 1 人关注 • 0 个回复 • 1083 次浏览 • 2016-08-05 00:48 • 来自相关话题

如何使用pandas把某些行的数据进行算术处理?

回复

李魔佛 发起了问题 • 1 人关注 • 0 个回复 • 1414 次浏览 • 2016-07-28 15:35 • 来自相关话题

tushare 源码分析 之 fundamental.py

李魔佛 发表了文章 • 0 个评论 • 7298 次浏览 • 2016-07-22 08:56 • 来自相关话题

python的tushare用来做数据分析是一个不错的工具。
 
下面来具体看看里面的一些具体的函数是怎么实现的。
 
fundamental.py  这个文件是获取企业的基本面信息的。 
 
比如 在主程序 main中,import tushare as ts
df=ts.get_stock_basics()那么我们来看看get_stock_basics函数的实现。def get_stock_basics():
"""
获取沪深上市公司基本情况
Return
--------
DataFrame
code,代码
name,名称
industry,细分行业
area,地区
pe,市盈率
outstanding,流通股本
totals,总股本(万)
totalAssets,总资产(万)
liquidAssets,流动资产
fixedAssets,固定资产
reserved,公积金
reservedPerShare,每股公积金
eps,每股收益
bvps,每股净资
pb,市净率
timeToMarket,上市日期
"""
request = Request(ct.ALL_STOCK_BASICS_FILE)
text = urlopen(request, timeout=10).read()
text = text.decode('GBK')
text = text.replace('--', '')
df = pd.read_csv(StringIO(text), dtype={'code':'object'})
df = df.set_index('code')
return df
上面通过urlib2的Request函数获取url的信息,然后保存为df格式然后返回。
url路径在这个变量里面: 
ct.ALL_STOCK_BASICS_FILE
 
跳转到这个变量





 
ALL_STOCK_BASICS_FILE = '%s%s/static/all.csv'%(P_TYPE['http'], DOMAINS['oss'])
 
P_TYPE 和DOMAINS 是字典变量, 在同一个文件内可以找到他们的值:P_TYPE = {'http': 'http://', 'ftp': 'ftp://'}

DOMAINS = {'sina': 'sina.com.cn', 'sinahq': 'sinajs.cn',
'ifeng': 'ifeng.com', 'sf': 'finance.sina.com.cn',
'vsf': 'vip.stock.finance.sina.com.cn',
'idx': 'www.csindex.com.cn', '163': 'money.163.com',
'em': 'eastmoney.com', 'sseq': 'query.sse.com.cn',
'sse': 'www.sse.com.cn', 'szse': 'www.szse.cn',
'oss': '218.244.146.57', 'idxip':'115.29.204.48',
'shibor': 'www.shibor.org', 'mbox':'www.cbooo.cn'}
 
然后把上面的字典值抽取出来:
 
那么url就是 http://218.244.146.57/static/all.csv , 你可以试试在浏览器里直接输入。 看到了吗?
可以直接下载一个all.csv格式的文件,打开后可以看到里面很多企业基本面的信息。
 






 
 
获取业绩报表
def get_report_data(year, quarter):
    """
        获取业绩报表数据
    Parameters
    --------
    year:int 年度 e.g:2014
    quarter:int 季度 :1、2、3、4,只能输入这4个季度
       说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度
       
    Return
    --------
    DataFrame
        code,代码
        name,名称
        eps,每股收益
        eps_yoy,每股收益同比(%)
        bvps,每股净资产
        roe,净资产收益率(%)
        epcf,每股现金流量(元)
        net_profits,净利润(万元)
        profits_yoy,净利润同比(%)
        distrib,分配方案
        report_date,发布日期
    """
 
函数主要通过 request = Request(url) 在财经网站获取信息。request = Request(ct.REPORT_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'],year, quarter, pageNo, ct.PAGE_NUM[1]))
text = urlopen(request, timeout=10).read()
Request里面的参数是一个可变量,通过循环的列表来获取所有的公司业绩报表。
通过定位参数里的变量,可以得到随意一个url, 比如 REPORT_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/mainindex/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s'
 
那么url =http://vip.stock.finance.sina.com.cn/q/go.php/vFinanceAnalyze/kind/mainindex/index.phtml?s_i=&s_a=&s_c=&reportdate=2014&quarter=1&p=1&num=38
 
那么直接在浏览器输入看看 是什么数据
 





 
看到了2014年第一节度的每个公司的业绩(因为有些是新股,所以2014的数据显示不全)
 
 
注意
df=ts.get_report_data(2016,4)
#第四季度就是年报
 根据作者的意思,这个参数写4就是年报。 (可以自己根据网址内容去到新浪财经去验证)

待续。 查看全部
python的tushare用来做数据分析是一个不错的工具。
 
下面来具体看看里面的一些具体的函数是怎么实现的。
 
fundamental.py  这个文件是获取企业的基本面信息的。 
 
比如 在主程序 main中,
import tushare as ts
df=ts.get_stock_basics()
那么我们来看看get_stock_basics函数的实现。
def get_stock_basics():
"""
获取沪深上市公司基本情况
Return
--------
DataFrame
code,代码
name,名称
industry,细分行业
area,地区
pe,市盈率
outstanding,流通股本
totals,总股本(万)
totalAssets,总资产(万)
liquidAssets,流动资产
fixedAssets,固定资产
reserved,公积金
reservedPerShare,每股公积金
eps,每股收益
bvps,每股净资
pb,市净率
timeToMarket,上市日期
"""
request = Request(ct.ALL_STOCK_BASICS_FILE)
text = urlopen(request, timeout=10).read()
text = text.decode('GBK')
text = text.replace('--', '')
df = pd.read_csv(StringIO(text), dtype={'code':'object'})
df = df.set_index('code')
return df

上面通过urlib2的Request函数获取url的信息,然后保存为df格式然后返回。
url路径在这个变量里面: 
ct.ALL_STOCK_BASICS_FILE
 
跳转到这个变量

goto.png

 
ALL_STOCK_BASICS_FILE = '%s%s/static/all.csv'%(P_TYPE['http'], DOMAINS['oss'])
 
P_TYPE 和DOMAINS 是字典变量, 在同一个文件内可以找到他们的值:
P_TYPE = {'http': 'http://', 'ftp': 'ftp://'}

DOMAINS = {'sina': 'sina.com.cn', 'sinahq': 'sinajs.cn',
'ifeng': 'ifeng.com', 'sf': 'finance.sina.com.cn',
'vsf': 'vip.stock.finance.sina.com.cn',
'idx': 'www.csindex.com.cn', '163': 'money.163.com',
'em': 'eastmoney.com', 'sseq': 'query.sse.com.cn',
'sse': 'www.sse.com.cn', 'szse': 'www.szse.cn',
'oss': '218.244.146.57', 'idxip':'115.29.204.48',
'shibor': 'www.shibor.org', 'mbox':'www.cbooo.cn'}

 
然后把上面的字典值抽取出来:
 
那么url就是 http://218.244.146.57/static/all.csv , 你可以试试在浏览器里直接输入。 看到了吗?
可以直接下载一个all.csv格式的文件,打开后可以看到里面很多企业基本面的信息。
 

allcsv.PNG


 
 
获取业绩报表
def get_report_data(year, quarter):
    """
        获取业绩报表数据
    Parameters
    --------
    year:int 年度 e.g:2014
    quarter:int 季度 :1、2、3、4,只能输入这4个季度
       说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度
       
    Return
    --------
    DataFrame
        code,代码
        name,名称
        eps,每股收益
        eps_yoy,每股收益同比(%)
        bvps,每股净资产
        roe,净资产收益率(%)
        epcf,每股现金流量(元)
        net_profits,净利润(万元)
        profits_yoy,净利润同比(%)
        distrib,分配方案
        report_date,发布日期
    """
 
函数主要通过 request = Request(url) 在财经网站获取信息。
request = Request(ct.REPORT_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'],year, quarter, pageNo, ct.PAGE_NUM[1]))
text = urlopen(request, timeout=10).read()

Request里面的参数是一个可变量,通过循环的列表来获取所有的公司业绩报表。
通过定位参数里的变量,可以得到随意一个url, 比如 REPORT_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/mainindex/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s'
 
那么url =http://vip.stock.finance.sina.com.cn/q/go.php/vFinanceAnalyze/kind/mainindex/index.phtml?s_i=&s_a=&s_c=&reportdate=2014&quarter=1&p=1&num=38
 
那么直接在浏览器输入看看 是什么数据
 

财报.PNG

 
看到了2014年第一节度的每个公司的业绩(因为有些是新股,所以2014的数据显示不全)
 
 
注意
        df=ts.get_report_data(2016,4)
#第四季度就是年报

 根据作者的意思,这个参数写4就是年报。 (可以自己根据网址内容去到新浪财经去验证)

待续。

30天学会量化交易模型 Day05

李魔佛 发表了文章 • 7 个评论 • 6930 次浏览 • 2016-07-19 22:52 • 来自相关话题

tushare数据写入SQLite
 这一节 我们学习如何把得到的数据写入数据库。
 
虽然也可以写入excel或者json,不过考虑到后面用的的排序和其他python脚本的调用,最后选择了轻量级的数据库SQLiite作为首选。# -*-coding=utf-8-*-
#数据库的操作
'''
http://30daydo.com
weigesysu@qq.com
'''
import sqlite3, time, datetime

__author__ = 'rocky'


class SqliteDb():


def __init__(self,dbtable):
'''
self.today = time.strftime("%Y-%m-%d")
self.DBname = self.today + '.db'
self.conn = sqlite3.connect(self.DBname)
'''
today = time.strftime("%Y-%m-%d")
DBname = today + '.db'
self.conn = sqlite3.connect(DBname)
self.dbtable=dbtable
create_tb = "CREATE TABLE %s (date varchar(10),id varchar(6), name varchar(30), p_change REAL,turnover REAL);" %self.dbtable
self.conn.execute(create_tb)
self.conn.commit()

def store_break_high(self,price_high_data):

#data 是创新高的个股信息 dataframe
#print today
#create_tb = 'CREATE TABLE STOCK (date TEXT,id text PRIMARY KEY, p_change REAL,turnover REAL);'

#conn.commit()
#print "(%s,%s,%f,%f)" %(price_high_data[0], price_high_data[1], price_high_data[2], price_high_data[3])
insert_data_cmd = "INSERT INTO %s(date,id,name,p_change,turnover) VALUES(\"%s\",\"%s\",\"%s\",%f,%f);" %(self.dbtable,price_high_data[0], price_high_data[1], price_high_data[2], price_high_data[3],price_high_data[4])
self.conn.execute(insert_data_cmd)
#self.conn.execute('INSERT INTO STOCK(date,id,name,p_change,turnover) VALUES(?,?,?,?,?)',(price_high_data[0], price_high_data[1], price_high_data[2], price_high_data[3],price_high_data[4]))
self.conn.commit()


def close(self):
self.conn.close()
上面创建的表名是 以日期为命名的(前面的下划线是因为数据库的命名规则不能以数字为首)
 
上一篇:30天学会量化交易模型 Day04 (tushare获取破新高的股票)
http://www.30daydo.com/article/70 查看全部
tushare数据写入SQLite
 这一节 我们学习如何把得到的数据写入数据库。
 
虽然也可以写入excel或者json,不过考虑到后面用的的排序和其他python脚本的调用,最后选择了轻量级的数据库SQLiite作为首选。
# -*-coding=utf-8-*-
#数据库的操作
'''
http://30daydo.com
weigesysu@qq.com
'''
import sqlite3, time, datetime

__author__ = 'rocky'


class SqliteDb():


def __init__(self,dbtable):
'''
self.today = time.strftime("%Y-%m-%d")
self.DBname = self.today + '.db'
self.conn = sqlite3.connect(self.DBname)
'''
today = time.strftime("%Y-%m-%d")
DBname = today + '.db'
self.conn = sqlite3.connect(DBname)
self.dbtable=dbtable
create_tb = "CREATE TABLE %s (date varchar(10),id varchar(6), name varchar(30), p_change REAL,turnover REAL);" %self.dbtable
self.conn.execute(create_tb)
self.conn.commit()

def store_break_high(self,price_high_data):

#data 是创新高的个股信息 dataframe
#print today
#create_tb = 'CREATE TABLE STOCK (date TEXT,id text PRIMARY KEY, p_change REAL,turnover REAL);'

#conn.commit()
#print "(%s,%s,%f,%f)" %(price_high_data[0], price_high_data[1], price_high_data[2], price_high_data[3])
insert_data_cmd = "INSERT INTO %s(date,id,name,p_change,turnover) VALUES(\"%s\",\"%s\",\"%s\",%f,%f);" %(self.dbtable,price_high_data[0], price_high_data[1], price_high_data[2], price_high_data[3],price_high_data[4])
self.conn.execute(insert_data_cmd)
#self.conn.execute('INSERT INTO STOCK(date,id,name,p_change,turnover) VALUES(?,?,?,?,?)',(price_high_data[0], price_high_data[1], price_high_data[2], price_high_data[3],price_high_data[4]))
self.conn.commit()


def close(self):
self.conn.close()

上面创建的表名是 以日期为命名的(前面的下划线是因为数据库的命名规则不能以数字为首)
 
上一篇:30天学会量化交易模型 Day04 (tushare获取破新高的股票)
http://www.30daydo.com/article/70

30天学会量化交易模型 Day04

李魔佛 发表了文章 • 4 个评论 • 12423 次浏览 • 2016-07-16 21:28 • 来自相关话题

tushare获取破新高的股票

 股市有句话,新高后有新高。
因为新高后说明消化了前面的套牢盘。 所以这个时候的阻力很小。
 
下面使用一个例子来用代码获取当天创新高的股票。
 






使用的是tushare#-*-coding=utf-8-*-
__author__ = 'rocky'
'''
http://30daydo.com
weigesysu@qq.com
'''
#获取破指定天数内的新高 比如破60日新高
import tushare as ts
import datetime
info=ts.get_stock_basics()

def loop_all_stocks():
for EachStockID in info.index:
if is_break_high(EachStockID,60):
print "High price on",
print EachStockID,
print info.ix[EachStockID]['name'].decode('utf-8')



def is_break_high(stockID,days):
end_day=datetime.date(datetime.date.today().year,datetime.date.today().month,datetime.date.today().day)
days=days*7/5
#考虑到周六日非交易
start_day=end_day-datetime.timedelta(days)

start_day=start_day.strftime("%Y-%m-%d")
end_day=end_day.strftime("%Y-%m-%d")
df=ts.get_h_data(stockID,start=start_day,end=end_day)

period_high=df['high'].max()
#print period_high
today_high=df.iloc[0]['high']
#这里不能直接用 .values
#如果用的df【:1】 就需要用.values
#print today_high
if today_high>=period_high:
return True
else:
return False

loop_all_stocks()
可以修改 函数 is_break_high(EachStockID,60) 中的60 为破多少天内的新高。
 
上一篇:30天学会量化交易模型 Day03
http://www.30daydo.com/article/15
 
下一篇: 30天学会量化交易模型 Day05 (tushare数据写入SQLite)
http://www.30daydo.com/article/73 查看全部
tushare获取破新高的股票

 股市有句话,新高后有新高
因为新高后说明消化了前面的套牢盘。 所以这个时候的阻力很小。
 
下面使用一个例子来用代码获取当天创新高的股票。
 

createhigh.PNG


使用的是tushare
#-*-coding=utf-8-*-
__author__ = 'rocky'
'''
http://30daydo.com
weigesysu@qq.com
'''
#获取破指定天数内的新高 比如破60日新高
import tushare as ts
import datetime
info=ts.get_stock_basics()

def loop_all_stocks():
for EachStockID in info.index:
if is_break_high(EachStockID,60):
print "High price on",
print EachStockID,
print info.ix[EachStockID]['name'].decode('utf-8')



def is_break_high(stockID,days):
end_day=datetime.date(datetime.date.today().year,datetime.date.today().month,datetime.date.today().day)
days=days*7/5
#考虑到周六日非交易
start_day=end_day-datetime.timedelta(days)

start_day=start_day.strftime("%Y-%m-%d")
end_day=end_day.strftime("%Y-%m-%d")
df=ts.get_h_data(stockID,start=start_day,end=end_day)

period_high=df['high'].max()
#print period_high
today_high=df.iloc[0]['high']
#这里不能直接用 .values
#如果用的df【:1】 就需要用.values
#print today_high
if today_high>=period_high:
return True
else:
return False

loop_all_stocks()

可以修改 函数 is_break_high(EachStockID,60) 中的60 为破多少天内的新高。
 
上一篇:30天学会量化交易模型 Day03
http://www.30daydo.com/article/15
 
下一篇: 30天学会量化交易模型 Day05 (tushare数据写入SQLite)
http://www.30daydo.com/article/73

30天学会量化交易模型 Day03

李魔佛 发表了文章 • 9 个评论 • 8292 次浏览 • 2016-05-18 23:33 • 来自相关话题

第二天讲到保存为csv文件,下面的命令将数据保存为我们更加常用,且兼容性更好的excel文件 和sql数据库文件。
 





 
常用参数说明:

excel_writer: 文件路径或者ExcelWriter对象
sheet_name:sheet名称,默认为Sheet1
sep : 文件内容分隔符,默认为,逗号
na_rep: 在遇到NaN值时保存为某字符,默认为’‘空字符
float_format: float类型的格式
columns: 需要保存的列,默认为None
header: 是否保存columns名,默认为True
index: 是否保存index,默认为True
encoding: 文件编码格式
startrow: 在数据的头部留出startrow行空行
startcol :在数据的左边留出startcol列空列


tushare数据保存到SQL数据库文件

df.to_sql(表名,数据库的连接器)
引用官方的参数:

pandas.DataFrame.to_sql

DataFrame.to_sql(name, con, flavor=None, schema=None, if_exists='fail', index=True, index_label=None,chunksize=None, dtype=None)[source]

Write records stored in a DataFrame to a SQL database.

Parameters:

name : string

Name of SQL table

con : SQLAlchemy engine or DBAPI2 connection (legacy mode)

Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported.

flavor : ‘sqlite’, default None

DEPRECATED: this parameter will be removed in a future version, as ‘sqlite’ is the only supported option if SQLAlchemy is not installed.

schema : string, default None

Specify the schema (if database flavor supports this). If None, use default schema.

if_exists : {‘fail’, ‘replace’, ‘append’}, default ‘fail’

fail: If table exists, do nothing.
replace: If table exists, drop it, recreate it, and insert data.
append: If table exists, insert data. Create if does not exist.

index : boolean, default True

Write DataFrame index as a column.

index_label : string or sequence, default None

Column label for index column(s). If None is given (default) and index is True, then the index names are used. A sequence should be given if the DataFrame uses MultiIndex.

chunksize : int, default None

If not None, then rows will be written in batches of this size at a time. If None, all rows will be written at once.

dtype : dict of column name to SQL type, default None

Optional specifying the datatype for columns. The SQL type should be a SQLAlchemy type, or a string for sqlite3 fallback connection.

这里只支持sqlalchemy和sqlite。 所以如果是用的mysql,需要安装sqlalchemy的插件才行。

这里使用简单的sqlite3 作为例子:import sqlite3
db=sqlite3.connect("testdb.db")
df = ts.get_k_data('300333',start='2016-01-01',end='2016-12-28')
df.to_sql("newtable",db,flavor='sqlite')

这样,数据就保存到到名字为testdb.db的数据库中,表名为 newtable


 
上一篇:30天学会量化交易模型 Day02 
http://30daydo.com/article/13 

下一篇:30天学会量化交易模型 Day04 (tushare获取破新高的股票)
链接: http://www.30daydo.com/article/70 

  查看全部
第二天讲到保存为csv文件,下面的命令将数据保存为我们更加常用,且兼容性更好的excel文件 和sql数据库文件。
 

excel.jpg

 
常用参数说明:

excel_writer: 文件路径或者ExcelWriter对象
sheet_name:sheet名称,默认为Sheet1
sep : 文件内容分隔符,默认为,逗号
na_rep: 在遇到NaN值时保存为某字符,默认为’‘空字符
float_format: float类型的格式
columns: 需要保存的列,默认为None
header: 是否保存columns名,默认为True
index: 是否保存index,默认为True
encoding: 文件编码格式
startrow: 在数据的头部留出startrow行空行
startcol :在数据的左边留出startcol列空列


tushare数据保存到SQL数据库文件

df.to_sql(表名,数据库的连接器)
引用官方的参数:


pandas.DataFrame.to_sql

DataFrame.to_sql(name, con, flavor=None, schema=None, if_exists='fail', index=True, index_label=None,chunksize=None, dtype=None)[source]

Write records stored in a DataFrame to a SQL database.

Parameters:

name : string

Name of SQL table

con : SQLAlchemy engine or DBAPI2 connection (legacy mode)

Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported.

flavor : ‘sqlite’, default None

DEPRECATED: this parameter will be removed in a future version, as ‘sqlite’ is the only supported option if SQLAlchemy is not installed.

schema : string, default None

Specify the schema (if database flavor supports this). If None, use default schema.

if_exists : {‘fail’, ‘replace’, ‘append’}, default ‘fail’

fail: If table exists, do nothing.
replace: If table exists, drop it, recreate it, and insert data.
append: If table exists, insert data. Create if does not exist.

index : boolean, default True

Write DataFrame index as a column.

index_label : string or sequence, default None

Column label for index column(s). If None is given (default) and index is True, then the index names are used. A sequence should be given if the DataFrame uses MultiIndex.

chunksize : int, default None

If not None, then rows will be written in batches of this size at a time. If None, all rows will be written at once.

dtype : dict of column name to SQL type, default None

Optional specifying the datatype for columns. The SQL type should be a SQLAlchemy type, or a string for sqlite3 fallback connection.


这里只支持sqlalchemy和sqlite。 所以如果是用的mysql,需要安装sqlalchemy的插件才行。

这里使用简单的sqlite3 作为例子:
import sqlite3
db=sqlite3.connect("testdb.db")
df = ts.get_k_data('300333',start='2016-01-01',end='2016-12-28')
df.to_sql("newtable",db,flavor='sqlite')

这样,数据就保存到到名字为testdb.db的数据库中,表名为 newtable


 
上一篇:30天学会量化交易模型 Day02 
http://30daydo.com/article/13 

下一篇:30天学会量化交易模型 Day04 (tushare获取破新高的股票)
链接: http://www.30daydo.com/article/70