python量化交易

python量化交易

基于文本及符号密度的网页正文提取方法 python实现

python李魔佛 发表了文章 • 0 个评论 • 328 次浏览 • 2019-09-10 15:19 • 来自相关话题

基于文本及符号密度的网页正文提取方法 python实现
 项目路径https://github.com/Rockyzsu/CodePool/tree/master/GeneralNewsExtractor
完成后在本文详细介绍,
请密切关注。 查看全部
基于文本及符号密度的网页正文提取方法 python实现
 项目路径https://github.com/Rockyzsu/CodePool/tree/master/GeneralNewsExtractor
完成后在本文详细介绍,
请密切关注。

根据东财股吧爬虫数据进行自然语言分析,展示股市热度

股票李魔佛 发表了文章 • 0 个评论 • 211 次浏览 • 2019-09-10 09:27 • 来自相关话题

根据东财股吧爬虫数据进行自然语言分析,展示股市热度
 项目开展中.....
https://github.com/Rockyzsu/StockPredict
 
完工后会把代码搬上来并加注释。
根据东财股吧爬虫数据进行自然语言分析,展示股市热度
 项目开展中.....
https://github.com/Rockyzsu/StockPredict
 
完工后会把代码搬上来并加注释。

python分析目前为止科创板企业省份分布

量化交易李魔佛 发表了文章 • 0 个评论 • 292 次浏览 • 2019-08-26 00:45 • 来自相关话题

科创板上市以来已经有一个多月了,我想看看到目前为止,上市企业都是归属哪些地方的。 因为个人觉得科创板是上证板块的,那么来自江浙一带的企业会更多。 毕竟现在深市和沪市在争夺资源,深市希望把深圳企业留回在深市的主板或者中小创版块。
 
首先获取行情数据,借助tushare这个框架:
在python3环境下,pip install tushare --upgrade ,记得要更新,因为用的旧版本会获取不到科创板的数据。
安装成功后试试import tushare as ts,看看有没有报错。没有就是安装成功了。
 
接下来抓取全市场的行情.




(点击查看大图)
查看前5条数据
 现在行情数据存储在df中,然后分析数据。
因为提取的是全市场的数据,然后获取科创板的企业:




(点击查看大图)

使用的是正则表达式,匹配688开头的代码。
 
接下来就是分析企业归属地:




(点击查看大图)

使用value_counts函数,统计该列每个值出现的次数。

搞定了! 是不是很简单?
 
而且企业地区分布和自己的构想也差不多,江浙沪一带占了一半,加上北京地区,占了80%以上的科创板企业了。
 
每周会定期更新一篇python数据分析股票的文章。
 
原创文章,欢迎转载
请注明出处:
 http://30daydo.com/article/528 

  查看全部
科创板上市以来已经有一个多月了,我想看看到目前为止,上市企业都是归属哪些地方的。 因为个人觉得科创板是上证板块的,那么来自江浙一带的企业会更多。 毕竟现在深市和沪市在争夺资源,深市希望把深圳企业留回在深市的主板或者中小创版块。
 
首先获取行情数据,借助tushare这个框架:
在python3环境下,pip install tushare --upgrade ,记得要更新,因为用的旧版本会获取不到科创板的数据。
安装成功后试试import tushare as ts,看看有没有报错。没有就是安装成功了。
 
接下来抓取全市场的行情.

a1.PNG
(点击查看大图)
查看前5条数据
 现在行情数据存储在df中,然后分析数据。
因为提取的是全市场的数据,然后获取科创板的企业:

a2.PNG
(点击查看大图)

使用的是正则表达式,匹配688开头的代码。
 
接下来就是分析企业归属地:

a3.PNG
(点击查看大图)

使用value_counts函数,统计该列每个值出现的次数。

搞定了! 是不是很简单?
 
而且企业地区分布和自己的构想也差不多,江浙沪一带占了一半,加上北京地区,占了80%以上的科创板企业了。
 
每周会定期更新一篇python数据分析股票的文章。
 
原创文章,欢迎转载
请注明出处:
 http://30daydo.com/article/528 

 

截止今天(2019-05-14)银行股今年的涨幅排名

股票李魔佛 发表了文章 • 0 个评论 • 728 次浏览 • 2019-05-14 23:59 • 来自相关话题

今年涨幅最少的是农业银行,最多的是新股 西安银行。 ticker secShortName secFullName y_chgPct
31 601288 农业银行 中国农业银行股份有限公司 -0.341178
11 600015 华夏银行 华夏银行股份有限公司 1.856174
45 601988 中国银行 中国银行股份有限公司 2.248533
32 601328 交通银行 交通银行股份有限公司 3.532657
30 601229 上海银行 上海银行股份有限公司 3.725781
35 601398 工商银行 中国工商银行股份有限公司 4.771403
40 601818 光大银行 中国光大银行股份有限公司 5.643119
27 601169 北京银行 北京银行股份有限公司 6.205580
14 600016 民生银行 中国民生银行股份有限公司 7.092815
5 002936 郑州银行 郑州银行股份有限公司 7.551112
49 601998 中信银行 中信银行股份有限公司 8.181956
43 601939 建设银行 中国建设银行股份有限公司 9.402651
41 601838 成都银行 成都银行股份有限公司 9.424554
52 603323 苏农银行 江苏苏州农村商业银行股份有限公司 12.375732
20 600926 杭州银行 杭州银行股份有限公司 12.933645
8 600000 浦发银行 上海浦东发展银行股份有限公司 14.752244
39 601577 长沙银行 长沙银行股份有限公司 14.792683
18 600908 无锡银行 无锡农村商业银行股份有限公司 16.181704
3 002807 江阴银行 江苏江阴农村商业银行股份有限公司 19.274586
48 601997 贵阳银行 贵阳银行股份有限公司 20.489563
4 002839 张家港行 江苏张家港农村商业银行股份有限公司 20.599511
25 601166 兴业银行 兴业银行股份有限公司 21.206503
24 601128 常熟银行 江苏常熟农村商业银行股份有限公司 21.571187
19 600919 江苏银行 江苏银行股份有限公司 23.218299
22 601009 南京银行 南京银行股份有限公司 26.297500
16 600036 招商银行 招商银行股份有限公司 27.518708
0 000001 平安银行 平安银行股份有限公司 31.624747
2 002142 宁波银行 宁波银行股份有限公司 31.729062
6 002948 青岛银行 青岛银行股份有限公司 48.602573
7 002958 青农商行 青岛农村商业银行股份有限公司 108.983776
42 601860 紫金银行 江苏紫金农村商业银行股份有限公司 115.147347
21 600928 西安银行 西安银行股份有限公司 128.496683 查看全部
今年涨幅最少的是农业银行,最多的是新股 西安银行。
	ticker	secShortName	secFullName	y_chgPct
31 601288 农业银行 中国农业银行股份有限公司 -0.341178
11 600015 华夏银行 华夏银行股份有限公司 1.856174
45 601988 中国银行 中国银行股份有限公司 2.248533
32 601328 交通银行 交通银行股份有限公司 3.532657
30 601229 上海银行 上海银行股份有限公司 3.725781
35 601398 工商银行 中国工商银行股份有限公司 4.771403
40 601818 光大银行 中国光大银行股份有限公司 5.643119
27 601169 北京银行 北京银行股份有限公司 6.205580
14 600016 民生银行 中国民生银行股份有限公司 7.092815
5 002936 郑州银行 郑州银行股份有限公司 7.551112
49 601998 中信银行 中信银行股份有限公司 8.181956
43 601939 建设银行 中国建设银行股份有限公司 9.402651
41 601838 成都银行 成都银行股份有限公司 9.424554
52 603323 苏农银行 江苏苏州农村商业银行股份有限公司 12.375732
20 600926 杭州银行 杭州银行股份有限公司 12.933645
8 600000 浦发银行 上海浦东发展银行股份有限公司 14.752244
39 601577 长沙银行 长沙银行股份有限公司 14.792683
18 600908 无锡银行 无锡农村商业银行股份有限公司 16.181704
3 002807 江阴银行 江苏江阴农村商业银行股份有限公司 19.274586
48 601997 贵阳银行 贵阳银行股份有限公司 20.489563
4 002839 张家港行 江苏张家港农村商业银行股份有限公司 20.599511
25 601166 兴业银行 兴业银行股份有限公司 21.206503
24 601128 常熟银行 江苏常熟农村商业银行股份有限公司 21.571187
19 600919 江苏银行 江苏银行股份有限公司 23.218299
22 601009 南京银行 南京银行股份有限公司 26.297500
16 600036 招商银行 招商银行股份有限公司 27.518708
0 000001 平安银行 平安银行股份有限公司 31.624747
2 002142 宁波银行 宁波银行股份有限公司 31.729062
6 002948 青岛银行 青岛银行股份有限公司 48.602573
7 002958 青农商行 青岛农村商业银行股份有限公司 108.983776
42 601860 紫金银行 江苏紫金农村商业银行股份有限公司 115.147347
21 600928 西安银行 西安银行股份有限公司 128.496683

