Tài nguyên đang được tải lên... tải...

Hệ thống kiểm tra ngược

Sau khi bạn hoàn thành việc thiết kế một chiến lược giao dịch định lượng, làm thế nào bạn có thể biết tình hình cơ bản của chiến lược của mình, chẳng hạn như logic của chiến lược và hướng lợi nhuận của chiến lược? Tất nhiên, chúng tôi không thể sử dụng tiền thật trực tiếp để chạy chiến lược trên thị trường giao dịch thực, nhưng chúng tôi có thể sử dụng dữ liệu lịch sử để kiểm tra chiến lược của bạn và biết lợi nhuận của chiến lược của bạn trong dữ liệu lịch sử.

Mô hình hệ thống thử nghiệm ngược

FMZ Quant Trading Platform chia hệ thống backtest thànhmức độ botMức độ mô phỏng. Các bot cấp là để backtest hoàn toàn theo các dữ liệu lịch sử đầy đủ; trong khi mô phỏng cấp backtest tạo ratickdữ liệu theo dữ liệu K-line thực tế theo khoảng thời gian thường xuyên để kiểm tra lại. Cả hai đều dựa trên dữ liệu lịch sử thực tế, nhưng dữ liệu cấp bot chính xác hơn và kết quả đáng tin cậy hơn. Tuy nhiên, kiểm tra lại chỉ là hiệu suất của chiến lược theo dữ liệu lịch sử. Dữ liệu lịch sử không thể đại diện đầy đủ cho thị trường tương lai. Thị trường lịch sử có thể lặp lại, hoặc nó cũng có thể dẫn đến Black Swan. Do đó, kết quả kiểm tra lại nên được xử lý hợp lý và khách quan.

CácCấp độ mô phỏng Ticktạo ra mô phỏngDữ liệu tickdựa trên thời gian K-line cơ bản, mỗi thời gian K-line cơ bản sẽ tạo ra tối đa 12 điểm thời gian backtest; Trong khiMức thị trường thực tế TickPhương pháp kiểm tra ngược của FMZ Quant cho phép chiến lược giao dịch nhiều lần trên một đường K duy nhất, tránh tình huống mà giao dịch chỉ có thể được thực hiện ở mức giá đóng cửa. Nó chính xác hơn trong khi tính đến tốc độ kiểm tra ngược.

Mô tả cơ chế hệ thống kiểm tra hậu quả

  • Đánh dấu cấp độ mô phỏng CácCấp độ mô phỏng Tickdựa trên dữ liệu đường K cơ bản của hệ thống backtest, mô phỏng dữ liệu tick để backtest trong khuôn khổ giá cao nhất, giá thấp nhất, giá mở và giá đóng của một thanh đường K cơ bản theo một thuật toán nhất định. Là dữ liệu tick thời gian thực trên chuỗi thời gian backtesting, nó trả về khi chương trình chiến lược gọi giao diện. Để biết chi tiết, vui lòng tham khảo:Mô tả cơ chế trình độ mô phỏng hệ thống kiểm tra ngược.

  • Đánh dấu mức bot Bot level backtest là dữ liệu về mức độ tick thực tế trong chuỗi thời gian Bar. Đối với các chiến lược dựa trên dữ liệu về mức tick, sử dụng mức thị trường thực để backtest gần hơn với thực tế. Trong bot level backtest, dữ liệu tick là dữ liệu ghi lại thực, không phải mô phỏng. Nó hỗ trợ dữ liệu độ sâu, ghi lại dữ liệu của giao dịch thị trường, độ sâu tùy chỉnh và mỗi dữ liệu giao dịch cá nhân. Kích thước tối đa của backtest dữ liệu cấp thị trường thực là tối đa 50MB, không có giới hạn về phạm vi thời gian backtest trong giới hạn trên của bộ dữ liệu. Nếu bạn cần mở rộng phạm vi thời gian backtest càng nhiều càng tốt, bạn có thể giảm giá trị của thiết lập độ sâu thiết lập và không sử dụng mỗi dữ liệu giao dịch cá nhân để tăng phạm vi thời gian backtest Call.GetDepth, GetTradesCác chức năng để có được dữ liệu thị trường phát lại.GetTicker, GetTrades, GetDepthGetRecordssẽ không đẩy thời gian nhiều lần khi thời gian di chuyển trên dòng thời gian backtest (điều này sẽ không kích hoạt một bước nhảy đến thời điểm dữ liệu thị trường tiếp theo). Các cuộc gọi lặp đi lặp lại đến một trong các chức năng trên sẽ đẩy thời gian backtest để di chuyển trên dòng thời gian backtest (nhảy đến thời điểm dữ liệu thị trường tiếp theo). Khi mức thị trường thực được sử dụng để backtest, không nên chọn thời gian trước đó. Có thể không có dữ liệu cấp thị trường thực trong khoảng thời gian sớm.

