Alpha-Nebula:Short-term stock price prediction based on echo state networks

原文链接:Short-term stock price prediction based on echo state networks

展示课件链接:Short-Term Stock Price Prediction based on Echo State Network

这篇文章讲的是将Echo State Network(回声状态网络)应用于股票数据的短期预测中。我之前没有听说过ESN,而这篇文章在ESN之外的创新也不多,所以算是介绍这样一个工具吧。

Echo State Network

ESN是什么呢?这里直接应用一篇个人认为写的很好的教学文章,不过这里我也准备用简单的语言讲一讲个人的理解。

ESN拥有一个叫做reservoir的状态储存池,我们将其记为x(i)向量,对于这个x(i)向量进行某种迭代

(1)   \begin{equation*}  x(i+1) = f(W*x(i)) \end{equation*}

其中f是任意非线性函数。现在我们x(i)充当了一种Memory的角色。

接着令u(i)表示第i时刻的输入,y(i)表示第i时刻的目标输出,我们将这个输入输出加到刚才的 (1)里面,得到实际的迭代式

(2)   \begin{equation*}  x(t+1) &= f(W^{in}u(t+1) + W x(t) + W^{back} y(t)) \end{equation*}

是不是感觉这里面x(t)就像回声一样在里面荡来荡去,这里就对了。

最后输出为

(3)   \begin{equation*}  y'(t+1) = W^{out} concat(u(n+1),x(n+1),y(n)) \end{equation*}

在式子(3)里面,y'(t+1),concat(u(n+1),x(n+1),y(n))以及y(t+1)已知,则可以用线性回归训练啦。

可以看出该算法有如下特点:

  • 训练是最小二乘法,速度快
  • 不会陷入局部最优解

另外也有一些需要注意的地方:

  • W不能太大,否则可能越乘越大,可以通过W的特征值的最大值的大小来限制
  • 为了使效果更优,W最好是稀疏矩阵(比如95%的零)

使用ESN预测短期股价

先说一些论文中的细节

  • 论文中非线性函数f(x)的选择为

    (4)   \begin{equation*}  f(x)  = \frac{1}{1+e^{-\alpha x + v}} \end{equation*}

  • 通过赫斯特指数选择训练输入数据,文章里面选择了Hurst指数最接近1的序列进行训练,原因不明…… 也许是因为hurst接近1的时候,序列特征更持久?
    相关文献:Some comments on Hurst exponent and the long memory processes on capital markets
  • 通过各种技术指标可以有效的提高效果,但是可能存在过拟合,所以通过PCA来进行数据降维。

想法与疑问

  • 一般的论文都通过平均百分比误差来表示效果,感觉这东西还是不太容易量化实际的收益……
  • 这里的LinearRegression是最简单的版本,我们是否可以给他加入更多的优化,比如局部回归,或者对于不同的部分采用不同的回归,甚至可以把决策树套进来。

 

RNN学习笔记 之 回声状态网络

教程:http://jlearning.cn/2017/05/29/ESN-basic-tutorial/

为什么还可以设计出这么优美的算法!老套路,sin函数预测,使用Ridge回归测得无帮助预测一千个迭代次数后的信号,平方误差约为2.97056501322e-08。倘若将回归方法改为线性回归,则误差进一步降至3.72410472914e-28。不过如果把预测函数改为x*sin(x),则就没有那么好了,线性回归产生了一个完全随机的波动函数,而Ridge回归则产生了一个波长为(大约为输入数据中位数)长度的稳定波。不过,这是无信息预测,如果知道前一个迭代的实际结果,应该会好很多,这里就不尝试了~

mhy的量化笔记 之 基于LSTM的股市趋势预测

思路

经过一段时间对LSTM的学习,大概了解了LSTM的运作规律。因此尝试运用LSTM预测股市走势。

参考:文章A  文章B

这篇文章是对于该方法的一种初步尝试,然而问题显而易见。

  1. 该算法将指数数据未经任何处理就丢到了LSTM里面,这是“不可能”学习出任何知识的。由于神经网络类机器学习算法是基于线性组合以及非线性函数,因此能够学习出“较大”,“正”,“上升”这一类描述,但无法学习出“区间最大值”,“日线高点出现”,“指数线交叉”。所以我们需要做的应该是将这类信息人工处理后丢入LSTM!

尝试1:上证指数K线4值

直接输入上证K线的open,close,high,low,预测1/5/10日收盘价涨跌.

正确率最后能够到达65%左右。

奇怪的是用GRU和LSTM效果没有显著的差别,感觉远期的信息并没有被学习进去……

全部都学成跌了,当然没有差别咯……算了一下,MCC相关系数仅有0.02,等于随机预测.

由于之前使用的是涨跌幅的log的平方和作为loss函数,可能确实在精度上也会有问题。

