Playing JavaScript with the old man - creating a buyer/seller partner and developing the tool code used by the robot

Author: The Little Dream, Created: 2017-03-15 11:22:52, Updated: 2017-10-11 10:37:43

Playing JavaScript with the old man, creating a partner who will buy and sell.


In the process of developing robots, many small code fragments have been accumulated, some of which can be used in their own quantitative strategy program, where the old man brings out some of the code he wrote to throw the quotation marks, as a comparison dish for beginners.

  • 1, converting any k-line cycle

    This code module is not written as a class library, but only writes a function, which can be modified and extended later. The function is to synthesize large cycles of K-line data based on the basic K-line data of a certain cycle. When you are watching the market or using the platform writing strategy, the default is the K-line of commonly used cycles, such as 1 day, 1 hour, 1 minute, etc. If you need to process data from other cycles, such as 4 hours, 6 hours, 8 hours K-line, then you need to do it yourself. The source code is:https://www.fmz.com/strategy/35986

    // K线周期合成  扩展为 根据基础K线 合成 为任意周期。
    

var cloneObj = function ((obj) { // Deep copy of the object function var str, newobj = obj.constructor === Array? [] : {}; if (typeof obj!== object) { return; } else if (JSON) { str = JSON.stringify ((obj); // object to be serialized newobj = JSON.parse ((str); // is rendered } else { for (var i in obj) { newobj[i] = type of obj[i] === Object type? cloneObj ((obj[i])): obj[i]; cloneObj is a clone of Obj (i) and Obj is a clone of Obj. I'm not sure. I'm not sure. return newobj; I'm not sure. What do you think? var DAY = 0; var HOURS = 1; var MINUTES = 2; var isFirstFind = true; var FirstStamp = null; What do you think? function GetDHM ((objTime, BaseCycle, NewCycleForMS) {) is a function that can be used to generate a function. var ret = []; if ((BaseCycle % (1000 * 60 * 60 * 24) === 0) { ret[0] = objTime.getDate (); and ret[1] = day; }else if ((BaseCycle % (1000 * 60 * 60) === 0) { Ret[0] = objTime.getHours (); ret[1] = HOURS; }else if ((BaseCycle % (1000 * 60) === 0) { ret[0] = objTime.getMinutes (); ret[1] = MINUTES; I'm not sure. if ((NewCycleForMS % (1000 * 60 * 60 * 24) === 0) { ret[2] = DAY; }else if ((NewCycleForMS % (1000 * 60 * 60) === 0) { ret[2] = HOURS; }else if ((NewCycleForMS % (1000 * 60) === 0) { ret[2] = MINUTES; I'm not sure. return ret; I'm not sure. What do you think? Search functionFirstTime ((ret, BaseCycle, NewCycleForMS) {) is a function that can be used to search for new cycles. if ((ret[1] === DAY && ret[2] === DAY) { var array_day = []; for ((var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)) { array_day.push ((i); I'm not sure. for ((var j = 0 ; j < array_day.length; j++)) { if ((ret[0] === array_day[j]) { return true; I'm not sure. I'm not sure. }else if(ret[1] === HOURS && ret[2] === HOURS) { var array_hours = []; for ((var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)) { array_hours.push ((i); I'm not sure. for ((var j = 0 ; j < array_hours.length ; j++) { if ((ret[0] === array_hours[j]) { return true; I'm not sure. I'm not sure. }else if(ret[1] === MINUTES && ret[2] === MINUTES) { var array_minutes = []; for ((var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)) { array_minutes.push (i); I'm not sure. for ((var j = 0; j < array_minutes.length; j++) { if ((ret[0] === array_minutes[j]) { return true; I'm not sure. I'm not sure. Other throw the target cycle and the base cycle do not match! target cycle milliseconds: throw + NewCycleForMS + " Base cycle milliseconds: " + BaseCycle; I'm not sure. I'm not sure. What do you think? function Calc_High ((AssRecords, n, BaseCycle, NewCycleForMS) {) var max = AssRecords[n].High; for ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) { Max = Math.max ((AssRecords[n + i].High, max) is the name of the file. I'm not sure. return max; I'm not sure. What do you think? function Calc_Low ((AssRecords, n, BaseCycle, NewCycleForMS) {) is the name of the function var min = AssRecords[n].Low; for ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) { min = Math.min ((AssRecords[n + i].Low, min); I'm not sure. return min; I'm not sure. What do you think? function AssembleRecords ((records, NewCycleForMS) {) is a function that can be used to assemble var AssRecords = records.slice ((0); // deep copy var AfterAssRecords = [];

if(!records || records.length < 2){
    throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2";
}
var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time;
if(NewCycleForMS % BaseCycle !== 0){
    throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!";
}
if(NewCycleForMS / BaseCycle > records.length){
    throw "基础K线数量不足,请检查是否基础K线周期过小!";
}

// Determine the time delay, find the start time of the base K line relative to the target K line. var objTime = new Date (); for (var i = 0; i < AssRecords.length; i++) { ObjTime.setTime ((AssRecords[i].Time) is the name of the object. var ret = GetDHM ((objTime, BaseCycle, NewCycleForMS)); and

    if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) {
        FirstStamp = AssRecords[i].Time;
        for (j = 0; j < i; j++) {
            AssRecords.shift();        // 把目标K线周期前不满足合成的数据排除。
        }
        isFirstFind = false;
        break;                         // 排除后跳出
    }else if(isFirstFind === false){
        if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){
            for (j = 0; j < i; j++) {
                AssRecords.shift();    // 把目标K线周期前不满足合成的数据排除。
            }
            break;
        }
    }
}
var BarObj = {                         // 定义一个 K线柱结构
    Time: 0,
    Open: 0,
    High: 0,
    Low: 0,
    Close: 0,
    Volume: 0,
};
var n = 0;
for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) {     // 合成
    /*
    {
    Time    :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样
    Open    :开盘价
    High    :最高价
    Low :最低价
    Close   :收盘价
    Volume  :交易量
    }
    */
    BarObj.Time = AssRecords[n].Time;
    BarObj.Open = AssRecords[n].Open;
    BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); 
    BarObj.Low =  Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); 
    BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close;
    BarObj.Volume = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Volume;
    AfterAssRecords.push(cloneObj(BarObj));
}

