Berbicara tentang pengalaman dalam mengembangkan strategi transaksi

Penulis:Mimpi kecil, Dibuat: 2019-08-06 17:15:13, Diperbarui: 2023-10-20 20:06:49

img

Berbicara tentang pengalaman dalam mengembangkan strategi transaksi

Tujuan dari artikel ini adalah untuk menceritakan beberapa pengalaman dalam pengembangan strategi, serta beberapa trik kecil yang dapat membantu pembaca dengan cepat memahami strategi perdagangan yang dikembangkan. Ketika menghadapi masalah detail yang sama dalam desain strategi, solusi yang masuk akal dapat segera dibuat. Platform perdagangan kuantitatif penemu digunakan sebagai platform untuk mengajar, menguji, dan berlatih. Bahasa pemrograman strategi: JavaScript Pasar perdagangan: pasar aset blockchain (BTC, ETH, dll.)

  • Pengadaan data

    Biasanya berdasarkan logika strategi yang berbeda, mungkin untuk menggunakan beberapa antarmuka yang berbeda untuk mendapatkan data pasar, karena logika perdagangan strategi biasanya didorong oleh data pasar (tentu saja ada juga beberapa strategi yang tidak melihat pasar, seperti strategi taruhan).

    • GetTicker: Dapatkan pasar tik secara real time. Biasanya digunakan untuk mendapatkan harga terbaru saat ini dengan cepat, beli satu harga, jual satu harga.

    • GetDepth: Mendapatkan Pemesanan Untuk Pasar Rendah. Umumnya digunakan untuk mendapatkan harga, jumlah pesanan, dan jumlah pesanan. Untuk strategi hedging, strategi pasar, dll.

    • GetTrade: Dapatkan catatan transaksi terbaru di pasar. Umumnya digunakan untuk menganalisis perilaku pasar dalam waktu singkat, untuk menganalisis perubahan mikro pasar. Biasanya digunakan untuk strategi frekuensi tinggi, strategi algoritma.

    • GetRecords: Dapatkan data K-line dari pasar. Biasanya digunakan sebagai strategi pelacakan tren. Untuk menghitung indikator.

    • Kesalahan

      Dalam merancang strategi, pemula biasanya akan mengabaikan berbagai situasi yang salah, secara intuitif menganggap bahwa hasil dari setiap langkah dalam strategi adalah sudah pasti. Tetapi sebenarnya tidak demikian. Dalam menjalankan program strategi, saat meminta data pasar, juga akan terjadi berbagai situasi yang tidak terduga. Beberapa antarmuka industri, misalnya, mengembalikan data yang tidak normal:

      var depth = exchange.GetDepth()
      
      // depth.Asks[0].Price < depth.Bids[0].Price      卖一价格低于了买一价格,这种情况不可能存在于盘面上,
      //                                                因为卖出的价格低于买入的价格,必定已经成交了。
      // depth.Bids[n].Amount = 0                       订单薄买入列表第n档,订单量为0
      // depth.Asks[m].Price = 0                        订单薄卖出列表第m档,订单价格为0
      

      Atau langsung exchange.GetDepth ((() mengembalikan nilai null.

      "Saya tidak tahu apa yang akan terjadi", kata dia. Karena itu, masalah-masalah yang dapat diantisipasi harus ditangani dengan cara yang sesuai, yang disebut penanganan kesalahan.

      Salah satu cara yang paling umum untuk mengatasi kesalahan adalah dengan membuang data dan mengambilnya kembali.

      Misalnya:

      function main () {
          while (true) {
              onTick()
              Sleep(500)
          }
      }
      
      function GetTicker () {
          while (true) {
              var ticker = exchange.GetTicker()
              if (ticker.Sell > ticker.Buy) {       // 以 检测卖一价格是不是小于买一价这个错误的容错处理为例,
                                                    // 排除这个错误,当前函数返回 ticker 。
                  return ticker
              }
              Sleep(500)
          }
      }
      
      function onTick () {
          var ticker = GetTicker()                  // 确保获取到的 ticker 不会存在 卖一价格小于买一价格这种数据错误的情况。
          // ...  具体的策略逻辑
      }
      

      Pengelolaan kesalahan yang dapat diprediksi lainnya dapat digunakan dengan cara yang sama. Prinsip desain adalah bahwa data yang salah sama sekali tidak dapat mendorong logika strategis.

    • Penggunaan data K-line

      Data K-line diambil dan dihubungi:

      var r = exchange.GetRecords()
      

      Data k-line yang diperoleh adalah suatu array, misalnya seperti ini:

      [
          {"Time":1562068800000,"Open":10000.7,"High":10208.9,"Low":9942.4,"Close":10058.8,"Volume":6281.887000000001},
          {"Time":1562072400000,"Open":10058.6,"High":10154.4,"Low":9914.5,"Close":9990.7,"Volume":4322.099},
          ...
          {"Time":1562079600000,"Open":10535.1,"High":10654.6,"Low":10383.6,"Close":10630.7,"Volume":5163.484000000004}
      ]
      

      Anda dapat melihat setiap tanda kurung.{}Di tengahnya terdapat waktu, harga buka, harga tertinggi, harga terendah, harga penutupan, volume transaksi. Ini adalah kolom garis K. Data garis K umum digunakan untuk menghitung indikator, misalnya: garis rata-rata MA, MACD, dll. Masukkan data K-line sebagai parameter (data mentah), lalu atur parameter indikator, dan hitung fungsi dari data indikator, yang kita sebut fungsi indikator. Ada banyak fungsi indikator yang tersedia di platform inventor kuantitatif.

      Sebagai contoh, kita menghitung indikator rata-rata yang berbeda berdasarkan siklus data K-line yang kita masukkan, yang dihitung adalah rata-rata periode yang sesuai. Sebagai contoh, data K-line harian yang dikirimkan (satu kolom K-line mewakili satu hari) dihitung adalah rata-rata harian. Demikian pula jika data K-line yang dikirimkan untuk fungsi indikator rata-rata adalah periode 1 jam, maka indikator yang dihitung adalah rata-rata 1 jam.

      Jika saya ingin menghitung indikator garis rata-rata 5 hari, pertama-tama kita harus mempersiapkan data garis K hari:

      var r = exchange.GetRecords(PERIOD_D1)  // 给GetRecords 函数传入参数 PERIOD_D1就是指定获取日K线,
                                              // 具体函数使用可以参看:https://www.fmz.com/api#GetRecords
      

      Dengan data garis K hari, kita bisa menghitung indikator rata-rata, kita harus menghitung garis rata-rata 5 hari, maka kita harus mengatur parameter indikator dari fungsi indikator menjadi 5.

      var ma = TA.MA(r, 5)        // TA.MA() 就是指标函数,用来计算均线指标,第一个参数设置刚才获取的日K线数据r,
                                  // 第二个参数设置5,计算出来的就是5日均线,其它指标函数同理。
      

      Kita mengabaikan masalah potensial, jika ada kurang dari 5 kolom K dalam data r-day K-line, bagaimana jika kita dapat menghitung indikator rata-rata 5 hari yang efektif? Jawabannya adalah tidak. Karena indikator rata-rata adalah rata-rata harga penutupan untuk sejumlah pilar K.

      img

      Jadi sebelum menggunakan data K-line, fungsi indikator harus menentukan apakah jumlah kolom K-line dalam data K-line memenuhi persyaratan untuk perhitungan indikator (parameter indikator).

      Jadi, sebelum menghitung garis rata-rata 5 hari, untuk menilai, kode lengkapnya adalah sebagai berikut:

      function CalcMA () {
          var r = _C(exchange.GetRecords, PERIOD_D1)     // _C() 是容错函数,目的就是避免 r 为 null , 具体可以查询文档:https://www.fmz.com/api#_C
          if (r.length > 5) {
              return TA.MA(r, 5)                         // 用均线指标函数 TA.MA 计算出均线数据,做为函数返回值,返回。
          }
      
          return false 
      }
      
      function main () {
          var ma = CalcMA()
          Log(ma)
      }
      

      img

      Hasil tes menunjukkan: [null, null, null, null, 4228.7, 4402.9400000000005,... ]

      Anda dapat melihat indikator rata-rata 5 hari yang dihitung, 4 yang pertama adalah nol, karena jumlah kolom K kurang dari 5, tidak dapat dihitung rata-rata.

    • Tips Mengetahui Pembaruan K-Line

      Skenario sering terjadi ketika kita menulis beberapa strategi, kita harus menangani beberapa operasi atau mencetak beberapa log saat setiap siklus K-line selesai. Bagaimana kita mencapai fungsi seperti ini? Untuk pemula yang tidak memiliki pengalaman pemrograman, mungkin tidak tahu apa yang harus dilakukan dengan mekanisme apa, di sini kita langsung memberikan tips.

      Jika kita memutuskan bahwa siklus kolom K telah selesai, kita dapat mulai dari atribut waktu dalam data kolom K, dan setiap kali kita mendapatkan data kolom K, kita memutuskan apakah nilai properti Time telah berubah dalam data kolom K terakhir dari data kolom K ini, jika terjadi perubahan, berarti ada kolom K baru yang dihasilkan (menunjukkan bahwa siklus kolom K sebelumnya yang baru dihasilkan telah selesai), jika tidak terjadi perubahan, berarti tidak ada kolom K baru yang menghasilkan kolom terakhir saat ini (periode kolom K belum selesai).

      Jadi kita harus memiliki variabel untuk mencatat waktu pada kolom K terakhir dari data K.

      var r = exchange.GetRecords()
      var lastTime = r[r.length - 1].Time       // lastTime 用来记录最后一根K线柱的时间。
      

      Dalam aplikasi praktis, strukturnya biasanya seperti ini:

      function main () {
          var lastTime = 0
          while (true) {
              var r = _C(exchange.GetRecords)
              if (r[r.length - 1].Time != lastTime) {
                  Log("新K线柱产生")
                  lastTime = r[r.length - 1].Time      // 一定要更新 lastTime ,这个至关重要。
      
                  // ... 其它处理逻辑
                  // ...
              }
      
              Sleep(500)
          }
      }
      

      img

      Seperti yang dapat dilihat dalam retest, siklus K baris diatur sebagai hari (exchange.GetRecords tidak menentukan parameter saat panggilan fungsi, tetapi berdasarkan siklus K baris yang diatur sebagai parameter default), setiap kali kolom K baris baru muncul, sebuah log dicetak.

  • Perhitungan digital

    • Menghitung waktu akses ke antarmuka pertukaran

      Jika Anda ingin memiliki tampilan atau kontrol tertentu tentang waktu yang dibutuhkan untuk mengakses antarmuka strategi, Anda dapat menggunakan kode berikut:

      function main () {
          while (true) {
              var beginTime = new Date().getTime()
              var ticker = exchange.GetTicker()
              var endTime = new Date().getTime()
      
              LogStatus(_D(), "GetTicker() 函数耗时:", endTime - beginTime, "毫秒")
              Sleep(1000)
          } 
      }
      

      Dengan kata lain, waktu yang dicatat setelah panggilan fungsi GetTicker dikurangi dengan waktu yang dicatat sebelum panggilan, untuk menghitung jumlah millisecond yang dialami, yaitu waktu yang dibutuhkan fungsi GetTicker dari pelaksanaan hingga hasil yang dikembalikan.

    • Menggunakan Math.min / Math.max pembatasan atas dan bawah untuk nilai-nilai

      Jika Anda ingin nilai memiliki batas, biasanya gunakan Math.min.

      Misalnya, dalam proses penjualan, jumlah unit yang dijual tidak boleh lebih besar dari jumlah koin yang ada di akun. Karena jika jumlah koin yang tersedia di akun lebih besar, maka pesanan akan dikembalikan dengan kesalahan.

      Biasanya kontrol seperti ini: Misalnya, Anda berencana untuk menjual 0.2 koin.

      var planAmount = 0.2
      var account = _C(exchange.GetAccount)
      var amount = Math.min(account.Stocks, planAmount)
      

      Dengan cara ini, Anda dapat memastikan bahwa jumlah uang yang akan Anda pesan tidak melebihi jumlah koin yang tersedia di akun Anda.

      Demikian pula, Math.max digunakan untuk memastikan batas bawah suatu nilai. Pada saat ini, banyak orang yang tidak tahu apa yang akan terjadi. Bursa umumnya memiliki batas jumlah pesanan minimum untuk beberapa pasangan perdagangan, dan jika jumlah pesanan minimum di bawah ini, maka mereka akan menolak pesanan. Asumsikan bahwa BTC biasanya memiliki jumlah minimum 0.01 unit. Strategi transaksi dengan menghitung kadang-kadang mungkin untuk menghasilkan jumlah yang lebih kecil dari 0.01 unit, jadi kita dapat menggunakan Math.max untuk memastikan jumlah yang paling sedikit.

    • Mengurangi jumlah pesanan, harga, kontrol presisi

      Fungsi _N() atau fungsi SetPrecision dapat digunakan untuk mengontrol presisi.

      Fungsi SetPrecision (()) diatur sekali, dan akan secara otomatis memotong jumlah unit dan angka harga dari sistem.

      Fungsi _N() adalah melakukan pemotongan digit kecil (pengendalian presisi) untuk suatu nilai

      Misalnya:

      var pi = _N(3.141592653, 2)
      Log(pi)
      

      Nilai pi dipotong dengan digit kecil, dengan mempertahankan 2 digit, yaitu: 3.14

      Untuk informasi lebih lanjut, lihat dokumentasi API.

  • Beberapa pengaturan logis

    • Timing, melakukan beberapa operasi pada periode waktu tertentu

      Mekanisme seperti ini dapat digunakan, dengan metode deteksi timeout, untuk menentukan timeout saat ini dikurangi timeout saat tugas penjadwalan terakhir selesai, menghitung waktu yang telah berlalu secara real-time, ketika waktu yang telah berlalu melebihi panjang waktu yang ditetapkan, yaitu melakukan operasi baru.

      Misalnya, dalam strategi investasi.

      var lastActTime = 0
      var waitTime = 1000 * 60 * 60 * 12   // 一天的毫秒数
      function main () {
          while (true) {
              var nowTime = new Date().getTime()
              if (nowTime - lastActTime > waitTime) {
                  Log("执行定投")
                  // ... 具体的定投操作,买入操作。
      
      
                  lastActTime = nowTime
              }
      
              Sleep(500)
          }
      }
      

      Ini adalah contoh sederhana.

    • Desain mekanisme pemulihan otomatis untuk kebijakan

      Dengan menggunakan fungsi _G() yang diukur oleh penemu, dan keluar dari fungsi simpan, sangat mudah untuk merancang kebijakan untuk keluar dari kemajuan simpan dan memulai kembali fungsi pemulihan otomatis.

      var hold = {
          price : 0, 
          amount : 0,
      }
      
      function main () {
          if (_G("hold")) {
              var ret = _G("hold")
              hold.price = ret.price
              hold.amount = ret.amount
              Log("恢复 hold:", hold)
          }
      
          var count = 1
          while (true) {
              // ... 策略逻辑
              // ... 策略运行中,可能开仓,交易,把开仓的持仓价格赋值给 hold.price ,开仓的数量赋值给 hold.amount,用以记录持仓信息。
      
              hold.price = count++     // 模拟一些数值
              hold.amount = count/10   // 模拟一些数值
      
              Sleep(500)
          }
      }
      
      function onexit () {    // 点击机器人上的停止按钮,会触发执行这个函数,执行完毕机器人停止。
          _G("hold", hold)
          Log("保存 hold:", JSON.stringify(hold))
      }
      

      img

      Seperti yang dapat dilihat, setiap kali robot berhenti, data dalam objek hold disimpan, dan setiap kali restart, data dibaca, mengembalikan nilai hold ke keadaan sebelum berhenti. Tentu saja ini adalah contoh sederhana, jika digunakan dalam strategi praktis, desain harus didasarkan pada data kunci yang perlu dipulihkan dalam strategi (umumnya informasi akun, kepemilikan, jumlah keuntungan, arah perdagangan, dll.). Namun, ada beberapa hal yang harus diperhatikan agar tidak terjadi pembatalan.

Di bawah ini adalah beberapa tips kecil untuk membuat strategi, semoga bermanfaat bagi para pemula dan pengembang strategi! Berlatih dengan tangan adalah langkah paling cepat! Semoga Anda mendapatkan bunga mawar panjang.


Berkaitan

Lebih banyak

Weix1aoTerima kasih untuk berbagi, sangat cocok untuk pemula yang tidak tahu apa yang harus ditulis, dan juga tanyakan apakah platform kami mendukung versi yang lebih tinggi, seperti apakah Anda terbiasa menggunakan?.

MAIKEOTerima kasih DreamWorks! DreamWorks guru, benar-benar baik, teknologi pemrograman yang tinggi, artikel yang baik, mengagumkan!

Mimpi kecilHalo, saat ini mendukung standar ES8.

Mimpi kecilTerima kasih atas dukungannya untuk FMZ Quantify!