The inventor's quantitative chemistry diary (II) (completed)

Author: The Little Dream, Created: 2016-05-22 20:05:36, Updated: 2019-08-01 10:31:58

A few days ago, after solving a few problems, when writing code for clients, I felt it was necessary to write a chart template that showed indicators (especially the indicators I wrote), trading positions, etc. Since I am also a beginner, I am not familiar with highcharts, but I saw an example of a commodity futures with a Z-size, I feel that the cat should be able to do it.

Question one:

 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);
}

The code is not good - it may look a little bit blurry, you can paste it to get sublime text inside, first of all, simply say the problem, is that the code is written at run time, encounters a strange scene, look at the picture:

It's strange, the progress bar goes to 100% and it's stuck, it's not moving, it's not fake dead, it should be stuck. I also used various methods to test, for example: limiting the number of cycles, showing what the number of cycles is, showing what is running until the last cycle is stuck dead. I looked at the program code and I thought there should be no problem. I couldn't figure it out. I worked on it for a long time and finally found the problem. When I initialized the graph, I wrote the data sequence like this:

 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:[]}   //......
        ] 

The program writes the data into a graph like this:

  chart.add([1,[globalR.........    (太长了 没写完)      //   可以看到这里 我写入索引为1 的数据序列,就是add后面[ 符号后的 1,代表写入到{type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]},  这个序列中。问题就在这,我越过了索引0,直接写入索引1的数据序列里,就会导致卡死。

So I changed it to:

  series: [//系列
        {type:'candlestick',yAxis:0,name:'K',id:'wt',data:[]},
        {name:'wt2',type:'spline',yAxis:1,data:[]},
        {type:'flags',onSeries:'wt',data:[]}
        ]  

All the code that is written to the graph is changed (mainly 1 to 0).

 chart.add([0,[globalRecords[globalRecords.length - 1].Time,globalRecords[globalRe..........(太长了。。。)

It's amazing, it doesn't stick, it runs without problems. Although I don't know what the exact cause is, I feel it should be a problem in the chart library.


Question two

Today I updated the post because a friend in the group asked a question, researched it, solved it, recorded it. If new users have similar doubts, please explain.

Getticker gets the price of the futures why is it different from the actual price?img

I tested it myself and it's really different. The inventor quantified the robot. The exchange is OK futures, the latest market price obtained with GetTicker. I wrote a piece of code to test specifically:

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);
    }
}

How it works:img imgI'm trying to get the exchange rate here using two different API functions. (OK, on the official futures website, you can set the exchange rate to yuan)imgI've seen the introduction of the API, OK futures are not using their own exchange rate?

If you want to see the results of the calculation, you can do it yourself and check it out!imgSince the price on OK's official website is only 1 digit after the decimal (the rest are not shown in full), it is estimated that there will be a slight error. Seeing that the results are basically the same, it is not entirely certain that the market price obtained by GetTicker and the difference on the OK futures website is probably due to the inconsistency of the exchange rate.


Question 3: Bitcoin OKcoin Platform Market List Question (This question has been adjusted and now unifies the market list at the time of retesting and the real-time market list. The second parameter for buying and selling is the amount of RMB, and the second parameter for selling is the number of items on the list.https://www.fmz.com/bbs-topic/474


Question 4: Late last night, a friend asked me where I could find an example of how to use the interaction button strategy, and I thought, just write and practice, and by the way, learn together, the old way, code first!

/* 交互按钮 测试
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);
    }
}

I've tested the above code, it's not publicly available in the square, so if you want to test it, you need to add an interactive button manually.imgIn this case, you can do it as shown above.

Here's a look at how it works:

img img

Of course, it is not possible to test the policy retesting, you need to create your own robot, test it with the analogue disk, click the interaction button, and the corresponding operation will be marked on the chart.


Question 5: A user asks how to get the name of the currently operating e-currency and how to get the current K-line cycle. I have solved the problem of getting the current K-line cycle using a comparatively clever method.

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);
}

Friends interested can try it. Welcome to follow for better ways.


Question 6: If you do not understand the functionality added to the new Commodity Futures Trading Library, you can share the new annotated version of the code to the QQ group.

  • The strategy template can be copied at Strategy Square.img

Question 7: What does x = [1 for i in range ((n)) ] mean?

  • I've been reading python for two days, and I'm not having any trouble learning it, but I'm still having a lot of problems. I'll keep that in mind.

    Question: What does x = [1 for i in range ((n)) ] mean? When I first saw it, I was already a grown-up, and it seemed like I had never seen such a grammar before. Guess what, guess what, guess what it means.

This is a list parsing in Python, meaning to form a list from 1 to n. One of the strongest features of Python is its list parsing, which provides a compact way to map a list to another list by applying a function to each element in the list. List comprehension is more streamlined and faster than for, especially for larger data, and can replace most cases where maps and filters are needed. List derivation provides a simple way to create links without using map, filter, and lambda. 2. Basic list parsing basic [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] Multi-valued [ %s = %s for (k, v) in a_map.items (()) ] Two cycles l1 is equal to [1, 2, 3, 4]. L2 is equal to [1, 2, 3, 4]. [x+y for x in l1 for y in l2] So let's say that we have two, three, four, five, three, four, five, six, four, five, six, seven, five, six, seven, eight You can call the function [ func ((x) for x in l1] # equivalent to map Note that list parsing does not change the value of the original list, but creates a new list. 3. Condition list parsing [ x for x in range ((100) if x%2 == 0 ] 4., nested list parse mat = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]] swap arrays [ [row[i] for row in mat] for i in (0, 1, 2) ] # [[1, 4, 7], [2, 5, 8], [3, 6, 9]] The above is taken from the CSDN blog post by Ling Yue.

To be honest, I don't understand the above, but it seems a little clear conceptually that the sentence should have some kind of iterative function.
See also other enthusiastic help:

i is cycled over the range ((n), i.e. i = 0, 1, 2,..., n-1, respectively, the value of the expression before computing for, as the item in the list The expression is 1, the corresponding values are 1, 1, 1..., for n 1, and produces a list containing n 1s [1, 1...]

This seems to be clearer, let's see.

x = [i for i in list] Map a list to another list, each element set to a variable i x = [1 for i in range ((n) ] Map list range ((n) to list x, with each element set to constant 1 Welcome to forpython.com for discussion

Problem 8: Python foundation is not solid, returned neglected for half a day, see below for the problem

Yesterday, I wrote a test strategy for the Python CTP Commodity Futures Equilibrium, and my boss asked me to test the Python CTP Commodity Futures Retesting System. Today we continue to test and find that the strategy is completely not in line with the straightforward gold fork dead fork to open the stock and feel there must be a problem, check, test, find each function. The cross function does not return the correct value code as designed:

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

How? See this, a very newbie mistake! I wrote the return n in the conditional branch, which seems to be no problem. What is the value that will be returned?

We did a little experiment:

img

Define a test function that will output only one message

img

So let's call it, let's write it like this, and let's see if none is equal to negative 1.

img

It is clear from the results that when the function does not execute return, the function returns None, and None is not equal to −1, but if None is less than 0, this is true.

Question 9: The JS loop reference problem.

For example, this code will give an 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 (this error took me half an hour!), This error was checked on Baidu.

After half a day of thinking, I found the problem.obj.exchange = exchange;The resulting loop reference jumps past, tries, and tries when k === is encountered in the for ((var k in obj) loop.

The code is as follows:

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

It's okay, but can you see how the citation is being cycled?

Question 10: Commodity futures Open position, hold position on Friday evening, after opening the market on the following Monday, call the GetPosition function Get hold information, why

img

The reason is as follows:

img

For the specific values of the type attribute of the positions stored information object, see:https://www.fmz.com/bbs-topic/672

Seeing this, I feel like I should start practicing... what about you?

More

botvsing2It's a direct link.

The Little DreamI'm ready to write a lot, so I applied for a QQ space, so it's easy to see and find.