BarObj.Time = AssRecords[n - (NewCycleForMS/BaseCycle) ].Time + NewCycleForMS; // The last time cannot be changed, and the last time cannot be changed. BarObj.Open = AssRecords[n].Open; and BarObj.Close = AssRecords [AssRecords.length - 1].Close; BarObj.Volume = AssRecords[AssRecords.length - 1].Volume; var max = AssRecords[n].High; var min = AssRecords[n].Low; for ((var index_n = n + 1 ;index_n < AssRecords.length; index_n++) { Max = Math.max ((max, AssRecords[index_n].High) is the name of the file. min = Math.min (min, AssRecords[index_n].Low); I'm not sure. BarObj.High = max; BarObj.Low = min; AfterAssRecords.push ((cloneObj ((BarObj)));

return AfterAssRecords;

I'm not sure. What do you think? function main() { // test code while(!exchange.IOThis is the same as the LogStatus ((((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) I'm not sure. var Info = _C ((exchange.SetContractType, hydrogen MA705); // synthesis of K-line data from the test methanol 705 contract var records = exchange.GetRecords (); while (!records.length < 24) { records = exchange.GetRecords (); I'm not sure.
// handles the interface parameters, which you can refer to if you write your own policy. var Num_UI_NewCycleForMS = 1; var arrayNum = UI_NewCycleForMS.split (("*"); for ((var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++) { Num_UI_NewCycleForMS = Num_UI_NewCycleForMS * Number ((arrayNum[indexNum]); and I'm not sure. Log ( custom cycle millisecond time is: , Num_UI_NewCycleForMS);
while ((true) { records = _C (exchange.GetRecords); // Log (( raw K-line data: length bars, records.length, data bars: bars, records); records = AssembleRecords ((records, Num_UI_NewCycleForMS); // The first parameter is the base K line, the second parameter is the milliseconds of the cycle to be converted, 1000 * 60 * 20 which is converted to 20 minutes // Log (after converting the K-line data: lengths, records.length, log data: arrays, records); This is the first time that the site has been linked to the news. // throw stop ; // ceshi Sleep ((1000); I'm not sure. I'm not sure.


- #### 2、传统期货差价监控 (CTP)

当需要分析两个品种差价走势的时候,会用上这段代码。有时候也会把这段代码修改集成到自己的策略程序里面(比如跨期对冲策略),代码会绘制出一个差价走势图,在学习如何让机器人程序画图也是很有帮助的,很好的例子。
源码地址: https://www.fmz.com/strategy/5379

var __lastDiff = 0; var __AType = [Last button, Buy button, Sell button][AType]; var __BType = [Last button, Buy button, Sell button][BType]; What do you think? function _N ((v, precision) { if (typeof(precision)!= number ) { precision = 4; I'm not sure. var d = parseFloat ((v.toFixed ((Math.max ((10, precision + 5))); s = d.toString (().split ((""); if (s.length < 2 godu s[1].length <= precision) { return d; I'm not sure. What do you think? var b = Math.pow ((10, precision); return Math.floor ((d * b) / b; I'm not sure. What do you think? function EnsureCall ((method) { This is not true. while (!(r = method.apply(this, Array.prototype.slice.call ((arguments).slice))) { Sleep (interval); I'm not sure. return r; I'm not sure. What do you think? function is on Tick ((() { var a = EnsureCall ((exchange.SetContractType, AInstrument)); and Var ticker A = EnsureCall ((exchange.GetTicker)); and var b = EnsureCall ((exchange.SetContractType, BInstrument)); and Var ticker B = EnsureCall (exchange.GetTicker); var diff = _N (ticker A [__AType] - ticker B [__BType]); LogStatus ((a.InstrumentName, _N ((tickerA[__AType]), b.InstrumentName, _N ((tickerB[__BType])), and the difference between: If (__lastDiff! = 0) { if (Math.abs(Math.abs(diff) - Math.abs ((__lastDiff)) > 200) { return; I'm not sure. I'm not sure. if (diff!= __lastDiff) { // add adds data to series, with the parameter format [series serial number, data]; __chart.add (([0, [new Date (().getTime ((), diff))); __lastDiff = diff; I'm not sure. I'm not sure. What do you think? function main (() { If (exchange.GetName)).indexOf ((Futures_CTP)) == -1) { The throw tab only supports traditional futures (CTP) tabs. I'm not sure. SetErrorFilter (login already in control of the flow, connection failed, timeout button); // must be a context-independent construct passed to the Chart function ((Added HighStocks rules, detailed parameters How to use HighStocks) __chart = Chart This is a tooltip: xDateFormat: %Y-%m-%d %H:%M:%S, %A I'm not sure. title: { text: Chart of the analysis of the price of nickel I'm not sure. range Selector: { Button: Type: hour, count: 1, text: sh1h sh1 ♪ I'm going ♪ Type: hour, Count: three. text: sh3h sh3 ♪ I'm going ♪ Type: hour, Count: eight. text: sh8h sh8 ♪ I'm going ♪ I'm not sure what you mean. text: All I'm not going to lie. selected: 0, inputEnabled: false I'm not sure. x-axis: { type: Date and time tick I'm not sure. So the y-axis: { PlotLines: [{ is the length of the line} value: NormalDiff, Color: yellow-green orange, DashStyle: Shortdash shorts, shortdash shorts, shortdash shorts, shortdash shorts width: 1, ♪ I'm going ♪ value: HighDiff, Color: yellowish-red, DashStyle: Shortdash shorts, shortdash shorts, shortdash shorts, shortdash shorts width: 1, ♪ I'm going ♪ value: -NormalDiff, Color: yellow-green orange, DashStyle: Shortdash shorts, which have been downloaded from the official website of the Russian Federation. width: 1, ♪ I'm going ♪ value: -HighDiff, Color: yellowish-red, DashStyle: Shortdash shorts, shortdash shorts, shortdash shorts, shortdash shorts width: 1, I'm not sure. I'm not sure. series: [{ Name: The price of aluminum is falling data: [], This is a tooltip: valueDecimals: 2 I'm not sure. I'm not sure. It's not that simple. // reset Clear all information before the chart // __chart.reset (); // chart.reset (); // chart.reset (); // chart.reset (); // chart.reset (); // chart.reset (); // chart.reset (); // chart.reset (); var a = EnsureCall ((exchange.SetContractType, AInstrument)); and var b = EnsureCall ((exchange.SetContractType, BInstrument)); and Log ((a.InstrumentName + . + __AType, -, b.InstrumentName + . + __BType, difference as earnings is shown in the chart bar); TickInterval = Math.max ((TickInterval, 50)); the value of the value of TickInterval is the value of the value of TickInterval. Interval = Math.max ((Interval, 50)); and while (true) { This is the first time I've seen this. Sleep ((TickInterval)); and I'm not sure. I'm not sure.


- #### 3、CTP手动全平CTP商品期货持仓

在Simnow 上测试 商品期货策略时经常需要把已经开过的仓位平掉重新测试代码,这样就需要个类似一键平仓的程序来处理 恢复模拟账号未开仓状态。这里使用了一个交易处理模块: $.NewPositionManager 就是该模块的接口函数,作用是生成一个对象,可以调用该对象的方法处理具体操作,比如 全平仓: CoverAll(); 。  做了一点额外的功能,在全部平仓完以后,会打印出所有交易的标的物名称。

var p = $.NewPositionManager(); function main() { while(true){ if(exchange.IO("status") === true) { p.CoverAll (((); and var positions = _C (exchange.GetPosition); if ((positions.length === 0) { Log ((positions is :, positions); I'm going to break. I'm not sure. ♪ Other ♪ LogStatus (server not connected, waiting for log); I'm not sure. Sleep ((2000)); I'm not sure. var dict =exchange.IO("instruments"); // Returns a list of all the products on the exchange{ product name: details} in dictionary form for ((var k in dict) { Log (( product name: , k, Details: product name: , dict[k]); I'm not sure. Log ((exit., _C ((exchange.GetPosition)); and I'm not sure.

  
- #### 4、商品期货主力合约过滤

  在处理商品期货合约的连续性时会遇到主力合约的问题,如何更快的过滤识别出主力合约呢? 同样也写了个代码模块,可以改造,嵌入,或者单独使用。
  在 filter 变量中指定要 扫描的合约代码头。(即不含日期信息的合约代码的部分)  
    

var str = null; var strArray = []; function main (() { var filter = [MA,CF,zn,SR,pp,l,ni,i,v,jm,al,jd,cs,p]; var products = []; Log (waiting to connect to the transaction server); while (!exchange.IO(Sleep ((1000)); Log (you start to get all the contracts you can); var instruments = _Cexchange.IOI'm not sure what you mean. Log (List of contracts to get the successful link); var len = 0; for (var instrumentId in instruments) { This is a very interesting article. I'm not sure. Log (the length of the list of contracts is: log, len); for (var instrumentId in instruments) { if (instruments[instrumentId].IsTrading) { is the value of the var found = false; for (var i = 0; i < filter.length; i++) { if (instruments[instrumentId].ProductID == filter[i]) { found = true; I'm not sure. I'm not sure. if (!found) { continue; I'm not sure. if (typeof(products[instruments[instrumentId].ProductID]) === undefined) { This is a list of products[instruments[instrumentId].ProductID] = []; I'm not sure. This is a list of all the different ways products[instruments[instrumentId].ProductID].push ((instrumentId)) is credited in the database. I'm not sure. I'm not sure. for (var product in products) { var ss = products; Log ((Log subscription, product, Lots of Lots, ss.length, Lots of contracts, to identify the main contract Lots); var vol = 0, and the volIdx = 0; for (var i = 0; i < ss.length; i++) { _C ((exchange.SetContractType, ss[i]); I'm not sure. Sleep ((5000)); for (var i = 0; i < ss.length; i++) { _C ((exchange.SetContractType, ss[i]); This is a list of all the different ways Exchange.GetTicker is credited in the database.

        if (ticker) {
            var obj = JSON.parse(exchange.GetRawJSON());
            if (obj.OpenInterest > vol) {
                vol = obj.OpenInterest;
                volIdx = i;
            }
        }
    }
    // 取消订阅行情(之后此合约K线将停止收集), 当然也可以不取消, 这里演示用
    for (var i = 0; i < ss.length; i++) {
        _C(exchange.SetContractType, "-" + ss[i]);
    }
    strArray.push(ss[volIdx]);
    Log("主力合约为", ss[volIdx], "持仓", vol, '#ff0000');
}
for(var i = 0 ; i < strArray.length; i++){
    str += strArray[i] + ',';
}
Log("主力合约:", str);

}


- #### 5、交互模块

  有时候需要给机器人交互,需要下命令、改参数、获取详细运行状态参数 就需要交互代码了。
  

function get_Command ((() {// Function responsible for interaction, interaction timely updates Related values, familiar users can extend themselves var keyValue = 0;// The parameters that the command sends var way = null; // routing var cmd = GetCommand ((); // get the interactive command API If (cmd) { Log (click on the button: log, cmd);// log shows arrStr = cmd.split ((":"); // The GetCommand function returns a string, which I've been having trouble dealing with because I want to get familiar with JSON. //, so we first process the string and divide the returned string into 2 strings with: number.

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

} }


  有时我们甚至需要在机器人运行时插入运行JS 代码:

var cmd = GetCommand ((); // Calls the API to get the message from the interface interaction controller. if (cmd) { // Determines whether there is a message var js = cmd.split ((:, 2) [1]; // Split Returns a message String, restricted to returning 2, assigns an element of index 1 to a variable named js Log (( executed debug code:??, js); // output Code executed try { // detecting anomalies eval ((js); // Execute the eval function, which executes the input parameter ((code)). } catch(e) { // throw an exception Log ((Exception, e); // output an error message I'm not sure. I'm not sure.




当然还有很多代码工具尽在 : https://www.fmz.com/square


#### 先写到这,欢迎读者给我留言!提出建议和意见,如果感觉好玩可以分享给更多热爱程序热爱交易的朋友 
https://www.fmz.com/bbs-topic/735

### 程序员 littleDream 原创

More