是不是将label设为涨跌幅log平方的符号函数会更好一些呢?

最后,模型准确率平均在51%左右,且在训练过程中有时候会跳到49%,相关性也会在有些时候呈现负相关,具体来说就是没有训练处结果。

尝试2:加入更多数据

测试数据

随机选择股票

000416 000996 600096 600291 600695 000416 000996 600096 600291 600695 000951 300143  600155 600354 600785

收集2010-2017的日线数据进行分为训练集与测试集。

指标选择

由最初的四个数据拓展到更多的指标

  • open 开盘价
  • close 收盘价
  • high 最高价
  • low 最低价
  • volume 成交量
  • sh 上证指数
  • sz  深证成指
  • hs300 沪深300
  • cyb 创业板指数
  • ma_5 5日均线
  • ma_10 10日均线
  • ma_20 20日均线
  • ma_60 60日均线
  • macd_dif macd短线
  • macd_ema macd长线
  • macd_macd macd柱状线
  • rsi rsi指数
  • adx adx指数
  • cci cci指数

将指数分组进行归一化,例如将ochl和均线值统一进行归一化,指数独自归一化。

分类函数

之前是将误差平方和作为loss函数,后来发现这在二分类问题中非常的不优美。

对于典型的二分类问题

loss =- (X * log(X’) + (1-X)*log(1-X’))

作为误差函数会更加容易收敛。

分组训练

之前的分组训练是直接取相邻区间,仔细想想确实bug非常严重,本身分batch就是为了防止出现边界数据,导致将梯度影响错误的方向。这里我们改成使用随机batch_size个数据使得训练表现好了一些

优化指标

之前指标发现实际上大盘数据对于一只股票并没有太大的用处,因为我不知道这个股票的类型,因此考虑增加:

  • is_sh 是否为沪市
  • is_sz 是否为深市
  • is_cyz 是否为创业板

至此,已经可以将模型准确率提高至53%

修改分类函数

将之前的二分类改为三分类,其中表示随机波动的分类0产生的所有结果不计入loss函数。准确率提高至55%,不过这个55%的含义与之前不同,这里计算的只是非零分类的准确率。

 

Tushare数据自动缓存

tushare是一个财经数据获取库,内置若干财经数据的获取爬虫,将各种数据的爬取封装在了一起。但是tushare有一个很大的缺点,就是其抓取的数据无法缓存在本地。故考虑实现一组自己的api用以缓存tushare数据。

import tushare as ts
industry_info = ts.get_industry_classified()
profit_info = ts.get_profit_data(2017,1)

这是python中获取tushare数据的典型例子,我们考虑实现一个简单的装饰函数,将函数调用以及调用的参数进行记忆化!

ts.get_industry_classified = data_cacher(ts.get_industry_classified)
ts.get_profit_data = data_cacher(ts.get_profit_data)

industry_info = ts.get_industry_classified()
profit_info = ts.get_profit_data(2017,1)

这里面data_cacher函数包装后的ts.api增加了将返回值保存为以“函数名”、“参数”命名的文件中,供下次调用直接使用。

最后,如何实现data_cacher函数呢?直接上代码:

import attr
import pandas as pd

def data_cacher(func):
    def inner_function(*args,**kwargs):
        path = 'data/'+func.__name__
        for w in args:
            path += '&'+str(w)
        for w in kwargs:
            path += '&'+w+'='+str(kwargs[w])
        try:
            data = pd.DataFrame().from_csv(path)
            print("Use cache :",path)
        except FileNotFoundError:
            if 'fast_mode' in kwargs.keys() and kwargs['fast_mode'] == True:
                return pd.DataFrame()
            elif 'fast_mode' in kwargs.keys():
                del kwargs['fast_mode']
            print("Online => ",path)
            data = func(*args,**kwargs)
            #print(data,type(data),len(data))
            if len(data) == 0:
                print("Empty...")
                return data
            data.to_csv(path)
            data = pd.DataFrame().from_csv(path)
        return data
    return inner_function

 

 

RNN学习笔记 之 利用tensorflow-lstm实现sin预测

RNN用于处理不定长的序列数据,而简谐波预测就是一个很好的例子,显然,对于机器学习,sin(x)、cos(x)、a*sin(x) + b*cos(x)甚至x*sin(x)都没有任何难度上的差别。

那么我们就用RNN来预测吧!

(CNMB……由于一个偶然的错误,我发现这个问题直接线性规划类型的神经网络就可以很精确的计算出来!!!而且LSTM根本比不上!!!)

考虑

sin(a(k-1)+b)、sin(ak+b) 和sin(a(k+1)+b)的关系

sin(a(k-1)+b) = sin(ak+b-a) = sin(ak+b)cos(a) – cos(ak+b)sin(a)

sin(a(k+1)+b) = sin(ak+b+a) = sin(ak+b)cos(a) + cos(ak+b)sin(a)

