《量化投资:以MATLAB为工具》

MATLAB技术论坛

 找回密码
 注册账号
查看: 836|回复: 32
收起左侧

[其它] 【原创】量化学习笔记(新手上路)

[复制链接]

签到天数: 2 天

[LV.1]初来乍到

发表于 2017-5-14 10:34:40 | 显示全部楼层 |阅读模式
主要是记录思路,不一定有源码

评分

参与人数 1贝壳 +10 收起 理由
dynamic + 10 感谢您分享自己珍贵的资料

查看全部评分

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-10-7 22:21:03 | 显示全部楼层
MNIST深入学习——使用卷积神经网络

# =============================================================================
# 自动下载和导入MNIST数据集。它会自动创建一个'MNIST_data'的目录来存储数据。
# =============================================================================
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# =============================================================================
# 运行TensorFlow的InteractiveSession
# =============================================================================
import tensorflow as tf
sess = tf.InteractiveSession()

# =============================================================================
# 权重初始化
# =============================================================================
'''
为了创建这个模型,我们需要创建大量的权重和偏置项。
这个模型中的权重在初始化时应该加入少量的噪声来打破对称性以及避免0梯度。
由于我们使用的是ReLU神经元,因此比较好的做法是用一个较小的正数来初始化偏置项,
以避免神经元节点输出恒为0的问题(dead neurons)。
为了不在建立模型的时候反复做初始化操作,我们定义两个函数用于初始化。
'''

def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

# =============================================================================
# 卷积和池化
# =============================================================================
'''
TensorFlow在卷积和池化上有很强的灵活性。
我们怎么处理边界?步长应该设多大?
在这个实例里,我们会一直使用vanilla版本。
我们的卷积使用1步长(stride size),0边距(padding size)的模板,
保证输出和输入是同一个大小。
我们的池化用简单传统的2x2大小的模板做max pooling。
为了代码更简洁,我们把这部分抽象成一个函数。
'''

def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')
  
# =============================================================================
# 构建Softmax 回归模型
# =============================================================================
#为输入图像和目标输出类别创建节点,开始构建计算图。
#占位符,None表示其值大小不定
x = tf.placeholder("float", shape=[None, 784])
y_ = tf.placeholder("float", shape=[None, 10])

#变量
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
sess.run(tf.global_variables_initializer())

#类别预测与损失函数
y = tf.nn.softmax(tf.matmul(x,W) + b)
  
# =============================================================================
# 第一层卷积
# =============================================================================
'''
现在我们可以开始实现第一层了。
它由一个卷积接一个max pooling完成。
卷积在每个5x5的patch中算出32个特征。
卷积的权重张量形状是[5, 5, 1, 32],
前两个维度是patch的大小,接着是输入的通道数目,最后是输出的通道数目。
而对于每一个输出通道都有一个对应的偏置量。
'''
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

'''
为了用这一层,我们把x变成一个4d向量,
其第2、第3维对应图片的宽、高,
最后一维代表图片的颜色通道数(因为是灰度图所以这里的通道数为1,如果是rgb彩色图,则为3)。
'''
x_image = tf.reshape(x, [-1,28,28,1])

'''
我们把x_image和权值向量进行卷积,加上偏置项,然后应用ReLU激活函数,最后进行max pooling。
'''
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

# =============================================================================
# 第二层卷积
# =============================================================================
'''
为了构建一个更深的网络,我们会把几个类似的层堆叠起来。
第二层中,每个5x5的patch会得到64个特征。
'''
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

# =============================================================================
# 密集连接层
# =============================================================================
'''
现在,图片尺寸减小到7x7,我们加入一个有1024个神经元的全连接层,用于处理整个图片。
我们把池化层输出的张量reshape成一些向量,乘上权重矩阵,加上偏置,然后对其使用ReLU。
'''
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

'''
为了减少过拟合,我们在输出层之前加入dropout。
我们用一个placeholder来代表一个神经元的输出在dropout中保持不变的概率。
这样我们可以在训练过程中启用dropout,在测试过程中关闭dropout。
TensorFlow的tf.nn.dropout操作除了可以屏蔽神经元的输出外,还会自动处理神经元输出值的scale。
所以用dropout的时候可以不用考虑scale。
'''
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# =============================================================================
# 输出层
# =============================================================================
'''
最后,我们添加一个softmax层,就像前面的单层softmax regression一样。
'''
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