Tick cấp botTick cấp độ mô phỏngcác chế độ, cơ chế khớp giao dịch của hệ thống backtest: khớp giao dịch lệnh được thực hiện theo giá nhìn thấy và toàn bộ khối lượng được giao dịch. do đó, kịch bản giao dịch một phần không thể được kiểm tra trong hệ thống backtest.

Hệ thống Backtesting hỗ trợ nhiều ngôn ngữ lập trình

Hệ thống backtesting hỗ trợ các chiến lược backtesting được viết và thiết kế bởi:JavaScript, TypeScript, Python, C++, PINE, MyLanguage, Blocklyhình dung. Kiểm tra hậu quả củaJavaScriptC++chiến lược giao dịch được tiến hành trong trình duyệt, và các bot thị trường thực sự hoặcWexAppthị trường thực tế (tức làWexApptrao đổi mô phỏng của nền tảng FMZ Quant Trading) chạy mà không cần cài đặt bất kỳ phần mềm, thư viện hoặc mô-đun nào khác. Kiểm tra hậu quả củaPythonđược thực hiện trên docker; nó có thể được thực hiện trên máy chủ công cộng được thêm vào bởi nền tảng FMZ Quant Trading, và nó cũng có thể được thực hiện trên docker của người dùng.PythonNếu một số thư viện là cần thiết, chúng cần phải được cài đặt bằng tay (chỉ thông thườngPythoncác thư viện được hỗ trợ trên các máy chủ công cộng FMZ Quant).

Nó hỗ trợJavaScriptPhân lỗi backtesting chiến lược trong Chrome DevTools,xin vui lòng tham khảo.

Các trao đổi được hỗ trợ trong hệ thống kiểm tra ngược

  • Tiền điện tử Sàn giao dịch giao dịch và tương lai chính cho tiền điện tử; hỗ trợ dữ liệu về tất cả các loại sàn giao dịch.
  • Chứng khoán Futu Cổ phiếu Hồng Kông, cổ phiếu Mỹ và các thị trường khác.

Phương pháp kiểm tra ngược tối ưu hóa tham số hệ thống

Chức năng tối ưu hóa tham số của hệ thống backtest của FMZ Quant Trading Platform là thiết lập các kết hợp tham số theo từng tùy chọn tối ưu hóa tham số trong quá trình backtesting.Tối ưu hóatùy chọn ở phía bên phải của các tham số chiến lược để hiển thị các cài đặt tối ưu hóa.

  • Giá trị tối thiểu: để giới hạn giá trị khởi động của các thông số.
  • Giá trị tối đa: để giới hạn giá trị tối đa của các thông số sau khi thay đổi từng bước.
  • Kích thước bước: số lượng biến thể gia tăng của các thông số.
  • Các sợi đồng thời: Trong quá trình tối ưu hóa tham số, đặt số lượng các luồng để thực thi đồng thời của mỗi sự kết hợp tham số backtest. Tùy chọn này chỉ hỗ trợ tối ưu hóa tham số chiến lược trongJavaScript, PINE, vàMy Language, và không hỗ trợ tối ưu hóa tham số trên mẫu.

