Chơi JavaScript với người già - tạo ra một đối tác bán hàng nhỏ để phát triển các công cụ mã được sử dụng bởi robot

Tác giả:Giấc mơ nhỏ, Tạo: 2017-03-15 11:22:52, Cập nhật: 2017-10-11 10:37:43

Bạn có thể chơi với một người đàn ông và một người đàn bà JavaScript để tạo ra một đối tác bán hàng.


Trong quá trình phát triển robot tích lũy được rất nhiều đoạn mã nhỏ, một số có thể được dựa vào các chương trình chiến lược định lượng của mình, đây là một số mã mà ông viết để đặt dấu chấm dẫn, như là một món ăn so sánh cho người mới bắt đầu, các độc giả phải.

  • 1, chuyển đổi bất kỳ chu kỳ đường K

    Mô-đun mã này không được viết như một thư viện lớp, chỉ viết một hàm, cũng dễ dàng sửa đổi sau đó mở rộng. Nhiệm vụ là tổng hợp dữ liệu K-line theo chu kỳ cơ bản của một chu kỳ nhất định. Trong thời gian xem thị trường thông thường, hoặc sử dụng chiến lược viết nền tảng, mặc định là K-line của chu kỳ thông thường, chẳng hạn như 1 ngày, 1 giờ, 1 phút, vv. Địa chỉ mã nguồn:https://www.fmz.com/strategy/35986

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