sin(a(k+1)+b) = -sin(a(k-1)+b) + 2sin(ak+b)cos(a)

其中由于a我取的是整数,所以非常容易估计,于是实际上sin数列的每一项可以由前两项线性表示出来……

即使a不是整数,也可通过三角带换,得到近似于线性表达的公式

但是现在就出现这样一个问题。

既然是如此简单的问题,LSTM的表现为啥这么渣呢???

原因可能如下:

  1. LSTM变量太多了,训练会出现梯度消失的问题
  2. 使用LSTM,倒数第二项作用于倒数第一项,中间有若干非线性层,导致本来非常简单的线性组合变得非常难以模拟了!
  3. 写错了……

脑残的把最后一层加了一个sigmoid函数,然而并不知道sigmoid的返回值是一个正数,并不包含sin(x)的值域区间

import tensorflow as tf
import numpy as np
import talib
import random
from matplotlib import pyplot

max_length = 20
total_branches = 10010
batch_size = 31
hidden_size = 16
start_position = 10
test_batch_index = 0
num_input_classes = 1
difficulity = 10
total_layers = 1

test_x = None
test_y = None
test_seqlen = None

def gen_sine_wave(length):
    L = random.randint(1,difficulity)
    R = random.randint(1,difficulity)
    if L>R:
        L,R = R,L
    x = np.linspace(L,R,length+1)
    y = np.sin(x)
    return y[:-1],y[-1]

def generate_batches():
    global test_x,test_y,test_seqlen
    test_x = []
    test_y = []
    test_seqlen = []
    test_batch_len = 0
    for i in range(0,total_branches):
        length = random.randint(start_position,max_length)
        x,y = gen_sine_wave(length)
        x = np.append(np.array([t for t in x]),np.array([0 for i in range(max_length-length)]))
        x = np.reshape(x,[max_length,num_input_classes])
        test_seqlen.append(length)
        test_x.append(x)
        test_y.append(y)

def next_batch(total_branches = total_branches):
    global test_batch_index,test_x,test_y,test_seqlen
    if test_batch_index == total_branches:
        test_batch_index = 0
    xs = test_x[test_batch_index:min(test_batch_index+batch_size,total_branches)]
    ys = test_y[test_batch_index:min(test_batch_index+batch_size,total_branches)]
    seqlens = test_seqlen[test_batch_index:min(test_batch_index+batch_size,total_branches)]
    test_batch_index = min(test_batch_index + batch_size,total_branches)
    return xs,ys,seqlens


if __name__ == '__main__':
    generate_batches()
    #sess = tf.InteractiveSession()
    input_data = tf.placeholder(tf.float32,[None,max_length,num_input_classes])
    input_seqlen = tf.placeholder(tf.int32,[None])
    input_labels = tf.placeholder(tf.float32,[None])
    keep_prob = tf.placeholder(tf.float32)
    current_batch_size = tf.shape(input_data)[0]

    with tf.name_scope('lstm_layer'):
        method = 'lstm'
        data = input_data
        print(data.shape)#10*20*1
        if method == 'lstm':
            def create_lstm():
                lstm_cell = tf.contrib.rnn.BasicLSTMCell(hidden_size,state_is_tuple = True)
                #lstm_cell = tf.nn.rnn_cell.DropoutWrapper(lstm_cell, output_keep_prob=keep_prob,state_keep_prob=keep_prob)
                return lstm_cell
            lstm_cell = create_lstm()
            #lstm_cell = tf.nn.rnn_cell.MultiRNNCell([create_lstm() for i in range(total_layers)], state_is_tuple=True)
            #state = lstm_cell.zero_state(current_batch_size,tf.float32)
            data = tf.unstack(data,axis=1)
            outputs,state = tf.nn.static_rnn(lstm_cell,data,dtype=tf.float32,sequence_length=input_seqlen)
            outputs = tf.stack(outputs,axis=1)
            #outputs =  tf.transpose(outputs,[1,0,2])
        else:
            gru_cell = tf.contrib.rnn.GRUCell(hidden_size)
            outputs,state = tf.nn.dynamic_rnn(gru_cell,data,dtype=tf.float32,sequence_length=input_seqlen)

        print(outputs.shape)
        output = tf.gather_nd(outputs, tf.stack([tf.range(current_batch_size), input_seqlen-1], axis=1))

    with tf.name_scope('final_layer'):
        final_w = tf.Variable(tf.truncated_normal([hidden_size,1],.1))
        tf.summary.histogram('weight',final_w)
        final_b = tf.Variable(tf.constant(.1,shape=[1]))
        tf.summary.histogram('bias',final_b)

    with tf.name_scope('output_layer'):
        result = tf.tanh(tf.matmul(output,final_w) + final_b)
        print(result.shape)
        result = tf.reshape(result,[-1])
        loss = tf.reduce_mean(tf.losses.mean_squared_error(labels = input_labels,predictions=result))
        tf.summary.scalar('loss',loss)

    optimizer = tf.train.AdamOptimizer().minimize(loss)

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        merged = tf.summary.merge_all()
        writer = tf.summary.FileWriter("logs/",sess.graph)

        steps = 0
        while True:
            batch_x , batch_y, batch_seqlen = next_batch()
            sess.run(optimizer, feed_dict={input_data:batch_x,
                input_labels:batch_y,
                input_seqlen:batch_seqlen,
                keep_prob:.95})
            if steps%50 == 0:
                print(steps,sess.run(loss,feed_dict={input_data:batch_x,input_labels:batch_y,input_seqlen:batch_seqlen,keep_prob:1}))
                print("PREDICT",sess.run(result,feed_dict={input_data:batch_x,input_labels:batch_y,input_seqlen:batch_seqlen,keep_prob:1}))
                print("LABEL",sess.run(input_labels,feed_dict={input_data:batch_x,input_labels:batch_y,input_seqlen:batch_seqlen,keep_prob:1}))
                merged_result = sess.run(merged, feed_dict={input_data:batch_x,
                    input_labels: batch_y,
                    input_seqlen: batch_seqlen,
                    keep_prob:1})
                writer.add_summary(merged_result,steps)
            steps += 1
            if steps%1000 == 0:
                batch_x , batch_y, batch_seqlen = next_batch()
                current_result = sess.run(result,feed_dict={input_data:batch_x,input_seqlen:batch_seqlen,keep_prob:1})
                X = batch_x[0][:batch_seqlen[0]]
                Y = current_result[0]
                Z = batch_y[0]
                plt = pyplot.figure()
                pyplot.plot(np.linspace(1,len(X),len(X)),X)
                pyplot.plot(len(X)+1,Y,'r+')
                pyplot.plot(len(X)+1,Z,'r^')
                pyplot.show()

 