Kết hợp tham số được tạo ra dựa trênminimum, maximum, vàstep sizeCác hệ thống backtesting lặp lại thông qua các kết hợp tham số này để backtesting (tức là, backtesting mỗi sự kết hợp tham số một lần).sốloại có thể được tối ưu hóa trong hệ thống backtesting.

Lưu cài đặt Backtest

Trongtrang chỉnh sửa chiến lược, trong trang của Backtest (đặc biệt là hệ thống backtest), bạn có thể đặt các tùy chọn như cấu hình backtest và tham số chiến lược để kiểm tra lại chiến lược. Khi các thông số này được thiết lập, bạn có thể làm theo các thiết lập backtesting chiến lược, sau đó làm thế nào để lưu các thiết lập cấu hình thông tin?

    1. Bạn có thể sử dụng nút Save Backtest Settings trênTrang chỉnh sửa chiến lượcđể ghi lại tất cả các thông tin cấu hình backtest (bao gồm cài đặt backtest và cài đặt tham số chiến lược) trong mã nguồn chiến lược dưới dạng mã.
    1. Khi bạn lưu một chiến lược bằng cách nhấp vào nút Save Strategy trên trang chỉnh sửa chiến lược, nền tảng sẽ tự động ghi lại các cài đặt backtest hiện tại, cấu hình tham số chiến lược và thông tin khác. Làm thế nào để tải cấu hình backtest vào hệ thống backtest?
    1. Khi làm mới trang chỉnh sửa chiến lược hoặc mở lại trang chỉnh sửa chiến lược này, thông tin cấu hình backtest được ghi bởi nút Save Backtest Settings sẽ tự động được tải đầu tiên.
    1. Nếu không có thông tin cấu hình backtest được ghi lại trong mã chiến lược hiện tại dưới dạng bình luậnbacktest(được lưu trong mã chiến lược thông qua nút Save Backtest Settings), hệ thống backtest tự động cấu hình các cài đặt backtest theo thông tin cấu hình backtest khi nút Save Strategy được nhấp lần cuối cho chiến lược hiện tại.
    1. Nếu thông tin cấu hình backtest được ghi lại dưới dạng bình luận ở đầu mã chiến lược được sửa đổi trên trang chỉnh sửa chiến lược, bạn cần đồng bộ hóa thông tin cấu hình backtest được cập nhật hiện tại với tùy chọn giao diện backtest chiến lược.backtesttrong lĩnh vực chỉnh sửa chiến lược.
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
'''backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
'''
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Nhấp vào Save backtest settings, có một chút sự khác biệt định dạng trênJavaScript/Python/C++/MyLanguage/PINEngôn ngữ khi lưu cài đặt backtest vào mã chiến lược: MyLanguage:

(*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*)

Ngôn ngữ PINE:

/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Nguồn dữ liệu tùy chỉnh

Hệ thống backtesting của nền tảng giao dịch FMZ Quant hỗ trợ các nguồn dữ liệu tùy chỉnh, hệ thống backtesting sử dụngGETPhương pháp để yêu cầu một URL tùy chỉnh (URL có thể truy cập công khai) để lấy một nguồn dữ liệu bên ngoài cho backtest. Các tham số yêu cầu bổ sung là như sau:

