var ChartObj = {//画图
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},
chart: { zoomType:'x',panning:true },//图表类型
title: { text: ''}, //标题
rangeSelector: {
buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
selected: 0,
inputEnabled: false
},
subtitle: {text: " "},//副标题
xAxis:{type: 'datetime'},
yAxis: [{
title: {text: 'K线'},//标题
style: {color: '#4572A7'},//样式
opposite: false //生成右边Y轴
},
{
title:{text: 'WT'},
opposite: true //生成右边Y轴 ceshi
}
],
series: [//系列
{name:'wt1',type:'spline',yAxis:1,data:[]},
{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]},
{name:'wt2',type:'spline',yAxis:1,data:[]},
{type:'flags',onSeries:'wt',data:[]}
]
};
var chart = Chart(ChartObj);
var isFirst = true;
var preRecordTime = 0;
function Draw(){
var strState = "";
var fcolor = "";
var msg = "";
getRecords();
if(isFirst === true){
chart.reset();
isFirst = false;
preRecordTime = globalRecords[globalRecords.length - 1].Time;
}
if(preRecordTime === globalRecords[globalRecords.length - 1].Time){
chart.add([1,[globalRecords[globalRecords.length - 1].Time,globalRecords[globalRecords.length - 1].Open,globalRecords[globalRecords.length - 1].High,globalRecords[globalRecords.length - 1].Low,globalRecords[globalRecords.length - 1].Close ],-1]);
}else{
//更新前一柱
chart.add([1,[globalRecords[globalRecords.length - 2].Time,globalRecords[globalRecords.length - 2].Open,globalRecords[globalRecords.length - 2].High,globalRecords[globalRecords.length - 2].Low,globalRecords[globalRecords.length - 2].Close ],-1]);
chart.add([1,[globalRecords[globalRecords.length - 1].Time,globalRecords[globalRecords.length - 1].Open,globalRecords[globalRecords.length - 1].High,globalRecords[globalRecords.length - 1].Low,globalRecords[globalRecords.length - 1].Close ]]);
preRecordTime = globalRecords[globalRecords.length - 1].Time;
}
chart.update(ChartObj);
//chart.reset(500);
}
代码贴的不好~可能看着比较费眼,可以粘贴下来弄到 sublime text 里面看,先简单说下问题,就是代码写完在运行的时候,遇到诡异的一幕,看图:
很奇怪,进度条走到100% 一直卡着,一直不动,不是假死,应该卡死了。我也用了各种办法去测试,比如:限制循环次数,显示循环次数什么的,显示的都是运行到循环的最后一次卡死了。 看了看程序代码 感觉应该没什么问题。 百思不得其解 。整来整去,整了好长时间,终于发现问题了,原因是这个。 在图表初始化的时候 数据序列我是这样写的:
series: [//系列
{name:'wt1',type:'spline',yAxis:1,data:[]}, // 索引为0的 数据项,
{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]}, // 索引为1
{name:'wt2',type:'spline',yAxis:1,data:[]}, //索引为2
{type:'flags',onSeries:'wt',data:[]} //......
]
在程序中往图表里写数据是这样的:
chart.add([1,[globalR......... (太长了 没写完) // 可以看到这里 我写入索引为1 的数据序列,就是add后面[ 符号后的 1,代表写入到{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]}, 这个序列中。问题就在这,我越过了索引0,直接写入索引1的数据序列里,就会导致卡死。
于是 我修改成:
series: [//系列
{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]},
{name:'wt2',type:'spline',yAxis:1,data:[]},
{type:'flags',onSeries:'wt',data:[]}
]
所有往图表写数据的代码改成 (主要是把 1 改成 0)
chart.add([0,[globalRecords[globalRecords.length - 1].Time,globalRecords[globalRe..........(太长了。。。)
很神奇,不卡了,运行没问题了。。。虽然不知道具体是什么原因,感觉应该是图表库里的问题吧。
今天把帖子更新下,是因为在群里有朋友提出问题,通过研究,问题解决,特此记录。如果有新用户有类似的疑惑,方便讲解。OK 问题如下:
getticker 获取期货价格 为什么和实际价格不一样?
我自己测试了一下,确实不一样 发明者量化 上机器人 交易所是OK期货,用 GetTicker 获取的 最新行情 价格 确实 和 OK期货官网上的有差别,确实奇怪,肯定是哪没弄明白。 于是写了段代码具体测试:
function main(){
exchange.SetContractType("this_week");
var ticker = exchange.GetTicker();
var huilv = exchange.GetRate();
var OKhuilv = exchange.GetUSDCNY();
while(true){
huilv = exchange.GetRate();
ticker = exchange.GetTicker();
OKhuilv = exchange.GetUSDCNY();
LogStatus("ticker:",ticker,"\n","huilv",huilv,"OKhuilv",OKhuilv);
Sleep(1000);
}
}
运行情况: 发现汇率不一样,我这里获取汇率 用了2个不同的API函数。(OK期货官网上,可以设置成人民币计价的) 看了API的介绍,莫非 OK期货 用了自家汇率?
动手换算 并且验证一下吧!结果直接上图: 因为OK 官网上的 价格只有小数位后1位(剩下的没显示全),估计会有一点误差。 看到结果基本上相等,可以不完全确定,GetTicker 取得的行情价 和 OK期货官网上的 有差别,应该就是 汇率不一致引起的。
/* 交互按钮 测试
while (true) {
var cmd = GetCommand();
if (cmd) {
Log(cmd);
}
Sleep(1000);
}
*/
function main(){
var cmd = null; //初始化一些用到的变量,这个变量是直接接受 GetCommand 函数 返回值的。
var jsonObjStr = null; //接收JSON对象字符串 的变量
var jsonObj = null; // JSON 对象
var keyValue = null; // JSON 对象中的 KEY 的值
var arrStr = null; // 字符串数组
var ticker = exchange.GetTicker();
while(true){
$.Draw(); // 画图函数 , 图表模板的 导出函数
while(!ticker){
ticker = exchange.GetTicker();
Sleep(500);
}
cmd = GetCommand(); //获取 交互命令
if (cmd) {
Log("按下了按钮:",cmd);
arrStr = cmd.split(":"); // GetCommand 函数返回的 是一个字符串,这里我处理的麻烦了,因为想熟悉一下JSON ,所以先对字符串做出处理,把函数返回的字符串以 : 号分割成2个字符串。储存在字符串数组中。
jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新 拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。
//Log(jsonObjStr);//ceshi
//Log(typeof(cmd));//ceshi
/*ceshi
for(var obj1 in cmd){ // 测试用 注释掉了
Log(cmd[obj1]);
}
*/
jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象
//Log("ceshi"); //ceshi
for(var key in jsonObj){ // 遍历对象中的 成员名
keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值
}
Log(keyValue); //ceshi
switch(keyValue){ // 分支选择 操作
case 1:
$.SignOP((new Date()).getTime(),ticker.Last,1,keyValue ); //开多仓
break;
case 2:
$.SignOP((new Date()).getTime(),ticker.Last,1,keyValue ); // 开空仓
break;
case 0:
$.SignOP((new Date()).getTime(),ticker.Last,1,keyValue );//平仓
break;
default: break;
}
}
Sleep(2000);
}
}
以上代码我测试过了,没有在广场公开,所以 朋友们想要测试,需要手动添加上 交互按钮。还要添加上 一个 图表模板。我都有截图。 按照上图设置就行。
看看运行的情况:
当然策略回测是无法测试的,需要自己创建机器人,用模拟盘测试,点一下交互按钮,在图表上就会标记相应的操作。这里抛砖引玉,希望大家都写出NB的策略。(注意:机器人跑的时候 会默认隐藏交互按钮界面。需要自己点开。)
function main() {
var records = exchange.GetRecords();
while(!records || records.length < 2){
records = exchange.GetRecords();
Sleep(500);
}
var currency = exchange.GetCurrency();
var diffTime = records[records.length - 1].Time - records[records.length - 2].Time;
if(diffTime/1000 >= 1 && diffTime/1000 < 60){
Log("周期:",diffTime/1000,"秒");
}else if(diffTime/1000/60 >= 1 && diffTime/1000/60 < 60 ){
Log("周期:",diffTime/1000/60,"分钟");
}else if(diffTime/1000/60/60 >= 1 && diffTime/1000/60/60 < 24 ){
Log("周期:",diffTime/1000/60/60,"小时");
}else if(diffTime/1000/60/60/24 >= 1){
Log("周期:",diffTime/1000/60/60/24,"天");
}
Log("货币品种:",currency);
}
有兴趣的朋友可以测试一下。有更好的方法的欢迎跟帖。
这两天有空时在看python ,整体学习起来没什么难度,但是还是遇到不少问题,我都先记下。时间长了自己也可以复习复习,python的新手遇到同样的问题不用头大了 =_=!
如题: x = [1 for i in range(n)] 代表什么意思? 当初看到这里我也已经头大了,这样的语法似乎以前从没见过。猜来猜去,猜不出是什么意思。果断百度一下,百度也发现讲这个的不多。所幸还是找到了一些。
这是python的列表解析,含义就是形成一个从1到n的列表。关于列表解析可以看下面的描述: 1.定义和说明>Python 的强大特性之一是其对 list 的解析,它提供一种紧凑的方法,可以通过对 list 中的每个元素应用一个函数,从而将一个 list 映射为另一个 list。>列表解析,又叫列表推导式( list comprehension)>列表解析比 for 更精简,运行更快,特别是对于较大的数据,列表解析可以替代绝大多数需要用到 map和 filter的场合 列表推导式提供了一个创建链表的简单途径,无需使用 map() , filter() 以及 lambda 。以定义方式得到列表通常要比使用构造函数创建这些列表更清晰。每一个列表推导式包括在一个 for 语句之后的表达式,零或多个 for 或 if 语句。返回值是由 for 或 if 子句之后的表达式得到的元素组成的列表。如果想要得到一个元组,必须要加上括号。 2.基本列表解析基本 [x for x in range(5)] # [0, 1, 2, 3, 4]l1 = [1,2,3,4][ x*2 for x in l1] #[2,4,6,8] 多个值的[ ‘%s = %s’ for (k, v) in a_map.items()] 两次循环 l1 = [1,2,3,4] l2 = [1,2,3,4] [x+y for x in l1 for y in l2] [2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7, 8] 可以调用函数[ func(x) for x in l1] #等价于map 注意,列表解析不会改变原有列表的值,会创建新的list 3.条件列表解析[ x for x in range(100) if x%2 ==0 ] 4.、嵌套列表解析mat = [ [1, 2, 3],[4, 5, 6], [7, 8, 9]]交换行列[ [row[i] for row in mat] for i in (0,1,2)] #[[1, 4, 7], [2, 5, 8], [3, 6, 9]] 以上转自凌岳的CSDN博客文章。
i 在 range(n)的范围内循环,即 i=0,1,2,…,n-1,分别计算for之前的表达式的值,作为列表的项 表达式是1,对应的值分别为 1,1,1…,供n个1,生成了包含n个1的列表[1,1…]
x = [i for i in list] 将一个 list 映射为另一个 list,每个元素设为变量i x = [1 for i in range(n)] 将列表range(n)映射到列表x,每个元素设为常量1 欢迎访问forpython。com进行交流
昨天写了一个 python CTP商品期货均线的测试策略,老大让测试一下 python 的CTP商品期货回测系统。 今天继续测试发现策略完全没按照均线金叉死叉去开仓平仓操作,感觉一定有问题,逐个函数检查、测试,发现 交叉函数没有按照设计返回正确的值代码如下:
def Cross(records,fast,slow): # 交叉函数 ,参数是 records K线数据 、 fast 快线周期 、slow 慢线周期
global array_S_MA,array_F_MA # 使用外部的 全局变量
array_F_MA = TA.MA(records,fast) # 调用指标函数
array_S_MA = TA.MA(records,slow)
n = 0 # 返回的信号值 0:不操作 , 1 : 金叉 -1: 死叉
if array_F_MA[-2] > array_S_MA[-2] and array_F_MA[-3] < array_S_MA[-3] and array_F_MA[-4] < array_S_MA[-4]:
n = 1
return n
elif array_F_MA[-2] < array_S_MA[-2] and array_F_MA[-3] > array_S_MA[-3] and array_F_MA[-4] > array_S_MA[-4]:
n = -1
return n
怎么样?看到这看出来了吧,一个非常新手的错误! 我把 return n 写到了条件分支里面了,这个看似没什么问题。测试问题就来了,当不触发金叉、死叉的时候 Cross函数 会返回什么值呢?
定义一个测试函数,只输出一条信息
我们来调用一下,这样写,顺便看看None 是不是等于 -1
看看结果就明白了,函数中没有执行return时 取函数的返回值会得到 None ,None 也不等于 -1 , 但是判断None 小于 0 , 这个是 真值 。
比如这段代码,会报错:
function main(){
obj = {
exchange : null,
initAccount : null,
state : 0,
exchangeName : "",
}
obj.name = "OKCoin";
obj.exchange = exchange;
obj.initAccount = obj.exchange.GetAccount();
obj.state = 2;
var table = {
type : 'table',
title : '测试',
cols : ['obj属性名', '值'],
rows : [],
};
for(var k in obj){
table.rows.push([k, obj[k]]);
}
LogStatus('`' + JSON.stringify(table) + '`');
}
TypeError: Converting circular structure to JSON (这个错误虐我半个小时啊!),这个报错,在百度查了一下。是说代码里面有循环引用,JSON 无法解析。
想了半天,发现问题了,一定是因为 obj.exchange = exchange;
这句导致的循环引用,果断在for(var k in obj) 循环中遇到k === ‘exchange’ 的时候跳过去,试试。
代码如下:
function main(){
obj = {
exchange : null,
initAccount : null,
state : 0,
exchangeName : "",
}
obj.name = "OKCoin";
obj.exchange = exchange;
obj.initAccount = obj.exchange.GetAccount();
obj.state = 2;
var table = {
type : 'table',
title : '测试',
cols : ['obj属性名', '值'],
rows : [],
};
for(var k in obj){
if(k === 'exchange'){ // 增加的代码
continue;
}
table.rows.push([k, obj[k]]);
}
LogStatus('`' + JSON.stringify(table) + '`');
}
果然正常了,不过能看出是怎么循环引用的么?(暂时还有点糊涂,高手指点!)
原因是这样的:
具体的 positions 持仓信息对象的 type 属性 的各个值参看: https://www.fmz.com/bbs-topic/672
botvsing2 直接贴出来啊
小小梦 准备写很多,所以专门申请了个QQ 空间,这样看着也方便,好找。