Các chiến lược giao dịch phát triển kinh nghiệm

Tác giả:Giấc mơ nhỏ, Tạo: 2019-08-06 17:15:13, Cập nhật: 2023-10-20 20:06:49

img

Các chiến lược giao dịch phát triển kinh nghiệm

Mục đích của bài viết này là kể về một số kinh nghiệm trong việc phát triển chiến lược, cùng với các mẹo nhỏ để giúp độc giả nhanh chóng hiểu được ý tưởng trong việc phát triển chiến lược giao dịch. Khi gặp phải một số vấn đề chi tiết tương tự trong thiết kế chiến lược, bạn có thể lập tức nghĩ ra một giải pháp hợp lý. Các nhà phát minh sử dụng nền tảng giao dịch định lượng như một nền tảng giảng dạy, thử nghiệm và thực hành. Ngôn ngữ lập trình chiến lược: JavaScript Thị trường giao dịch: Thị trường tài sản blockchain (BTC, ETH, v.v.)

  • Việc truy cập và xử lý dữ liệu

    Thông thường, tùy thuộc vào logic chiến lược, có thể sử dụng một vài giao diện khác nhau để lấy dữ liệu thị trường, vì logic giao dịch của chiến lược thường được điều khiển bởi dữ liệu thị trường (dĩ nhiên cũng có một số chiến lược không phụ thuộc vào thị trường, chẳng hạn như chiến lược đặt cược).

    • GetTicker: Nhận thị trường đánh dấu trong thời gian thực. Nó thường được sử dụng để truy cập nhanh vào giá mới nhất hiện tại, mua một giá, bán một giá.

    • GetDepth: Thu thập các đơn đặt hàng trên thị trường sâu. Thông thường được sử dụng để có được giá hàng, số lượng đơn đặt hàng. Các công cụ này được sử dụng trong các chiến lược phòng ngừa rủi ro, chiến lược thị trường, v.v.

    • GetTrade: Thu thập các giao dịch gần đây trên thị trường. Thông thường được sử dụng để phân tích hành vi thị trường trong thời gian ngắn, phân tích những thay đổi vi mô của thị trường. Thông thường sử dụng chiến lược tần số cao, chiến lược thuật toán.

    • GetRecords: Thu thập dữ liệu về thị trường K-line. Thông thường được sử dụng trong chiến lược theo dõi xu hướng. Các công cụ này được sử dụng để tính toán các chỉ số.

    • Nhận sai

      Trong quá trình thiết kế chiến lược, người mới thường bỏ qua các tình huống sai lầm, trực giác cho rằng kết quả hoạt động của các liên kết trong chiến lược là đã được xác định. Nhưng thực tế không phải như vậy, trong quá trình hoạt động của các chương trình chiến lược, khi yêu cầu dữ liệu thị trường, cũng sẽ gặp phải các tình huống bất ngờ. Ví dụ, một số giao diện thị trường đã trả về dữ liệu bất thường:

      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
      

      hoặc trực tiếp exchange.GetDepth () trả về giá trị null.

      Có rất nhiều trường hợp kỳ lạ như vậy. Vì vậy, phải có những giải pháp tương ứng cho những vấn đề có thể dự đoán được, giải pháp như vậy được gọi là xử lý nhầm lẫn.

      Cách thông thường để xử lý lỗi là bỏ dữ liệu và lấy lại.

      Ví dụ:

      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 不会存在 卖一价格小于买一价格这种数据错误的情况。
          // ...  具体的策略逻辑
      }
      

      Các phương pháp xử lý lỗi khác có thể được dự đoán cũng có thể được sử dụng theo cách tương tự. Một nguyên tắc thiết kế là không thể đưa ra dữ liệu sai để điều khiển logic chiến lược.

    • Sử dụng dữ liệu K-line

      Nhập dữ liệu từ K-Line, gọi:

      var r = exchange.GetRecords()
      

      Dữ liệu k được lấy là một mảng, ví dụ như như thế này:

      [
          {"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}
      ]
      

      Bạn có thể nhìn thấy mỗi dấu ngoặc chữ cái.{}Trong đó có thời gian, giá mở, giá cao nhất, giá thấp nhất, giá đóng, khối lượng giao dịch. Đây là một cột đường K. Thông thường dữ liệu đường K được sử dụng để tính các chỉ số, ví dụ: đường trung bình MA, MACD, vv. Nhập dữ liệu đường K như một tham số (dữ liệu nguyên liệu) và đặt tham số chỉ số, tính toán hàm của dữ liệu chỉ số, chúng ta gọi là hàm chỉ số. Có rất nhiều chức năng chỉ số trên nền tảng giao dịch định lượng của nhà phát minh.

      Ví dụ, chúng ta tính toán chỉ số đường trung tuyến, dựa trên chu kỳ của dữ liệu đường K mà chúng ta truyền, và tính toán đường trung tuyến của chu kỳ tương ứng. Ví dụ, dữ liệu đường K ngày được truyền (một cột đường K đại diện cho một ngày) được tính là đường trung bình ngày, tương tự nếu dữ liệu đường K của hàm chỉ số đường trung bình được truyền là chu kỳ 1 giờ, thì chỉ số được tính là đường trung bình 1 giờ.

      Một vấn đề mà chúng ta thường bỏ qua khi tính toán chỉ số là nếu tôi tính toán chỉ số đường trung bình 5 ngày, chúng ta sẽ chuẩn bị dữ liệu đường trung bình K ngày trước:

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

      Với dữ liệu đường K ngày, chúng ta có thể tính toán đường trung bình, nếu chúng ta tính đường trung bình 5 ngày, thì chúng ta phải đặt tham số chỉ số của hàm chỉ số là 5.

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

      Chúng tôi đã bỏ qua một vấn đề tiềm ẩn, nếu trong dữ liệu đường K ngày r, có ít hơn 5 cột đường K, thì làm thế nào để tính toán một chỉ số đường trung bình 5 ngày hiệu quả? Câu trả lời chắc chắn là không. Vì chỉ số đường trung bình là giá trung bình của giá đóng cửa cho một số lượng các cột đường K.

      img

      Vì vậy, trước khi sử dụng dữ liệu đường K, tính toán các hàm chỉ số dữ liệu chỉ số, phải xác định số lượng các cột đường K trong dữ liệu đường K có đáp ứng các điều kiện tính toán chỉ số (các tham số chỉ số) hay không

      Vì vậy, trước khi tính đường trung bình 5 ngày, hãy xem xét, mã đầy đủ như sau:

      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

      Các bài kiểm tra cho thấy: [null,null,null,null,null, 4228.7,4402.9400000000005,... ]

      Bạn có thể thấy các chỉ số đường trung bình 5 ngày được tính toán, 4 đầu tiên là không, vì số lượng các cột đường K là ít hơn 5, không thể tính toán đường trung bình.

    • Mẹo nhỏ để đánh giá bản cập nhật K-Line

      Một tình huống thường xảy ra khi chúng ta viết một số chính sách, chúng ta phải xử lý một số hoạt động khi mỗi chu kỳ đường K được hoàn thành, hoặc in một số nhật ký. Làm thế nào chúng ta có thể thực hiện chức năng như vậy? Đối với những người mới bắt đầu lập trình mà không có kinh nghiệm, có thể không nghĩ đến cơ chế để xử lý, ở đây chúng tôi đưa ra một vài mẹo.

      Khi chúng ta quyết định một vòng quay K-thần hoàn thành, chúng ta có thể bắt đầu từ thuộc tính thời gian trong dữ liệu K-thần, mỗi khi chúng ta lấy dữ liệu K-thần, chúng ta quyết định giá trị thuộc tính Time có thay đổi trong dữ liệu của K-thần cuối cùng của dữ liệu K-thần này hay không, nếu thay đổi, nghĩa là có một K-thần mới được tạo ra (bằng chứng là vòng quay K-thần trước của K-thần mới được tạo ra đã hoàn thành), nếu không thay đổi, nghĩa là không có một K-thần mới được tạo ra trong vòng quay cuối cùng hiện tại (châu quay K-thần chưa hoàn thành).

      Vì vậy, chúng ta cần một biến để ghi lại thời gian của cột cuối cùng của dữ liệu đường K.

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

      Trong thực tế, nó thường được cấu trúc như sau:

      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

      Bạn có thể thấy trong kiểm tra lại, chu kỳ đường K được thiết lập là ngày (exchange.GetRecords không chỉ định tham số khi gọi hàm, tùy thuộc vào chu kỳ đường K được thiết lập để kiểm tra lại là tham số mặc định), mỗi khi một cột đường K mới xuất hiện, nó in một nhật ký.

  • Tính toán số

    • Tính toán thời gian truy cập giao diện giao dịch

      Nếu bạn muốn có một số hiển thị hoặc kiểm soát thời gian giao diện truy cập vào sàn giao dịch, bạn có thể sử dụng mã sau:

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

      Nói một cách đơn giản, tính theo thời gian được ghi lại sau khi gọi hàm GetTicker trừ thời gian trước khi gọi và tính số milliseconds trải qua, tức thời gian từ khi thực hiện đến khi trả về kết quả.

    • Sử dụng Math.min / Math.max để giới hạn giá trị số

      Nếu bạn muốn một số có một giới hạn, thường sử dụng giới hạn Math.min

      Ví dụ, trong quá trình bán hàng, số tiền bán không thể lớn hơn số tiền trên tài khoản. Vì nếu số tiền có sẵn trong tài khoản lớn hơn, đơn sẽ bị lỗi.

      Thông thường điều khiển như thế này: Ví dụ, dự định bán 0.2 đồng.

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

      Điều này đảm bảo rằng số tiền sắp đặt sẽ không vượt quá số tiền có sẵn trong tài khoản.

      Tương tự, Math.max được sử dụng để đảm bảo giới hạn dưới của một số. Điều này thường áp dụng cho những tình huống như thế nào? Các sàn giao dịch thông thường có giới hạn số lượng đặt hàng tối thiểu cho một số cặp giao dịch, nếu dưới số lượng đặt hàng tối thiểu này, họ sẽ từ chối đặt hàng. Giả sử BTC thường là 0.01 đơn vị nhỏ nhất. Các chiến lược giao dịch cho thấy rằng đôi khi có thể tạo ra một đơn vị nhỏ hơn 0.01 bằng cách tính toán, vì vậy chúng ta có thể sử dụng Math.max để đảm bảo một đơn vị nhỏ nhất.

    • Số lượng, giá cả, kiểm soát chính xác

      Có thể sử dụng hàm _N() hoặc hàm SetPrecision để kiểm soát độ chính xác.

      Chức năng SetPrecision () chỉ được đặt một lần và sẽ tự động cắt bỏ số lượng đơn và số lượng giá dư thừa trong hệ thống.

      Chức năng _N() là một chức năng cắt nhỏ số đối với một số.

      Ví dụ:

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

      Giá trị của pi được cắt các số nhỏ, để lại 2 số nhỏ, đó là: 3.14

      Để biết thêm chi tiết, hãy xem tài liệu API.

  • Một số thiết lập logic

    • Thời gian, thực hiện một số hoạt động theo một chu kỳ thời gian nhất định

      Một cơ chế như vậy có thể được sử dụng để xác định thời gian hiện tại trừ thời gian hoàn thành nhiệm vụ hẹn giờ trước, tính toán thời gian đã trôi qua trong thời gian thực, tức là thực hiện một hoạt động mới sau khi thời gian đã trôi qua vượt quá độ dài thời gian được thiết lập.

      Ví dụ như trong chiến lược đầu tư.

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

      Đây là một ví dụ đơn giản.

    • Thiết kế cơ chế phục hồi tự động cho chính sách

      Sử dụng hàm _G() được định lượng bởi các nhà phát minh, và chức năng thoát khỏi lưu trữ, rất thuận tiện để thiết kế chính sách thoát khỏi tiến trình lưu trữ và khởi động lại chức năng phục hồi tự động.

      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

      Bạn có thể thấy rằng mỗi khi robot dừng lại, dữ liệu trong đối tượng hold được lưu lại, mỗi khi khởi động lại, dữ liệu được đọc, đưa giá trị của hold trở lại trạng thái trước khi dừng lại. Tất nhiên, đây là một ví dụ đơn giản, nếu được sử dụng trong chiến lược thực tế, bạn nên thiết kế dựa trên dữ liệu quan trọng cần được khôi phục trong chiến lược (thường là thông tin tài khoản, nắm giữ, số lượng lợi nhuận, hướng giao dịch, v.v.). Tuy nhiên, một số điều kiện có thể được đặt ra để xem liệu có thể khôi phục hay không.

Dưới đây là một số mẹo nhỏ khi phát triển chiến lược, chúng tôi hy vọng sẽ hữu ích cho những người mới bắt đầu và các nhà phát triển chiến lược! Hãy bắt tay luyện tập là bước tiến nhanh nhất! Chúc các bạn thành công trong việc thực hiện công việc của mình.


Có liên quan

Thêm nữa

Weix1aoBạn có thể hỏi liệu nền tảng của chúng tôi có hỗ trợ các phiên bản cao hơn của es, ví dụ như bạn có quen sử dụng không?

MAIKEOCảm ơn bạn! giáo viên của bạn, bạn thực sự là một người giỏi lập trình, kỹ thuật lập trình rất cao, bài viết rất hay, rất đáng ngưỡng mộ!

Giấc mơ nhỏXin chào, hiện đang hỗ trợ các tiêu chuẩn ES8.

Giấc mơ nhỏXin cảm ơn vì đã ủng hộ FMZ Quantify!