Type/to search
8
Follow
1376
Followers
2.5 Exibição de interface, interação de estratégia de API
Tutorials
Created 2016-11-08 23:42:43  Updated 2019-08-01 09:25:38
 14
 6649

Interface de exibição, interação de estratégias de API


  • Função LogStatus: Informações são exibidas na barra de status acima do log (tabela, cadeia de caracteres multilínea, imagem).

    Descrição da documentação da API:

LogStatus(Msg) 此信息不保存到日志列表里, 只更新当前机器人的状态信息, 在日志上方显示, 可多次调用, 更新状态 LogStatus('这是一个普通的状态提示'); LogStatus('这是一个红色字体的状态提示 #ff0000'); LogStatus('这是一个多行的状态信息\n我是第二行'); LogStatus支持打印base64编码后的图片, 以"`"开头, 以"`"结尾, 如LogStatus("`data:image/png;base64,AAAA`") var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}; LogStatus('`' + JSON.stringify(table)+'`'); // JSON序列化后两边加上`字符, 视为一个复杂消息格式(当前支持表格) LogStatus('第一行消息\n`' + JSON.stringify(table)+'`\n第三行消息'); // 表格信息也可以在多行中出现 LogStatus('`' + JSON.stringify([table, table])+'`'); // 支持多个表格同时显示, 将以TAB显示到一组里

E talvez alguém me pergunte, se eu já tenho uma função Log para expor informações, por que usar a função LogStatus?
Resposta: Há uma especialização, há situações em que a função Log tem uma vantagem, e há situações em que a função LogStatus é mais adequada. Por exemplo, quando o retorno ou o disco rígido, eu quero ver as mudanças nas variáveis internas da estratégia.

Em seguida, vamos familiarizar-nos com o uso da função LogStatus através de uma série de testes de código, para que a estratégia tenha uma boa exibição.

