跳到主要內容

Gekko 交易機器人 - 基於 ConvNetJs 深度學習 (Deep Learning) 框架的交易策略 (Strategy),隨時間市場自動調整參數



這是一個在 Discord 群翻到的 Gekko 策略,它本身並沒有 .toml 檔也就是沒有參數需要設置,因為它的參數是隨市場、時間自動運算的,但跟之前以 MA 線判定牛 / 熊市的 RSI 策略又不太一樣,因為 RSI 那個策略是固定的兩組參數,簡單來說市場對策略來說非牛即熊,並不能真的很有彈性地去變化。但原作者也有提到 Neural Network 的策略並不是簡單的複製貼上,你必須要了解它的內容和原理才能真正使用它。

這是一個基於 ConvNetJs 深度學習框架的交易策略,光是需要載入的程式庫就一大堆,但卻沒有用到技術指標和 Gekko 內建的 Tulip、TA-Lib ,真正跑起來運算量也比一般策略大上不少,有興趣的人可以把策略拆開來研究研究。

Js Code : 

var convnetjs = require('convnetjs')
var z = require('zero-fill')
var stats = require('stats-lite')
var n = require('numbro')
var math = require('mathjs')
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
var _ = require('lodash');
var gauss = require('gauss');

const deepqlearn = require('convnetjs/build/deepqlearn');

var log = require('../core/log.js');
// the below line starts you at 0 threads
global.forks = 0
// the below line is for calculating the last mean vs the now mean.
var oldmean = 0
getOption = function () {

  }




// let's create our own method
var method = {};
options = "Options Set";
options.period = "1m";
options.period_length = "1m";
options.activation_1_type = "regression";
options.neurons_1 = 1;
options.depth = 4;
options.selector = "Gdax.BTC-USD";
options.min_periods = 1500;
options.min_predict = 1;
options.momentum =0.2;
options.decay = 0.1;
options.threads = 4;
options.learns = 2;
/*
[myStoch]
highThreshold = 80
lowThreshold = 20
optInFastKPeriod = 14
optInSlowKPeriod = 5
optInSlowDPeriod = 5

[myLongEma]
optInTimePeriod = 100

[myShortEma]
optInTimePeriod = 50

[stopLoss]
percent = 0.9*/

var hasbought = false;
var stochParams = {
    optInFastKPeriod: 8,
    optInSlowKPeriod: 3,
    optInSlowDPeriod: 3
  };

var VarList = new gauss.Collection();
var Lowdiff = [];
var Topdiff = [];
var lowup = 0;



neural = undefined;
// prepare everything our method needs
method.init = function() {
    this.requiredHistory = this.tradingAdvisor.historySize;


    if (neural === undefined) {
        // Create the net the first time it is needed and NOT on every run
        neural = {
          net : new convnetjs.Net(),
          layer_defs : [
            {type:'input', out_sx:4, out_sy:4, out_depth:options.depth},
            {type:'fc', num_neurons:options.neurons_1, activation:options.activation_1_type},
            {type:'regression', num_neurons:5}
          ],
          neuralDepth: options.depth
      }
        neural.net.makeLayers(neural.layer_defs);
        neural.trainer = new convnetjs.SGDTrainer(neural.net, {learning_rate:0.05, momentum:options.momentum, batch_size:10, l2_decay:options.decay});
      }






}



var haspredicted = false;
var predictioncount = 0;
var maxaccuracy = 0;
var lowaccuracy = 0;
var highpeak =6;
var lowpeak =-100;
previouspred = 0;



// what happens on every new candle?
method.update = function(candle) {
    this.HCL = (this.candle.high + this.candle.close + this.candle.open) /3;
  //  if(Price.length > 1000){
  //    Price.shift()
  //  }
    Price.push(candle.close);
    if(Price.length > 2)
    {
        var tlp = []
        var tll = []

          var my_data = Price;
          var learn = function () {
              for (var i = 0; i < Price.length - 1; i++) {

                this.data = my_data.slice(i, i + 1); //previous price
                this.real_value = [my_data[i + 1]]; //this price
                this.aver = [(data[0] + real_value[0])/2];
                x = new convnetjs.Vol(data);
            //    y = new convnetjs.Vol(aver);
                neural.trainer.train(x, real_value);
            //    neural.trainer.train(y, x);
                this.predicted_values =neural.net.forward(x);
            //    test = [predicted_values.w[0]];

            //    y = new convnetjs.Vol(test);
            //    neural.trainer.train(y, x);
            //    this.predicted_values1 =neural.net.forward(y);
               // this.predicted_values1 =neural.net.forward(real_value);
             //   this.predicted_values2 =neural.net.forward();
                this.accuracy = predicted_values.w[0] -real_value
             //   this.accuracy = previouspred -real_value
                this.accuracymatch = predicted_values.w[0] == real_value;
                this.rewardtheybitches = neural.net.backward(accuracymatch);
                if(accuracy > 0)
                {
                  if(accuracy > maxaccuracy) {maxaccuracy = accuracy}
                }
                if(accuracy <0)
                {
                  if(accuracy < lowaccuracy) {lowaccuracy = accuracy}

                }
                predictioncount++;
                haspredicted = true;

              }
            }
            learn();

            // var json = neural.net.toJSON();
            // // the entire object is now simply string. You can save this somewhere
            // var str = JSON.stringify(json);
            // log.debug(str);

    }

}