“电商力量”暑期实践总结

电子商务,是一种极具互联网时代特色的新型商务模式。

在电商小镇的展示中心中,陈列着琳琅满目的商品。而这些商品,正是通过电商的渠道,源源不断的被发往五湖四海。

 

也正是这种突破地域限制的商业模式,使得生产商出于降低成本,扩大知名度等原因聚集在了一个地方。而这就是我们的调查目标“淘宝村”

7月8-14日,我们清华大学计算机系的视窗计划同学们组成了“电商力量”暑期实践支队,奔赴曹县、义乌调查电商发展情况。

曹县,位于山东省菏泽市,是“演出服”与“木制品”聚集地,这个仅有一百多万人的县城,仍然保持着农村特有的乡土气息,让人很难与互联网联系在一起。

然而,正是这个曾经贫穷的县城,电子商务深深铭刻在了人们的心中。走在街上,四处可见“淘宝饭店”,“淘宝旅馆”等招牌。宣传的大字标语也是随处可见。这种近似洗脑的宣传手段可以看出淘宝在人民心中的地位。

曹县的电商普及,源于本身有大企业领头,政府也有对应的补助、推广。

这里的人们,在淘宝普及时,由于周围亲朋好友投入电商,而自己也开始尝试。等到尝到了甜头,便坚持做了下来。

本身教育程度不高,却又遇到了突如其来的财富。人们注定会将自己的富裕归功于“电子商务”本身,但并不明白其内在逻辑。

缺乏商业前瞻意识,没有刻意的品牌意识,在竞争日益激烈的电商领域,倘若盲目信赖“电商”本身而非“正确的商业策略”,可能会在日后的转型中失败。

电子商务,让部分电商老板得到了巨大的财富,但是也有更多的“打工者”,在这里拥有和其他地方相同的低工资。这也是一点值得探讨的问题。电商,真的让人们富起来了么?

作为中国小商品集散地的义乌,其发展水平已经非常高,而我们去的青岩刘村则完全不同。

整齐的规划,现代的建筑风格,使得这座城中村显得更加的富裕。短短一个街区,竟然有三家“电子商务培训学校”,这里的人们相比于曹县,拥有更加敏锐的商业头脑。他们相信个人直觉,而非盲目从众。很多商家正在从“电商”向“微商”转型。而他们,也都发展出了自己独特的品牌。这样的商业模式,远比“曹县”要健康许多。

青岩刘村的原住民,拥有可以持续创造价值的天价地产。毋庸置疑早已脱离了贫困。但是其中有多少人继续进入了电商环节打拼,我们还不太清楚,不过可以清楚的是,青岩刘村的电商,外来人员撑起了一大片天。

我们走访的街道,与其说是电商一条街,不如说是“体验店”一条街,由于青岩刘作为电商第一村,吸引了一大批人前来参观。平均能达到每天好几批。故这条街兼具一种“对外宣传”的作用。毋庸置疑,其中肯定存在着一定程度的美化。

