跳到主要內容

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

TLS / SSL 金鑰轉檔,「.crt / .key」如何轉成「.pem」?( OpenSSL 教學)

不管是哪個 Certificate Authority (CA) 發的憑證多半金鑰檔都是給「.crt / .key」格式的檔案,像是「ca_bundle.crt」、「 certificate.crt」和「.private.key」這種檔案, 但是在實際使用 (Nginx、Apache...等伺服器) 卻會需要的是「.pem」檔 ,那要怎麼轉換呢?其實可以直接使用 OpenSSL 這個軟體和幾行指令來達成。 OpenSSL 官方網站 :  https://www.openssl.org 下載頁面 :  https://www.openssl.org/source sudo apt-get install openssl 以 Linux (Ubuntu / Debian ...等) 為例,可以直接使用 apt-get 指令下載安裝 OpenSSL,如果是其他系統可以參考官方網站的說明。 openssl rsa -in private.key -text > private.pem openssl x509 -inform PEM -in certificate.crt > certificate.pem openssl x509 -inform PEM -in ca_bundle.crt > ca_bundle.pem 以前述所提到的「ca_bundle.crt」、「 certificate.crt」和「.private.key」三個檔案為例,就可以用上方的指令完成轉檔,其實同副檔名的轉檔指令都相同,所以兩個「.crt」的指令其實是重複的,也要記得套換成自己的檔案名稱。 如果需要申請免費的 SSL 憑證也可以參考之前介紹過的 SSL For Free ,它是使用「Let's Encrypt」核發的憑證,以及如果覺得申請憑證和定期更新太麻煩,也可以考慮自動化的 Caddy Server 能自動幫網站升級 HTTPS。

Ubuntu 打不出中文怎麼辦?安裝 gcin 注音輸入法輕鬆打出繁體中文 (Chinese input / Type Chinese)

如果第一次使用 Ubuntu 一定會有這個疑問,就是鍵盤怎麼按就是打不出中文字,其實不是你的 Ubuntu 壞了而是本來就需要安裝專用的中文輸入法才能用注音打中文,解法也很簡單,只要到 Ubuntu 軟體內找尋 gcin 這個中文輸入法就可以了。 在左上角 「尋找你的電腦」找到 Ubuntu 軟體 ,這就像是 Windows 軟體市集一樣,在這裡安裝小工具都不需要任何的指令,只要點一點就可以簡單的完成。 查詢 「gcin」 這個中文輸入法。 安裝時會需要管理員身份,只要輸入 Ubuntu 的密碼就可以了。 接著打開 設定 > 語言支援 。 將鍵盤輸入法系統改為「gcin」後 重新登入 就可以打中文啦。