【可转债剩余转股比例数据排序】【2019-05-06】

股票李魔佛 发表了文章 • 0 个评论 • 434 次浏览 • 2019-05-06 15:28 • 来自相关话题

数据如下:










 
剩余的比例越少,上市公司下调转股价的欲望就越少。 也就是会任由可转债在那里晾着,不会积极拉正股。
 
数据定期更新。
 
原创文章,
转载请注明出处:
http://30daydo.com/article/472
  查看全部
数据如下:

剩余比例1.PNG


剩余比例2.PNG

 
剩余的比例越少,上市公司下调转股价的欲望就越少。 也就是会任由可转债在那里晾着,不会积极拉正股。
 
数据定期更新。
 
原创文章,
转载请注明出处:
http://30daydo.com/article/472
 

2月

股票Freedom 发表了文章 • 6 个评论 • 379 次浏览 • 2019-02-27 22:06 • 来自相关话题

 
 
这样的行情自己也第一次经历 
记录下
开始职业就是熊市,弄得现在看不懂就赶紧空仓。。。

1.png

 
 
这样的行情自己也第一次经历 
记录下
开始职业就是熊市,弄得现在看不懂就赶紧空仓。。。

可转债价格分布堆叠图 绘制 可视化 python+pyecharts

量化交易李魔佛 发表了文章 • 0 个评论 • 1116 次浏览 • 2019-01-30 10:59 • 来自相关话题

这一节课带大家学习如何利用可视化,更好的呈现数据。
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:





 点击查看大图

如果我用下面的图形就可以看出规律:




 点击查看大图

横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
 
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
 
那么如何使用代码实现呢?from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)

result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)


# 确定价格的范围

value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))

ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1

retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1

retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1

retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1

retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1

bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
 
上面代码运行后就可以得到上面最开始那张堆叠图了。
github:https://github.com/Rockyzsu/convertible_bond​ 
 
 
原创文章
转载请注明出处:
 http://30daydo.com/article/400 

  查看全部
这一节课带大家学习如何利用可视化,更好的呈现数据。
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:

可转债数据.JPG

 点击查看大图

如果我用下面的图形就可以看出规律:
可转债价格分布.JPG

 点击查看大图

横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
 
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
 
那么如何使用代码实现呢?
from  setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)

result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)


# 确定价格的范围

value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))

ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1

retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1

retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1

retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1

retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1

bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)

如果没有安装pyecharts,需要用pip安装即可。
 
上面代码运行后就可以得到上面最开始那张堆叠图了。
github:https://github.com/Rockyzsu/convertible_bond​ 
 
 
原创文章
转载请注明出处:
 http://30daydo.com/article/400 

 

为什么使用talib查找K线形态和优矿上查到的不一样?

股票camel 回复了问题 • 2 人关注 • 1 个回复 • 1910 次浏览 • 2018-11-01 20:16 • 来自相关话题

numpy logspace的用法

量化交易李魔佛 发表了文章 • 0 个评论 • 1631 次浏览 • 2018-10-28 17:54 • 来自相关话题

numpy.logspace

numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)[source]

Return numbers spaced evenly on a log scale.

In linear space, the sequence starts at base ** start (base to the power of start) and ends with base ** stop (see endpoint below).

Parameters:

start : float

base ** start is the starting value of the sequence.

stop : float

base ** stop is the final value of the sequence, unless endpoint is False. In that case, num + 1 values are spaced over the interval in log-space, of which all but the last (a sequence of length num) are returned.

num : integer, optional

Number of samples to generate. Default is 50.

endpoint : boolean, optional

If true, stop is the last sample. Otherwise, it is not included. Default is True.

base : float, optional

The base of the log space. The step size between the elements in ln(samples) / ln(base) (or log_base(samples)) is uniform. Default is 10.0.

dtype : dtype

The type of the output array. If dtype is not given, infer the data type from the other input arguments.

Returns:

samples : ndarray

num samples, equally spaced on a log scale


 

上面是官方的文档,英文说的很明白,但网上尤其是csdn的解释,(其实都是你抄我,我抄你),实在让人看的一头雾水
 
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
 
比如 np.logspace(0,10,9)
那么会有结果是:
array([1.00000000e+00, 1.77827941e+01, 3.16227766e+02, 5.62341325e+03,
1.00000000e+05, 1.77827941e+06, 3.16227766e+07, 5.62341325e+08,
1.00000000e+10])
第一位是开始值0,第二位是结束值10,然后在这0-10之间产生9个值,这9个值是均匀分布的,默认包括最后一个结束点,就是0到10的9个等产数列,那么根据等差数列的公式,a1+(n-1)*d=an,算出,d=1.25,那么a1=0,接着a2=1.25,a3=2.5,。。。。。a9=10,然后再对这9个值做已10为底的指数运算,也就是10^0, 10^1.25 , 10^2.5 这样的结果 查看全部


numpy.logspace

numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)[source]

Return numbers spaced evenly on a log scale.

In linear space, the sequence starts at base ** start (base to the power of start) and ends with base ** stop (see endpoint below).

Parameters:

start : float

base ** start is the starting value of the sequence.

stop : float

base ** stop is the final value of the sequence, unless endpoint is False. In that case, num + 1 values are spaced over the interval in log-space, of which all but the last (a sequence of length num) are returned.

num : integer, optional

Number of samples to generate. Default is 50.

endpoint : boolean, optional

If true, stop is the last sample. Otherwise, it is not included. Default is True.

base : float, optional

The base of the log space. The step size between the elements in ln(samples) / ln(base) (or log_base(samples)) is uniform. Default is 10.0.

dtype : dtype

The type of the output array. If dtype is not given, infer the data type from the other input arguments.

Returns:

samples : ndarray

num samples, equally spaced on a log scale



 


上面是官方的文档,英文说的很明白,但网上尤其是csdn的解释,(其实都是你抄我,我抄你),实在让人看的一头雾水
 
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
 
比如 np.logspace(0,10,9)
那么会有结果是:
array([1.00000000e+00, 1.77827941e+01, 3.16227766e+02, 5.62341325e+03,
1.00000000e+05, 1.77827941e+06, 3.16227766e+07, 5.62341325e+08,
1.00000000e+10])

第一位是开始值0,第二位是结束值10,然后在这0-10之间产生9个值,这9个值是均匀分布的,默认包括最后一个结束点,就是0到10的9个等产数列,那么根据等差数列的公式,a1+(n-1)*d=an,算出,d=1.25,那么a1=0,接着a2=1.25,a3=2.5,。。。。。a9=10,然后再对这9个值做已10为底的指数运算,也就是10^0, 10^1.25 , 10^2.5 这样的结果

python数据分析入门 --分析雪球元卫南每个月打赏收入

量化交易李魔佛 发表了文章 • 2 个评论 • 2935 次浏览 • 2018-10-24 14:34 • 来自相关话题

************************* 2019-08-18日 更新 ******************************
最近居然被元神拉黑了。因为帖子不知道被哪位挖坟,估计被元神看到了。
 
重新跑了下原来的代码,还能跑通,看来雪球并没有改动什么代码。但是雪球经历了一波app下架风波,2019年前的帖子全部无法见到了。
 
重新获取数据:




点击查看大图

统计数据:




点击查看大图

2019年1月到现在(8月),元神收到的赏金为31851.6,数额比他2019年前所有的金额都要多,虽然总额不高,但是说明了元神这一年影响力大增了。
 
 
************************* 写于 2018-11 *******************************
 在上一篇 雪球的元卫南靠打赏收割了多少钱 ? python爬虫实例 中,统计出来元卫南所有打赏收入为 24128.13 ,这个数字出乎不少人的意料。因为不少人看到元卫南最近收到的打赏都很多,不少都是100,200的。 那么接下来我就顺便带大家学一下,如何用python做数据分析。
 
数据来源于上一篇文章中获取到的数据。
首先,从数据库mongodb中读取数据










(点击查看大图)

上面显示数据的前10条,确保数据被正常载入。
 
观察到列 created_at 是打赏的时间, 导入的数据是字符类型,那么对列 created_at 进行换算, 转化为dataframe中的datetime类型。重新定义一列 pub_date 为打赏时间,设为index,因为dataframe可以对时间index做很多丰富的操作。










 (点击查看大图) 