两个地方,政府都扮演了举足轻重的作用。虽然电子商务本身的特性意味着政府无法从中直接获得利益。不过政府在发展中确实起了非常重要的作用。不论是孵化中心,以及信用贷款等,都对电商发展起了重要的作用。

之前总有一个问题困扰着我,为什么有些地方可以发展出电子商务,而有些地方则不行?在行程中,我获得了满意的答案——

1. 政府的政策支持、孵化园区的建设,以及电商专用信用贷款

2. 内部存在一些机制来平衡竞争:比如曹县演出服不同商家做不同款式,互相代卖;义乌则是拥有非常分散的商品类别。

3. 发展前期存在龙头企业

最后,感谢一直支持着我们实践的政府工作人员以及电商从业人员,然我们对电子商务有了新的了解!

mhy的量化笔记 之 老鼠仓识别

最近看到一个股市中非常有趣的趋势——老鼠仓

大概的原理可自行百度,而这只股票每隔10天左右会有一个约9%的下影线,换句话说,如果提前在当日开盘价-9%位置埋单,并且成交,就能在隔日获得几乎一个涨停的收益!

于是现在希望写一个脚本找出所有可能形成老鼠仓的股票——

满足老鼠仓的K线图满足如下要求:

  • 单日涨跌幅小于2%
  • 单日最低价大于-8%
  • 从跌2%到接近最低价所用时间小于5分钟
  • 整体平均值跌幅小于3%

在代码编写中,发现一个问题,即可能在分时图上股价并没有太大的变化,但在日K线中有一个很长的下影线,这是由于一单非理性限价单成交导致的。这也对于K线实际的意义产生了质疑。任意一个挂单都可以使K线产生巨大的形态变化,这应该能够成为操作市场的一个方式(如果我没有理解错的话)

代码

import tushare as ts
import time
import numpy as np
import logging
'''
通过识别“老鼠仓”实现的套利策略
'''

def check_rat(stock,date,end_day):
    logger = logging.getLogger(__name__)
    logger.info("Check Pit <%s,%s,%s>..."%(stock,date,end_day))
    if end_day:
        summary = get_hist_data_sp(stock,date)
        #summary = ts.get_hist_data(stock,date,date)
        if len(summary['low']) != 1:
            logger.warning("Error occur at <%s>"%stock)
            return False
        if (float(summary['low'][0])/float(summary['open'][0]) > 0.92):
            return False
        logger.debug("Big Hole...checked")
        if (abs(1.0-float(summary['open'][0])/float(summary['close'][0])) > .2):
            return False
        if (float(summary['high'][0])/float(summary['open']) > 1.2):
            return False
        logger.debug("Slightly fluctuating...checked")
        rt = get_tick_data(stock,date = date)
        rt = rt[['time','price','change']]
        low_value = np.min(rt['price'])
        if (low_value/float(summary['open'][0]) > 0.92):
            return False
        #rt.to_csv('save.csv',sep='\t')

        lower_bound = float(low_value) * 1.01
        upper_bound = float(summary['open'][0]) * 0.985
        pos_x = rt['time'].size-1
        pos_y = -1
        for i in range(rt['time'].size-1,-1,-1):
            if (rt['price'][i] > upper_bound):
                pos_x = i
            if (rt['price'][i] < lower_bound):
                pos_y = i
                break
        time_x = time.strptime('2000 '+rt['time'][pos_x],'%Y %H:%M:%S')
        time_y = time.strptime('2000 '+rt['time'][pos_y],'%Y %H:%M:%S')
        time_x = time.mktime(time_x)
        time_y = time.mktime(time_y)
        delta = time_y-time_x
        if (delta > 5 * 60):
            return False
        logger.debug("Fast down...checked")
        return True


def build_list():
    logger = logging.getLogger(__name__)
    info = ts.get_stock_basics()
    stocks = info.index
    for stock in stocks:
        realtime = ts.get_realtime_quotes(stock)
        logger.info("Begin Stock <%s>"%stock)
        check_result = True
        if (float(realtime['low']) < float(realtime['open'])*0.92):
            check_result = True
        if (check_result):
            recent =ts.get_k_data(stock)
            check_range = 80
            if (recent.size < 100):
                continue
            recentId = recent.index[-check_range:]
            for w in recentId:
                count = 0
                check_h_result = check_rat(stock,end_day = True, date = recent['date'][w])
                if (check_h_result):
                    logger.warning("Pit found <%s,%s>"%(stock,recent['date'][w]))
                    count += 1
            if (count > 2):
                logger.error("Pit Stock Found <%s,%s/%s>"%(stock,count,check_range))

效果:高频率的老鼠仓只存在于002072一支股票,也让我非常失望。

