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);
}
El código pegado no es bueno ~ puede parecer un poco descuidado, se puede pegar para ver dentro del texto sublime, antes de decir simplemente el problema, es que el código se escribe en el momento de la ejecución, se encuentra con una escena extraña, vea el gráfico:
Es extraño, la barra de progreso llega al 100% y se queda atascada, no se mueve, no está muerta, debería estar atascada. También utilizo varios métodos para probar, por ejemplo: limitar el número de ciclos, mostrar el número de ciclos, mostrar todo lo que se ejecuta hasta la última vez que el ciclo está atascado. Mirando el código del programa, siento que no debería haber ningún problema. Bautista no puede resolverlo. Después de todo, después de mucho tiempo, finalmente descubrí el problema, y esta es la razón. Cuando inició el gráfico, la secuencia de datos que escribí fue así:
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:[]} //......
]
En el programa, escribir los datos en un gráfico es como esto:
chart.add([1,[globalR......... (太长了 没写完) // 可以看到这里 我写入索引为1 的数据序列,就是add后面[ 符号后的 1,代表写入到{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]}, 这个序列中。问题就在这,我越过了索引0,直接写入索引1的数据序列里,就会导致卡死。
Así que lo cambié a:
series: [//系列
{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]},
{name:'wt2',type:'spline',yAxis:1,data:[]},
{type:'flags',onSeries:'wt',data:[]}
]
Todos los códigos que se escriben en el gráfico se cambian (principalmente 1 a 0).
chart.add([0,[globalRecords[globalRecords.length - 1].Time,globalRecords[globalRe..........(太长了。。。)
Es maravilloso, no se pega, funciona sin problemas. Aunque no se sabe exactamente por qué, la sensación es que debería ser un problema en la biblioteca de gráficos.
Hoy he actualizado el post porque algunos amigos en el grupo me han hecho preguntas, investigando, resolviendo, registrando. Si hay nuevos usuarios con dudas similares, es fácil explicar.
¿Por qué los precios de los futuros son diferentes de los precios reales?
Lo probé yo mismo, y es muy diferente. El inventor cuantificó el robot. La bolsa es OK futures, con las últimas tendencias del mercado obtenidas con GetTicker. En la página de Facebook de la empresa, se puede leer el siguiente artículo:
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);
}
}
El funcionamiento: Encontré que los tipos de cambio no son iguales, aquí obtuve el tipo de cambio con 2 funciones API diferentes.¿No es OK que los futuros utilicen su propio tipo de cambio?
En la página web de Facebook de la empresa, se puede encontrar una lista de los resultados obtenidos:Debido a que el precio en la página oficial de OK es de 1 dígito después de un decimal (el resto no aparece completo), se estima que habrá un pequeño error. Al ver que los resultados son básicamente iguales, no se puede estar seguro de que la diferencia entre el precio de mercado obtenido por GetTicker y el precio de mercado obtenido por OK Futures se debe a la incoherencia de los tipos de cambio.
/* 交互按钮 测试
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);
}
}
He probado el código anterior y no está disponible en la plaza, así que los amigos que quieran probarlo tendrán que añadir manualmente un botón interactivo.En el caso de los niños, el sistema de control es el siguiente:
Mira cómo funciona:
Por supuesto, la revisión de la estrategia no se puede probar, se requiere crear el propio robot, probar con el disco de simulación, pulsar el botón de interacción, y se marcará la operación correspondiente en el gráfico. Aquí se lanza un guión, se espera que todos escriban la política de 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);
}
Los amigos interesados pueden probar. Hay mejores maneras de hacer seguimiento.
Los dos días libres en el que estoy viendo Python, en general no es muy difícil aprender, pero todavía se encuentran con muchos problemas, primero tengo que recordar.
¿Qué significa x = [1 para i en rango (n) ]? Al principio, cuando vi esto, yo también me había crecido la cabeza, y parecía que nunca había visto una gramática así.
Esta es una lista de parálisis en Python, que significa formar una lista de 1 a n. Una de las características más potentes de Python es su resolución de listas, que ofrece un método compacto para asignar una función a cada elemento de una lista y así asignar una lista a otra list. La resolución de listas, también llamada comprensión de listas, es más eficiente y más rápida que la resolución de listas de for, especialmente para datos más grandes. La resolución de listas puede reemplazar la mayoría de los casos en los que se requiere el uso de mapas y filtros. 2. Lista básica para resolver la lista básica [x para x en rango ((5)] # [0, 1, 2, 3, 4] l1 = [1, 2, 3,4] [x*2 para x en l1] # [2, 4, 6,8] Varios valores de [
%s = %s for (k, v) in a_map.items (()) ] Así que el número de vueltas de l1 es [1, 2, 3, 4]. L2 es igual a [1, 2, 3, 4]. [x + y para x en l1 para y en l2] [2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7 y 8] Así que ahora vamos a ver si esto es cierto. Se puede llamar a la función [ func ((x) for x in l1] # equivalente a map Tenga en cuenta que el análisis de listas no cambia el valor de la lista original, sino que crea una nueva lista. 3. Parálisis de la lista de condiciones [ x para x en rango ((100) if x%2 == 0 ] 4., lista de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz de la matriz. Este es un artículo del blog de CSDN de Ling Yue.
i circula en el rango de range ((n), es decir, i = 0, 1, 2,..., n-1, respectivamente, calcula el valor de la expresión anterior for, como un elemento de la lista La expresión es 1, cuyos valores correspondientes son 1, 1, 1..., respectivamente, para n 1, que genera una lista que contiene n 1 [1, 1...]
x = [i para i en la lista] Mapear una lista a otra lista con cada elemento configurado como variable i x = [1 para i en el rango ((n) ] Mapear el rango de la lista ((n) a la lista x, con cada elemento establecido como una constante de 1. Bienvenido a forpython.com para hablar.
Ayer escribí una estrategia de prueba de la línea uniforme de futuros de productos de Python CTP, y el jefe me pidió que probara el sistema de retrospección de futuros de productos de Python CTP. Continuando con las pruebas de hoy, descubrimos que la estrategia no sigue en absoluto la línea uniforme de la horquilla de oro para abrir operaciones de liquidación. Las funciones cruzadas no devuelven el código de valor correcto según su diseño:
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
¿Cómo? ¿Ves esto, un error muy novedoso? He escrito el retorno n en la rama condicional, que parece ser un problema. ¿Cuál es el valor que devuelve?
Define una función de prueba que sólo produce un mensaje.
Así que vamos a llamar a esto y escribirlo así, por cierto, para ver si ninguno es igual a -1.
Cuando no se ejecuta return en la función, se obtiene el valor de retorno de la función: None, que tampoco es igual a -1, pero si se determina que None es menor a 0, este es el valor verdadero.
Por ejemplo, este código da un error:
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 (¡este error me ha costado media hora!), este error, que busqué en Baidu, significa que hay referencias circulares en el código y que JSON no se puede resolver.
Después de pensarlo durante medio día, descubrí el problema.obj.exchange = exchange;
La frase que da lugar a la referencia circular, decide saltar al pasado cuando se encuentra k ===
El código es el siguiente:
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) + '`');
}
Es normal, pero ¿puedes ver cómo se hace el ciclo de citas? (por ahora hay un poco de confusión, puntillas)
La razón es la siguiente:
Para ver los valores de las propiedades de tipo de los objetos de información almacenados de posiciones específicas:https://www.fmz.com/bbs-topic/672
- ¿Qué quieres decir?¿Qué es eso?
Un sueño pequeño.Estoy listo para escribir mucho, así que he solicitado un espacio QQ para que sea fácil de ver y encontrar.