雁起平沙的网络日志

数量金融与R

R语言版的cntrade程序

| Comments

本文展示的是R语言版的cntrade程序

李春涛和张璇两位老师写了个名叫cntrade的stata程序,用来从网易财经网获取沪深两市股票日度行情数据。

我用R重写了这个程序,请看:

(cntrade.r) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# cntrade R语言版 
# 作者:陈堰平(统计之都,chen@yanping.me) 
# 使用网易股票数据接口 原stata版的作者为:
#   李春涛(中南财经政法大学,chtl@znufe.edu.cn) 
#   张璇(中南财经政法大学,zhangx@znufe.edu.cn) 
# example: 
#   cntrade(c('600000', '000008'), path ='D:/stockprice', start = 20010104, end = 20120124)

cntrade <- function(tickers, path = "", start = 19910101, end = "") {

  address <- "http://quotes.money.163.com/service/chddata.html"
  field <- "&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP"

  if (path == "") {
    path <- getwd()
  }

  if (!file.exists(path)) {
    dir.create(path)
  }

  if (substr(path, nchar(path), nchar(path)) != "/") {
    path <- paste(path, "/", sep = "")
  }

  if (end == "") {
    year <- substr(Sys.time(), 1, 4)
    month <- substr(Sys.time(), 6, 7)
    day <- substr(Sys.time(), 9, 10)
    end <- paste(year, month, day, sep = "")
  }

  count <- 0
  tickers <- as.character(tickers)
  for (name in tickers) {
    while (nchar(name) < 6) {
      name <- paste("0", name, sep = "")
    }

    if (nchar(name) > 6) {
      warning(paste("invalid stock code: ", name, sep = ""))
      next
    }

    if (as.numeric(name) > 600000) {
      url <- paste(address, "?code=0", name, "&start=", start, "&end=", end, field, sep = "")
    } else {
      url <- paste(address, "?code=1", name, "&start=", start, "&end=", end, field, sep = "")
    }
    destfile <- paste(path, name, ".csv", sep = "")
    download.file(url, destfile, quiet = TRUE)
    count <- count + 1
  }

  if (count == 0) {
    cat("一个数据文件都没下载下来!\n")
  } else {
    cat("数据下载完成!\n")
    cat(paste("共下载", count, "个文件\n", sep = ""))
  }
}

调用举例

1
2
3
4
5
cntrade(c('600000', '000001', '600810'), path = "d:\temp", start = 19990101, end = 20121231)
cntrade(c(600000, 000001, 600810))
cntrade('000002', start = 19990101)
cntrade(000002, end = 19990101)
cntrade(c(2, 16))

stata版的介绍请看http://blog.sina.com.cn/s/blog_6af14ae20101ggnz.html

用R获取郑州商品交易所历史数据

| Comments

本文主要讨论如何用R语言从郑州商品交易所网站上获取期货合约交易数据

郑商所网站提供了查询每日行情的页面,它提供的数据比大商所的要复杂一些,2010年至2013年的网页格式一样,地址也是同样的形式,请看

打开网页可以看到,网页提供了“打印”,“Excel”和“txt”三个选项,只要把地址后面的.html改为.txt就可以得到文本格式的数据,那么就可以逐一下载数据文件,读入数据。

这四年的数据可以这样获取:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
getZceData <- function(dates){
  require(RCurl)
  zceDatabase <- data.frame()
  for (date in dates) {
    str1 <- "http://www.czce.com.cn/portal/exchange/"
    str2 <- "/datadaily/"
    date <- as.character(date)
    year <- substr(date, 1, 4)
    url <- paste(str1, year, str2, date, ".txt", sep = "")
    if (!url.exists(url)) {
      next
    } else {
      colnames <- c("品种月份", "昨结箿", "今开盘", "最高价", "最低价",
        "今收盘", "今结算", "涨跌1", "涨跌2", "成交量", "空盘量",
        "增减量", "成交额", "交割结算价")
      fileName <- paste("zce", date, ".txt", sep = "")

      if (!file.exists(fileName)) {
        download.file(url, fileName, quiet = T)
      }
      zceData <- read.table(fileName, header = F, skip = 1, sep = ",", col.names = colnames)
      zceData <- zceData[(zceData[, 1] != "小计") & (zceData[, 1] != "总计"), ]
      zceData$date <- date
      zceDatabase <- rbind(zceDatabase, zceData)
    }
  }
  return(zceDatabase)
}

但是查询2009年及之前的数据返回的是网页形式,那就需要从网页上读取。

看下面几个链接

网页格式很统一,数据在被table标签包裹,并且是在第二个table标签中,XML包的readHTMLTable函数可以读取table标签中的内容,但是当网页中有汉字的时候,汉字会变成乱码,慎用!

不过,本文的情况有点特殊,汉字只出现在table的第一行表头,以及“小计”、“总计”的行,这些行本来就是要去掉的,所以对我们没影响。

下面只给出关键代码:

1
2
3
4
5
6
require(XML)
require(stringr)
url <- "http://www.czce.com.cn/portal/exchange/jyxx/hq/hq20060106.html"
tb <-readHTMLTable(url)[[2]]
tb <- sapply(tb,str_trim)
df <-as.data.frame(apply(tb,2,function(x) iconv(x, from = "gb2312", to = "UTF-8")))