可以看到转换后的时间精确到小时,分,秒,而我们需要统计的是每个月(或者每周,每季度,每年都可以)的数据,那么我们就需要重新采样, pandas提供了很好的resample函数,可以对数据按照时间频次进行重新采样。 





 (点击查看大图)
 
现在可以看到获取到2018年9月的所有打赏金额的数据。
 
那么现在就对所有数据进行重采样,并打赏金额进行求和






 (点击查看大图)
 
现在可以看到,每个月得到的打赏金额的总和都可以看到了。从2016年7月到现在2018年10月,最多的月份是这个月,共1.4万,占了所有金额的60%多,所以才让大家造成一个错觉,元兄靠打赏赚了不少粉丝的打赏钱,其实只是最近才多起来的。
 
还可以绘制条形图。






 (点击查看大图)
 
不过因为月份金额差距过大,导致部分月份的条形显示很短。
 
不过对于赏金的分布也一目了然了吧。
 
原创文章
转载请注明出处:
http://30daydo.com/article/362 
  
个人公众号: 查看全部
************************* 2019-08-18日 更新 ******************************
最近居然被元神拉黑了。因为帖子不知道被哪位挖坟,估计被元神看到了。
 
重新跑了下原来的代码,还能跑通,看来雪球并没有改动什么代码。但是雪球经历了一波app下架风波,2019年前的帖子全部无法见到了。
 
重新获取数据:
元卫南1.PNG

点击查看大图

统计数据:
元卫南赏金.PNG

点击查看大图

2019年1月到现在(8月),元神收到的赏金为31851.6,数额比他2019年前所有的金额都要多,虽然总额不高,但是说明了元神这一年影响力大增了。
 
 
************************* 写于 2018-11 *******************************
 在上一篇 雪球的元卫南靠打赏收割了多少钱 ? python爬虫实例 中,统计出来元卫南所有打赏收入为 24128.13 ,这个数字出乎不少人的意料。因为不少人看到元卫南最近收到的打赏都很多,不少都是100,200的。 那么接下来我就顺便带大家学一下,如何用python做数据分析。
 
数据来源于上一篇文章中获取到的数据。
首先,从数据库mongodb中读取数据

捕获a12.JPG


top10.JPG

(点击查看大图)

上面显示数据的前10条,确保数据被正常载入。
 
观察到列 created_at 是打赏的时间, 导入的数据是字符类型,那么对列 created_at 进行换算, 转化为dataframe中的datetime类型。重新定义一列 pub_date 为打赏时间,设为index,因为dataframe可以对时间index做很多丰富的操作。

捕获a22.JPG


resample1.JPG

 (点击查看大图) 

可以看到转换后的时间精确到小时,分,秒,而我们需要统计的是每个月(或者每周,每季度,每年都可以)的数据,那么我们就需要重新采样, pandas提供了很好的resample函数,可以对数据按照时间频次进行重新采样。 

捕获a24.JPG

 (点击查看大图)
 
现在可以看到获取到2018年9月的所有打赏金额的数据。
 
那么现在就对所有数据进行重采样,并打赏金额进行求和


捕获a25.JPG

 (点击查看大图)
 
现在可以看到,每个月得到的打赏金额的总和都可以看到了。从2016年7月到现在2018年10月,最多的月份是这个月,共1.4万,占了所有金额的60%多,所以才让大家造成一个错觉,元兄靠打赏赚了不少粉丝的打赏钱,其实只是最近才多起来的。
 
还可以绘制条形图。


捕获a26.JPG

 (点击查看大图)
 
不过因为月份金额差距过大,导致部分月份的条形显示很短。
 
不过对于赏金的分布也一目了然了吧。
 
原创文章
转载请注明出处:
http://30daydo.com/article/362 
  
个人公众号:

可转债价格分布堆叠图 绘制 可视化 python+pyecharts

量化交易李魔佛 发表了文章 • 0 个评论 • 1116 次浏览 • 2019-01-30 10:59 • 来自相关话题

这一节课带大家学习如何利用可视化,更好的呈现数据。
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:





 点击查看大图

如果我用下面的图形就可以看出规律:




 点击查看大图

横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
 
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
 
那么如何使用代码实现呢?from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)

result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)


# 确定价格的范围

value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))

ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1

retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1

retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1

retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1

retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1

bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
 
上面代码运行后就可以得到上面最开始那张堆叠图了。
github:https://github.com/Rockyzsu/convertible_bond​ 
 
 
原创文章
转载请注明出处:
 http://30daydo.com/article/400 

  查看全部
这一节课带大家学习如何利用可视化,更好的呈现数据。
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:

可转债数据.JPG

 点击查看大图

如果我用下面的图形就可以看出规律:
可转债价格分布.JPG

 点击查看大图

横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
 
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
 
那么如何使用代码实现呢?
from  setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)

result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)


# 确定价格的范围

value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))

ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1

retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1

retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1

retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1

retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1

bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)

如果没有安装pyecharts,需要用pip安装即可。
 
上面代码运行后就可以得到上面最开始那张堆叠图了。
github:https://github.com/Rockyzsu/convertible_bond​ 
 
 
原创文章
转载请注明出处:
 http://30daydo.com/article/400 

 

可转债套利【一】 python找出折价可转债个股

量化交易李魔佛 发表了文章 • 8 个评论 • 9672 次浏览 • 2018-03-16 17:17 • 来自相关话题

关于可转债的定义,可以到https://xueqiu.com/6832369826/103042836 这里科普一下。
 
下面的内容默认你对可转债已经有一定的了解。
 
可转债的价值=正股价格/转股价格 + 利息,忽略可转债的利息,直接用公式 可转债的价值=正股价格/转股价格 计算可转债的价值。
 
如果当前可转债的交易价格(在交易软件上显示的价格)如:




所以万信转债的价格是121.5元,然后万信转债的价值呢? 按照上面的公式,万信转债的正股是万达信息,今天万达信息  (2018-03-16)的股价是





以收盘价为例,17.25。
 
而万信转债的股转价格呢? 这个可以到万信转债F10页面的公告中找到,为13.11元。 所以万信转债的价值是
17.25/13.11 = 1.315 , 可转债单位是100, 所以万信转债的内在价值是1.315*100=131.5, 而当前的交易价格为 121.5





 
 
也就是你用121.5元买到一个价值 131.5的商品, 所以相当于打折买到了一个超值的商品,所以当前的万信转债是折价状态。
 
所以本次任务就是要找出可交易的可转债中折价状态的可转债。
 
然后直接上干货。上python代码。#-*-coding=utf-8
'''
可转债监控
'''
import tushare as ts
from setting import get_engine
engine = get_engine('db_bond')
import pandas as pd
import datetime
class ConvertBond():

def __init__(self):
self.conn=ts.get_apis()
self.allBonds=ts.new_cbonds(pause=2)
self.onSellBond=self.allBonds.dropna(subset=['marketprice'])
self.today=datetime.datetime.now().strftime('%Y-%m-%d %H:%M')

def stockPrice(self,code):
stock_df = ts.get_realtime_quotes(code)
price = float(stock_df['price'].values[0])
return price

def dataframe(self):
price_list=[]
for code in self.onSellBond['scode']:
price_list.append(self.stockPrice(code))
self.onSellBond['stock_price']=price_list
self.onSellBond['ratio'] = (
self.onSellBond['marketprice']
/(self.onSellBond['stock_price'] / self.onSellBond['convprice'])-1)*100
self.onSellBond['Updated']=self.today
self.onSellBond.to_sql('tb_bond',engine,if_exists='replace')

def closed(self):
ts.close_apis(self.conn)

def main():
bond=ConvertBond()
bond.dataframe()
bond.closed()
if __name__=='__main__':
main()







 上面的setting库,把下面的*** 替换成你自己的Mysql用户和密码即可。import os
import MySQLdb
MYSQL_USER = *********
MYSQL_PASSWORD = ********
MYSQL_HOST = *********
MYSQL_PORT = *****