function main(){ LogStatus("状态栏显示文本!"); // 在状态栏上显示一行文本 }

Resultados do backtesting:

img

Podemos tentar adicionar um trocador de linha. Modificar o LogStatus ("A barra de status mostra o texto!"); para o LogStatus ("A barra de status mostra o texto!\n A segunda linha de texto");

Resultados do backtesting:
img

A seguir, adicionamos alguns parâmetros de variáveis após a função LogStatus.

function main(){ var num = 10; // 声明一个 数值 var str = "ABC"; // 声明一个 字符串 var obj = { // 声明一个 对象 name: "tom", age: 14 }; var array = [1,2,5,4,7]; // 声明一个 数组 LogStatus("状态栏显示文本!\n 第二行文本", num, str, obj, array); // 在状态栏里面把以上变量当做参数传入。 }

O backtesting mostra:
img

A função LogStatus, além de exibir texto e variáveis, também pode ser exibida como uma tabela. Isso permite que os valores da política sejam mais ordenados.

function main(){ // 我们就直接复制API 上的代码来测试。 var table = { // 在状态栏显示表格需要一个对象, 我们这里声明一个 对象叫 table type: 'table', // 对象必须有这个属性。 title: '持仓信息', // 这个是表格的标题 cols: ['列1', '列2'], // 这个是表格表头 rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']] // 这里是具体的表格内的单元格。 // ['abc', 'def'] 对应的是第一行内容, ['ABC', 'support color #ff0000'] 对应的是第二行内容, // 在文本后加上#ff0000 十六进制颜色值可以设置当前位置文本的颜色(很多地方适用)。 }; // 设置好想要显示的数据了,下面调用 LogStatus 就可以显示出来了。 LogStatus('`' + JSON.stringify(table) + '`'); // 设置好table ,调用JSON.stringify函数把table对象序列化,再作为参数传入LogStatus函数。 // 注意 参数前后要加上 字符 ` ,这个字符就是键盘TAB键上边的和 ~ 字符 同一个按键。 }

img

Também é possível exibir duas tabelas ao mesmo tempo, ampliando muito a capacidade da caixa de status, e há algumas estratégias de multi-variedades e multi-mercados para não ter medo de exibir dados sem localização!

function main(){ // 我们就直接复制API 上的代码来测试。 var table = { // 在状态栏显示表格需要一个对象, 我们这里声明一个 对象叫 table type: 'table', // 对象必须有这个属性。 title: '持仓信息', // 这个是表格的标题 cols: ['列1', '列2'], // 这个是表格表头 rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']] // 这里是具体的表格内的单元格。 // ['abc', 'def'] 对应的是第一行内容, ['ABC', 'support color #ff0000'] 对应的是第二行内容, // 在文本后加上#ff0000 十六进制颜色值可以设置当前位置文本的颜色(很多地方适用)。 }; var table2 = { // 第二个表格 type: 'table', title: '第二个表格', cols: ['cols1', 'cols2', 'cols3'], rows: [ ['1', '2', '3'], ['A', "B#FF5634", 'C'], ['一', '二', '三']] }; // 设置好想要显示的数据了,下面调用 LogStatus 就可以显示出来了。 LogStatus('`' + JSON.stringify([table, table2]) + '`'); // 注意 参数前后要加上 字符 ` ,这个字符就是键盘TAB键上边的和 ~ 字符 同一个按键。 }

img
O texto pode ser exibido ao mesmo tempo na parte de baixo do formulário (individual ou múltipla).

把上边代码中LogStatus('`' + JSON.stringify([table, table2]) + '`'); 这句, 替换为 LogStatus( "表格上一行 \n" + '`' + JSON.stringify([table, table2]) + '`' + "\n 表格下一行"); 可以在表格上下显示文本。

O backtesting mostra:
img

Agora vamos ver se as imagens também podem ser exibidas na barra de status, mas vamos tratar disso.

//LogStatus支持打印base64编码后的图片, 以"`"开头, 以"`"结尾, 如LogStatus("`data:image/png;base64,AAAA`") //网上有转换工具,比如这个网站: http://tool.css-js.com/base64.html 。 //选择图片转换后的代码直接替换掉 LogStatus("`data:image/png;base64,AAAA`")中的 `data:image/png;base64,AAAA` 就可以了。

img
Veja o código:

function main(){ LogStatus("`data:image/jpg;base64,/9j/4AAQSkZJRgABAQEA... // 太长了省略了 ,编辑器差点崩了。 }

Observação: data precede `O blogueiro também escreveu sobre o assunto: "O que é um símbolo?
img
E o original pode ser em formato GIF, cool!

  • Função Chart: traçar gráficos.

    Descrição da documentação da API:

Chart({...}) 图表绘图函数 参数为可以JSON序列化的HighStocks的Highcharts.StockChart参数, 比原生的参数增加一个__isStock属性, 如果指定__isStock: false, 则显示为普通图表 返回对像可以调用add([series索引(如0), 数据])向指定索引的series添加数据, 调用reset()清空图表数据, reset可以带一个数字参数, 指定保留的条数 可以调用add([series索引(如0), 数据, 此数据在series中的索引])来更改数据 可以为负数, -1指最后一个, -2是倒数第二个, 如: chart.add([0, 13.5, -1]), 更改series[0].data的倒数第一个点的数据 HighStocks: http://api.highcharts.com/highstock

** O inventor da quantificação do sistema fornece uma interface de gráficos para a estratégia: Chart, que inclui a biblioteca de gráficos HighCharts, para que os colegas interessados possam ver. A função Chart permite que a estratégia gere um gráfico (por enquanto só pode gerar um).
Site oficial do Highcharts

Quando eu era estudante, a função triangular me impressionou muito, então vamos desenhar uma curva sine e cosine, e a codificar como segue:

var chart = { // 用于初始化 图表的对象 title: {text: "line数值触发 plotLines 值"}, // 图表标题 yAxis: { // Y轴 相关 设置 plotLines: [{ // 垂直于Y轴的 水平线, 用作触发线, 是一个结构数组, 可以设置多条触发线。 value: 0, // 触发线的值,设置多少 这条线就在相应的数值位置显示。 color: 'red', // 设置触发线的颜色 width: 2, // 宽度 label: { // 显示的标签 text: '触发值', //标签文本 align: 'center' //标签位置 居中 }, }], }, xAxis: {type: "datetime"}, // X轴相关设置, 这里设置类型是 时间轴 series: [{name: "sin", type: "spline", data: []}, {name: "cos", type: "spline", data: []}] // 这个是比较重要的数据系列,可以设置多个数据系列,根据数组索引控制 }; function main(){ var pi = 3.1415926535897; // 圆周率 var time = 0; // 用于记录时间戳的变量 var angle = 0; // 角度 var y = 0; // 坐标y值 , 用于接收 正弦值、余弦值 var objChart = Chart(chart); // 调用API 接口 用chart 对象初始化 图表 objChart.reset(); // 初始清空图表 chart.yAxis.plotLines[0].value = 1; // 设置触发线的值为1 while(true){ // 循环 time = new Date().getTime(); // 获取当前时刻的时间戳 y = Math.sin(angle * 2 * pi / 360); // 每 5000ms 角度 angle 增加 5 度,计算正弦值。 objChart.add(0, [time, y]); // 把计算出来的y 值写入图表 相应索引的数据系列 add 函数第一个参数 为 指定的索引 y = Math.cos(angle * 2 * pi / 360); // 计算余弦值 objChart.add(1, [time, y]); objChart.update(chart); // 增加新数据后,更新图表。 angle += 5; // 增加5度 Sleep(5000); // 暂停5秒 ,一面画图太频繁,数据增长过快。 } }

O backtesting mostra:
img

  • Interação estratégica

    Descrição da documentação da API:

交互类 按钮开关, 字符串, 数字型, 布尔型, 选择型 [ 按钮型 :A button with name 字符串 :String 数字型 :Number 布尔型 :true或者false 选择型 :用'|'分开, 如aa|bb|cc表示列表有三个选项, 对应值为0,1,2 ] 如果为按钮, 则发送"按钮名称"做为命令, 其它发送"按钮名称:参数值", 被GetCommand()接收, 如果按钮描述为"@"则隐藏描述, 只显示按钮

Eu escrevi uma função get_Command para lidar com interações de interface, os controles interativos usados são o tipo de dígito e o tipo de botão, então a função usa esses dois tipos para testar, e os colegas interessados em outros tipos de controles podem se expandir, o código-fonte é o seguinte:

function get_Command(){//负责交互的函数,交互及时更新 相关数值 ,熟悉的用户可以自行扩展 var keyValue = 0;// 命令传来的参数 数值 var way = null; //路由 var cmd = GetCommand(); //获取 交互命令API if (cmd) { Log("按下了按钮:",cmd);//日志显示 arrStr = cmd.split(":"); // GetCommand 函数返回的 是一个字符串,这里我处理的麻烦了,因为想熟悉一下JSON //,所以先对字符串做出处理,把函数返回的字符串以 : 号分割成2个字符串。储存在字符串数组中。 if(arrStr.length === 2){//接受的不是 按钮型的,是数值型。 jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新 //拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。 jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象 for(var key in jsonObj){ // 遍历对象中的 成员名 keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值 } if(arrStr[0] == "upDateAmount"){// 此处为 数字型 。这里处理分为 按钮 和 数字型 。 详见 策略参数 设置界面 下的 交互设置 way = 1; } if(arrStr[0] == "扩展1"){ way = 2; } if(arrStr[0] == "扩展2"){ way = 3; } if(arrStr[0] == "扩展3"){ way = 4; } }else if(arrStr.length === 1){// 此处为 按钮型 //路由 if(cmd == "cmdOpen"){ way = 0; } if(cmd == "cmdCover"){ way = 5; } }else{ throw "error:" + cmd + "--" + arrStr; } switch(way){ // 分支选择 操作 case 0://处理 发出开仓信号 tiaojian = 1; break; case 1://处理 Amount = keyValue;//把交互界面设置的 数值 传递给 Amount Log("开仓量修改为:",Amount);//提示信息 break; case 2://处理 break; case 3://处理 break; case 4://处理 break; case 5://处理 发出平仓信号 tiaojian = 2; break; default: break; } } }

Em seguida, aplicamos essa função dentro da estratégia para ver o que funciona, e testamos o código da seguinte forma:

var isOpen = false; // 是否 开仓 var price = 0; // 全局变量 价格 var amount = 0; // 全局变量 下单量 // 函数 function get_Command(){//负责交互的函数,交互及时更新 相关数值 ,熟悉的用户可以自行扩展 var keyValue = 0;// 命令传来的参数 数值 var way = null; //路由 var cmd = GetCommand(); //获取 交互命令API if (cmd) { Log("按下了按钮:",cmd);//日志显示 arrStr = cmd.split(":"); // GetCommand 函数返回的 是一个字符串,这里我处理的麻烦了,因为想熟悉一下JSON //,所以先对字符串做出处理,把函数返回的字符串以 : 号分割成2个字符串。储存在字符串数组中。 if(arrStr.length === 2){//接受的不是 数值型的,是按钮型的。 jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新 //拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。 jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象 for(var key in jsonObj){ // 遍历对象中的 成员名 keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值 } if(arrStr[0] == "UpdatePrice"){// 此处为 数字型 。这里处理分为 按钮 和 数字型 。 详见 策略参数 设置界面 下的 交互设置 way = 1; } if(arrStr[0] == "UpdateAmount"){ way = 2; } if(arrStr[0] == "扩展2"){ way = 3; } if(arrStr[0] == "扩展3"){ way = 4; } }else if(arrStr.length === 1){// 此处为 按钮型 //路由 if(cmd == "isOpen"){ way = 0; } if(cmd == ""){ way = 5; } }else{ throw "error:" + cmd + "--" + arrStr; } switch(way){ // 分支选择 操作 case 0://处理 isOpen 按钮 isOpen = true; break; case 1://处理 UpdatePrice 控件 price = keyValue; break; case 2://处理 UpdateAmount 控件 amount = keyValue; break; case 3://处理 break; case 4://处理 break; case 5://处理 break; default: break; } } } function main(){ while(true){ get_Command(); // 调用 自己实现的 get_Command 函数。 LogStatus("当前的开仓信息 ----> price:", price, "amount:", amount, "isOpen:", isOpen); // 在状态栏显示当前设定的开仓价格,开仓数量。 if(isOpen === true){ Log("buy ", amount, "个BTC", "按价格:", price, "下单。"); // 模拟下单 isOpen = false; // 下单后重置 } Sleep(2000); } }

img
img

Veja o resultado do simulador:
Iniciação sem qualquer operação.

img

Vamos definir o preço de compra e a quantidade de compra simulados: preço para 1000, quantidade para 1.

img

Veja as mudanças:

img

Continuem a modificar o "amount" e vejam.

img

Related Recommendations
Comment
All comments (14)

    有个问题是,好像每次按按钮后不是立即响应,要等一个while循环的时间,而且如果一个循环周期内产生了多次点击事件,每个循环只能响应其中的一个点击事件,请问这是什么原因造成的?可以解决么

    4 years ago

    您好,这个交互过程是,浏览器页面上点击,发送请求到FMZ平台,FMZ平台发送交互指令到实盘,所以这个过程有时间消耗。所以是有可能要等一个循环的。这个事件是队列的,如果点击多次,GetCommand函数会逐个捕获。因为可能你的策略代码设计的是一次轮询GetCommand一次,所以就响应一个点击事件。

    4 years ago

    LogStatus() 函数在状态栏的输出是覆盖式的吗?如果两条 LogStatus() 语句中间没有足够长的 Delay 的话,是不是前一条的输出就看不到了?

    8 years ago

    是的 ,这个LogStatus 是 覆盖刷新 的。另外 页面 上有刷新 频率,如果 您 程序 轮寻 很快,可能有些 信息 是来不及显示出来,就会覆盖的。

    8 years ago

    明白了,谢谢!

    8 years ago

    策略交互例子中,

    javascript
    jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; jsonObj = JSON.parse(jsonObjStr); for(var key in jsonObj){ keyValue = jsonObj[key]; }

    这段代码的意义是什么?keyValue 不就是 arrStr[1] 吗?

    8 years ago

    测试传入string类型的数据,json解析会有问题,SyntaxError: invalid json (at offset 9) get_Command FILE:79 main FILE:138,但是在传入的控件上,自己在字符串的两端加上双引号,那么json就能正确解析了

    9 years ago

    有具体 例子代码么 ?我研究下。

    9 years ago

    看的头都大了,为啥看不懂

    9 years ago

    这个时候要耐心 一点一点看,边看边动手 试试, 总结,看完了 基本都做过一遍了,用到的时候 就得心应手了,不会无所适从。

    9 years ago

    添加下拉框类型时,提示 下拉框类型必须是以 "

    9 years ago

    第一项|第二项|第三项 这样设置的 和参数上的下拉框一样

    9 years ago

    梦总,请教两个问题:

    1. 策略交互和策略参数两部分有什么区别?
    2. 我用教程中的Js代码并且添加了策略交互中的参数,然后使用模拟回测 以及 机器人托管运行,都没有出来图中的策略交互的控制界面,这个界面是如何在回测中显示出来的?
    3. 发现放到策略参数里面才有效,但策略参数里面没有button型,无法运行那个开仓
    4. 引用的模板里面可以有其他模板的交互元素,这是什么原理?
    9 years ago

    您好~ 感谢提供了 很多 python 测试代码 ^^
    1、策略参数是 策略启动时对 策略一些变量 、设置 的设定。策略交互 则是 在策略运行中,通过API 函数 GetCommand 实时获取 策略交互控件的触发。
    2、回测中 因为速度很快 ,时间序列是很快变化的,所以 交互控件 是无法使用的。只在实盘有效。策略添加交互控件以后在实盘机器人页面就会显示出:
    img

    9 years ago
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)