Spielen Sie mit Old White JavaScript - Erstellen Sie einen kleinen Partner, der einkaufen und verkaufen kann und entwickeln Sie Tools, die für Roboter verwendet werden

Schriftsteller:Kleine Träume, Erstellt: 2017-03-15 11:22:52, Aktualisiert: 2017-10-11 10:37:43

Mit dem alten Weiß spielt man mit JavaScript-Möbeln und schafft einen kleinen Partner, der Kauf und Verkauf macht.


Bei der Entwicklung von Robotern haben sich viele kleine Code-Fragmente angesammelt, von denen einige aus dem eigenen Quantifizierungsstrategieprogramm abgeleitet werden können.

  • 1, um beliebige K-Linienzyklen umzuwandeln

    Der Code-Modul ist nicht in eine Klassengruppe geschrieben, sondern nur eine Funktion, die später geändert und erweitert werden kann. Die Funktion ist die K-Linie, die basierend auf bestimmten Perioden die Daten der Basis K-Linien zusammenstellt. Die Quelle ist:https://www.fmz.com/strategy/35986

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

var cloneObj = function ((obj) { // Vervielfältigung von Objektfunktionen Var str, newobj = obj.constructor === Array? [] : {}; Wenn (typeof obj!== object) { zurück. } anders wenn (JSON) { Str = JSON.stringify ((obj); // Serialisierte Objekte newobj = JSON.parse ((str); // wiedergegeben } else { für (var i in obj) { Newobj[i] = typeof obj[i] === Object-Typ? cloneObj ((obj[i]) : obj[i]; Wir sind hier. Wir sind hier. return newobj; Ich bin nicht derjenige. Das ist nicht wahr. Var DAY = 0; Var HOURS = 1; Var MINUTES = 2; Var istFirstFind = true; Var FirstStamp = null; Das ist nicht wahr. Funktion GetDHM (objTime, BaseCycle, NewCycleForMS) { VAR ret = []; if ((BaseCycle % (1000 * 60 * 60 * 24) === 0) { Ret[0] = objTime.getDate (); Ret[1] = Tag; }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; Wir sind hier. wenn ((NewCycleForMS % (1000 * 60 * 60 * 24) === 0) { Ret[2] = Tag; }else if ((NewCycleForMS % (1000 * 60 * 60) === 0) { Ret[2] = HOURS; }else if ((NewCycleForMS % (1000 * 60) === 0) { RET[2] = MINUTES; Wir sind hier. Das ist nicht so einfach. Wir sind hier. Das ist nicht wahr. Funktion SearchFirstTime ((ret, BaseCycle, NewCycleForMS) if ((ret[1] === DAY && ret[2] === DAY) { VAR-Array_day = []; Für ((var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)) Hier ist eine Liste von Array_day.push ((i)); Wir sind hier. für ((var j = 0 ; j < array_day.length; j++) { Wenn es nicht möglich ist, dass die Array_day_[j]) return true; Wir sind hier. Wir sind hier. }else if(ret[1] === HOURS && ret[2] === HOURS) { Var-Array_hours = []; Für ((var i = 0 ; i < 24; i + = (NewCycleForMS / BaseCycle)) Hier ist eine Liste von Array_hours.push (i); Wir sind hier. für ((var j = 0 ; j < array_hours.length ; j++) { Wenn das nicht der Fall ist, dann ist das nicht der Fall. return true; Wir sind hier. Wir sind hier. }else if(ret[1] === MINUTES && ret[2] === MINUTES) { Das ist ein sehr schwieriger Fall. Für ((var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)) Hier ist eine Liste von Array_minutes.push (i); Wir sind hier. für ((var j = 0; j < array_minutes.length; j++) { Wenn es nicht möglich ist, dass die Daten in einem anderen Array gespeichert werden, dann können wir die Daten in einem anderen Array speichern. return true; Wir sind hier. Wir sind hier. Das ist alles. Die Zielphase ist nicht mit der Basisphase übereinstimmend. Zielphase-Millisekundenzahl: Myl + NewCycleForMS + " Basisphase-Millisekundenzahl: " + BaseCycle; Wir sind hier. Wir sind hier. Das ist nicht wahr. Funktion Calc_High ((AssRecords, n, BaseCycle, NewCycleForMS) Var max = AssRecords[n].High; für ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) { max = Math.max ((AssRecords[n + i].High, max); Wir sind hier. Das ist ein sehr schwieriger Fall. Wir sind hier. Das ist nicht wahr. Funktion Calc_Low ((AssRecords, n, BaseCycle, NewCycleForMS) Var min = AssRecords[n].Low; für ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) { Min = Math.min ((AssRecords[n + i].Low, min); Wir sind hier. return min; Wir sind hier. Das ist nicht wahr. Funktion AssembleRecords ((Records, NewCycleForMS) Das ist ein sehr schwieriger Fall. 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线周期过小!";
}

// Beurteilt die Zeitspanne und findet die Anfangszeit der Basis-K-Linie gegenüber der Ziel-K-Linie. var objTime = new Date ((); für (var i = 0; i < AssRecords.length; i++) { objTime.setTime ((AssRecords[i].Time); Das ist ein sehr schwieriges Problem, aber es ist nicht einfach, es zu lösen.

    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; // Die letzte Uhrzeit kann nicht geändert werden, da sie nicht mit der Datenbank verknüpft ist. BarObj.Open = AssRecords[n].Open; BarObj.Close = AssRecords [AssRecords.length - 1].Schließen; BarObj.Volume = AssRecords [AssRecords.length - 1].Volume; Var max = AssRecords[n].High; Var min = AssRecords[n].Low; für ((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); Wir sind hier. BarObj.High = max; BarObj.Low = min; Nach AssRecords.push ((cloneObj ((BarObj)));

return AfterAssRecords;

Wir sind hier. Das ist nicht wahr. Funktion main (() { // Testcode while(!exchange.IODas ist ein sehr schwieriges Problem. LogStatus (WEB ist nicht verbunden! Wir sind hier. var Info = _C ((exchange.SetContractType, SodiumMA705); // Synthese von K-Linien-Daten aus Versuchsmethanol 705 Var records = exchange.GetRecords (); while (!records.length < 24) { records = exchange.GetRecords ((); Wir sind hier.
// Verarbeiten Sie die Interface-Parameter, wenn Sie Ihre eigene Politik schreiben Das ist das erste Mal, dass ich das Buch gelesen habe. var arrayNum = UI_NewCycleForMS.split (("*"); for ((var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++) { Num_UI_NewCycleForMS = Num_UI_NewCycleForMS * Number ((arrayNum[indexNum]); Wir sind hier. Log (( Anpassungszyklus Millisekundenzeit ist: , Num_UI_NewCycleForMS);
while (true) { records = _C ((exchange.GetRecords); // Log (( Primär-K-Liniendaten: Längenstangen, records.length, Längendaten: Längen, records); records = AssembleRecords ((records, Num_UI_NewCycleForMS); // Der erste Parameter ist die Basis-K-Linie, der zweite Parameter ist die Anzahl der Millisekunden des Zyklus, der umgewandelt werden soll, 1000 * 60 * 20 oder umgewandelt in 20 Minuten // Log ((K-Liniendaten nach der Umwandlung von K-Liniendaten: Längenzeile, records.length, Längendaten: Längenzeile, records); Das ist ein sehr schwieriges Thema, aber es gibt viele andere Möglichkeiten, wie man es lösen kann. - Was ist das? Schlaf ((1000); Wir sind hier. Wir sind hier.


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

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

Das ist ein sehr schwieriges Problem. var __AType = [Last, Buy, Sell][AType]; Var __BType = [LastType, BuyType, SellType][BType]; Das ist nicht wahr. Funktion _N ((v, Präzision) { wenn (typeof ((precision)!= number) { Precision = 4; Wir sind hier. V.toFixed (Math.max, Präzision + 5))); s = d.toString (().split ((""); if (s.length < 2 godu s[1].length <= precision) { zurück d; Wir sind hier. Das ist nicht wahr. VAR b = Math.pow ((10, Präzision); return Math.floor ((d * b) / b; Wir sind hier. Das ist nicht wahr. Funktion SicherungCall ((method) { Das ist nicht wahr. while (!(r = method.apply ((this, Array.prototype.slice.call ((arguments).slice))) { Schlaf (intervall); Wir sind hier. return r; Wir sind hier. Das ist nicht wahr. Funktion auf Tick (() { Das ist ein sehr schwieriges Problem, aber es ist nicht einfach. Das ist ein sehr schwieriger Fall. Das Programm ist für die Bereitstellung von Informationen über die Funktionsweise der Software und die Funktionsweise der Software. Das ist ein sehr schwieriger Fall. Var diff = _N (ticker A [__AType] - ticker B [__BType]); LogStatus (a. InstrumentName, _N ((tickerA[__AType]), b. InstrumentName, _N ((tickerB[__BType]), Differenz zwischen den beiden Typen: Wenn (__lastDiff! = 0) { wenn (Math.abs(Math.abs(diff) - Math.abs ((__lastDiff)) > 200) { zurück. Wir sind hier. Wir sind hier. Wenn (diff!= __lastDiff) { // add fügt Daten zu einer Serie hinzu, wobei der Parameterformat [Series-Seriennummer, Daten] ist; __chart.add (([0, [new Date (().getTime ((), diff))); __lastDiff = diff; Wir sind hier. Wir sind hier. Das ist nicht wahr. Funktion main (() { if (exchange.GetName)).indexOf ((Futures_CTP) == -1) { Die Throw-Lösung unterstützt nur traditionelle Futures (CTP) -Lösungen. Wir sind hier. SetErrorFilter ((loginin 已登录 已流程控制 连接失败 时机过); // Das, was an die Chart-Funktion weitergegeben wird, muss ein Kontext-unabhängiger Struktur sein ((HighStocks Regeln, Detailparameter zur Verwendung von HighStocks) __chart = Chart Ein Tooltip: xDateFormat: %Y-%m-%d %H:%M:%S, %A Wir sind hier, um zu sprechen. Titel: { Text: Chart der Analyse der Preise für Aluminium Wir sind hier, um zu sprechen. Der Auswahlbereich: { Schaltflächen: [{ Typ: hour Count: 1 Text: 1h ist zu spät Wir haben es geschafft. Typ: hour Count: drei. Text: 3h Wir haben es geschafft. Typ: hour - Ich habe keine Ahnung. Text: 8h Wir haben es geschafft. Der Typ: Text: All Ich bin nicht derjenige. selected: 0, InputAktiviert: falsch Wir sind hier, um zu sprechen. Die x-Achse: { Typ: Datumzeit Wir sind hier, um zu sprechen. Und das ist die y-Achse. PlotLines: [{] Wert: NormalDiff Farbe: grüner Kürbis, DashStyle: Das ist ein kurzes Dash-Spiel. width: 1, Wir haben es geschafft. Wir haben eine Reihe von Lösungen gefunden. Farbe: Rot oder rot DashStyle: Das ist ein kurzes Dash-Spiel. width: 1, Wir haben es geschafft. - NormalDiff Farbe: grüner Kürbis, DashStyle: Das ist ein kurzes Dash-Spiel. width: 1, Wir haben es geschafft. -HighDiff Farbe: Rot oder rot DashStyle: Das ist ein kurzes Dash-Spiel. width: 1, Ich weiß nicht. Wir sind hier, um zu sprechen. Ich bin nicht sicher, ob ich das kann. Name: Preis für Aluminium schwankt Daten: [], Ein Tooltip: WertDezimal: 2 Wir sind hier. Ich weiß nicht. Das ist nicht wahr. // reset Löscht alle Informationen vor dem Diagramm // __chart.reset (); Das ist ein sehr schwieriges Problem, aber es ist nicht einfach. Das Programm ist für die Bereitstellung von Informationen über die Funktionsweise der Software und die Funktionsweise der Software. Log ((a.InstrumentName + . + __AType, -, b.InstrumentName + . + __BType, -Differenz als Gewinn wird an der Tabelle angezeigt); TickInterval = Math.max (TickInterval, 50); Interval = Math.max ((Interval, 50); Während (true) { Das ist ein sehr schwieriges Thema. Schlaf (TickInterval); Wir sind hier. Wir sind hier.


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

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

Die Daten werden von der Datenbank verarbeitet. Funktion main() { Während ((wahr)) { wennexchange.IO("status") === wahr) { Sie sind in der Nähe. Das ist ein sehr schwieriges Problem. Wenn es eine Position ist, dann ist es eine Position, wenn es eine Position ist. Log ((positions is :, positions); Ich bin nicht derjenige. Wir sind hier. Das ist alles. LogStatus (Log ist nicht mit dem Server verbunden, wartet auf Log); Wir sind hier. Schlaf ((2000); Wir sind hier. War dict =exchange.IO("instruments"); // Geben Sie eine Liste aller Produkte an der Börse {Produktname: Details} an Für (var k in dict) { Log (Produktbezeichnung: , k, Details: Produktbezeichnung , dict[k]); Wir sind hier. Log ((exit., _C ((exchange.GetPosition)); Wir sind hier.

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

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

Var str = null; Var strArray = []; Funktion main (() { var filter = [MA,CF,zn,SR,pp,l,ni,i,v,jm,al,jd,cs,p]; VAR-Produkte Log (Log wartet auf eine Verbindung zum Transaktionsserver); Während (!exchange.IO("status")) Sleep ((1000); Log (die Anzeige beginnt, alle Anzeigen zu erhalten); Das ist ein sehr schwieriger Fall.exchange.IODas ist ein sehr schwieriges Thema. Log (Liste der erfolgreichen Verträge); Der Wert von var len = 0 für (var instrumentId in instruments) { Len++; Wir sind hier. Log (Längen der Liste der Kontrakte sind: log, len); für (var instrumentId in instruments) { wenn (instruments[instrumentId].IsTrading) { var found = falsch; für (var i = 0; i < filter.length; i++) { wenn (instruments[instrumentId].ProductID == filter[i]) { Found = wahr; Wir sind hier. Wir sind hier. Wenn (!found) { Weiter; Wir sind hier. if (typeof(products[instruments[instrumentId].ProductID]) === undefined) { Produkte[Instrumente[InstrumentId].ProduktID] = []; Wir sind hier. Produkte[Instrumente[Instrument-Id].Produkt-ID].Push ((Instrument-Id); Wir sind hier. Wir sind hier. für (var Produkt in Produkten) { Var ss = Produkte; Log (Log, Produkt, Abonnements, Längen, Längen der Linsen, Linsenverträge, um die wichtigsten Linsen zu identifizieren); Das ist der Wert von 0, VolIdx = 0; für (var i = 0; i < ss.length; i++) { _C ((exchange.SetContractType, ss[i]); Wir sind hier. Schlaf ((5000); für (var i = 0; i < ss.length; i++) { _C ((exchange.SetContractType, ss[i]); Das ist nicht nur ein Problem, sondern auch ein Problem.

        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 ((() {// Funktion, die für die Interaktion verantwortlich ist und die Interaktion zeitgemäß aktualisiert wird var keyValue = 0;// Die Parameter, die der Befehl übermittelt hat VAR way = null; // Routen var cmd = GetCommand ((); // Erhalten Interaktionsbefehl API Wenn (cmd) { Log (siehe unten) Hier habe ich die Schwierigkeiten gelöst, weil ich mit JSON vertraut sein wollte. //, so dass man zuerst die String verarbeitet und die zurückgegebene String in zwei Strichen unterteilt wird.

  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 ((); // Anrufe der API, um Nachrichten über die Interface-Interaktionssteuerung zu erhalten. if (cmd) { // Beurteilt, ob eine Nachricht vorliegt var js = cmd.split ((:, 2) [1]; // Split Die zurückgegebene Nachricht Die String, die 2 zurückgibt, wird als Element des Index 1 bezeichnet. Log (( Ausführung des Debugging-Codes:??, js); // Ausgabe Versuchen Sie { // Ausnahmeschutz eval ((js); // führt die eval-Funktion aus, die die eingegangenen Parameter ((Code) ausführt. } catch(e) { // Abweichungen geworfen Log ((Exception, e); // Ausgabe von Fehlern Wir sind hier. Wir sind hier.




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


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

### 程序员 littleDream 原创

Mehr