Parameter Ý nghĩa Giải thích
biểu tượng Tên biểu tượng Dữ liệu thị trường giao ngay, chẳng hạn như:BTC_USDT, dữ liệu thị trường tương lai như:BTC_USDT.swap, dữ liệu tỷ lệ tài trợ hợp đồng vĩnh viễn tương lai, chẳng hạn như:BTC_USDT.funding, dữ liệu chỉ số giá hợp đồng tương lai vĩnh viễn, chẳng hạn như:BTC_USDT.index
eid Chuyển đổi như OKX, Futures_OKX
tròn Sự chính xác của dữ liệu True có nghĩa là độ chính xác cụ thể được xác định trong dữ liệu được cung cấp bởi nguồn dữ liệu tùy chỉnh. Yêu cầu được gửi bởi FMZ Quant Trading Platform Backtesting System đến nguồn dữ liệu tùy chỉnh được cố định là:round=true
thời gian Khoảng thời gian dữ liệu đường K (mi-lít giây) như:60000là khoảng thời gian 1 phút
độ sâu Mức độ sâu 1-20
thương mại Có cần chia dữ liệu hay không true ((1) / false ((0)
từ Thời gian bắt đầu Unix timestamp
đến Thời kỳ kết thúc Unix timestamp
chi tiết Yêu cầu dữ liệu chi tiết biểu tượng True có nghĩa là nó cần được cung cấp bởi một nguồn dữ liệu tùy chỉnh. Yêu cầu được gửi bởi FMZ Quant Trading Platform Backtesting System đến nguồn dữ liệu tùy chỉnh được cố định như sau:detail=true
tùy chỉnh Parameter này có thể bị bỏ qua

Khi nguồn dữ liệu của các đối tượng giao dịch giao dịch tức thời và giao dịch tương lai được thiết lập cho một nguồn dữ liệu tùy chỉnh (feeder), hệ thống backtesting gửi yêu cầu đến dịch vụ nguồn dữ liệu tùy chỉnh:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Bitget&from=1351641600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_OKX&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=1

Định dạng dữ liệu

Định dạng được trả về phải là một trong hai định dạng sau đây (mà sẽ được hệ thống nhận ra tự động):

  • Mức mô phỏng Tick, sau đây là một ví dụ về dữ liệu JSON:

    {
        "detail": {
            "eid": "Binance",
            "symbol": "BTC_USDT",
            "alias": "BTCUSDT",
            "baseCurrency": "BTC",
            "quoteCurrency": "USDT",
            "marginCurrency": "USDT",
            "basePrecision": 5,
            "quotePrecision": 2,
            "minQty": 0.00001,
            "maxQty": 9000,
            "minNotional": 5,
            "maxNotional": 9000000,
            "priceTick": 0.01,
            "volumeTick": 0.00001,
            "marginLevel": 10
        },
        "schema":["time", "open", "high", "low", "close", "vol"],
        "data":[
            [1564315200000, 9531300, 9531300, 9497060, 9497060, 787],
            [1564316100000, 9495160, 9495160, 9474260, 9489460, 338]
        ]
    }
    
  • Đánh dấu mức độ bot, sau đây là một ví dụ về dữ liệu JSON: Dữ liệu backtest Tick-level (có chứa thông tin về độ sâu của thị trường, và định dạng độ sâu là một mảng[price, volume]Nó có thể có nhiều mức độ sâu,asksđối với lệnh tăng giá,bidscho thứ tự giảm giá).

    {
        "detail": {
            "eid": "Binance",
            "symbol": "BTC_USDT",
            "alias": "BTCUSDT",
            "baseCurrency": "BTC",
            "quoteCurrency": "USDT",
            "marginCurrency": "USDT",
            "basePrecision": 5,
            "quotePrecision": 2,
            "minQty": 0.00001,
            "maxQty": 9000,
            "minNotional": 5,
            "maxNotional": 9000000,
            "priceTick": 0.01,
            "volumeTick": 0.00001,
            "marginLevel": 10
        },
        "schema":["time", "asks", "bids", "trades", "close", "vol"],
        "data":[
            [1564315200000, [[9531300, 10]], [[9531300, 10]], [[1564315200000, 0, 9531300, 10]], 9497060, 787],
            [1564316100000, [[9531300, 10]], [[9531300, 10]], [[1564316100000, 0, 9531300, 10]], 9497060, 787]
        ]
    }
    
Vùng Mô tả
chi tiết Thông tin chi tiết về kiểu dữ liệu được yêu cầu,

bao gồm tên của đồng tiền, tên của Tiền tệ giao dịch, độ chính xác, số lượng đặt hàng tối thiểu, v.v. ∙ ∙ Nó xác định các thuộc tính của các cột trong dữ liệu mảng, mà là nhạy cảm với chữ cái lớn và chỉ giới hạn thời gian, mở, cao, thấp, gần, vol, hỏi, giá thầu, giao dịch Dữ liệu. Cấu trúc cột, dữ liệu được ghi theo sơ đồ cài đặt.

trường chi tiết

Vùng Mô tả
eid Exchange ID, xin lưu ý rằng chỗ và tương lai của một
Một số giao dịch có những hiệu ứng khác nhau.
biểu tượng Mã sản phẩm giao dịch
tên giả Biểu tượng trong trao đổi tương ứng với hiện tại
Mã sản phẩm giao dịch
Tiền cơ bản Tiền tệ giao dịch
báo giáTiền tệ Tiền tệ theo mệnh giá
marginTiền tệ Đồng tiền ký quỹ
cơ sởChính xác Chính xác tiền tệ giao dịch
trích dẫnChính xác Giá tiền tệ chính xác
MinQty Số lượng đặt hàng tối thiểu
maxQty Số lượng đặt hàng tối đa
Tiêu chuẩn Số lượng đơn đặt hàng tối thiểu
maxThiên định Số lượng đặt hàng tối đa
giáTick Giá tăng
VolumeTick Giá trị thay đổi tối thiểu của số lượng đơn đặt hàng (một bước nhảy vào
số lượng đặt hàng)
marginLevel Giá trị đòn bẩy tương lai
hợp đồngLoại Đối với các hợp đồng vĩnh viễn:swap, các

hệ thống backtest sẽ tiếp tục gửi tỷ lệ tài trợ và chỉ số giá yêu cầu.

Các thuộc tính cột đặc biệtasks, bids, trades:

Vùng Mô tả Nhận xét
yêu cầu / đề nghị [giá, khối lượng],...] Ví dụ, dữ liệu trong

cácLive Trading Level TickVí dụ dữ liệu:[[9531300, 10]]Ừm. Các giao dịch. Thời gian, hướng, giá, khối lượng. ví dụ, dữ liệu trongLive Trading Level TickVí dụ dữ liệu:[[1564315200000, 0, 9531300, 10]] |

Khi backtesting hợp đồng vĩnh viễn trên sàn giao dịch tương lai, tùy chỉnh Các nguồn dữ liệu cũng yêu cầu thêm dữ liệu về tỷ lệ tài trợ và giá hệ thống backtesting sẽ tiếp tục gửi yêu cầu Đối với tỷ lệ tài trợ chỉ khi dữ liệu thị trường được yêu cầu được trả lại và trường chi tiết trong cấu trúc trả về chứa"contractType": "swap"cặp giá trị khóa.

Khi hệ thống backtesting nhận được dữ liệu tỷ lệ tài trợ, nó sẽ tiếp tục gửi yêu cầu dữ liệu chỉ số giá.

Cấu trúc dữ liệu tỷ lệ tài trợ là như sau:

{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.funding",
        "alias": "BTC_USDT.funding",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "marginCurrency": "",
        "basePrecision": 8,
        "quotePrecision": 8,
        "minQty": 1,
        "maxQty": 10000,
        "minNotional": 1,
        "maxNotional": 100000000,
        "priceTick": 1e-8,
        "volumeTick": 1e-8,
        "marginLevel": 10
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [
            1584921600000,
            -16795,
            -16795,
            -16795,
            -16795,
            0
        ],
        [
            1584950400000,
            -16294,
            -16294,
            -16294,
            -16294,
            0
        ]
        // ...
    ]
}
  • Khoảng thời gian giữa các giai đoạn liền kề là 8 giờ
  • Ví dụ, tỷ lệ tài trợ của Binance được cập nhật mỗi 8 giờ. Số liệu về tỷ lệ tài trợ là -16795? Bởi vì giống như dữ liệu đường K, để tránh mất độ chính xác dấu phẩy động trong quá trình truyền mạng, dữ liệu sử dụng kiểu nguyên số; dữ liệu tỷ lệ tài trợ cũng có thể là âm.

