首先我们先捋一下实现过程:
1 首先要获取到量化交易的数据
我们在聚宽这个平台可以看到它为几乎所有主流的语言都提供了API接口,其中就有我们前端开发常用到的nodejs接口。
对于nodejs接口,还是比较友好的。虽然这个request依赖包已经停止更新,但是不耽误使用,没有依赖的下载一下就ok了,这里就不做赘述了。利用这个api我们只需要注册一个账号就可以获取到每天一百万条的免费数据,对于我们做基础分析或者前端技术练习都足够了。
看到这里同学们可能会在想,请求到数据怎么储存和处理的问题了,在这之前我看到过前辈有用docker作为容器来处理,这里对于新手不是很友好,如果只用nodejs和ajax能不能实现同样的效果呢?我的思路是:用nodejs的http,fs,url三个框架在本地搭建服务器,将获取到的数据存储到本地的文档中(这里就不必用数据库了,我直接用text来存)。这样我们就可以用最简洁的代码实现所有功能。八十行代码就可以完全实现上述功能。
var http = require('http')
var fs = require('fs')
var url = require('url')
//创建服务器
http.createServer(function (request, response) {
//解析请求
var pathname = url.parse(request.url).pathname
fs.readFile(pathname.substr(1), function (err, data) {
if (err) {
console.log(err);
}
else {
response.writeHead(200, { 'content-Type': 'text.html' })
response.write(data.toString())
response.end()
}
})
}).listen(8080)
//API接口
var request = require('request');
//获取本地时间模块
let time= new Date()
let day=time.toLocaleString()//获取本地时间
console.log('日期'+day);
//剪切处理数据
let arr=day.substr(0,10).split('/')
let n=day.substr(0,10).split('/')[1]
let m=day.substr(0,10).split('/')[2]
if(n<10){//加零
arr[1]=0+n
}
if(m<10){//加零
arr[2]=0+m
}
let dayU=arr.join('-')//转化当日时间成功
var url1 = "https://dataapi.joinquant.com/apis";
var requestData = {
"method": "get_token",
"mob": "你的手机号",
"pwd": "你的密码" //密码和账号
};
function updata() {
request({
url: url1,
method: "POST",
body: JSON.stringify(requestData)
}, function (error, response, token) {
var requestData = {
"method": "get_price_period",
"token": token,
"code": "IF9999.CCFX",
"unit": "1m",
"date": dayU+"09:30:00",
"end_date":dayU+"15:00:00",
"fq_ref_date": "2018-12-18"
};
request({
url: url1,
method: "POST",
body: JSON.stringify(requestData)
}, function (error, response, body) {
console.log('写入文件');
fs.writeFile('ipit.txt',body, function (err) {//把body写如到ipit的记事本
if (err) {
return console.error(err);
}
console.log('数据写入成功');
console.log('------');
console.log('读取文件数据');
})
});
});
}
updata()
setInterval(updata,20000)
这里要注意,我保存数据的txt文件路径是在上层的,大家注意根据自己实际情况进行更改。因为聚宽提供的数据是字符串,我们要根据要求把数据处理成所需要的字符串,这里是比较麻烦的,但是总体来讲不难而且有趣。最后将数据导入到需要的echarts图标就行了。我用的是K线图。
2 图表的选择
这是我最后实现的效果:
根据自己的需求和偏好,我们可以在echarts官网上去去选,很多绚丽的图标,但是想找到一个特别符合的也并不容易,需要综合不同风格和功能的图标,这就要看自己的想法了。这里就是跟大家分享一下我的思路,没有进行太深入的研究。
具体可以去官网查看
具体的用法也可以看官方的文档。
我们真正要做的是获取数据并进行抽离,把我们要的设想算法转换成可视化的图行,比如常用的macd指标,顶底背离等。这涉及到一些逻辑算法,这里也先不探讨,留以后有时间再说。
回过头来看我们获取到初始数据:
我们看到这个字符串是很规整的,这样就好办多了。因为echarts图标需要的都是些数组数据。
并且有金融尝试的同学一定知道,k线图无非就是要开盘价 收盘价 最高和最低四个价格,那么我们获取的数据这些都是有的,只要按照所需顺序进行剪接就行了。这方面的工作我就直接在html的js代码中完成了。
我们在nodejs和html的js代码中都是用了定时器,因为都是在学习js初期的小作品所以没有考虑到效能和异步请求,大佬这里可以忽略。
我觉得有趣的地方是在剪切字符串并重新组合的过程,最后把想要的数据实时更新到页面实现自己的小算法的时候确实比较兴奋。我们可以对几个成功率极高的算法进行糅合过滤,最后给量化套利提供足够优质的策略参考。
setInterval(function () {
window.location.reload(true)
}, 10000)//刷新页面 暂时用此方法需要改进
var arrPrice = []
$.ajax({
url: './ipit.txt', /* url:请求地址 */
type: 'get', /* type:请求类型:post/get */
// data: 'a=1&b=2',
dataType: 'text', /* dataType:服务器返回的数据类型 text/xml/script/html/json/jsonp */
success: function (data) { /* 回调函数 */
var arr = data.split('\n')//把字符串转化成数组
//先分离标题
var arrNtitle = arr.splice(1)//只有时间和价格的数组
var arrUsed = []
for (let i = 0, length = arrNtitle.length; i < length; i++) {
arrUsed.push(arrNtitle[i].split(','))
}
// 把时间提取出来变成一个单独数组 并和价格数据一一对应
var arrData = [] //纯时间坐标
arrUsed.forEach(function (el) {//截取时间
arrData.push(el.shift())
})
arrUsed.forEach(function (el) {
let a = []
el.map(function (el) {
a.push(parseInt(el * 10) / 10) //转化成一位小数的小数
})
let [op, cp, hp, lp] = a //解构赋值 只要有用的前四位元素
arrPrice.push([op, cp, hp, lp])
})
for (let i = 0; i < arrData.length; i++) {
arrPrice[i].unshift(arrData[i])//把data加入元素 一一对应
}
charts(arrPrice)
//执行echarts画图函数
// console.log(arrPrice);
let lowerPrice=[]
arrPrice.forEach(function(el,i){
lowerPrice.push(el[2])
})
for(let i=0,l=lowerPrice.length;i<l;i++){
max=max[i]<max[i+1] ? max[i+1]:max[i]
}
}
});
具体实现过程并不复杂,甚至因为当时刚学基础方法显得笨拙,但是思路还是值得参考,对于量化也是具有不少实际意义的。希望大家也能从中汲取所需,上述代码用到的jQuery的ajax。