def get_engine(db):
engine = create_engine('mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(MYSQL_USER, MYSQL_PASSWORD, MYSQL_HOST, MYSQL_PORT, db))
return engine 
上面的少于100行的代码就能够满足你的要求。
运行后会把结果保存在MySQL 数据库。如下图所示:







点击放大
  2018-03-16 可转债表格
 
其中折价率是ratio列。按照ratio列进行排列,只有2个是正,也就是当前市场是只有2只可转债是处于折价状态的,其余的都是溢价状态(价格比内在价值要贵,忽略利息的前提下,如果把4~5%的利息也算进去的话,-3~4%的折价率其实也算小折价吧)
 
目前万信转债折价10个点,宝信转债折价5.8个点。 所以适合低风险投资者建仓。 因为可转债有兜底价格,所以出现亏损的概率很低(除非遇到黑天鹅,公司破产了,像遇到乐视这种PPT独角兽公司,欠债不还的。 但是A股上能够有资格发行可转债的,本身对公司的盈利,分红都有硬性要求)。
 
所以可以保存上面的代码,可以每天运行一次,可以很方便地找出折价的个股,当然也可以在盘中一直监测,因为可转债的价格是实时变化的,一旦遇到大跌,跌到折价状态,你也可以择时入手标的。

原文链接:
http://30daydo.com/article/286
转载请注明出处 查看全部
关于可转债的定义,可以到https://xueqiu.com/6832369826/103042836 这里科普一下。
 
下面的内容默认你对可转债已经有一定的了解。
 
可转债的价值=正股价格/转股价格 + 利息,忽略可转债的利息,直接用公式 可转债的价值=正股价格/转股价格 计算可转债的价值。
 
如果当前可转债的交易价格(在交易软件上显示的价格)如:
wxzz.GIF

所以万信转债的价格是121.5元,然后万信转债的价值呢? 按照上面的公式,万信转债的正股是万达信息,今天万达信息  (2018-03-16)的股价是

万达信息.GIF

以收盘价为例,17.25。
 
而万信转债的股转价格呢? 这个可以到万信转债F10页面的公告中找到,为13.11元。 所以万信转债的价值是
17.25/13.11 = 1.315 , 可转债单位是100, 所以万信转债的内在价值是1.315*100=131.5, 而当前的交易价格为 121.5

wxzz.GIF

 
 
也就是你用121.5元买到一个价值 131.5的商品, 所以相当于打折买到了一个超值的商品,所以当前的万信转债是折价状态。
 
所以本次任务就是要找出可交易的可转债中折价状态的可转债。
 
然后直接上干货。上python代码。
#-*-coding=utf-8
'''
可转债监控
'''
import tushare as ts
from setting import get_engine
engine = get_engine('db_bond')
import pandas as pd
import datetime
class ConvertBond():

def __init__(self):
self.conn=ts.get_apis()
self.allBonds=ts.new_cbonds(pause=2)
self.onSellBond=self.allBonds.dropna(subset=['marketprice'])
self.today=datetime.datetime.now().strftime('%Y-%m-%d %H:%M')

def stockPrice(self,code):
stock_df = ts.get_realtime_quotes(code)
price = float(stock_df['price'].values[0])
return price

def dataframe(self):
price_list=[]
for code in self.onSellBond['scode']:
price_list.append(self.stockPrice(code))
self.onSellBond['stock_price']=price_list
self.onSellBond['ratio'] = (
self.onSellBond['marketprice']
/(self.onSellBond['stock_price'] / self.onSellBond['convprice'])-1)*100
self.onSellBond['Updated']=self.today
self.onSellBond.to_sql('tb_bond',engine,if_exists='replace')

def closed(self):
ts.close_apis(self.conn)

def main():
bond=ConvertBond()
bond.dataframe()
bond.closed()
if __name__=='__main__':
main()







 上面的setting库,把下面的*** 替换成你自己的Mysql用户和密码即可。
import os
import MySQLdb
MYSQL_USER = *********
MYSQL_PASSWORD = ********
MYSQL_HOST = *********
MYSQL_PORT = *****

def get_engine(db):
engine = create_engine('mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(MYSQL_USER, MYSQL_PASSWORD, MYSQL_HOST, MYSQL_PORT, db))
return engine
 
上面的少于100行的代码就能够满足你的要求。
运行后会把结果保存在MySQL 数据库。如下图所示:


Screenshot_from_2018-03-28_09-14-35.png


点击放大
  2018-03-16 可转债表格
 
其中折价率是ratio列。按照ratio列进行排列,只有2个是正,也就是当前市场是只有2只可转债是处于折价状态的,其余的都是溢价状态(价格比内在价值要贵,忽略利息的前提下,如果把4~5%的利息也算进去的话,-3~4%的折价率其实也算小折价吧)
 
目前万信转债折价10个点,宝信转债折价5.8个点。 所以适合低风险投资者建仓。 因为可转债有兜底价格,所以出现亏损的概率很低(除非遇到黑天鹅,公司破产了,像遇到乐视这种PPT独角兽公司,欠债不还的。 但是A股上能够有资格发行可转债的,本身对公司的盈利,分红都有硬性要求)。
 
所以可以保存上面的代码,可以每天运行一次,可以很方便地找出折价的个股,当然也可以在盘中一直监测,因为可转债的价格是实时变化的,一旦遇到大跌,跌到折价状态,你也可以择时入手标的。

原文链接:
http://30daydo.com/article/286
转载请注明出处

dataframe reindex和reset_index区别

量化交易李魔佛 发表了文章 • 0 个评论 • 21959 次浏览 • 2017-12-30 15:58 • 来自相关话题

reset_index的作用是重新设置dataframe的index,范围为0~len(df)。 df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50]})
df2 = pd.DataFrame({'A': [6], 'B': [60]})
print 'df\n', df
print 'df2\n', df2

df_x = [df, df2]
result = pd.concat(df_x)
print 'first result\n', result 
上面代码把df和df2合并为一个result,但是result的index是乱的。





 
那么执行result2= result.reset_index()
得到如下的result2: (默认只是返回一个copy,原来的result没有发生改变,所以需要副本赋值给result2)





可以看到,原来的一列index现在变成了columns之一,新的index为[0,1,2,3,4,5]
如果添加参数 reset_index(drop=True) 那么原index会被丢弃,不会显示为一个新列。result2 = result.reset_index(drop=True)



 
reindex的作用是按照原有的列进行重新生成一个新的df。
 
还是使用上面的代码
result目前是df和df2的合并序列。
如下:




 
可以看到index为[0,1,2,3,4,0]
执行 result3 = result.reindex(columns=['A','C'])




 
可以看到,原index并没有发生改变,而列变成了A和C,因为C是不存在的,所以使用了NaB填充,这个值的内容可以自己填充,可以改为默认填充0或者任意你想要的数据。reindex(columns=..)的作用类似于重新把列的顺序整理一遍, 而使用reindex(index=....) 则按照行重新整理一遍。

原文链接:http://30daydo.com/article/257 
欢迎转载,注明出处
  查看全部
reset_index的作用是重新设置dataframe的index,范围为0~len(df)。
    df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [10, 20, 30, 40, 50]})
df2 = pd.DataFrame({'A': [6], 'B': [60]})
print 'df\n', df
print 'df2\n', df2

df_x = [df, df2]
result = pd.concat(df_x)
print 'first result\n', result
 
上面代码把df和df2合并为一个result,但是result的index是乱的。

df4.PNG

 
那么执行
result2= result.reset_index()

得到如下的result2: (默认只是返回一个copy,原来的result没有发生改变,所以需要副本赋值给result2)

df5.PNG

可以看到,原来的一列index现在变成了columns之一,新的index为[0,1,2,3,4,5]
如果添加参数 reset_index(drop=True) 那么原index会被丢弃,不会显示为一个新列。
result2 = result.reset_index(drop=True)
df6.PNG

 
reindex的作用是按照原有的列进行重新生成一个新的df。
 
还是使用上面的代码
result目前是df和df2的合并序列。
如下:
df7.PNG

 
可以看到index为[0,1,2,3,4,0]
执行 
result3 = result.reindex(columns=['A','C'])

df8.PNG

 
可以看到,原index并没有发生改变,而列变成了A和C,因为C是不存在的,所以使用了NaB填充,这个值的内容可以自己填充,可以改为默认填充0或者任意你想要的数据。reindex(columns=..)的作用类似于重新把列的顺序整理一遍, 而使用reindex(index=....) 则按照行重新整理一遍。

原文链接:http://30daydo.com/article/257 
欢迎转载,注明出处
 

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

量化交易李魔佛 发表了文章 • 56 个评论 • 14708 次浏览 • 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 
 

为什么使用talib查找K线形态和优矿上查到的不一样?

回复

股票camel 回复了问题 • 2 人关注 • 1 个回复 • 1910 次浏览 • 2018-11-01 20:16 • 来自相关话题

求港股数据获取PYTHON代码

回复

股票李魔佛 回复了问题 • 3 人关注 • 1 个回复 • 4171 次浏览 • 2018-06-07 16:09 • 来自相关话题

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

回复

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

基于文本及符号密度的网页正文提取方法 python实现

python李魔佛 发表了文章 • 0 个评论 • 328 次浏览 • 2019-09-10 15:19 • 来自相关话题