Một ví dụ về yêu cầu dữ liệu tỷ lệ tài trợ từ backtesting hệ thống là:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.funding&to=1611244800&trades=0

Cấu trúc dữ liệu chỉ số giá như sau:


{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.index",
        "alias": "BTCUSDT",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "index",
        "marginCurrency": "USDT",
        "basePrecision": 3,
        "quotePrecision": 1,
        "minQty": 0.001,
        "maxQty": 1000,
        "minNotional": 0,
        "maxNotional": 1.7976931348623157e+308,
        "priceTick": 0.1,
        "volumeTick": 0.001,
        "marginLevel": 10,
        "volumeMultiple": 1
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [1584921600000, 58172, 59167, 56902, 58962, 0],
        [1584922500000, 58975, 59428, 58581, 59154, 0],
        // ...
    ]
}

Một ví dụ về yêu cầu dữ liệu chỉ số giá được gửi bởi backtesting hệ thống là:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.index&to=1611244800&trades=0

Ví dụ về nguồn dữ liệu tùy chỉnh

Xác định địa chỉ nguồn dữ liệu, ví dụ:http://120.24.2.20:9090/data. Chương trình dịch vụ nguồn dữ liệu tùy chỉnh được viết bằng cách sử dụngGolang:

package main

import (
    "fmt"
    "net/http"
    "encoding/json"
)

