Diario de aprendizaje de química cuantitativa del inventor (II) (Completado)

El autor:Un sueño pequeño., Creado: 2016-05-22 20:05:36, Actualizado: 2019-08-01 10:31:58

Hace unos días, después de resolver algunos problemas, cuando escribí el código para el cliente, sentí la necesidad de escribir una plantilla de gráficos que mostraran indicadores (especialmente indicadores escritos por mí mismo), posiciones de negociación, etc. Como soy un principiante, no estoy familiarizado con los highcharts, pero vi un ejemplo de un futuro de productos de Z, siento que el tigre de fotografía debe ser capaz de resolverlo.

¿Qué es lo que está pasando?

 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.


El problema 2

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?img

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:img imgEncontré que los tipos de cambio no son iguales, aquí obtuve el tipo de cambio con 2 funciones API diferentes.img¿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:imgDebido 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.


Problema 3: Precio de la lista de mercado de la plataforma Bitcoin OKcoin (este problema ha sido ajustado y ahora se unifica el precio de la lista de mercado en tiempo real y el precio de la lista de mercado en tiempo real).https://www.fmz.com/bbs-topic/474


Pregunta 4: A última hora de la noche, un amigo me preguntó dónde estaba el ejemplo de uso de la estrategia de los botones de interacción, y pensé, simplemente escriba y practique, por cierto, para que todos aprendan juntos, el viejo método, primero el código.

/* 交互按钮 测试
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.imgEn el caso de los niños, el sistema de control es el siguiente:

Mira cómo funciona:

img img

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.


Pregunta 5: Un usuario pregunta cómo obtener el nombre de la moneda electrónica que está operando actualmente y cómo obtener el ciclo de la línea K actual. Obtener la moneda de la bolsa actual tiene una función API disponible, y he resuelto el problema de obtener el ciclo de la línea K con una forma más ingeniosa.

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.


Pregunta 6: Si no entiende las funciones añadidas a la nueva biblioteca de commodity futures, puede compartir el código de la nueva versión de comentarios con el grupo QQ.

  • La plantilla de estrategia se puede copiar en la Plaza de la Estrategia.img

Pregunta 7: ¿Qué significa x = [1 para i en rango ((n)) ]?

  • 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.

A decir verdad, no entiendo mucho lo anterior, pero conceptualmente parece un poco claro que la frase debería tener algún tipo de función de repetición.
En la página web de la organización, se puede leer más:

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...]

Esto parece más claro, vamos a ver.

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.

Problema 8: Python no tiene una base sólida, fue devuelto, se pasó medio día sin hacer nada, vea el problema a continuación.

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?

¿Qué es lo que está sucediendo?

img

Define una función de prueba que sólo produce un mensaje.

img

Así que vamos a llamar a esto y escribirlo así, por cierto, para ver si ninguno es igual a -1.

img

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.

Pregunta 9: ¿Qué pasa con las referencias circulares de JS?

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) + '`');
}

img

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 === exchange en el ciclo for ((var k in obj)).

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) + '`');
}

img

Es normal, pero ¿puedes ver cómo se hace el ciclo de citas? (por ahora hay un poco de confusión, puntillas)

Pregunta 10: Futuros de productos El viernes por la noche, abrir posiciones, mantener posiciones, después de la apertura del mercado el próximo lunes, llamar a la función GetPosition Obtener información sobre las posiciones y por qué

img

La razón es la siguiente:

img

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

Al ver esto, me siento como si me hubiera puesto a la práctica... ¿Y tú?

Más.

- ¿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.