# =============================================================================
# 训练和评估模型
# =============================================================================
'''
这个模型的效果如何呢?

为了进行训练和评估,我们使用与之前简单的单层SoftMax神经网络模型几乎相同的一套代码,
只是我们会用更加复杂的ADAM优化器来做梯度最速下降,
在feed_dict中加入额外的参数keep_prob来控制dropout比例。
然后每100次迭代输出一次日志。
'''
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.global_variables_initializer())
for i in range(1000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={
        x:batch[0], y_: batch[1], keep_prob: 1.0})
    print("step %d, training accuracy %g"%(i, train_accuracy))
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

print("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
#以上代码,在最终测试集上的准确率大概是99.2%。
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-6-14 19:39:39 | 显示全部楼层
读取央行公开市场操作的程序片段。暂缺注释
Date为8位数字日期,如果返回空值,应该意味着当天无操作吧
没写得太细致,可能有bug,有的话自行更改吧!

示例日期
20170614
20170510
20170509
20160613
上述日期亲证可用

function [Details,url_2] = get_Interest_PBOC_Web(Date)
%% 1
if nargin == 0
    Date = today;
else
    Date = datenum(num2str(Date),'yyyymmdd');
end

%% 2
ii = 0;
url_2 = [];

while isempty(url_2)
    ii = ii+1;
   
    url = ['http://www.pbc.gov.cn/zhengcehuobisi/125207/125213/125431/125475/17081/index',num2str(ii),'.html'];
    HtmlText = get_HtmlText(url);
   
    %%
    TempText = get_TempText(HtmlText);
    url_2 = get_url_2(TempText,Date);
    if url_2 == -1
        Details = [];
        return
    end
end
Details = get_Details_PBOC(url_2);
end

function Details = get_Details_PBOC(url)

HtmlText = [];
count = 0;

ie = actxserver('internetexplorer.application');
while length(HtmlText) < 20000 && count <= 10
    ie.Navigate(url);
    ie.Visible = 1;
    while ~isequal(ie.ReadyState,'READYSTATE_COMPLETE')
    end
    HtmlText = ie.Document.body.innerHTML;
    count = count+1;
end
ie.Quit;

%%
expr_1h1 = '<p></p>';
expr_1h2 = '</table>';
expr_TempText = [expr_1h1,'(.*?)',expr_1h2];

TempText = regexp(HtmlText,expr_TempText,'match');
TempDetails = regexp(TempText,'>([\d\.]+?)%?<','tokens');
if ~isempty(TempDetails)
    Details = reshape(cell2mat(cellfun(@(x)str2num(x),[TempDetails{1}{:}],'Uni',0)),3,[]);
else
    Details = [];
end
end

function HtmlText = get_HtmlText(url)
%%

HtmlText = [];
count = 0;

ie = actxserver('internetexplorer.application');
while length(HtmlText) < 20000 && count <= 5
    ie.Navigate(url);
    ie.Visible = 1;
    while ~isequal(ie.ReadyState,'READYSTATE_COMPLETE')
    end
    HtmlText = ie.Document.body.innerHTML;
    count = count+1;
end
ie.Quit;
end


function TempText = get_TempText(HtmlText)
expr_1h1 = '<td height="22" align="left">';
expr_1h2 = '</span></td> ';
expr_TempText = [expr_1h1,'(.*?)',expr_1h2];

TempText = regexp(HtmlText,expr_TempText,'match');
end


function url_2 = get_url_2(TempText,Date)
if ~isempty(TempText)
    TempDateList = regexp(TempText,'(\d{4}-\d{2}-\d{2})','tokens');
    TempDateList2 = [TempDateList{:}];
    DateList = cell2mat(cellfun(@(x)datenum(x,'yyyy-mm-dd'),TempDateList2,'Uni',0));
    [flag,ii] = ismember(Date,DateList);
   
    if flag
        Text1 = TempText{ii};        
        expr_2 = 'href="(.*?)"';
        url_2h2 = regexp(Text1,expr_2,'tokens');
        url_2h1 = 'http://www.pbc.gov.cn';
        url_2 = [url_2h1,url_2h2{1}{1}];        
    elseif Date < DateList(end)
        url_2 = [];
    else
        url_2 = -1;
    end
end
end
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-9-21 18:10:38 | 显示全部楼层
tensorflow初体验:

把神经网络43个例子中的意大利红酒数据拿出来替代MNIST。把该mat数据拿到同一文件夹下。
自定义的函数写得有点问题,将就用一下。
代码如下

import tensorflow as tf
import scipy.io as sio  
import matplotlib.pyplot as plt  
import numpy as np

'''
第一部分:matlab数据导入及处理
'''

# matlab文件名  
matfn = './chapter_WineClass.mat'  
data = sio.loadmat(matfn)

def mapminmax(x):  
    Max = np.max(x)
    Min = np.min(x)
    y = (x - Min) / (Max - Min)
    return y;   

def labels2tensor(x):
    elements = np.unique(x)
    tensor = np.zeros((len(x),len(elements)))
    for l in range(len(x)):
        index = np.nonzero(elements == x[l])
        tensor[l,index] = 1   
    return tensor   

# 将matlab数据转化为变量
wine = data['wine']
wine_labels = data['wine_labels']

# 选定训练集和测试集

# 将第一类的1-30,第二类的60-95,第三类的131-153做为训练集
train_wine = np.vstack((wine[0:30,:],wine[59:95,:],wine[130:153,:]))
# 相应的训练集的标签也要分离出来
train_wine_labels = labels2tensor(np.vstack((wine_labels[0:30,:],wine_labels[59:95,:],wine_labels[130:153,:])))
# 将第一类的31-59,第二类的96-130,第三类的154-178做为测试集
test_wine = np.vstack((wine[30:59,:],wine[95:130,:],wine[153:178,:]))
# 相应的测试集的标签也要分离出来
test_wine_labels = labels2tensor(np.vstack((wine_labels[30:59],wine_labels[95:130],wine_labels[153:178])))

'''
第二部分:数据预处理,将训练集和测试集归一化到[0,1]区间
'''

[mtrain,ntrain] = np.shape(train_wine);
[mtest,ntest] = np.shape(test_wine);

dataset = np.vstack((train_wine,test_wine))

# mapminmax为MATLAB自带的归一化函数
for w in range(wine.shape[1]):
    dataset_scale[:,w] = mapminmax(dataset[:,w])

train_wine = dataset_scale[0:mtrain,:]
test_wine = dataset_scale[mtrain:(mtrain+mtest),:]

'''
第三部分:照搬MNIST的代码(部分参数修改)
'''
x = tf.placeholder(tf.float32, [None, 13])
W = tf.Variable(tf.zeros([13,3])) # weight of regression
b = tf.Variable(tf.zeros([3])) # bias

y = tf.nn.softmax(tf.matmul(x,W) + b)

y_ = tf.placeholder("float", [None,3])


# loss function: cross entropy
cross_entropy = -tf.reduce_sum(y_*tf.log(y))

# train step
# 用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵。
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

# initialization global variables
init = tf.global_variables_initializer()

# start the Graph
sess = tf.Session()
sess.run(init)

for i in range(1000):
    sess.run(train_step, feed_dict={x: train_wine, y_: train_wine_labels})
  
    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
   
    print(sess.run(accuracy, feed_dict={x: test_wine, y_: test_wine_labels}))
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-5-14 11:32:26 | 显示全部楼层
本帖最后由 dapanji 于 2017-5-14 11:39 编辑

个人研究准备工作(针对商品交易,股票略有不同):
1、数据读取程序:从数据提供商下载交易数据
2、数据清洗、整理
3、策略生成器:
1)读取本地数据程序(参数包括而不限于:交易品种名称、起止时间、采用的时间周期)
2)指标函数/计算(这部分是可替换的,根据不同模型、指标命名并调用)
3)生成信号(时间、方向)
4)生成交易记录
4、策略回测平台:根据信号/交易记录按时间顺序生成交易回报(价格、方向、数量),展示回测结果以及计算各种参数

