通达信批导出股票历史交易数据并用R语言写入SQLite数据库

要分析金融数据,首先要有数据,好在金融数据的比较容易获取,比如股票,通过看盘软件批量导出股票交易历史数据。下面就简单介绍从通达信批量导出历史交易数据,读取csv文件并简单处理后,在R语言下用sapply函数循环批量读取并写入SQLite数据库的教程。

其中使用数据库部分是针对无数据库基础的人的。使用的SQLite是一种轻量级的、不需要安装数据库软件也不需要配置环境的、直接安装对应的R包RSQLite即可使用的数据库,非常适合无数据库基础的R语言用户在R语言环境下管理自己的数据。同时,它也是专业级的,苹果iphone的ISO系统数据管理就是基于SQLite的,MAC 的OS X系统的从10.4后把SQLite这套相当出名的数据库软件放进了作业系统工具集里。

1

 

批量导出股票历史交易数据

因为实际分析过程中,即会用到复权数据也会用到未复权数据,所以2种数据我分别导出,我用的是通达信行情软件,以上证50指数成份股(截止2017年12月31日)为例,先导出前复权数据放到“../stock”中,再导出未复权的数据放到“../stock_F”中。

本文代码使用相对路径,“..” 代表代码文件所在文件夹的父文件夹,我的目录结构会在下面说明。不熟悉R语言文件和文件夹管理的可

回复“文件管理”

获取相应文件。

1.1

 

先导前复权数据

打开通达信客户端,依次点选:菜单>系统>数据导出,如下图所示(如果交易数据没有下载到最新日期,软件会提示下载到最新日期,重新按上述步骤操作):

第一步:点击上图中“高级导出”

通达信批导出股票历史交易数据并用R语言写入SQLite数据库

第二步:点击上图中的“添加品种”

通达信批导出股票历史交易数据并用R语言写入SQLite数据库

第三步:选取要导出的股票

通达信批导出股票历史交易数据并用R语言写入SQLite数据库

我们是要导出上证50指数成份股,所以在第一行先“指数板块”后在左侧选“上证50”,之后点“全选”,再点“确定”。

你可以根据需求选中相应的股票,比如:全部A股等。

第四步:设置导出选项

通达信批导出股票历史交易数据并用R语言写入SQLite数据库