对于该算法的拓展,我又尝试获得所有影线较长,但是开盘收盘价相差较小的股票,最后发现识别出的股票本身都是在强烈的震荡情况,也就是说无法判断一个大幅下跌属于影线还是正常的大跌,也就没有太强的实用价值。

mhy的量化笔记 之 tushare数据缓存

Tushare是python下一个金融数据的开放接口,个人感觉里面信息非常多。

链接:http://tushare.org/index.html#

但是由于其本身没有支持下载数据,因此每一次调用都是在线获取数据,这就导致了速度不高,以及请求频率不能太高,因此希望能够写一个第一次在线获取数据,并保存在本地的脚本。第二次获取相同的数据,就直接在本地数据库中查找。

当然,由于个人使用,只实现了ticks缓存以及日数据缓存。

实现过程中的主要难点如下:

  • python的logging模块,这是一个专门输出日志的模块,感觉老是会出现一些奇奇怪怪的bug,现在还没弄清楚……
  • pymongo的若干规则
    • 数据插入
    • 区间询问
  • Pandas的DataFrame类型构造方式:这里使用dict套list构造
  • python的datatime模块:datetime.timedelta使用
from pymongo import MongoClient
import json
import tushare as ts
import pandas as pd
import logging

client = MongoClient('127.0.0.1', port=27017)
db = client.tushare_database

def clear_database():
    db.drop_collection('tick_data')

def get_tick_data(stock,date):
    logger = logging.getLogger(__name__)
    collection = db.tick_data
    ww = collection.find_one({'stock':stock,'date':date})
    if (ww == None):
        logger.debug("ReFetch stock <%s,%s>",stock,date)
        df = ts.get_tick_data(stock,date=date)
        store_data = json.loads(df.to_json(orient='records'))
        for i in range(0,len(store_data)):
            store_data[i]['stock'] = stock
            store_data[i]['date'] = date
            collection.insert(store_data[i])
    ww = collection.find_one({'stock':stock,'date':date})
    result = dict()
    for w in ww.keys():
        if (w=='_id'):
            continue
        result[w] = []
    for item in collection.find({'stock':stock,'date':date}):
        for w in item.keys():
            if (w=='_id'):
                continue
            result[w].append(item[w])
    result = pd.DataFrame(result)
    return result

if __name__ == '__main__':
    clear_database()
    stock = '600848'
    date = '2014-12-22'
    result = get_tick_data(stock,date)
import pymongo
import json
import tushare as ts
import pandas as pd
import logging
import datetime
import time
client = MongoClient('127.0.0.1', port=27017)
db = client.tushare_database


def clear_database():
    db.drop_collection('hist_data')

def get_hist_data_day(stock,start,end):
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    logger.debug("CALL get_hist_data_day <%s,%s,%s>",stock,start,end)

    collection = db.hist_data
    result = []
    mx_time = None
    mn_time = None
    for bar in collection.find({'stock':stock,'ktype':'D'}).sort("date",pymongo.ASCENDING).limit(1):
        mn_time = bar['date']
    for bar in collection.find({'stock':stock,'ktype':'D'}).sort("date",pymongo.DESCENDING).limit(1):
        mx_time = bar['date']

    if mx_time != None and mx_time < start:
        _start = start
        start = mx_time
    tt = end
    delta_time = datetime.timedelta(days=20)
    start_time = datetime.datetime.strptime(start,'%Y-%m-%d')
    end_time = datetime.datetime.strptime(end,'%Y-%m-%d')

    #若数据库非空,则从数据库生成表头
    www = collection.find_one({'stock':stock,'ktype':'D'})
    if www != None:
        result = dict()
        for w in www.keys():
            if (w=='_id'):
                continue
            result[w] = []
        header = pd.DataFrame(result)
        df = header
        current_time = end_time
    else:
        df = ts.get_hist_data(stock,end,end)
        current_time = end_time-datetime.timedelta(days=1)

    #遍历时间区间,并且将数据库中缺失部分补充完整
    while current_time >= start_time:
        prev_time = current_time - datetime.timedelta(days=19)
        if mn_time == None or (not (prev_time.strftime('%Y-%m-%d') >= mn_time
            and current_time.strftime('%Y-%m-%d') <= mx_time)):
            dff = ts.get_hist_data(stock,
                    prev_time.strftime('%Y-%m-%d'),
                    current_time.strftime('%Y-%m-%d'))
            df = df.append(dff)
        current_time = current_time - datetime.timedelta(days=20)

    store_data = json.loads(df.to_json(orient='records'))
    for i in range(0,len(store_data)):
        www = collection.find_one({'stock':stock,'date':df.index[i],'ktype':'D'})
        if www != None:
            continue
        store_data[i]['stock'] = stock
        store_data[i]['date'] = df.index[i]
        store_data[i]['ktype'] = 'D'
        collection.insert(store_data[i])

    www = collection.find_one()
    result = dict()
    for w in www.keys():
        if (w=='_id'):
            continue
        result[w] = []
    for item in collection.find({'stock':stock,'ktype':'D','date':{'lte':end,'gte':start}}):
        for w in item.keys():
            if (w=='_id'):
                continue
            result[w].append(item[w])
    result = pd.DataFrame(result)
    return result