基于文本及符号密度的网页正文提取方法 python实现
 项目路径https://github.com/Rockyzsu/CodePool/tree/master/GeneralNewsExtractor
完成后在本文详细介绍,
请密切关注。 查看全部
基于文本及符号密度的网页正文提取方法 python实现
 项目路径https://github.com/Rockyzsu/CodePool/tree/master/GeneralNewsExtractor
完成后在本文详细介绍,
请密切关注。

根据东财股吧爬虫数据进行自然语言分析,展示股市热度

股票李魔佛 发表了文章 • 0 个评论 • 211 次浏览 • 2019-09-10 09:27 • 来自相关话题

根据东财股吧爬虫数据进行自然语言分析,展示股市热度
 项目开展中.....
https://github.com/Rockyzsu/StockPredict
 
完工后会把代码搬上来并加注释。
根据东财股吧爬虫数据进行自然语言分析,展示股市热度
 项目开展中.....
https://github.com/Rockyzsu/StockPredict
 
完工后会把代码搬上来并加注释。

python分析目前为止科创板企业省份分布

量化交易李魔佛 发表了文章 • 0 个评论 • 292 次浏览 • 2019-08-26 00:45 • 来自相关话题

科创板上市以来已经有一个多月了,我想看看到目前为止,上市企业都是归属哪些地方的。 因为个人觉得科创板是上证板块的,那么来自江浙一带的企业会更多。 毕竟现在深市和沪市在争夺资源,深市希望把深圳企业留回在深市的主板或者中小创版块。
 
首先获取行情数据,借助tushare这个框架:
在python3环境下,pip install tushare --upgrade ,记得要更新,因为用的旧版本会获取不到科创板的数据。
安装成功后试试import tushare as ts,看看有没有报错。没有就是安装成功了。
 
接下来抓取全市场的行情.




(点击查看大图)
查看前5条数据
 现在行情数据存储在df中,然后分析数据。
因为提取的是全市场的数据,然后获取科创板的企业:




(点击查看大图)

使用的是正则表达式,匹配688开头的代码。
 
接下来就是分析企业归属地:




(点击查看大图)

使用value_counts函数,统计该列每个值出现的次数。

搞定了! 是不是很简单?
 
而且企业地区分布和自己的构想也差不多,江浙沪一带占了一半,加上北京地区,占了80%以上的科创板企业了。
 
每周会定期更新一篇python数据分析股票的文章。
 
原创文章,欢迎转载
请注明出处:
 http://30daydo.com/article/528 

  查看全部
科创板上市以来已经有一个多月了,我想看看到目前为止,上市企业都是归属哪些地方的。 因为个人觉得科创板是上证板块的,那么来自江浙一带的企业会更多。 毕竟现在深市和沪市在争夺资源,深市希望把深圳企业留回在深市的主板或者中小创版块。
 
首先获取行情数据,借助tushare这个框架:
在python3环境下,pip install tushare --upgrade ,记得要更新,因为用的旧版本会获取不到科创板的数据。
安装成功后试试import tushare as ts,看看有没有报错。没有就是安装成功了。
 
接下来抓取全市场的行情.

a1.PNG
(点击查看大图)
查看前5条数据
 现在行情数据存储在df中,然后分析数据。
因为提取的是全市场的数据,然后获取科创板的企业:

a2.PNG
(点击查看大图)

使用的是正则表达式,匹配688开头的代码。
 
接下来就是分析企业归属地:

a3.PNG
(点击查看大图)

使用value_counts函数,统计该列每个值出现的次数。

搞定了! 是不是很简单?
 
而且企业地区分布和自己的构想也差不多,江浙沪一带占了一半,加上北京地区,占了80%以上的科创板企业了。
 
每周会定期更新一篇python数据分析股票的文章。
 
原创文章,欢迎转载
请注明出处:
 http://30daydo.com/article/528 

 

截止今天(2019-05-14)银行股今年的涨幅排名

股票李魔佛 发表了文章 • 0 个评论 • 728 次浏览 • 2019-05-14 23:59 • 来自相关话题

今年涨幅最少的是农业银行,最多的是新股 西安银行。 ticker secShortName secFullName y_chgPct
31 601288 农业银行 中国农业银行股份有限公司 -0.341178
11 600015 华夏银行 华夏银行股份有限公司 1.856174
45 601988 中国银行 中国银行股份有限公司 2.248533
32 601328 交通银行 交通银行股份有限公司 3.532657
30 601229 上海银行 上海银行股份有限公司 3.725781
35 601398 工商银行 中国工商银行股份有限公司 4.771403
40 601818 光大银行 中国光大银行股份有限公司 5.643119
27 601169 北京银行 北京银行股份有限公司 6.205580
14 600016 民生银行 中国民生银行股份有限公司 7.092815
5 002936 郑州银行 郑州银行股份有限公司 7.551112
49 601998 中信银行 中信银行股份有限公司 8.181956
43 601939 建设银行 中国建设银行股份有限公司 9.402651
41 601838 成都银行 成都银行股份有限公司 9.424554
52 603323 苏农银行 江苏苏州农村商业银行股份有限公司 12.375732
20 600926 杭州银行 杭州银行股份有限公司 12.933645
8 600000 浦发银行 上海浦东发展银行股份有限公司 14.752244
39 601577 长沙银行 长沙银行股份有限公司 14.792683
18 600908 无锡银行 无锡农村商业银行股份有限公司 16.181704
3 002807 江阴银行 江苏江阴农村商业银行股份有限公司 19.274586
48 601997 贵阳银行 贵阳银行股份有限公司 20.489563
4 002839 张家港行 江苏张家港农村商业银行股份有限公司 20.599511
25 601166 兴业银行 兴业银行股份有限公司 21.206503
24 601128 常熟银行 江苏常熟农村商业银行股份有限公司 21.571187
19 600919 江苏银行 江苏银行股份有限公司 23.218299
22 601009 南京银行 南京银行股份有限公司 26.297500
16 600036 招商银行 招商银行股份有限公司 27.518708
0 000001 平安银行 平安银行股份有限公司 31.624747
2 002142 宁波银行 宁波银行股份有限公司 31.729062
6 002948 青岛银行 青岛银行股份有限公司 48.602573
7 002958 青农商行 青岛农村商业银行股份有限公司 108.983776
42 601860 紫金银行 江苏紫金农村商业银行股份有限公司 115.147347
21 600928 西安银行 西安银行股份有限公司 128.496683 查看全部
今年涨幅最少的是农业银行,最多的是新股 西安银行。
	ticker	secShortName	secFullName	y_chgPct
31 601288 农业银行 中国农业银行股份有限公司 -0.341178
11 600015 华夏银行 华夏银行股份有限公司 1.856174
45 601988 中国银行 中国银行股份有限公司 2.248533
32 601328 交通银行 交通银行股份有限公司 3.532657
30 601229 上海银行 上海银行股份有限公司 3.725781
35 601398 工商银行 中国工商银行股份有限公司 4.771403
40 601818 光大银行 中国光大银行股份有限公司 5.643119
27 601169 北京银行 北京银行股份有限公司 6.205580
14 600016 民生银行 中国民生银行股份有限公司 7.092815
5 002936 郑州银行 郑州银行股份有限公司 7.551112
49 601998 中信银行 中信银行股份有限公司 8.181956
43 601939 建设银行 中国建设银行股份有限公司 9.402651
41 601838 成都银行 成都银行股份有限公司 9.424554
52 603323 苏农银行 江苏苏州农村商业银行股份有限公司 12.375732
20 600926 杭州银行 杭州银行股份有限公司 12.933645
8 600000 浦发银行 上海浦东发展银行股份有限公司 14.752244
39 601577 长沙银行 长沙银行股份有限公司 14.792683
18 600908 无锡银行 无锡农村商业银行股份有限公司 16.181704
3 002807 江阴银行 江苏江阴农村商业银行股份有限公司 19.274586
48 601997 贵阳银行 贵阳银行股份有限公司 20.489563
4 002839 张家港行 江苏张家港农村商业银行股份有限公司 20.599511
25 601166 兴业银行 兴业银行股份有限公司 21.206503
24 601128 常熟银行 江苏常熟农村商业银行股份有限公司 21.571187
19 600919 江苏银行 江苏银行股份有限公司 23.218299
22 601009 南京银行 南京银行股份有限公司 26.297500
16 600036 招商银行 招商银行股份有限公司 27.518708
0 000001 平安银行 平安银行股份有限公司 31.624747
2 002142 宁波银行 宁波银行股份有限公司 31.729062
6 002948 青岛银行 青岛银行股份有限公司 48.602573
7 002958 青农商行 青岛农村商业银行股份有限公司 108.983776
42 601860 紫金银行 江苏紫金农村商业银行股份有限公司 115.147347
21 600928 西安银行 西安银行股份有限公司 128.496683