method.log = function(candle) {
/*  if(Price.length > 4){
  console.log(' data:\t\t\t',data);
  console.log(' real value:\t\t',real_value);
  console.log(' price:\t\t\t',candle.close);
  console.log(' x:\t\t\t',x.w);
//  console.log(' y:\t\t\t',y.w);
  console.log(' predicted value:\t',predicted_values.w);
 // console.log(' predicted value1:\t',predicted_values1);
  console.log(' accuracymatch:\t\t',accuracymatch);
  console.log(' reward:\t\t\t',aver);
  console.log(' accuracy:\t\t',accuracy);
  console.log(' max accuracy:\t\t',maxaccuracy);
  console.log(' min accuracy:\t\t',lowaccuracy);
  console.log('=================================');
  }*/
}

method.handleposition  = function(){

}
var Price = [];
function per(num, amount){
    return num*amount/100;
    }

ManageSize = function(){


      var calculatedpercent = per(Price.length,6);
      Price.splice(0,calculatedpercent);

}
method.check = function(candle) {

          //Learn
          var predict = function(data) {
            var x = new convnetjs.Vol(data);
            var predicted_value = neural.net.forward(x);
         
            return predicted_value.w[0];
          }

          this.HCL = (this.candle.high + this.candle.close + this.candle.open) /3;
        //  console.log(' candle nummer:\t\t', Price.length);
        //  console.log('prediction count:\t', predictioncount);
         
          if(haspredicted & predictioncount > 1000)
          {
            var item = Price;
            prediction = predict(item)
            previouspred = prediction;
            mean = Price[Price.length -1];
           // oldmean = prediction
            meanp = math.mean(prediction, mean)
            global.meanp = meanp
            global.mean = mean
            var percentvar = (meanp-mean)/mean * 100;
            VarList.push(percentvar);
            if(VarList.length > 1000){
              VarList.shift()
            }

       /*     if(percentvar < 0) {

              prediction += lowaccuracy;
              percentvar += lowaccuracy;
              if(lowpeak > percentvar) { lowpeak = percentvar;}



            }
            if(percentvar > 0) {

              prediction -= maxaccuracy;
              percentvar -= maxaccuracy;
              if(highpeak < percentvar) { highpeak = percentvar;}
            }*/

            var VectorVar = VarList.toVector();
            var Variance =( VectorVar.variance());
            var Density30 = VectorVar.density(30);


                var top = per(Density30[Density30.length -1],-30);
                               // 1    x   1/100
                var low =(per(Density30[0],-10)) ;
               // log.debug("Variance :",Variance);
              //  console.log('top:\t', top);
              //  console.log('low:\t', low);
               
              if(percentvar > low){
                  var lowper = low - percentvar;
                  Lowdiff.push(lowper);
              } 
              if(percentvar < top){
                var topper = top - percentvar;
                Topdiff.push(topper);
            }         
               
                  if(Lowdiff.length > 20){Lowdiff.shift()}
                  if(Topdiff.length > 20){Topdiff.shift()}
               
                  lowup = math.sum(Lowdiff) / Lowdiff.length;
                  topup = math.sum(Topdiff) / Topdiff.length;


              //  console.log('topup', topup);
              //  console.log('differnce:', lowper);
              //  console.log('lowup', lowup);
               // console.log(' ');

                global.sig0 = global.meanp < global.mean && meanp != 0

                if (global.sig0 === false  && percentvar > low){
                  ManageSize();
                }
               
                if (global.sig0 === false  && percentvar > (low - lowup) && hasbought === false && candle.close > previousprice)
                   {

                          log.debug("IA - Buy - AT: \t\t",candle.close);
                        //  log.debug("Variance :",Variance);
                        //  log.debug("Density 30: low  ",low);
                          hasbought = true;
                          meanp = 0;
                          mean = 0;
                          haspredicted = false;
                          buyprice = candle.close;
                        //  ManageSize();
                          return this.advice('long');
                   }
                else if
                (global.sig0 === true && percentvar < top && hasbought === true)
                {
                      profit = (candle.close - buyprice)/buyprice*100;
                       log.debug("IA - Sell - At: \t",candle.close, 'profit:', profit.toFixed(2));
                    //   log.debug("Density 30 high : ",top);
                    //   log.debug("Variance :",Variance);
                      meanp = 0;
                      mean = 0;
                      hasbought = false;
                      haspredicted = false;
                      return this.advice('short');



                }
                previousprice = candle.close;

          }

}