这一步有几点要特别注意:

  • 位置1:选“日线”;

  • 位置2:选文件夹,复权数据我放在“stock_F”下;

  • 位置3:文件名格式要特别注意YY表市场(如SH表示上交所,SZ表示深交所),6个X表示代码,有些数据库表名不用数字开头,所以我们用YYXXXXXX.csv格式,写入数据库时用YYXXXXXX格式命名每个表;

  • 位置4:复权选 “前复权”,分隔符选“逗号”,日期格式….



  • 我们看一下导出的文件:

     

    str

    (

    dir

    (

    "../stock_F/"

    ))##  chr [1:50] "SH600000.csv" "SH600016.csv" "SH600019.csv" ...

    1.2

     

    导出未复权数据

    再导出上证50指数成份股的未复权数据。

    未复权数据导出选项设置 通达信批导出股票历史交易数据并用R语言写入SQLite数据库

    有几点与前一次不同:

  • 位置2:选文件夹,复权数据我放在“stock”下;

  • 位置3:未复权数据我们用XXXXXX.YY.csv格式命名文件,写入数据库时用我们将50个文件写入一张表SH50_stocks,并用XXXXXX.YY格式做为“code”列,以区分不同代码的数据;

  • 位置4:复权选 “前复权”。

  • 我们看一下对应文件夹:

     

    str

    (

    dir

    (

    "../stock/"

    ))##  chr [1:50] "600000.SH.csv" "600016.SH.csv" "600019.SH.csv" ...

    搞定,里面有50个文件。 

    dir()函数,它可以生成指定文件夹下的文件或文件夹的名称列表清单(格式为字符串向量),路径中的“..”代表代码文件所在的文件夹的父文件夹。

    2

     

    用R语言批量读取前复权股票历史交易数据

    我们先读取前复权的数据,读取后每个文件(每只股票)在数据库中建一个表并用YYXXXXXX格式命名每个表,表名在文件名中提取,还记得导出的前复权文件名吗?这样滴“SH600000.csv”…

    2.1

     

    工作目录的目录结构

    为了方便大家下载本文代码(地址见文末)和数据文件后直接运行代码,我使用相对路径,需要先对目录结构做一下说明。不熟悉代码的朋友可按下面目录创建目录和文件,即可直接运行本文代码(或按文末地址下载代码和数据文件直接运行代码)。

     

    system

    (

    "tree /f d:/Rdata/knitr/WX_QuantFinanceWithR"

    )



    从上面可以看出我的文件夹WX_QuantFinanceWithR下面文件夹和文件的位置,用到的3个分别是:

  • data_analysis

  • 文件夹下的Read_stocks_to_SQLite.Rmd就是本文的rmarkdown源文件,同名的html是本文运行后输出文件。

    rmarkdown是R语言运行环境RStudio所使用的扩展的markdown标签语言,是一种易学、易用,可实现代码、图文、数学公式等内容混合排版并输出为指定格式(包括:html、word、PDF等)的文档的标签语言,非常方便。 本文的源文件即为rmarkdown格式,你可以在文末提供的地址中下载,了解rmarkdown详细请

    回复 “rmarkdown”

    获取相应文章。

  • stock

  • 该文件夹放的是从行情软件导出的上证50成份股复权的csv格式文件(2017年12月31日);

    stock文件夹与data_analysis文件夹都在WX_QuantFinanceWithR文件夹下,而代码文件在data_analysis文件夹下的Read_stocks_to_SQLite.Rmd,所以路径中的“../stock”代表就是WX_QuantFinanceWithR文件夹下的stock文件夹。

  • stock_F

  • 该文件夹放的是从行情软件导出的上证50成份股复权的csv格式文件(2017年12月31日),注意文件名的格式不同,是在导出时分别设置的。

    2.2

     

    读取单个文件

    因为本文的源代码文件在WX_QuantFinanceWithR/data_analysis/下,我们要读取的复权股票历史交易数据在WX_QuantFinanceWithR/stock_F/中,使用相对路径应该是:“../stock_F/”。

    2.2.1

     

    列出文件列表

     file_list <-

    list.files

    (

    "../stock_F/"

    ,

    pattern =

    "csv"

    ,

    full.names =

    TRUE

    )  

     

    str

    (file_list)卷 新加卷 的文件夹 PATH 列表

    卷序列号为 C2D1-47DA

    D:\RDATA\KNITR\WX_QUANTFINANCEWITHR

    │  

    ├─data_analysis

    │      data_manipulation_with_RSQLite.html

    │      data_manipulation_with_RSQLite.Rmd

    │      

    ├─input

    │      WX_QuantFinanceWithR_SQLite_data.db

    │    

    │      WX_QuantFinanceWithR_SQLite_data.db

    │      

    ├─pic

    │      来源于公众号_R语言量化金融.png│ 

    │      

    ├─stock

    │      600000.SH.csv

    │      600016.SH.csv

    │      600019.SH.csv

    │ 

    ...省略46个文件..

    │      603993.SH.csv

    │      

    └─stock_F

    │     SH600000.csv     

    │     SH600016.csv      

    │     SH600019.csv

    │     ...省略46个文件..

    │     SH603993.csv



    list.files()函数列出指定文件夹下的文件名(而不包含文件夹)列表(注意:dir()会包含文件夹名),下面代码中的2个参数:

  • 参数pattern设为“csv” 表示只列出后缀为csv的文件,如果同文件夹下还有其它后缀的文件,该参数就有必要;

  • 参数full.names设为TRUE 表示列出的文件名为包含路径的文件名(如果设为FALSE就会列出不带路径的文件名),因为我们指定的文件夹为相对路径,所以带路径的文件名也是相对路径。

  • 2.2.2

     

    读取第1个csv文件

     SH600000_df <-

    read.csv

    (file_list[

    1

    ],

    header =

    FALSE

    ,

    sep =

    ","

    ,

    stringsAsFactors =

    FALSE

    )  

     

    head

    (SH600000_df,

    2

    )##           V1   V2   V3   V4   V5        V6         V7## 1 1999/11/10 0.93 0.96 0.63 0.72 174085000 4859102208## 2 1999/11/11 0.70 0.79 0.70 0.72  29403400  821582208

    为了避免新手中文字符出现乱码错误,我们导出时没有勾选“生成导出头部”,所以参数header设为FALSE,R自动分配V1~V7的列名称,我们用下面的代码改列名。

     

    names

    (SH600000_df) <-

    c

    (

    "date"

    ,

    "open"

    ,

    "high"

    ,

    "low"

    ,

    "close"

    ,

    "volume"

    ,

    "amt"

    )  

     

    tail

    (SH600000_df,

    2

    )##                 date  open  high   low close   volume       amt## 4277      2017/12/29 12.52 12.62 12.51 12.59 16351826 205752880## 4278 数据来源:通达信    NA    NA    NA    NA       NA        NA

    最后一行是数据来源的声明,我们需要删除这一行:

     SH600000_df <-

    SH600000_df[

    -

    nrow

    (SH600000_df),]  

    str

    (SH600000_df)## "data.frame":    4277 obs. of  7 variables:##  $ date  : chr  "1999/11/10" "1999/11/11" "1999/11/12" "1999/11/15" ...##  $ open  : num  0.93 0.7 0.73 0.77 0.74 0.58 0.66 0.69 0.62 0.57 ...##  $ high  : num  0.96 0.79 0.79 0.78 0.75 0.66 0.7 0.7 0.63 0.58 ...##  $ low   : num  0.63 0.7 0.72 0.72 0.57 0.56 0.61 0.61 0.55 0.53 ...##  $ close : num  0.72 0.72 0.76 0.72 0.58 0.66 0.64 0.62 0.57 0.57 ...##  $ volume: int  174085000 29403400 15007900 11921000 23223100 10052500 8446500 5374900 5535400 3843900 ...##  $ amt   : num  4.86e+09 8.22e+08 4.22e+08 3.33e+08 6.29e+08 ...

    删除后,数据框变为4272行,少了一行。

    2.2.3

     

    正确处理日期的格式避免写入SQLite数据库日期值错误

    为了正确地将日期写入SQLite数据库,date列需要的格式为“2017-01-01”的字符串,而不是“2017-1-1”或是“2017/1/1”等(注意月和日的格式是两位字符表示),不是日期格式。虽然读入的“date”列默认是字符格式,但有时导出后的日期值的月和日的格式是两位字符表示。这会导致,日期写入SQLite数据库后,有些值会不正确。这个是新手很容易碰到但较难解决问题。

    我们先转为日期,再转为字符格式,就可保证这一点。

     SH600000_df

    $

    date <-

    as.character

    (

    as.Date

    (SH600000_df

    $

    date))  

    str

    (SH600000_df)## "data.frame":    4277 obs. of  7 variables:##  $ date  : chr  "1999-11-10" "1999-11-11" "1999-11-12" "1999-11-15" ...##  $ open  : num  0.93 0.7 0.73 0.77 0.74 0.58 0.66 0.69 0.62 0.57 ...##  $ high  : num  0.96 0.79 0.79 0.78 0.75 0.66 0.7 0.7 0.63 0.58 ...##  $ low   : num  0.63 0.7 0.72 0.72 0.57 0.56 0.61 0.61 0.55 0.53 ...##  $ close : num  0.72 0.72 0.76 0.72 0.58 0.66 0.64 0.62 0.57 0.57 ...##  $ volume: int  174085000 29403400 15007900 11921000 23223100 10052500 8446500 5374900 5535400 3843900 ...##  $ amt   : num  4.86e+09 8.22e+08 4.22e+08 3.33e+08 6.29e+08 ...

    2.3

     

    数据库小白级SQLite数据库入门

    读取数据后,将数据写入数据库,我用的是SQLite数据库,前面已介绍了。SQLite是一种轻量级的数据库,非常适合没有数据库基础的非专业人士用来管理自己的数据。有多“轻”呢?它不需要安装数据库管理软件、不需要配置软件环境。安装R包RSQLite(及依赖的包)后就可以直接使用。

    安装RSQLite包后你就可以直接运行下面的代码体验一下,你会发现它像使用其它包一样,够“轻”吧。

  • 安装并加载RSQLite包

  • install.packages(“RSQLite”)安装RSQLite包,如果提示还有其它依赖包需要安装,用install.packages()直接安装好即可。

     

    library

    (RSQLite)
  • 创建数据库连接

  •  con_wx <-

    dbConnect

    (

    SQLite

    (),

    "../input/WX_QuantFinanceWithR_SQLite_data.db"

    )

    上面这行代码会创建一个连接到指定文件夹下WX_QuantFinanceWithR_SQLite_data.db数据库文件的名叫con_wx的SQLite数据库连接,如果指定的文件夹下没有数据文件,就会在这个文件夹下创建一个空的WX_QuantFinanceWithR_SQLite_data.db数据库文件,并建立连接,之后就可通过这个连接操作(读、写、更新等)数据库中的数据。

    对于没用过数据库的会问,用excel、csv、txt等格式保存文件不也是一样吗?

    肯定不一样!

    即不使用复杂的数据库操作,只以最简单地方式(数据库小白级)读、写数据,数据库也有以下几个优点:

  • 创建带主键的表可以避免重复数据,尤其是重复写入时,主键重复的数据行会自动被忽略或替换(需要设置);

  • 大表(百万/千万行或更大)可以按指定列(或多个列)条件筛选后读取所需的部门数据行,而不是全部行。



  • 如果稍学一些入门级SQL,则可以大大提高数据操作效率,回复

    “RSQLite”

    获取相关文章。

  • 创建SQLite数据表

  • 先创建表再写入数据。

     sql_create <-

    "CREATE TABLE if not exists "SH600000" (

         "date" DATE,

         "open" REAL,     

         "high" REAL,     

         "low" REAL,     

         "close" REAL,     

         "volume" INTEGER,     

          "amt" REAL,     

          PRIMARY KEY ("date" DESC) ON CONFLICT IGNORE);"

       

    dbSendQuery

    (con_wx,sql_create)## <SQLiteResult>##   SQL  CREATE TABLE if not exists "SH600000" (## ##      "date" DATE, ## ##      "open" REAL, ## ##      "high" REAL, ## ##      "low" REAL, ## ##      "close" REAL, ## ##      "volume" INTEGER, ## ##      "amt" REAL, ## ##      PRIMARY KEY ("date" DESC) ON CONFLICT IGNORE);##   ROWS Fetched: 0 [complete]##        Changed: 0  

    dbListTables

    (con_wx)## [1] "SH600000"

    创建数据表代码说明:

  • CREATE TABLE if not exists ‘SH600000’ 表示表SH600000不存在就创建,表名放在引号内。

  • 创建的字段名称和类型放在括号内。

  • 字段名称放在引号内,字段名称后是数据类型,字段名称与字段类型之间空一格。DATE是日期格式,REAL是浮点型值(以8字节IEEE浮点数存放),INTEGER是有符号整型值,TEXT是字符格式。

  • PRIMARY KEY (‘date’ DESC) 表示将date字段设为主键(倒序),可避免重复行并有排序保存数据等;

  • ON CONFLICT IGNORE 是指在写入数据时,如有重复就忽略(不写入)。除了忽略还可以选择“REPLACE”、“ABORT”、“FAIL”、“ROLLBACK”。

  • dbSendQuery(con_wx,sql_create) 将SQL语句sql_create通过con_wx提交给数据库引擎执行;

  • dbListTables(con_wx)查询con_wx所连接到的数据有哪些数据表。

  • SQLite标准的数据类型有5种,如下:

    序号数据类型说明

    1

    NULL

    空值。

    2

    INTEGER

    带符号的整型,具体取决有存入数字的范围大小。

    3

    REAL

    浮点数字,存储为8-byte IEEE浮点数。

    4

    TEXT

    字符串文本。

    5

    BLOB

    二进制对象。

    同时,SQLite兼容MySQL的数据类型比如上面用到的date类型。

    除了先创建表再写入数据外,还可以通过直接向数据库写入数据的方式创建表,见下文“向SQLite数据库写入数据”。

  • 向SQLite数据库写入数据

  •  

    dbWriteTable

    (con_wx,

    "SH600000"

    ,SH600000_df,

    append =

    TRUE

    ,

    row.names =

    FALSE

    )  

     

    dbWriteTable

    (con_wx,

    "SH600000_plus"

    ,SH600000_df,

    append =

    TRUE

    ,

    row.names =

    FALSE

    )

    dbWriteTable()是写入数据库的函数,用到的参数说明如下:

  • con_wx 是之前创建的数据库连接;

  • SH600000 是前面创建的数据库中要写入的表名;

  • SH600000_df 是上文用read.csv读取的SH600000.csv中的数据;

  • append = TRUE 表示向表中添加数据;

  • row.names = FALSE 意思是不要把数据框的行号做为一列写入数据中。



  • 写入不成功会有错误提示,首先检查append,row.names两个参数。

    上面第二行代码中的SH600000_plus表,我们未没有创建,直接写入数据创建的表,写入成功。可按下文的方法查看数据库中表的表单。

  • 查看数据库中的数据表清单

  •  

    head

    (

    dbListTables

    (con_wx))## [1] "SH600000"      "SH600000_plus"

    可以看到我们以直接写入数据的方式创建数据表SH60000_plus。不以这样创建的表不会创建主键,写入重复行时,不会自动忽略或覆盖,所以,最好是先创建带主键的数据表,再写入数据。

  • 从数据库中读取数据(查询)

  • 下面代码从表SH600000中查询整个表。

     SH600000_SQLite <-

    dbGetQuery

    (con_wx,

    "select * from SH600000;"

    )  

     

    head

    (SH600000_SQLite,

    2

    )##  date open high  low close    volume        amt## 1 1999-11-10 0.93 0.96 0.63  0.72 174085000 4859102208## 2 1999-11-11 0.70 0.79 0.70  0.72  29403400  821582208

    dbGetQuery(con_wx,“select * from SH600000;”) 将SQL查询语句 “select * from SH600000;” 通过数据库连接con_wx提交并返回查询结果。

    head(SH600000_SQLite,2)可以看出,表SH600000最早的记录是1999-11-10日的。下面代码返回日期大于等于2017-12-01的行。

     SH600000_SQLite2 <-

    dbGetQuery

    (con_wx,

    "select * from SH600000 where date >= "2017-12-01";"

    )    

    head

    (SH600000_SQLite2,

    2

    )##         date  open  high   low close   volume       amt## 1 2017-12-29 12.52 12.62 12.51 12.59 16351826 205752880## 2 2017-12-28 12.60 12.66 12.53 12.54 23870824 300834016

    SQL语句中的 “where date >= ‘2017-12-01’”,表示按>= ’2017-12-01’的条件筛选date列。

  • 清空数据表

  •  

    dbSendQuery

    (con_wx,

    "DELETE FROM SH600000;"

    )  

     

    #dbSendQuery(con_wx,"truncate table SH600000") #MySQL数据库用这句清空表。

     

    head

    (

    dbListTables

    (con_wx))## <SQLiteResult>##   SQL  DELETE FROM SH600000;##   ROWS Fetched: 0 [complete]##        Changed: 4277## [1] "SH600000"      "SH600000_plus"

    上面代码将con_wx连接到的数据库中的表SH600000中的数据清空,但表(结构)还在。

  • 删除数据表

  •  

    dbSendQuery

    (con_wx,

    "DROP TABLE SH600000;"

    )  

     

    head

    (

    dbListTables

    (con_wx))## <SQLiteResult>##   SQL  DROP TABLE SH600000;##   ROWS Fetched: 0 [complete]##        Changed: 4277## [1] "SH600000_plus"

    上面代码将con_wx连接到的数据库中的表SH600000删除。

    2.4

     

    批量循环读取csv并写入SQLite数据库

     result <-

    sapply

    (file_list,

    function

    (full_name){        table_name <-

    substr

    (

    basename

    (full_name),

    1

    ,

    8

    )    data_read <-

     

    read.csv

    (full_name,

    header =

    FALSE

    ,

    sep =

    ","

    )    data_read <-

    data_read[

    -

    nrow

    (data_read),]      

    names

    (data_read) <-

    c

    (

    "date"

    ,

    "open"

    ,

    "high"

    ,

    "low"

    ,

    "close"

    ,

    "volume"

    ,

    "amt"

    )    data_read

    $

    date <-

    as.character

    (

    as.Date

    (data_read

    $

    date))        sql_create <-

    paste

    (

    "CREATE TABLE IF NOT EXISTS "

    ,table_name,

    " (    

        "date" DATE,     

        "open" REAL,     

        "high" REAL,     

        "low" REAL,     

        "close" REAL,     

        "volume" INTEGER,     

        "amt" REAL,     

        PRIMARY KEY ("date" DESC) ON CONFLICT IGNORE);"

    ,

    sep=

    ""

    )        

    dbSendQuery

    (con_wx,sql_create)    

       

    dbWriteTable

    (con_wx,table_name,data_read,

    append =

    TRUE

    ,

    row.names =

    FALSE

    )

       

    print

    (

    paste

    (

    Sys.time

    (),

    "写入表"

    ,table_name,

    "中"

    ,

    nrow

    (data_read),

    "行。"

    ,

    sep=

    ""

    ))      })## [1] "2018-01-07 11:29:28写入表SH600000中4277行。"## [1] "2018-01-07 11:29:29写入表SH600016中4066行。"## [1] "2018-01-07 11:29:29写入表SH600019中3978行。"## [1] "2018-01-07 11:29:29写入表SH600028中3927行。"## [1] "2018-01-07 11:29:30写入表SH600029中3408行。"...省略44行...## [1] "2018-01-07 11:29:39写入表SH603993中1253行。"    

    #dbListTables(con_wx)

    上述代码说明:

  • file_list带路径的文件名向量,如:“../stock_F/SH600000.csv”;

  • basename(full_name) 从带路径的文件名中取基本文件名(不带路径),如:“SH600000.csv”;

  • substr(basename(full_name),1,8) 从基本文件名中取第1个到第8个字符,即:“SH600000”;

  • print()是输出每个表/每只股票写入的数据行数,循环过程中每循环有个输出是个好办法,一是知道执行到哪一步了,二是有异常报错时知道在哪个循环报的错。



  •  

    dbDisconnect

    (con_wx)

    dbDisconnect() 是断开连接,用完数据库要记得断开连接。

    3

     

    批量读写完整代码

    我们继续读写无复权股票数据文件,这次我将50个文件写入同一个数据表,用股票代码作code列以区别不同的股票的数据,需要先创建带复合主键的数据表。

     

    library

    (RSQLite)        con_wx <-

    dbConnect

    (

    SQLite

    (),

    "../input/WX_QuantFinanceWithR_SQLite_data.db"

    )        sql_create <-

    "CREATE TABLE if not exists "SH50stocks" (      

         "code" TEXT,      

         "date" DATE,       

         "open" REAL,       

         "high" REAL,       

         "low" REAL,       

         "close" REAL,       

         "volume" INTEGER,       

         "amt" REAL,       

         PRIMARY KEY ("code","date") ON CONFLICT IGNORE);"

       

    #这次设置复各主键,这个经常用到。

       

    dbSendQuery

    (con_wx,sql_create)        file_list <-

    list.files

    (

    "../stock/"

    ,

    pattern =

    "csv"

    ,

    full.names =

    TRUE

    )    result <-

    sapply

    (file_list,

    function

    (full_name){      code <-

    substr

    (

    basename

    (full_name),

    1

    ,

    9

    )

    #将股票代码做为一列,与上文不同。

         data_read <-

    read.csv

    (full_name,

    header =

    FALSE

    ,

    sep =

    ","

    )      data_read <-

    data_read[

    -

    nrow

    (data_read),]        

    names

    (data_read) <-

    c

    (

    "date"

    ,

    "open"

    ,

    "high"

    ,

    "low"

    ,

    "close"

    ,

    "volume"

    ,

    "amt"

    )      data_read

    $

    date <-

    as.character

    (

    as.Date

    (data_read

    $

    date))            

    # 下面这一行是code在前为了将code做为第一列,与创建的数据表保持一致,避免写入错误。

         data_read <-

    data.frame

    (

    code =

    code,data_read)            

    dbWriteTable

    (con_wx,

    "SH50_stocks"

    ,data_read,

    append =

    TRUE

    ,

    row.names =

    FALSE

    )    

           

    print

    (

    paste

    (

    Sys.time

    (),

    "写入数据表SH50stocks中代码为:"

    ,code,

    nrow

    (data_read),

    "行数据。"

    ),

    sep=

    " "

    )    })## <SQLiteResult>##   SQL  CREATE TABLE if not exists "SH50stocks" (## ##       "code" TEXT,##       "date" DATE, ##       "open" REAL, ##       "high" REAL, ##       "low" REAL, ##       "close" REAL, ##       "volume" INTEGER, ##       "amt" REAL, ##       PRIMARY KEY ("code","date") ON CONFLICT IGNORE);##   ROWS Fetched: 0 [complete]##        Changed: 0## [1] "2018-01-07 11:29:40 写入数据表SH50stocks中代码为: 600000.SH 4277 行数据。"## [1] "2018-01-07 11:29:40 写入数据表SH50stocks中代码为: 600016.SH 4066 行数据。"...省略47行...## [1] "2018-01-07 11:29:50 写入数据表SH50stocks中代码为: 603993.SH 1253 行数据。"

    3.1

     结束
  • 查看写入数据库的表(只列出了前6个表):

  •    

    print

    (

    head

    (

    dbListTables

    (con_wx),

    6

    ))## [1] "SH50_stocks"   "SH50stocks"    "SH600000"      "SH600000_plus"## [5] "SH600016"      "SH600019"
  • 查看2017-12-28日每只股票当天的交易记录:

  •  data.

    12.28

    <-

    dbGetQuery

    (con_wx,

    "select * from SH50_stocks where date = "2017-12-28" "

    )  

     

    head

    (data.

    12.28

    )##  code    date  open  high   low close    volume        amt## 1 600000.SH 2017-12-28 12.60 12.66 12.53 12.54  23870824  300834016## 2 600016.SH 2017-12-28  8.43  8.46  8.39  8.39  56503202  475605024## 3 600019.SH 2017-12-28  8.32  8.69  8.29  8.65  94868348  811240064## 4 600028.SH 2017-12-28  6.10  6.20  6.06  6.18 135822802  835696064## 5 600029.SH 2017-12-28 11.78 12.06 11.68 11.91  60573416  719252160## 6 600030.SH 2017-12-28 18.06 18.45 17.98 18.12 102101410 1864400896
  • 查看某只股票600016.SH的2017-12-01日以来的历史交易记录:

  •    sh600016 <-

    dbGetQuery

    (con_wx,

    "select * from SH50_stocks where code = "600016.SH" and date >= "2017-12-01" "

    )

       

    head

    (sh600016)##   code   date open high  low close    volume        amt## 1 600016.SH 2017-12-01 8.79 8.86 8.68  8.83 133017638 1167279616## 2 600016.SH 2017-12-04 8.79 8.86 8.76  8.84  86831890  765035712## 3 600016.SH 2017-12-05 8.82 9.10 8.80  9.03 239648915 2152088320## 4 600016.SH 2017-12-06 8.95 8.99 8.81  8.87 108223628  964007552## 5 600016.SH 2017-12-07 8.83 8.90 8.72  8.87 101262539  892833536## 6 600016.SH 2017-12-08 8.84 8.88 8.78  8.82  74920149  660720320  

    dbDisconnect

    (con_wx)

    怎么样,用数据库比用excel、csv高效很多吧,而且以上只是很基本、很简单的SQL语句,尤其是:并不难。 要不要把上面的源代码下载下来试一下?地址下面有。

    4

     

    本文源代码及数据文件下载地址

  • 下载地址

  • 百度网盘下载链接:http://pan.baidu.com/s/1kU9cQmr 密码:r0q9。



  • 本文由rmarkdown生成

  • rmarkdown在是R语言环境的markdown支持包,可实现

    图+文+代码+复杂数学公式等

    排版,并可输出成html、PDF、word等各种常用格式的报告,尤其是R语言很友好,输出的R语言代码,可直接复制到R中运行,如上文示例中的代码,而R输出到控制台的代码每一行都有“>”或“+”,复制到R语言需要删除才能再运行。

    如下所示:

    >   sql_create <- "CREATE TABLE if not exists "SH600000" (+     "date" DATE, +     "open" REAL, +     "high" REAL, +     "low" REAL, +     "close" REAL, +     "volume" INTEGER, +     "amt" REAL, +     PRIMARY KEY ("date" DESC));">   >   dbSendQuery(con_wx,sql_create)



    通达信批导出股票历史交易数据并用R语言写入SQLite数据库





    上述的下载地址中,包含本语言的rmarkdown源文件,

    回复“rmarkdown”

    可获取基于本文rmarkdown源文件的rmarkdown使用说明。



    比如本文的html格式在chrome下浏览的截图如下:



    通达信批导出股票历史交易数据并用R语言写入SQLite数据库



    本文rmarkdown输出html文件在chrome下浏览的截图