【可转债剩余转股比例数据排序】【2019-05-06】

股票李魔佛 发表了文章 • 0 个评论 • 434 次浏览 • 2019-05-06 15:28 • 来自相关话题

数据如下:










 
剩余的比例越少,上市公司下调转股价的欲望就越少。 也就是会任由可转债在那里晾着,不会积极拉正股。
 
数据定期更新。
 
原创文章,
转载请注明出处:
http://30daydo.com/article/472
  查看全部
数据如下:

剩余比例1.PNG


剩余比例2.PNG

 
剩余的比例越少,上市公司下调转股价的欲望就越少。 也就是会任由可转债在那里晾着,不会积极拉正股。
 
数据定期更新。
 
原创文章,
转载请注明出处:
http://30daydo.com/article/472
 

2月

股票Freedom 发表了文章 • 6 个评论 • 379 次浏览 • 2019-02-27 22:06 • 来自相关话题

 
 
这样的行情自己也第一次经历 
记录下
开始职业就是熊市,弄得现在看不懂就赶紧空仓。。。

1.png

 
 
这样的行情自己也第一次经历 
记录下
开始职业就是熊市,弄得现在看不懂就赶紧空仓。。。

可转债价格分布堆叠图 绘制 可视化 python+pyecharts

量化交易李魔佛 发表了文章 • 0 个评论 • 1116 次浏览 • 2019-01-30 10:59 • 来自相关话题

这一节课带大家学习如何利用可视化,更好的呈现数据。
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:





 点击查看大图

如果我用下面的图形就可以看出规律:




 点击查看大图

横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
 
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
 
那么如何使用代码实现呢?from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)

result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)


# 确定价格的范围

value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))

ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1

retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1

retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1

retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1

retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1

bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
 
上面代码运行后就可以得到上面最开始那张堆叠图了。
github:https://github.com/Rockyzsu/convertible_bond​ 
 
 
原创文章
转载请注明出处:
 http://30daydo.com/article/400 

  查看全部
这一节课带大家学习如何利用可视化,更好的呈现数据。
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:

可转债数据.JPG

 点击查看大图

如果我用下面的图形就可以看出规律:
可转债价格分布.JPG

 点击查看大图

横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
 
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
 
那么如何使用代码实现呢?
from  setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)

result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)


# 确定价格的范围

value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))

ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1

retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1

retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1

retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1

retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1

bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)

如果没有安装pyecharts,需要用pip安装即可。
 
上面代码运行后就可以得到上面最开始那张堆叠图了。
github:https://github.com/Rockyzsu/convertible_bond​ 
 
 
原创文章
转载请注明出处:
 http://30daydo.com/article/400 

 

numpy logspace的用法

量化交易李魔佛 发表了文章 • 0 个评论 • 1631 次浏览 • 2018-10-28 17:54 • 来自相关话题

numpy.logspace

numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)[source]

Return numbers spaced evenly on a log scale.

In linear space, the sequence starts at base ** start (base to the power of start) and ends with base ** stop (see endpoint below).

Parameters:

start : float

base ** start is the starting value of the sequence.

stop : float

base ** stop is the final value of the sequence, unless endpoint is False. In that case, num + 1 values are spaced over the interval in log-space, of which all but the last (a sequence of length num) are returned.

num : integer, optional

Number of samples to generate. Default is 50.

endpoint : boolean, optional

If true, stop is the last sample. Otherwise, it is not included. Default is True.

base : float, optional

The base of the log space. The step size between the elements in ln(samples) / ln(base) (or log_base(samples)) is uniform. Default is 10.0.

dtype : dtype

The type of the output array. If dtype is not given, infer the data type from the other input arguments.

Returns:

samples : ndarray

num samples, equally spaced on a log scale


 

上面是官方的文档,英文说的很明白,但网上尤其是csdn的解释,(其实都是你抄我,我抄你),实在让人看的一头雾水
 
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
 
比如 np.logspace(0,10,9)
那么会有结果是:
array([1.00000000e+00, 1.77827941e+01, 3.16227766e+02, 5.62341325e+03,
1.00000000e+05, 1.77827941e+06, 3.16227766e+07, 5.62341325e+08,
1.00000000e+10])
第一位是开始值0,第二位是结束值10,然后在这0-10之间产生9个值,这9个值是均匀分布的,默认包括最后一个结束点,就是0到10的9个等产数列,那么根据等差数列的公式,a1+(n-1)*d=an,算出,d=1.25,那么a1=0,接着a2=1.25,a3=2.5,。。。。。a9=10,然后再对这9个值做已10为底的指数运算,也就是10^0, 10^1.25 , 10^2.5 这样的结果 查看全部


numpy.logspace

numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)[source]

Return numbers spaced evenly on a log scale.

In linear space, the sequence starts at base ** start (base to the power of start) and ends with base ** stop (see endpoint below).

Parameters:

start : float

base ** start is the starting value of the sequence.

stop : float

base ** stop is the final value of the sequence, unless endpoint is False. In that case, num + 1 values are spaced over the interval in log-space, of which all but the last (a sequence of length num) are returned.

num : integer, optional

Number of samples to generate. Default is 50.

endpoint : boolean, optional

If true, stop is the last sample. Otherwise, it is not included. Default is True.

base : float, optional

The base of the log space. The step size between the elements in ln(samples) / ln(base) (or log_base(samples)) is uniform. Default is 10.0.

dtype : dtype

The type of the output array. If dtype is not given, infer the data type from the other input arguments.

Returns:

samples : ndarray

num samples, equally spaced on a log scale



 


上面是官方的文档,英文说的很明白,但网上尤其是csdn的解释,(其实都是你抄我,我抄你),实在让人看的一头雾水
 
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
 
比如 np.logspace(0,10,9)
那么会有结果是:
array([1.00000000e+00, 1.77827941e+01, 3.16227766e+02, 5.62341325e+03,
1.00000000e+05, 1.77827941e+06, 3.16227766e+07, 5.62341325e+08,
1.00000000e+10])

第一位是开始值0,第二位是结束值10,然后在这0-10之间产生9个值,这9个值是均匀分布的,默认包括最后一个结束点,就是0到10的9个等产数列,那么根据等差数列的公式,a1+(n-1)*d=an,算出,d=1.25,那么a1=0,接着a2=1.25,a3=2.5,。。。。。a9=10,然后再对这9个值做已10为底的指数运算,也就是10^0, 10^1.25 , 10^2.5 这样的结果

python数据分析入门 --分析雪球元卫南每个月打赏收入

量化交易李魔佛 发表了文章 • 2 个评论 • 2935 次浏览 • 2018-10-24 14:34 • 来自相关话题

************************* 2019-08-18日 更新 ******************************
最近居然被元神拉黑了。因为帖子不知道被哪位挖坟,估计被元神看到了。
 
重新跑了下原来的代码,还能跑通,看来雪球并没有改动什么代码。但是雪球经历了一波app下架风波,2019年前的帖子全部无法见到了。
 
重新获取数据:




点击查看大图

统计数据:




点击查看大图

2019年1月到现在(8月),元神收到的赏金为31851.6,数额比他2019年前所有的金额都要多,虽然总额不高,但是说明了元神这一年影响力大增了。
 
 
************************* 写于 2018-11 *******************************
 在上一篇 雪球的元卫南靠打赏收割了多少钱 ? python爬虫实例 中,统计出来元卫南所有打赏收入为 24128.13 ,这个数字出乎不少人的意料。因为不少人看到元卫南最近收到的打赏都很多,不少都是100,200的。 那么接下来我就顺便带大家学一下,如何用python做数据分析。
 
数据来源于上一篇文章中获取到的数据。
首先,从数据库mongodb中读取数据










(点击查看大图)

上面显示数据的前10条,确保数据被正常载入。
 
观察到列 created_at 是打赏的时间, 导入的数据是字符类型,那么对列 created_at 进行换算, 转化为dataframe中的datetime类型。重新定义一列 pub_date 为打赏时间,设为index,因为dataframe可以对时间index做很多丰富的操作。










 (点击查看大图) 

可以看到转换后的时间精确到小时,分,秒,而我们需要统计的是每个月(或者每周,每季度,每年都可以)的数据,那么我们就需要重新采样, pandas提供了很好的resample函数,可以对数据按照时间频次进行重新采样。 





 (点击查看大图)
 
现在可以看到获取到2018年9月的所有打赏金额的数据。
 