module.exports = method;


在 Js 起頭就可以看到呼叫了一大堆程式庫,所以如果你本身沒有裝這些程式庫的話要一一安裝完成才能正常使用,安裝指令如下 :

npm install convnetjs
npm install zero-fill
npm install stats-lite
npm install numbro
npm install mathjs
npm install cluster
npm install os
npm install lodash
npm install gauss




留言



這個網誌中的熱門文章

Linux (Ubuntu) 查詢硬碟容量、剩餘大小指令

在 Ubuntu Desktop 版本或有安裝 GUI 像 Xfce 的 Server 版本當然可以直接從圖形介面查看硬碟容量和已經使用的大小, 但如果是在純 CLI 版本或使用 SSH 連線時呢?那就需要用到指令了。 顯示硬碟容量、已使用、可用大小。 df -h 查詢資料夾所占硬碟的大小。 du -h 查詢檔案大小 ls -l

RealVNC - 支援多系統的 VNC Viewer,免費遠端桌面客戶端 (Windows / Linux (Ubuntu) / Raspberry Pi /...)

對於不熟悉 SSH 介面的使用者來說可能第一個想法都會是使用遠端桌面,但要知道大多數的 VPS 主機都是提供 Linux 系統 (Ubuntu / RedHat / Debian...等),它們架好的 VNC Server 多半是沒辦法直接以 Windows 系統內建的「遠端桌面連線」來操作的,就好像兩端的通道是開了起來但卻仍說著不同的語言,所以就需要專用的 VNC Viewer 來連線, 而 RealVNC 支援非常多不同的作業系統環境,包括 Windows、Linux、Raspberry Pi、Android、iOS...等,幾乎可以說是一應具全啦。 RealVNC 官方網站:  https://www.realvnc.com/en 下載頁面:  https://www.realvnc.com/en/connect/download/viewer 只要從 「File > new connection」 就可以新增一個連線,爾後只要點選介面中已設定好的連線就可以隨時進入遠端主機,而主機端 (VPS) 也記得要先架設好 VNC Server 和新增防火牆例外,避免被拒絕的連線。

如何將 ISO 檔上傳到 VMware ESXi 6.5 並且用虛擬光碟開機?適用於安裝 Linux 或其它作業系統

在將實體機器使用  VMware ESXi 6.5 虛擬化之後就可以在它所提供的網頁管理介面操作每個虛擬個體,但要怎麼把用來安裝系統的 ISO 檔傳到虛擬機呢?而這些 ISO 檔會需要做成開機隨身碟的模式才能用嗎? 其實 ESXi 6.5 可以直接建立一個虛擬光碟機來驅動安裝系統用的 ISO 檔 ,所以安裝起來甚至會比實體機更簡單方便。 首先進到 ESXi 的管理介面 > 儲存區 ,點選 資料存放區瀏覽器 。 然後就能上傳事先下載好的 ISO 檔,不一定要存在哪一層路徑或特定位址,但建議新開一個資料夾方便整理,之後也可以直接指定這個路徑內的 ISO 檔。 然後在 虛擬機電源關閉 的情況下進入編輯設定。 新增一台 CD/DVD 光碟機。 選擇資料存放區 ISO 檔案。 瀏覽到剛剛上傳 ISO 檔的位址。 並且在虛擬機器選項的地方強制在 下次開機時強制進入 BIOS 設定畫面。 然後啟動虛擬機電源並開機後 到 Boot 的地方將 CD-ROM Drive 順位提高 ,就能以剛剛掛載的虛擬光碟機開機了。