任意のK線周期を変換

作者: リン・ハーン小さな夢, 日付: 2017-02-16 18:35:13
タグ:エクステント-API

戦略例

  • 基本K線を任意のK線周期に変換する
  • 暫定的にサポートされていません 秒級 テスト版は,BUGや問題がある場合は,ご報告ください.

// K线周期合成  扩展为 根据基础K线 合成 为任意周期。
var cloneObj = function(obj) {                             // 深拷贝 对象函数
    var str, newobj = obj.constructor === Array ? [] : {};
    if (typeof obj !== 'object') {
        return;
    } else if (JSON) {
        str = JSON.stringify(obj);                         //系列化对象
            newobj = JSON.parse(str);                      //还原
    } else {
        for (var i in obj) {
            newobj[i] = typeof obj[i] === 'object' ?
                cloneObj(obj[i]) : obj[i];
        }
    }
    return newobj;
};

var DAY = 0;
var HOURS = 1;
var MINUTES = 2;
var isFirstFind = true;
var FirstStamp = null;

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

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;
            }
        }
    }else{
        throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle;
    }
}

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

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

function AssembleRecords(records, NewCycleForMS) {
    var AssRecords = records.slice(0); // 深拷贝
    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线周期过小!";
    }

    // 判断时间戳, 找到 基础K线  相对于 目标K线的起始时间。
    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;  // 最后一根时间不能变,
    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;
}

function main() {                                                    // 测试代码
    var records = exchange.GetRecords();
    while (!records || records.length < 24) {
        records = exchange.GetRecords();
    }
    
    // 处理界面参数,  如果写到自己的策略里面 可以参考下
    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("自定义周期毫秒时间为:", Num_UI_NewCycleForMS);
    

    while(true){
        records = _C(exchange.GetRecords);
        // Log("原始K线数据:长度", records.length, "数据:", records);
        records = AssembleRecords(records, Num_UI_NewCycleForMS);        // 第一个参数是 基础K线, 第二个参数是 要转换的周期的 毫秒数, 1000 * 60 * 20 就是 转换为 20分钟
        // Log("转换后K线数据:长度", records.length, "数据:", records);
        $.PlotRecords(records, 'BTC');
        // throw "stop"; // ceshi
        Sleep(1000);
    }
}

関連性

もっと

バムマン3時間のk線で18時間の線を合成すると問題なく,日差しを合成するとエラーになります.

バムマンgetDHMの論理記述は少し問題があるように見えるが,総エラーが返ってくる. 目標周期と基礎周期が一致していない!

クンシアン・ワングなぜAPIの内部に 円形を組み込まないの?

ジャオチェン解決できるのか? 私の戦略は,これ以上復習できないからです.

ジャオチェンなぜokexデータ復習時にk線周期が1分を選択するが,エラー返却対象である周期240000トンはベース周期180000トンの整数倍数ではない. 合成はできない! しかし,復習設定パラメータで1分を選択した.

スーパー888コードでは4時間K線が30分で回転正常 (図のK線は4小時間隔) 5分で回転異常 (回転時間の12点以降は1時間K線になります)

小さな夢この合成コードはかなり古くから書かれています.

バムマンこの合成関数は,取引所が提供していないk線周期を使う必要があるためではなく,時線と日線の両方を同時に使う必要があるため使用しています. この場合,GetRecordsを2回呼び出すとそれぞれ3時間線と日線が取れます. fmz底層は2回のネットワークリクエストを送信しませんか?

小さな夢現在,プラットフォームは,カスタマイズされたK線サイクルを直接サポートし,プラットフォームの機能を直接利用することができます.

小さな夢いくつかの取引所は周回線データをサポートする.あるものはサポートしない.一般的に統一周期をパッケージ化している.他の周期は小周期で合成することができる.

小さな夢K線を1分周期に設定してみました. 下のパラメータは1000*60*4を設定すると,4分になります.

ジャオチェンOKEXのフューチャーを選択して,基本K線を1分に設定し,それを4分にします. 周期240000トンは基本周期180000トンの整数倍数ではなく,合成できません!

ジャオチェンこれは私のコード while ((true) { records = Call ((exchange.GetRecords,PERIOD_M1); 記録は,Call (exchange.GetRecords,PERIOD_M1) と呼ばれる //Log (("原始K線データ:長さ", records.length, "データ:" records); records = AssembleRecords ((records, Num_UI_NewCycleForMS); // 最初のパラメータはベースKラインで,第二のパラメータは変換される周期のミリ秒数で,1000 * 60 * 20は20分に変換されます. // Log (("K行データ:長さ", records.length",データ:" records"を変換した後に); $PlotRecords ((records, 'BTC'); $PlotRecords (BTC) について ストップを投げる スリープ ((1000); {cH00ffff} これは,パラメータの設定です https://dn-filebox.qbox.me/e0f51cd46827d68f42cbeffadba1c7a842fb0fb1.jpg 設定は1分ですが,K線周期が3分であることを提示します.

小さな夢QQの設定をクリックするときに設定するパラメータ スクリーンショットを見るか,または直接QQのグループに移動する.

小さな夢現在更新され,処理要求の基本サイクルを目標サイクルと一致させるようにしました. 例えば,目標サイクルは6時間の合成で,基本サイクルは1時間の使用で,より小さな反面のトラブルを使用し,多くの才能を収集します. テスト中,または使用にBUGの問題がある場合は,私にメッセージを送信したりQQしたりすることができます. また,質問してくれてありがとう ^^

小さな夢ありがとうございました. コードを確認しました. 処理しました.