def get_hist_data_sp(stock,date,ktype='D'):
    logger = logging.getLogger(__name__)
    logger.debug("CALL get_hist_data_sp <%s,%s,%s>",stock,date,ktype)
    collection = db.hist_data
    ww = collection.find_one({'stock':stock,'date':date,'ktype':ktype})
    if (ww == None):
        logger.debug("ReFetch... <%s,%s>",stock,date)
        df = ts.get_hist_data(stock,start = date,ktype=ktype)
        store_data = json.loads(df.to_json(orient='records'))
        for i in range(0,len(store_data)):
            www = collection.find_one({'stock':stock,'date':df.index[i],'ktype':ktype})
            if (www!=None):
                continue
            store_data[i]['stock'] = stock
            store_data[i]['date'] = df.index[i]
            store_data[i]['ktype'] = ktype
            collection.insert(store_data[i])
    else:
        logger.debug("Use cache..")
    ww = collection.find_one({'stock':stock,'date':date,'ktype':ktype})
    if ww == None:
        ww = collection.find_one()
    result = dict()
    for w in ww.keys():
        if (w=='_id'):
            continue
        result[w] = []
    for item in collection.find({'stock':stock,'date':date,'ktype':ktype}):
        for w in item.keys():
            if (w=='_id'):
                continue
            result[w].append(item[w])
    result = pd.DataFrame(result)
    return result

if __name__ == '__main__':
    #clear_database()
    stock = '002082'
    date = '2016-10-30'
    result = get_hist_data_day(stock,'2016-11-01','2017-01-01')

 

“电商力量”暑期实践日记

Day1

日程

上午从北京出发前往菏泽曹县,下午到达居住宾馆基本就是晚饭时间了。晚饭时间同张局长进行了一些简单的交流,了解了曹县的电商发展以及政府在其中扮演的角色。

感想

也许是清华大学的自带光环吧,政府对我们的接待规格远高于预期,本身路上奔波已经做好了最坏的打算,但是一到宾馆眼前一亮~

与张局长的交流初步了解了当前情况,并不是来之前所猜测的已达到“市场饱和”,而是仍然有较大缺口,并且保持着高速的发展态势。

由于电商本身税收制度不够完善,政府本身并不是电商发展的直接受益者。为什么电商没有成熟的税收政策?也许是因为政府现在对其的扶持态度。那么换句话来说,当电商发展成熟,政府势必通过税收等政策,到那个时候,淘宝村将会何去何从,这确实是一个值得探讨的问题。

Day2

日程

上午在张科长的带领下,前往孙庄,参观了庆生表演服饰有限公司,对于电商产业的服饰销售模式有了基本的了解。之后我们在街道上进行分组采访,最后和农村信用社的孙书记进行了交流。

下午参观了大集电商工业园区,包括电商发展展览馆、鼎鼎服饰工厂、朝阳服饰厂以及上游的布场。

感想

街道两旁交错分布着服装店、快递点,还有其他淘宝相关的店铺,而店铺背后,就是绿油油的农田。十年的发展,将一个完全依赖于农业的小村庄,改变成如今的模样,确实非常可怕。

分组采访的对象有些非常nice,也有些非常不nice,还有的是听说我们是清华的学生后非常nice……不过,这些就不在意了。而分组采访最大的收获就是发现了淘宝在村民心中的地位之高。

四处可见“淘宝致富”的标语,便利店,旅馆以“淘宝”命名。可以想象,淘宝,已经深深的铭刻在每一个村民的心中。电子商务、互联网科技,对于社会的影响在此刻变得格外清晰。也许淘宝在村民的心中正如改革开放在中国人心中的地位吧。

接着是农村信用社的调研。总结下来,村庄的电商普及和农村信用社的“低门槛”借贷分不开。

下午的交流,一大收获是了解了为什么曹县能够发展成为淘宝村聚居地,而其他地方不行。是因为本村落自发形成了互相合作的氛围。独立招揽客户,但是共享产品。这样,每一个产品一般来说只有一家做,这也就解决了之前我们疑惑的关于“产品同质化”的问题。

风来了,曹县人民成功的搭上了电商化这股风,从此致富。这是今天所感。

Day3

行程

今天一天分别看了不同的木制品加工厂,囊括了木质装饰品、家具、对外的木材加工,淘宝日用品销售网点,以及一位残疾人的电商之路交流。

感想