那么现在就对所有数据进行重采样,并打赏金额进行求和






 (点击查看大图)
 
现在可以看到,每个月得到的打赏金额的总和都可以看到了。从2016年7月到现在2018年10月,最多的月份是这个月,共1.4万,占了所有金额的60%多,所以才让大家造成一个错觉,元兄靠打赏赚了不少粉丝的打赏钱,其实只是最近才多起来的。
 
还可以绘制条形图。






 (点击查看大图)
 
不过因为月份金额差距过大,导致部分月份的条形显示很短。
 
不过对于赏金的分布也一目了然了吧。
 
原创文章
转载请注明出处:
http://30daydo.com/article/362 
  
个人公众号: 查看全部
************************* 2019-08-18日 更新 ******************************
最近居然被元神拉黑了。因为帖子不知道被哪位挖坟,估计被元神看到了。
 
重新跑了下原来的代码,还能跑通,看来雪球并没有改动什么代码。但是雪球经历了一波app下架风波,2019年前的帖子全部无法见到了。
 
重新获取数据:
元卫南1.PNG

点击查看大图

统计数据:
元卫南赏金.PNG

点击查看大图

2019年1月到现在(8月),元神收到的赏金为31851.6,数额比他2019年前所有的金额都要多,虽然总额不高,但是说明了元神这一年影响力大增了。
 
 
************************* 写于 2018-11 *******************************
 在上一篇 雪球的元卫南靠打赏收割了多少钱 ? python爬虫实例 中,统计出来元卫南所有打赏收入为 24128.13 ,这个数字出乎不少人的意料。因为不少人看到元卫南最近收到的打赏都很多,不少都是100,200的。 那么接下来我就顺便带大家学一下,如何用python做数据分析。
 
数据来源于上一篇文章中获取到的数据。
首先,从数据库mongodb中读取数据

捕获a12.JPG


top10.JPG

(点击查看大图)

上面显示数据的前10条,确保数据被正常载入。
 
观察到列 created_at 是打赏的时间, 导入的数据是字符类型,那么对列 created_at 进行换算, 转化为dataframe中的datetime类型。重新定义一列 pub_date 为打赏时间,设为index,因为dataframe可以对时间index做很多丰富的操作。

捕获a22.JPG


resample1.JPG

 (点击查看大图) 

可以看到转换后的时间精确到小时,分,秒,而我们需要统计的是每个月(或者每周,每季度,每年都可以)的数据,那么我们就需要重新采样, pandas提供了很好的resample函数,可以对数据按照时间频次进行重新采样。 

捕获a24.JPG

 (点击查看大图)
 
现在可以看到获取到2018年9月的所有打赏金额的数据。
 
那么现在就对所有数据进行重采样,并打赏金额进行求和


捕获a25.JPG

 (点击查看大图)
 
现在可以看到,每个月得到的打赏金额的总和都可以看到了。从2016年7月到现在2018年10月,最多的月份是这个月,共1.4万,占了所有金额的60%多,所以才让大家造成一个错觉,元兄靠打赏赚了不少粉丝的打赏钱,其实只是最近才多起来的。
 
还可以绘制条形图。


捕获a26.JPG

 (点击查看大图)
 
不过因为月份金额差距过大,导致部分月份的条形显示很短。
 
不过对于赏金的分布也一目了然了吧。
 
原创文章
转载请注明出处:
http://30daydo.com/article/362 
  
个人公众号:

雪球的元卫南靠打赏收割了多少钱 ? python爬虫实例

python爬虫李魔佛 发表了文章 • 7 个评论 • 20954 次浏览 • 2018-10-23 18:37 • 来自相关话题

********* 2019-08-18 更新 ***********
 
今天重新爬了一下,元卫南今年的人气暴涨,在2019年开始到现在,已经获取了31851.6元的打赏金额,虽然金额也不是特别高,但是已经比他2019年前所有打赏金额之和还要高了。 具体分析过程见 http://30daydo.com/article/362
 
 ********* 2019-08-05 更新 ***********

文章是去年写的,没想到最近居然在雪球火了。 后续会更新下最新的数据,还有趴一趴释老毛的打赏金额。

 雪球的元卫南每天坚持发帖,把一个股民的日常描述的栩栩如生,让人感叹股民的无助与悲哀。 同时也看到上了严重杠杆后,对生活造成的压力,靠着借债来给股票续命。
 
元卫南雪球链接:https://xueqiu.com/u/2227798650
 
而且不断有人质疑元卫南写文章,靠打赏金来消费粉丝。 刚开始我也这么觉得,毕竟不少人几十块,一百块的打赏,十几万的粉丝,那每天的收入都很客观呀。 于是抱着好奇心,把元卫南的所有专栏的文章都爬下来,获取每个文章的赏金金额,然后就知道元兄到底靠赏金拿了多少钱。
 
撸起袖子干。 代码不多,在python3的环境下运行,隐去了header的个人信息,如果在电脑上运行,把你个人的header和cookie加上即可# -*-coding=utf-8-*-

# @Time : 2018/10/23 9:26
# @File : money_reward.py
import requests
from collections import OrderedDict
import time
import datetime
import pymongo
import config

session = requests.Session()
def get_proxy(retry=10):
proxyurl = 'http://{}:8081/dynamicIp/common/getDynamicIp.do'.format(config.PROXY)
count = 0
for i in range(retry):
try:
r = requests.get(proxyurl, timeout=10)
except Exception as e:
print(e)
count += 1
print('代理获取失败,重试' + str(count))
time.sleep(1)

else:
js = r.json()
proxyServer = 'http://{0}:{1}'.format(js.get('ip'), js.get('port'))
proxies_random = {
'http': proxyServer
}
return proxies_random


def get_content(url):
headers = {
# 此处添加个人的header信息
}
try:
proxy = get_proxy()
except Exception as e:
print(e)
proxy = get_proxy()

try:
r = session.get(url=url, headers=headers,proxies=proxy,timeout=10)
except Exception as e:
print(e)
proxy = get_proxy()
r = session.get(url=url, headers=headers,proxies=proxy,timeout=10)

return r


def parse_content(post_id):
url = 'https://xueqiu.com/statuses/reward/list_by_user.json?status_id={}&page=1&size=99999999'.format(post_id)
r = get_content(url)
print(r.text)
if r.status_code != 200:
print('status code != 200')
failed_doc.insert({'post_id':post_id,'status':0})
return None

try:

js_data = r.json()
except Exception as e:
print(e)
print('can not parse to json')
print(post_id)
failed_doc.insert({'post_id': post_id, 'status': 0})
return

ret =
been_reward_user = '元卫南'
for item in js_data.get('items'):
name = item.get('name')
amount = item.get('amount')
description = item.get('description')
user_id = item.get('user_id')
created_at = item.get('created_at')
if created_at:
created_at = datetime.datetime.fromtimestamp(int(created_at) / 1000).strftime('%Y-%m-%d %H:%M:%S')

d = OrderedDict()
d['name'] = name
d['user_id'] = user_id
d['amount'] = amount / 100
d['description'] = description
d['created_at'] = created_at
d['been_reward'] = been_reward_user
ret.append(d)

print(ret)
if ret:
doc.insert_many(ret)
failed_doc.insert({'post_id':post_id,'status':1})



def get_all_page_id(user_id):
doc = db['db_parker']['xueqiu_zhuanglan']

get_page_url = 'https://xueqiu.com/statuses/original/timeline.json?user_id={}&page=1'.format(user_id)
r = get_content(get_page_url)
max_page = int(r.json().get('maxPage'))

for i in range(1, max_page + 1):
url = 'https://xueqiu.com/statuses/original/timeline.json?user_id=2227798650&page={}'.format(i)
r = get_content(url)
js_data = r.json()
ret =

for item in js_data.get('list'):
d = OrderedDict()

d['article_id'] = item.get('id')
d['title'] = item.get('title')
d['description'] = item.get('description')
d['view_count'] = item.get('view_count')
d['target'] = 'https://xueqiu.com/' + item.get('target')
d['user_id']= item.get('user_id')
d['created_at'] = datetime.datetime.fromtimestamp(int(item.get('created_at')) / 1000).strftime(
'%Y-%m-%d %H:%M:%S')

ret.append(d)
print(d)
doc.insert_many(ret)

def loop_page_id():
doc = db['db_parker']['xueqiu_zhuanglan']
ret = doc.find({},{'article_id':1})
failed_doc = db['db_parker']['xueqiu_reward_status']
failed_ret = failed_doc.find({'status':1})
article_id_list =
for i in failed_ret:
article_id_list.append(i.get('article_id'))

for item in ret:
article_id = item.get('article_id')
print(article_id)
if article_id in article_id_list:
continue
else:
parse_content(article_id)