func Handle (w http.ResponseWriter, r *http.Request) {
    // e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data

    // request: GET http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=OKX&from=1584921600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
    //              http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1599958800&period=3600000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=0
    fmt.Println("request:", r)

    // response
    defer func() {
        // response data
        /* e.g. data
        {
            "detail": {
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10
            },
            "schema": [
                "time",
                "open",
                "high",
                "low",
                "close",
                "vol"
            ],
            "data": [
                [1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151],
                [1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738],
                [1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875],
                [1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777],
                [1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292],
                [1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666],
                [1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405],
                [1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768],
                [1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797],
                [1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692]
            ]
        }
        */
        
        // /* Simulation level Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time","open","high","low","close","vol"},
            "data": []interface{}{
                []int64{1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151},  // 1610755200000 : 2021-01-16 08:00:00
                []int64{1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738},  // 1610841600000 : 2021-01-17 08:00:00
                []int64{1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875},
                []int64{1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777},
                []int64{1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292},
                []int64{1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666},
                []int64{1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405},
                []int64{1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768},
                []int64{1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797},
                []int64{1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692},
            },
        }
        // */

        /* Bot level Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time", "asks", "bids", "trades", "close", "vol"},
            "data": []interface{}{
                []interface{}{1610755200000, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{1610755200000, 0, 9531300, 10}}, 9497060, 787},
                []interface{}{1610841600000, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{1610841600000, 0, 9531300, 11}}, 9497061, 789},                
            },
        }
        */

        b, _ := json.Marshal(ret)
        w.Write(b)
    }()
}
func main () {
    fmt.Println("listen http://localhost:9090")
    http.HandleFunc("/data", Handle)
    http.ListenAndServe(":9090", nil)
}

Chiến lược thử nghiệm,JavaScriptví dụ:

/*backtest
start: 2021-01-16 08:00:00
end: 2021-01-22 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
args: [["number",2]]
*/

function main() {
    var ticker = exchange.GetTicker()
    var records = exchange.GetRecords()
    Log(exchange.GetName(), exchange.GetCurrency())
    Log(ticker)
    Log(records)
}

Local Backtest Engine

FMZ Quant Trading Platform đã mở nguồn choJavaScriptngôn ngữ vàPythonngôn ngữ của công cụ backtest cục bộ, hỗ trợ cài đặt Thời gian K-line cơ bản trong quá trình backtesting.

Chìa khóa phím tắt trang backtest

  • Chìa khóa tắt để chuyển đổi giữa trang chiến lược Editing và trang Backtesting Sử dụng chìa khóa.Ctrl +,để chuyển trở lại trang Backtest và trang Edit Strategy.Ctrl, nhấn phím,.

  • Chìa khóa tắt cho chiến lược tiết kiệm Sử dụng chìa khóa.Ctrl + sđể cứu chiến lược.

  • Chọn tắt để bắt đầu backtest chiến lược Sử dụng chìa khóa.Ctrl + bđể cho phép Start Backtest.