木制品工业和之前的演出服不同,由于较强的产品同质化,所以木制品加工产业存在较强的竞争,虽然不能称之为恶性竞争,但是仍然存在着压价销售的问题。由此导致的另一个问题,就是木制品工业的销售业绩峰值在2015年左右,从15年往后,销售业绩存在一定的下滑。各种公司的负责人大多都将其归功于竞争和经济下行的影响。但是并没有明确的转型意愿。

当然,这里的木制品产业都与由于廉价的劳动力有关,据说工人们的工资实际上也与其他县镇相差无几,所以电商化是否有利于整体的脱贫致富还有待考证。当看到弥漫着浓浓油漆味的车间中用五种语言写的“Made in China”的时候,自豪和无奈并存……

另外,今天也发现了企业家和政府直接说话的矛盾之处,感觉双方各自都站在不同的立场,因此可能会对我们产生一些误导,所以估计明天前往孵化中心可以更加详细的调查一下政府在电商发展中的作用。

最后,感觉自己的照相技术比来的时候好多啦~

Day4

行程

上午看了看孵化中心,不过并没有什么好看的,下午晚上都在火车上度过

感想

正好腾讯把未备案域名给封掉了,我也就不想再补感想了,由于在车上,也没有什么照片。

Day5

行程

上午在火车上度过

下午前往青岩刘村调研

感想

凌晨两点被吵醒

早上五点被吵醒

早上七点被吵醒

……

火车上熊孩子战斗力max

下午青岩刘村调研,突突突的把预计两天的东西全都干掉了,于是明天就可以随便去玩了。

下午的调研,搞清楚了微商与电商的区别,而且撕了很久关于分级销售的微商是否属于传销。不过后来发现法律规定“代理层数超过三级算作传销”。

另外还碰巧跑进了一个疑似空壳公司,里面和外面丝毫不沾边,里面的工作人员不仅在学跳“鬼步”,还是疑问三不知

问:你们主营业务是什么呀?

答:问之前你们要好好观察,你们猜我们是什么呀

……

问:你们预计的盈利方式是什么?

答:这东西比较复杂,没有40页ppt是给你们讲不懂的!

问:你们的ppt呢?

答:还没做

……

回归正题,如果说曾经选择义乌的想法是能否从先进地方吸取经验用以辅助欠发达地区。但是现在看来,义乌与菏泽确实存在着非常大的区别。义乌有着非常多样化的销售领域,同时义乌的电商经营者都是城市居民(外来或本地),拥有极强的商业头脑,反之菏泽则是以农名居多,人云亦云的情况较为普遍。在菏泽,人民争先恐后插足淘宝天猫等电商领域,即使存在非常显著地市场泡沫以及利润下滑趋势。而在义乌,以及有非常多的经营者从电商转为微商,可以看出深刻的社会洞察力以及经营头脑。当然,也和义乌市遍地的商业培训机构有关。

在义乌的参观中,我们实际的体会到了政府带领我们参观的确实存在一些偏向性,不能代表所有人的水平。比较“好的”无法代表整体,“不好的”又没有参观的意义。

Day6

行程

上午爬鸡鸣山,前往义乌市国际商贸中心参观。

下午玩密室逃脱,以及桌游。

感想

由于前一天拉得太快,于是今天没事干,就只有去浪了。也当是辛苦一周之后的放松

首先是爬山,由于天气太热,所以也走的比较急。本来山上很多可以慢慢玩的地方都跳过去了。

然后沿着山底的湖又走了走

于是一个小时解决了原定半天的事情。本来准备直接回宾馆,但是考虑到要走很长的录,索性一起坐公交到国际商贸城。顺便解决午饭。

国际商贸城可以看做一个面向批发商的商城。里面有“玩具”,“珠宝”,“装饰”等区域,里面入驻了非常多的批发商。特别是珠宝区,满墙珠宝琳琅满目。不过其成本价格多在十元附近。也看到标价2200的首饰,询问批发价,答曰“全部一折”。另外一点比较好玩的是,看到一个小杯子,买几个做装饰。店主说一个七毛,但拒绝单卖,加价都不行……

下午去玩密室,感觉一般般吧,55分钟通关。之后玩“达芬奇密码”桌游,比较靠智商……

就是这样,没啥高水平的感想

 

RNN学习笔记2-Tensorflow代码阅读

Tensorflow中文文档中有非常详细的RNN实现教程,链接:

tensorflow中文文档:http://www.tensorfly.cn/tfdoc/tutorials/overview.html

但是其中对于模型本身的原理没有涉及,故理解RNN、LSTM需要另找资料:

一篇LSTM英文教程:http://colah.github.io/posts/2015-08-Understanding-LSTMs/

从文章中看出,对LSTM的理解其实就是对这张图的理解。

尝试阅读如下代码:

RNN实现文本感情判断:https://github.com/roopalgarg/lstm-tensorflow