loop_page_id()
然后就是开始爬。
因为使用了代理,所有速度回有点慢,大概10分钟就把所有内容爬完了。




点击查看大图

数据是存储在mongodb数据库中,打开mongodb,可以查看每一条数据,还可以做统计。



点击查看大图

 从今天(2018-10-23)追溯到元兄第一篇专栏文章(2014-2-17),元兄总共发了1144篇文章。



点击查看大图

 然后再看另外一个打赏的列表



点击查看大图

 从最新的开始日期(2018-10-23),这位 金王山而 的用户似乎打赏的很多次,看了是元兄的忠实粉丝。
 
统计了下,元神共有4222次打赏。




点击查看大图
 
打赏总金额为:
24128.13



点击查看大图

 好吧,太出乎意料了!!! 还以为会有几百万的打赏金额呀,最后算出来才只有24128,这点钱,元兄只够补仓5手东阿阿胶呀。
 
 
然后按照打赏金额排序:



点击查看大图

 打赏最高金额的是唐史主任,金额为250元,200元的有十来个, 还看到之前梁大师打赏的200元,可以排在并列前10了。
 
其实大部分人都是拿小钱来打赏下,2元以下就有2621,占了50%了。
 
还是很支持元神每天坚持发帖,在当前的行情下或可以聊以慰藉,或娱乐大家,或引以为戒,让大家看到股市对散户生活造成的影响,避免重蹈覆辙。
 

原创文章
转载请注明出处:
http://30daydo.com/article/361 
 
 
个人公众号:





下篇:
python数据分析入门 分析雪球元卫南每个月打赏收入 查看全部
********* 2019-08-18 更新 ***********
 
今天重新爬了一下,元卫南今年的人气暴涨,在2019年开始到现在,已经获取了31851.6元的打赏金额,虽然金额也不是特别高,但是已经比他2019年前所有打赏金额之和还要高了。 具体分析过程见 http://30daydo.com/article/362
 
 ********* 2019-08-05 更新 ***********

文章是去年写的,没想到最近居然在雪球火了。 后续会更新下最新的数据,还有趴一趴释老毛的打赏金额。

 雪球的元卫南每天坚持发帖,把一个股民的日常描述的栩栩如生,让人感叹股民的无助与悲哀。 同时也看到上了严重杠杆后,对生活造成的压力,靠着借债来给股票续命。
 
元卫南雪球链接:https://xueqiu.com/u/2227798650
 
而且不断有人质疑元卫南写文章,靠打赏金来消费粉丝。 刚开始我也这么觉得,毕竟不少人几十块,一百块的打赏,十几万的粉丝,那每天的收入都很客观呀。 于是抱着好奇心,把元卫南的所有专栏的文章都爬下来,获取每个文章的赏金金额,然后就知道元兄到底靠赏金拿了多少钱。
 
撸起袖子干。 代码不多,在python3的环境下运行,隐去了header的个人信息,如果在电脑上运行,把你个人的header和cookie加上即可
# -*-coding=utf-8-*-

# @Time : 2018/10/23 9:26
# @File : money_reward.py
import requests
from collections import OrderedDict
import time
import datetime
import pymongo
import config

session = requests.Session()
def get_proxy(retry=10):
proxyurl = 'http://{}:8081/dynamicIp/common/getDynamicIp.do'.format(config.PROXY)
count = 0
for i in range(retry):
try:
r = requests.get(proxyurl, timeout=10)
except Exception as e:
print(e)
count += 1
print('代理获取失败,重试' + str(count))
time.sleep(1)

else:
js = r.json()
proxyServer = 'http://{0}:{1}'.format(js.get('ip'), js.get('port'))
proxies_random = {
'http': proxyServer
}
return proxies_random


def get_content(url):
headers = {
# 此处添加个人的header信息
}
try:
proxy = get_proxy()
except Exception as e:
print(e)
proxy = get_proxy()

try:
r = session.get(url=url, headers=headers,proxies=proxy,timeout=10)
except Exception as e:
print(e)
proxy = get_proxy()
r = session.get(url=url, headers=headers,proxies=proxy,timeout=10)

return r


def parse_content(post_id):
url = 'https://xueqiu.com/statuses/reward/list_by_user.json?status_id={}&page=1&size=99999999'.format(post_id)
r = get_content(url)
print(r.text)
if r.status_code != 200:
print('status code != 200')
failed_doc.insert({'post_id':post_id,'status':0})
return None

try:

js_data = r.json()
except Exception as e:
print(e)
print('can not parse to json')
print(post_id)
failed_doc.insert({'post_id': post_id, 'status': 0})
return

ret =
been_reward_user = '元卫南'
for item in js_data.get('items'):
name = item.get('name')
amount = item.get('amount')
description = item.get('description')
user_id = item.get('user_id')
created_at = item.get('created_at')
if created_at:
created_at = datetime.datetime.fromtimestamp(int(created_at) / 1000).strftime('%Y-%m-%d %H:%M:%S')

d = OrderedDict()
d['name'] = name
d['user_id'] = user_id
d['amount'] = amount / 100
d['description'] = description
d['created_at'] = created_at
d['been_reward'] = been_reward_user
ret.append(d)

print(ret)
if ret:
doc.insert_many(ret)
failed_doc.insert({'post_id':post_id,'status':1})



def get_all_page_id(user_id):
doc = db['db_parker']['xueqiu_zhuanglan']

get_page_url = 'https://xueqiu.com/statuses/original/timeline.json?user_id={}&page=1'.format(user_id)
r = get_content(get_page_url)
max_page = int(r.json().get('maxPage'))

for i in range(1, max_page + 1):
url = 'https://xueqiu.com/statuses/original/timeline.json?user_id=2227798650&page={}'.format(i)
r = get_content(url)
js_data = r.json()
ret =

for item in js_data.get('list'):
d = OrderedDict()

d['article_id'] = item.get('id')
d['title'] = item.get('title')
d['description'] = item.get('description')
d['view_count'] = item.get('view_count')
d['target'] = 'https://xueqiu.com/' + item.get('target')
d['user_id']= item.get('user_id')
d['created_at'] = datetime.datetime.fromtimestamp(int(item.get('created_at')) / 1000).strftime(
'%Y-%m-%d %H:%M:%S')

ret.append(d)
print(d)
doc.insert_many(ret)

def loop_page_id():
doc = db['db_parker']['xueqiu_zhuanglan']
ret = doc.find({},{'article_id':1})
failed_doc = db['db_parker']['xueqiu_reward_status']
failed_ret = failed_doc.find({'status':1})
article_id_list =
for i in failed_ret:
article_id_list.append(i.get('article_id'))

for item in ret:
article_id = item.get('article_id')
print(article_id)
if article_id in article_id_list:
continue
else:
parse_content(article_id)

loop_page_id()

然后就是开始爬。
因为使用了代理,所有速度回有点慢,大概10分钟就把所有内容爬完了。

捕获2_副本.jpg
点击查看大图

数据是存储在mongodb数据库中,打开mongodb,可以查看每一条数据,还可以做统计。
mongo1_副本.jpg
点击查看大图

 从今天(2018-10-23)追溯到元兄第一篇专栏文章(2014-2-17),元兄总共发了1144篇文章。
捕获3_副本.jpg
点击查看大图

 然后再看另外一个打赏的列表
捕获4_副本.jpg
点击查看大图

 从最新的开始日期(2018-10-23),这位 金王山而 的用户似乎打赏的很多次,看了是元兄的忠实粉丝。
 
统计了下,元神共有4222次打赏。

捕获6_副本.jpg
点击查看大图
 
打赏总金额为:
24128.13
捕获7_副本.jpg
点击查看大图

 好吧,太出乎意料了!!! 还以为会有几百万的打赏金额呀,最后算出来才只有24128,这点钱,元兄只够补仓5手东阿阿胶呀。
 
 
然后按照打赏金额排序:
捕获5_副本.jpg
点击查看大图

 打赏最高金额的是唐史主任,金额为250元,200元的有十来个, 还看到之前梁大师打赏的200元,可以排在并列前10了。
 
其实大部分人都是拿小钱来打赏下,2元以下就有2621,占了50%了。
 
还是很支持元神每天坚持发帖,在当前的行情下或可以聊以慰藉,或娱乐大家,或引以为戒,让大家看到股市对散户生活造成的影响,避免重蹈覆辙。
 

原创文章
转载请注明出处:
http://30daydo.com/article/361 
 
 
个人公众号:
qrcode_for_gh_e9d12a50c25d_258.jpg


下篇:
python数据分析入门 分析雪球元卫南每个月打赏收入