针对不同交易种类,策略生成器也是有差异的,分为:日内交易(开盘前不持有隔夜头寸,收盘前平仓)、连续交易、配对交易。
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-5-14 11:48:43 | 显示全部楼层
目前的研究进展:
1、日内交易:复制了很多国外著名的区间突破策略,如RBreaker、DualThrust等,效果不好。自研了一个策略,效果比前面的好,但用在实盘肯定不行。
2、配对交易:配对交易里面一些细节没理顺,策略生成器没写好。以前用excel做过一两个比较低效但能赚钱的模型。
3、连续交易:主要使用15分钟周期,复制和自研了一些趋势交易指标,用在螺纹(RB)上效果较好,橡胶的结果可以接受,其他品种不怎么样。
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-5-15 19:53:47 | 显示全部楼层
早上朋友问了个问题:是否需要针对品种的波动特性开发策略?这种量体裁衣的策略会不会失效得很快?

我的思考如下:
一、先谈点别的:策略(指标)设计的依据是?
每个人的回答都不尽相同,我个人观点:哪里能赚钱去哪。
所以我设计的策略也很简单,比如,统计前面n个周期多头还是空头赚钱了。多头赚钱了就做多,空头赚钱了就做空。
至于谁赚钱了怎么衡量,那就是每个人心中的哈姆雷特了。
还有个问题:策略中的这个n,取100的时候多头赚钱,取200的时候空头赚钱,怎么执行?
1、加个300,少数服从多数;
2、一半多一半空,执行前一个信号。
我设计的RB策略大致就是这样了。