var cloneObj = function ((obj) { // Phân bản sâu các hàm đối tượng var str, newobj = obj.constructor === Array? [] : {}; if (typeof obj!== object) { return; } else if (JSON) { str = JSON.stringify ((obj); // đối tượng nối chuỗi newobj = JSON.parse ((str); // chuyển đổi } else { for (var i in obj) { newobj[i] = typeof obj[i] === object? cloneObj ((obj[i]) : obj[i]; ♪ ♪ ♪ ♪ return newobj; }; Không có gì đâu. var DAY = 0; var HOURS = 1; var MINUTES = 2; var isFirstFind = true; var FirstStamp = null; Không có gì đâu. function GetDHM ((objTime, BaseCycle, NewCycleForMS) { var ret = []; if ((BaseCycle % (1000 * 60 * 60 * 24) === 0) { ret[0] = objTime.getDate ((); 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; ♪ ♪ 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; ♪ ♪ return ret; ♪ ♪ Không có gì đâu. function SearchFirstTime ((ret, BaseCycle, NewCycleForMS) { if ((ret[1] === DAY && ret[2] === DAY) { var array_day = []; for ((var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)) { array_day.push ((i); ♪ ♪ for ((var j = 0 ; j < array_day.length; j++) { if ((ret[0] === array_day[j]) { return true; ♪ ♪ ♪ ♪ }else if(ret[1] === HOURS && ret[2] === HOURS) { var array_hours = []; for ((var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)) { array_hours.push ((i); ♪ ♪ for ((var j = 0 ; j < array_hours.length ; j++) { if ((ret[0] === array_hours[j]) { return true; ♪ ♪ ♪ ♪ }else if(ret[1] === MINUTES && ret[2] === MINUTES) { var array_minutes = []; for ((var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)) { array_minutes.push ((i); ♪ ♪ for ((var j = 0; j < array_minutes.length; j++) { if ((ret[0] === array_minutes[j]) { return true; ♪ ♪ ♪ ♪ - Không. Throw mục tiêu chu kỳ không khớp với chu kỳ cơ bản! Số millisecond của chu kỳ mục tiêu: + NewCycleForMS + " Số millisecond của chu kỳ cơ bản: " + BaseCycle; ♪ ♪ ♪ ♪ Không có gì đâu. 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); ♪ ♪ return max; ♪ ♪ Không có gì đâu. function Calc_Low ((AssRecords, n, BaseCycle, NewCycleForMS) { var min = AssRecords[n].Low; for ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) { min = Math.min ((AssRecords[n + i].Low, min); ♪ ♪ return min; ♪ ♪ Không có gì đâu. function AssembleRecords ((records, NewCycleForMS) { var AssRecords = records.slice ((0); // sao chép sâu 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线周期过小!";
}

// Xác định thời gian, tìm thời gian bắt đầu của đường K cơ bản so với đường K mục tiêu. var objTime = new Date (); for (var i = 0; i < AssRecords.length; i++) { ObjTime.setTime ((AssRecords[i].Time); var ret = GetDHM ((objTime, BaseCycle, NewCycleForMS);

    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; // Thời gian cuối cùng không thể thay đổi, BarObj.Open = AssRecords[n].Open; 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); min = Math.min ((min, AssRecords[index_n].Low); BarObj.High = max; BarObj.Low = min; AfterAssRecords.push ((cloneObj ((BarObj)));

return AfterAssRecords;

♪ ♪ Không có gì đâu. function main() { // Kiểm tra mã while(!exchange.IO("status")) { LogStatus (không kết nối!); var Info = _C ((exchange.SetContractType, MA705); // tổng hợp dữ liệu tuyến K của hợp đồng methanol 705 thử nghiệm var records = exchange.GetRecords (); while (!records.length < 24) { records = exchange.GetRecords ();
// xử lý các thông số giao diện, nếu bạn viết chính sách của riêng bạn, bạn có thể tham khảo 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]); ♪ Log (( tùy chỉnh chu kỳ millisecond thời gian là: , Num_UI_NewCycleForMS);
while ((true) { records = _C ((exchange.GetRecords); // Log (( nguyên bản K-line dữ liệu: dài, records.length, dài dữ liệu: , records); records = AssembleRecords ((records, Num_UI_NewCycleForMS); // Đối số đầu tiên là đường K cơ bản, đối số thứ hai là số millisecond của chu kỳ để chuyển đổi, 1000 * 60 * 20 hoặc chuyển đổi thành 20 phút // Log (được chuyển đổi sau khi K-line dữ liệu: dài, records.length, dữ liệu: dài, records); Trong khi đó, một số công ty khác cũng đang tìm kiếm cách tìm kiếm tài liệu này. // Throw stop ; // ceshi Sleep ((1000);


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

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

var __lastDiff = 0; var __AType = [Last, Buy, Sell][AType]; var __BType = [Last,Buy,Sell][BType]; Không. function _N ((v, precision) { if (typeof ((precision)!= number ) { precision = 4; ♪ var d = parseFloat ((v.toFixed ((Math.max ((10, precision + 5))); s = d.toString (().split ((""); if (s.length < 2つの s[1].length <= precision) { return d; ♪ Không. var b = Math.pow ((10, precision); return Math.floor ((d * b) / b; ♪ Không. function EnsureCall ((method) { var r; while (!(r = method.apply(this, Array.prototype.slice.call ((arguments).slice))) { Ngủ (Interval); ♪ return r; ♪ Không. function on Tick ((() { var a = EnsureCall ((exchange.SetContractType, AInstrument); var tickerA = Đảm bảo gọi (exchange.GetTicker); var b = EnsureCall ((exchange.SetContractType, BInstrument); var tickerB = Đảm bảo gọi (exchange.GetTicker); var diff = _N ((ticker A [__AType] - ticker B [__BType]); LogStatus ((a.InstrumentName, _N ((tickerA[__AType]), b.InstrumentName, _N ((tickerB[__BType]), Giá chênh lệch: , diff); if (__lastDiff! = 0) { if (Math.abs(Math.abs(diff) - Math.abs ((__lastDiff)) > 200) { return; ♪ ♪ if (diff!= __lastDiff) { // add thêm dữ liệu vào series, định dạng tham số là [series serial, data]; __chart.add (([0, [new Date (().getTime ((), diff))); __lastDiff = diff; ♪ ♪ Không. function main (() { if (exchange.GetName)).indexOf ((Futures_CTP) == -1) { Throw chỉ hỗ trợ các giao dịch tương lai (CTP) truyền thống; ♪ SetErrorFilter ((logininreadydeflowcontrol) SetErrorFilter (loginreadydeflowcontrol) SetErrorFilter ((loginreadydeflowcontrol)) SetErrorFilter (loginreadydeflowcontrol)) SetErrorFilter (loginreadydeflowcontrol) SetErrorFilter (loginreadydeflowcontrol) SetErrorFilter (logindeflowcontrol) SetErrorFilter) SetErrorFilter (logindeflowcontrol) SetErrorFilter (logindeflowcontrol) SetErrorFilter) SetErrorFilter (logindeflowcontrol) SetErrorFilter (loginreadydeflowcontrol) SetErrorFilter (Timeout)); // Chart phải được chuyển đến một cấu trúc không liên quan đến ngữ cảnh (được thêm vào quy tắc HighStocks, chi tiết về cách sử dụng HighStocks) __chart = Chart # # # # # # xDateFormat: %Y-%m-%d %H:%M:%S, %A }, title: { text: Phân tích chênh lệch giá kim loại }, 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 }, X-axis: { type: datetime }, Trục y: { PlotLines: [{ value: NormalDiff, Màu sắc: DashStyle: shortdash width: 1, ♪ ♪ value: HighDiff, Màu sắc: DashStyle: shortdash width: 1, ♪ ♪ value: -NormalDiff, Màu sắc: DashStyle: shortdash width: 1, ♪ ♪ value: -HighDiff, Màu sắc: DashStyle: shortdash width: 1, ♪ }, series: [{ name: Giá vàng giảm, data: [], # # # # # # valueDecimals: 2 ♪ ♪ }); // reset xóa tất cả thông tin trước biểu đồ // __chart.reset ((); var a = EnsureCall ((exchange.SetContractType, AInstrument); var b = EnsureCall ((exchange.SetContractType, BInstrument); Log ((a.InstrumentName + . + __AType, -, b.InstrumentName + . + __BType, giá chênh lệch làm cho lợi nhuận hiển thị trên biểu đồ); TickInterval = Math.max ((TickInterval, 50); Interval = Math.max ((Interval, 50); while (true) { onTick ((); Sleep (Tick Interval); ♪ ♪


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

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

var p = $.NewPositionManager ((); chức năng chính (() { while (true) { nếuexchange.IO("status") === true) { p.CoverAll ((); var positions = _C ((exchange.GetPosition); if ((positions.length === 0) { Log (positions is: , positions); break; - Không. LogStatus (không kết nối máy chủ, đang chờ); Sleep ((2000); var dict =exchange.IO("instruments"); // Trả về danh sách tất cả các sản phẩm trên sàn giao dịch for ((var k in dict) { Log (địa chỉ sản phẩm: , k, Thông tin chi tiết: Địa chỉ sản phẩm: , dict[k]); Log ((exit., _C ((exchange.GetPosition));

  
- #### 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 ( chờ kết nối với máy chủ giao dịch); while (!exchange.IO("status")) Sleep ((1000); Log (đang bắt đầu lấy tất cả các hợp đồng); var instruments = _C(exchange.IO, instruments); Log (đặt danh sách các hợp đồng để có được các khóa thành công); var len = 0; for (var instrumentId in instruments) { len++; Log (lên danh sách các hợp đồng dài: len, len); for (var instrumentId in instruments) { if (instruments[instrumentId].IsTrading) { var found = false; for (var i = 0; i < filter.length; i++) { if (instruments[instrumentId].ProductID == filter[i]) { found = true; ♪ ♪ if (!found) { Continue; if (typeof(products[instruments[instrumentId].ProductID]) === undefined) { products[instruments[instrumentId].ProductID] = []; ♪ ♪ products[instruments[instrumentId].ProductID].push ((instrumentId); ♪ ♪ ♪ ♪ for (var product in products) { var ss = products[product]; Log (( đăng ký , product, của , ss.length, hợp đồng, để xác định hợp đồng chính); var vol = 0, volIdx = 0; for (var i = 0; i < ss.length; i++) { _C ((exchange.SetContractType, ss[i]); Sleep ((5000); for (var i = 0; i < ss.length; i++) { _C ((exchange.SetContractType, ss[i]); var ticker = exchange.GetTicker ();

        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 (() {// chức năng chịu trách nhiệm tương tác, tương tác cập nhật kịp thời Các giá trị liên quan, người dùng quen thuộc có thể tự mở rộng var keyValue = 0;// Các tham số được truyền bởi lệnh var way = null; // đường dẫn var cmd = GetCommand ((); // lấy API lệnh tương tác if (cmd) { Log (được nhấn nút: log, cmd); / hiển thị nhật ký ArrStr = cmd.split ((":"); // GetCommand sẽ trả về một chuỗi, và tôi đã giải quyết vấn đề ở đây vì tôi muốn làm quen với JSON //, vì vậy trước tiên xử lý các chuỗi, chia các chuỗi trả về các hàm thành hai chuỗi: số;; lưu trữ trong mảng chuỗi;;

  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 ((); // Gọi API để nhận thông báo về điều khiển tương tác giao diện. if (cmd) { // Xác định có tin nhắn hay không var js = cmd.split ((:, 2) [1]; // Split Trả về tin nhắn Dòng, hạn chế trả về 2 và đặt phần tử chỉ mục là 1 Đặt giá trị cho một biến tên là js Log (( thực hiện mã chỉnh sửa: , js); // đầu ra try { // Khám phá sự bất thường eval ((js); // thực hiện hàm eval, hàm này thực hiện các tham số (công thức) được truyền. } catch(e) { // Thả ngoại lệ Log ((Exception, e); // xuất thông tin sai




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


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

### 程序员 littleDream 原创

Thêm nữa