再把第一列为NA的行去除就行了。

用R获取大连商品交易所历史数据

| Comments

本文主要讨论如何用R语言从大连商品交易所网站上获取期货合约交易数据

大商所的网站上有提供查询历史的页面。但是它只能对某一个品种查询某一天的报价,或者某一天所有品种的报价,如果我想批量获取交易数据,应该怎么做呢?

首先剖析一下这个页面,用firefox的firebug查看日行情表的代码

日行情表

可以看到,这个表实际上是用iframe实现的,查看页面的源文件可以查出这个iframe引用页面地址为http://www.dce.com.cn/PublicWeb/MainServlet?action=Data_service。用上面的方法继续剖析这个页面,发现它引用了http://www.dce.com.cn/PublicWeb/MainServlet?action=Pu00011_search

用jekyll和jQuery实现异步加载文章列表

| Comments

本文主要讨论如何用基于jQuery的插件waypoint,实现异步加载jekyll模板生成的json文件,生成文章列表。

我在另一个博客的文章列表里使用了异步加载的技术,不过直接看页面的html源代码是看不出来的。编译之前的代码在这里

首先,生成文章列表数据的json模板是:

1
2
3
4
5
6
7
8
9
10
11
12
---
layout: nil
---

[
{% for post in site.posts %}
  {"title":"{{post.title}}", 
  "url":"{{site.url}}{{post.url}}", 
  "date":"{{ post.date | date:'%Y-%m-%d' }}", 
  "tags":[{% for tag in post.tags %}"{{tag}}"{% if forloop.last == false %} ,{% endif %}{% endfor %}]}
  {% if forloop.last == false %},{% endif %}{% endfor %}
]

这在前面的文章里提到过。

头部YAML数据部分:

1
2
3
4
5
6
---
layout: default
title: 全部文章
initItem: 50
perPageItem: 100
---

initItem是初始加载时显示的文章主题数,perPageItem是每次页面下拉到底部时读取json数据并新生成的文章主题数。

初始加载网页时,文章主题列表是静态的html,由jekyll生成:

1
2
3
4
5
6
7
<ul class="posts">
{% for post in site.posts limit:page.initItem %}
  <li class="listing-item">
    <time datetime="{{ post.date | date:"%Y-%m-%d" }}">{{ post.date | date:"%Y-%m-%d" }}</time>
    <a href="{{site.baseurl}}{{ post.url }}" title="{{ post.title }}">{{ post.title }}</a>
  </li>{% endfor %}
</ul>

上面的limit:page.initItem限定了列表的项数不超过initItem。当向下拉页面,waypoint会捕捉到页面下拉到底部的事件,并调用getJSON方法来读取json数据,形成文章列表。

在Windows下使用jekyll如何避免出现中文字符集错误

| Comments

在windows下使用jekyll时经常会遇到字符集错误,比如遇到提示Liquid error: incompatible character encodings: UTF-8 and GBK。本文将介绍几种解决方案。

1. 修改bash的字符集:C:\Documents and Settings\用户名下,找到文件.bash_profile,后面加两行

1
2
set LC_ALL=en_US.UTF-8
set LANG=en_US.UTF-8

DecisionTools培训课程大纲

| Comments

本人近期将推出《DecisionTools高级应用:数量风险建模与决策分析》课程,有需要培训的团体或个人与我联系。

课程目标

DecisionTools是一套在Microsoft Excel量身定制集成程序,从而使用户可以在一个软件包中针对不确定因素完成风险优化及决策分析的操作。DecisionTools Suite包括使用蒙特卡罗模拟执行风险分析的@RISK、执行决策分析的PrecisionTree和执行灵敏度分析的TopRank。此外,软件还包括执行预测、数据分析和最优化的 StatTools、NeuralTools和Evolver。

本课程适用于从事风险建模、数据分析工作的人员。本课程使用项目成本评估、折现现金流模型等常规案例来讲解蒙特卡罗模拟的思想和软件操作技巧。学员将在课程中学习如何在Excel环境中建立风险评估模型和不确定性条件下的决策模型。

除了@RISK以外,本课程也会介绍DecisionTools套件的其他组件, 这些组件可以完善和补充@RISK的模拟功能。主要涉及的主题包括:

  • 使用PrecisionTree做序列决策建模以及敏感性分析;
  • 结合@RISK和PrecisionTree;
  • 使用RISKOptimizer做不确定性优化;
  • 使用TopRank做敏感性分析;
  • 使用StatTools和NeuralTools做统计分析和预测

下一步学习的目标

| Comments

不给自己定太遥远的目标了,为了把R语言捡起来,为了把数量金融方面捡起来,我决定以 Using SAS in Financial Research 为蓝本,用R语言来实现每章的案例,来个 Using R in Financial Research 。涉及的案例有:

  • 资产价格的随机游走理论:方差比率检验
  • 谁是赢家谁是输家:使用R来检验过度反应假设
  • 资本资产定价模型的实证检验:使用横截面方法
  • 事件研究
  • 价格-盈利关系的分析:关联类型研究方法
  • 使用财务压力特征模型来预测破产
  • 使用会计信息来预测市场绩效
  • 交易数据的分析