跳到主要內容

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




留言



這個網誌中的熱門文章

WinRAR - 繁體中文版、免費版,別再破解了,老牌壓縮軟體直接免費給你用

WinRAR 應該對於所有 Windows 使用者一點都不陌生,可能也是很多人壓縮、解壓縮檔案的首選,舉凡 RAR、ZIP、7-Zip、TAR ...等檔案格式都可以處理,製作自解壓縮 (.EXE) 檔也沒問題,也算是最老牌的解壓縮軟體之一。 WinRAR 官方網站 :  https://www.win-rar.com 繁體中文版 :  https://rar.tw/download.html 永久免費簡體版 :  http://www.winrar.com.cn/download.htm 其實我也不太理解為什麼一個 WinRAR 可以有這麼多版本、不同語系的官網,畢竟在最原始的官網內也有「漢語」(簡體中文) 的選項,所以其他的國家自己的官網算代理商嗎? 如果真的要說我會比較建議到 英文版的官網 下載,畢竟這種軟體轉了一手又一手,加了什麼都不知道。

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

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

如何領取 Monero 分叉幣 MoneroV?附 Remote Node 免下載區塊鏈、快速同步

MoneroV 在先前已經完成分叉,目前也有在一兩間小型的交易所上市可以買賣,只要在  Monero 區塊高度 1,564,965 時持有 XMR 就可以得到十倍的 XMV, 但必須得是在自行保管私鑰的錢包、MyMonero 或有支援的交易所才能領的到 ,前兩項可以自行領取,交易所則得等所方派發,但如果你使用的交易所沒有支援這項 Fork 那當然就領不到啦。 MoneroV Wallet GitHub :  https://github.com/monerov/monerov GUI Wallet :  https://github.com/monerov/monerov-gui 上方的連結是 GitHub 原始碼,不知道為什麼在 GitHub 上 MoneroV 並沒有 Release 成可以直接使用的執行檔,但在官方網站上還是有提供的,可以到 官網 找到自己對應系統的錢包下載,如果不熟指令介面可以選擇 GUI Wallet。 開啟 GUI Wallet 後選擇 「Restore wallet from keys or mnemonic seed」 來匯入原本的 Monero 錢包,如果不放心將私鑰匯入可以先將 Monero 錢包內的餘額移出,已經產生過快照就不需要擔心沒辦法 Claim 自己的 XMV 了。 如果是使用私鑰來匯入的話則依序填入公開地址、View key、Spend key,以及選擇錢包名稱和儲存在哪個路徑, 即使是錢包檔也應該要好好保管,否則之後就得靠私鑰再匯入一次。 接著設定密碼,這就是開啟這個錢包檔的鑰匙,但如果錢包檔遺失了這個密碼也沒辦法將 XMV 取回,只能靠私鑰再重新匯入。 5.199.161.136 : 9538 接著選擇使用 Remote node,這樣就不必自己下載數十 GB 的區塊鏈檔案和花一大堆時間驗證、同步。 使用別人的 Daemon 來交易和領取 XMV 並不會有安全疑慮 ,只是在連接時對方可以知道的 IP。但其實就算是自己 Host Full Node 也是相同的,仍然會需要 P2P 的和它人連接也將 IP 暴露在公網上。 接著就會開始和遠端的 Node 同步了,左下角可以看到同步進度,完成後 XMV 就會顯示在你...