Quay lại dữ liệu kiểm tra

  • Tải xuống dữ liệu nhật ký hệ thống kiểm tra ngược Mở chiến lược cụ thể và chuyển sang Backtest Page để kiểm tra lại chiến lược. Trong cột Status Information của chiến lược được hiển thị sau khi kiểm tra lại, có một nút Download Table ở góc trên bên phải. Nhấp vào nó để tải xuống một tệp CSV của dữ liệu cột trạng thái ở cuối kiểm tra lại.
  • Quay lại dữ liệu thanh trạng thái hệ thống Mở chiến lược cụ thể và chuyển sang Backtest Page để kiểm tra lại chiến lược. Trong cột Log Information của chiến lược được hiển thị sau khi kiểm tra lại, có một nút Download Table ở góc trên bên phải. Nhấp vào nó để tải xuống tệp định dạng CSV của dữ liệu nhật ký kiểm tra lại.

Sharpe thuật toán trong hệ thống kiểm tra ngược

Mã nguồn của thuật toán Sharpe trong hệ thống backtesting:

function returnAnalyze(totalAssets, profits, ts, te, period, yearDays) {
    // force by days
    period = 86400000
    if (profits.length == 0) {
        return null
    }
    var freeProfit = 0.03 // 0.04
    var yearRange = yearDays * 86400000
    var totalReturns = profits[profits.length - 1][1] / totalAssets
    var annualizedReturns = (totalReturns * yearRange) / (te - ts)

    // MaxDrawDown
    var maxDrawdown = 0
    var maxAssets = totalAssets
    var maxAssetsTime = 0
    var maxDrawdownTime = 0
    var maxDrawdownStartTime = 0
    var winningRate = 0
    var winningResult = 0
    for (var i = 0; i < profits.length; i++) {
        if (i == 0) {
            if (profits[i][1] > 0) {
                winningResult++
            }
        } else {
            if (profits[i][1] > profits[i - 1][1]) {
                winningResult++
            }
        }
        if ((profits[i][1] + totalAssets) > maxAssets) {
            maxAssets = profits[i][1] + totalAssets
            maxAssetsTime = profits[i][0]
        }
        if (maxAssets > 0) {
            var drawDown = 1 - (profits[i][1] + totalAssets) / maxAssets
            if (drawDown > maxDrawdown) {
                maxDrawdown = drawDown
                maxDrawdownTime = profits[i][0]
                maxDrawdownStartTime = maxAssetsTime
            }
        }
    }
    if (profits.length > 0) {
        winningRate = winningResult / profits.length
    }
    // trim profits
    var i = 0
    var datas = []
    var sum = 0
    var preProfit = 0
    var perRatio = 0
    var rangeEnd = te
    if ((te - ts) % period > 0) {
        rangeEnd = (parseInt(te / period) + 1) * period
    }
    for (var n = ts; n < rangeEnd; n += period) {
        var dayProfit = 0.0
        var cut = n + period
        while (i < profits.length && profits[i][0] < cut) {
            dayProfit += (profits[i][1] - preProfit)
            preProfit = profits[i][1]
            i++
        }
        perRatio = ((dayProfit / totalAssets) * yearRange) / period
        sum += perRatio
        datas.push(perRatio)
    }

    var sharpeRatio = 0
    var volatility = 0
    if (datas.length > 0) {
        var avg = sum / datas.length;
        var std = 0;
        for (i = 0; i < datas.length; i++) {
            std += Math.pow(datas[i] - avg, 2);
        }
        volatility = Math.sqrt(std / datas.length);
        if (volatility !== 0) {
            sharpeRatio = (annualizedReturns - freeProfit) / volatility
        }
    }

    return {
        totalAssets: totalAssets,
        yearDays: yearDays,
        totalReturns: totalReturns,
        annualizedReturns: annualizedReturns,
        sharpeRatio: sharpeRatio,
        volatility: volatility,
        maxDrawdown: maxDrawdown,
        maxDrawdownTime: maxDrawdownTime,
        maxAssetsTime: maxAssetsTime,
        maxDrawdownStartTime: maxDrawdownStartTime,
        winningRate: winningRate
    }
}
Trình soạn thảo chiến lược Chức năng nhập chiến lược