二、为什么要量体裁衣?
我针对RB设计的策略用在pp上效果很差——有可能是过拟合,但我认为不一定。有可能因为品种的运动特性不一样。
1、期货是对未来价格的预测,下面开始瞎掰。大致有如下公式:
期货价格 = 现货价格 + 利多升水 - 利空贴水
期货价格可以近似认为是现货价格的线性函数,拥有与现货相近的季节性和库存周期。
因此,在调指标的时间参数时,有1-2个区间效果特别好,可能是切中了周期。也有可能就是样本内过拟合。
由于品种之间的周期不仅相同,所以……
2、品种的交易时间、制度不一样。
比如rb和pp。rb没有外盘,跳空基本上是顺基本面方向的;而pp跳空有可能是顺原油方向而逆基本面方向的。
针对它们设计的系统就应该有差异了。

下面是虚拟场景:
假如rb和pp现在都是5000块,准备往上涨,每天涨100块。原油下跌趋势,每天跌5毛。
rb每天开盘往上跳空10块,pp每天开盘跳空低开10块。
对于rb,判断出往上,一直拿着就好了;
对于pp,判断自身趋势往上,但是原油趋势往下,因此每天低开买入,收盘卖出,多赚10块。

虽然瞎掰,但为什么要针对不同品种量体裁衣设计策略,好像回答清楚了。

三、至于会不会快速失效,可能要看策略针对的品种统计特性会不会改变了,难说啊。
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-5-16 17:16:07 | 显示全部楼层
20170516:
今天主要工作放在了设计选股模型

为了不与市场都在用的多因子选股模型重合,我选择了另外一条路径:全市场选股=〉选行业=〉行业内选股=〉形成股票池,综合打分配置权重
1、全市场选股=〉选行业:使用特定指标进行板块过滤。
2、……
效率很低,只做了第1步的一小部分工作,但是效果还可以。把输家减掉,组合绩效很有可能增强。
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-5-17 14:00:09 | 显示全部楼层
20170517

以前做了一个可能是过拟合的多因子模型,2010年至今大概6倍多的收益。
这是什么概念呢?今天算了一笔帐,A股医药行业里面的标杆之一,恒瑞医药,同时期涨幅不超过4倍。

也就是说,在虚拟测试中,买入并长期持有绩优股不是一个很好的策略。必须做轮动和高抛低吸,也就是乘法。
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-6-1 19:12:18 | 显示全部楼层
最近看了篇文章,在python开发的回测平台的论坛很火,我看能不能用matlab实现

SSRN-id2701346.pdf

238.69 KB, 下载次数: 4, 下载积分: 贝壳 -1

回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-6-6 08:43:59 | 显示全部楼层
今天打算复制附件的报告

这个作者的风格是样本内过拟合,所以我估计做不出什么结果。练练手吧。

20170412-方正证券-方正证券CTA专题研究:蜘蛛网爱国债期货.pdf

1.57 MB, 下载次数: 9, 下载积分: 贝壳 -1

回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

 楼主| 发表于 2017-6-6 08:45:35 | 显示全部楼层
dapanji 发表于 2017-6-1 19:12
最近看了篇文章,在python开发的回测平台的论坛很火,我看能不能用matlab实现

复制了其中一条公式,跑起来花好几个小时,估计是程序写得有点问题
回复 支持 反对

使用道具 举报

签到天数: 78 天

[LV.6]常住居民II

发表于 2017-6-6 10:17:41 | 显示全部楼层
看帖回帖是种美德。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|网站地图|MATLAB技术论坛|Simulink仿真论坛 ( 陕ICP备08102094号  

GMT+8, 2017-10-18 19:15 , Processed in 1.117370 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表