리소스 로딩... 로딩...

백테스트 시스템

양적 거래 전략의 디자인을 완료한 후, 전략의 논리와 전략의 수익 방향과 같은 전략의 기본 상황을 어떻게 알 수 있습니까? 물론, 우리는 실제 거래 시장에서 전략을 실행하기 위해 실제 돈을 직접 사용할 수 없지만, 우리는 전략을 테스트하고 역사적 데이터에서 전략의 이익을 알 수있는 역사적 데이터를 사용할 수 있습니다.

백테스트 시스템 모델

FMZ 퀀트 트레이딩 플랫폼은 백테스트 시스템을bot 수준그리고시뮬레이션 레벨. 보트 레벨은 전체 역사 데이터에 따라 완전히 백테스트를 수행하는 반면 시뮬레이션 레벨 백테스트를 생성tick역 테스트를 위해 규칙적인 간격에서 실제 K-라인 데이터에 따라 데이터를 사용합니다. 둘 다 실제 역사 데이터에 기반하고 있지만 bot 수준 데이터는 더 정확하고 결과는 더 신뢰할 수 있습니다. 그러나 역 테스트는 역사적 데이터에 따라 전략의 수행입니다. 역사적 데이터는 미래 시장을 완전히 표현할 수 없습니다. 역사적 시장은 반복 될 수 있습니다. 또는 블랙 스완으로 이어질 수도 있습니다. 따라서 역 테스트 결과는 합리적이고 객관적으로 취급되어야합니다.

시뮬레이션 레벨시뮬레이션된틱 데이터기본 K-라인 기간에 기초하여, 각 기본 K-라인 기간은 최대 12 개의 백테스트 시간 포인트를 생성합니다.실제 시장 수준백테스팅은 실제 수집된 초당 틱 데이터를 사용합니다. 데이터의 양은 매우 크고 백테스팅 속도는 느리기 때문에 매우 긴 시간 동안 백테스팅 할 수 없습니다. FMZ 퀀트의 백테스팅 메커니즘은 전략이 단일 K 라인에서 여러 번 거래 할 수 있도록 허용하여 거래가 종료 가격에서만 실행 될 수있는 상황을 피합니다. 백테스팅 속도를 고려하면서 더 정확합니다.

백테스팅 시스템 메커니즘 설명

  • 시뮬레이션 레벨 틱 의시뮬레이션 레벨백테스트 시스템의 기본 K-라인 데이터에 기반하여, 특정 알고리즘에 따라 주어진 기본 K-라인 바의 최고 가격, 최저 가격, 오픈 가격 및 종료 가격 값의 틀 내에서 백테스트에 틱 데이터를 시뮬레이션합니다. 백테스트 시간 시리즈에 실시간 틱 데이터로, 전략 프로그램이 인터페이스를 호출 할 때 반환됩니다. 자세한 내용은 다음을 참조하십시오.백테스팅 시스템 시뮬레이션 레벨 메커니즘 설명.

  • 봇 레벨 틱 봇 레벨 백테스트는 바 시간 계열의 실제 틱 레벨 데이터입니다. 틱 레벨 데이터에 기반한 전략의 경우 실제 시장 레벨을 사용하여 백테스트는 현실에 더 가깝습니다. 봇 레벨 백테스트에서 틱 데이터는 실제 기록 된 데이터이며 시뮬레이션 된 것이 아닙니다. 깊이 데이터, 시장 거래의 기록 데이터 재생, 사용자 정의 깊이 및 각 개별 거래 데이터를 지원합니다. 실제 시장 수준의 데이터 백테스트의 최대 크기는 최대 50MB입니다. 데이터 세트의 상한 범위 내에서 백테스트 시간 범위에 제한이 없습니다. 백테스트 시간 범위를 최대한 확대해야하는 경우 기어 깊이 설정의 값을 줄일 수 있으며 각 개별 거래 데이터를 사용하여 백테스트 시간 범위를 증가시키지 마십시오.GetDepth, GetTrades시장 데이터를 재생하는 기능을 얻습니다. 시간 라인에서 시장 데이터의 순간에, 전화GetTicker, GetTrades, GetDepth그리고GetRecords시간이 백테스트 타임라인에서 여러 번 움직일 때 시간을 밀어붙이지 않을 것입니다. 위의 함수 중 하나에 대한 반복적인 호출은 백테스트 타임라인에서 이동하기 위해 백테스트 시간을 밀어붙일 것입니다. 실제 시장 수준이 백테스트에 사용되면 이전 시간을 선택하는 것이 권장되지 않습니다. 조기 시간대에 실제 시장 수준 데이터가 없을 수 있습니다.

봇 레벨 틱그리고시뮬레이션 레벨 틱모드, 백테스트 시스템의 트랜잭션 매칭 메커니즘: 주문 트랜잭션 매칭은 보인 가격에 따라 수행되며 전체 볼륨이 거래됩니다. 따라서 부분 트랜잭션 시나리오는 백테스트 시스템에서 테스트 할 수 없습니다.

백테스팅 시스템은 여러 프로그래밍 언어를 지원합니다.

백테스팅 시스템은 다음과 같이 작성하고 설계된 백테스팅 전략을 지원합니다.JavaScript, TypeScript, Python, C++, PINE, MyLanguage, Blockly시각화. 그 후의 테스트자바스크립트그리고C++트레이딩 전략은 브라우저에서 수행되고 실제 시장 보트 또는WexApp에뮬레이션 교환 실제 시장 (즉WexAppFMZ 양 거래 플랫폼의 에뮬레이션 교환) 다른 소프트웨어, 라이브러리 또는 모듈을 설치하지 않고 실행됩니다. 그 후의 테스트파이썬도커에서 수행됩니다. FMZ 퀀트 트레이딩 플랫폼에 의해 추가 된 공개 서버에서 수행 될 수 있으며 사용자 자신의 도커에서도 수행 될 수 있습니다. 실제 시장 운영과 백테스트 모두파이썬도커가 위치한 시스템에 설치됩니다. 일부 라이브러리가 필요한 경우, 그들은 수동으로 설치해야합니다 (일반적인파이썬FMZ Quant 공공 서버에서 라이브러리가 지원됩니다.)

지원합니다.자바스크립트Chrome DevTools에서 전략 백테스팅 디버깅,참고로.

백테스팅 시스템에서 지원되는 교환

  • 암호화폐 암호화폐의 주류 현장 거래소 및 선물 거래소; 모든 유형의 거래소에 대한 데이터를 지원합니다.
  • 퓨투 증권 홍콩 주식, 미국 주식 그리고 다른 시장

백테스팅 시스템 매개 변수 최적화

FMZ 양자 거래 플랫폼의 백테스트 시스템의 매개 변수 최적화 기능은 백테스팅 중에 모든 매개 변수 최적화 옵션에 따라 매개 변수 조합을 설정하는 것입니다.최적화전략 매개 변수의 오른쪽에서 최적화 설정을 표시하는 옵션.

  • 최소 값: 매개 변수의 시작 값을 제한합니다.
  • 최대 값: 점진적 변경 후 매개 변수의 최대 값을 제한합니다.
  • 단계 크기: 매개 변수의 추가 변수 크기.
  • 동시다발적인 실: 매개 변수 최적화 도중, 각 백테스트 매개 변수 조합의 동시 실행을 위한 스레드의 수를 설정합니다. 이 옵션은 오직JavaScript, PINE, 그리고My Language, 템플릿에 대한 매개 변수 최적화를 지원하지 않습니다.

매개 변수 조합은minimum, maximum, 그리고step size설정. 백테스팅 시스템은 이러한 매개 변수 조합을 통해 백테스팅을 반복합니다.번호backtesting 시스템에서 최적화 될 수 있습니다.

백테스트 설정을 저장

이 지역에서는전략 편집 페이지, Backtest (즉 백테스트 시스템) 의 페이지링에서 전략을 백테스트하기 위해 백테스트 구성 및 전략 매개 변수와 같은 옵션을 설정할 수 있습니다. 백테스트 설정은 백테스트 시간 범위, 교환 플랫폼, 슬립포인트 및 서비스 수수료 등을 참조합니다. 전략 매개 변수는 전략을 위한 매개 변수 옵션을 설정하는 데 사용됩니다. 이 매개 변수가 설정되면, set backtesting 전략을 따라가면, set 구성 정보를 어떻게 저장할 수 있을까요?

    1. Backtest 설정 저장 버튼을 사용할 수 있습니다전략 편집 페이지모든 백테스트 구성 정보를 (백테스트 설정 및 전략 매개 변수 설정 포함) 코드 형태로 전략 소스 코드에 기록합니다.
    1. 전략 편집 페이지의 Save Strategy 버튼을 클릭하여 전략을 저장하면 플랫폼은 현재 백테스트 설정, 전략 매개 변수 구성 및 기타 정보를 자동으로 기록합니다. 어떻게 백테스트 구성을 백테스트 시스템에 로드합니까?
    1. 전략 편집 페이지를 갱신하거나 이 전략 편집 페이지를 다시 열 때, Backtest Settings 버튼에 의해 기록된 백테스트 구성 정보는 먼저 자동으로 로드됩니다.
    1. 현재 전략 코드에서 코멘트로 기록된 백테스트 구성 정보가 없다면backtest(Save Backtest Settings 버튼을 통해 전략 코드에 저장), 백테스트 시스템은 자동으로 백테스트 설정이 현재 전략에 대한 Save Strategy 버튼이 마지막으로 클릭되었을 때 백테스트 구성 정보로 구성됩니다.
    1. 전략 코드의 시작에 댓글 형태로 기록 된 백테스트 구성 정보가 전략 편집 페이지에서 수정되면 현재 업데이트 된 백테스트 구성 정보를 전략 백테스트 인터페이스 옵션에 동기화해야합니다.backtest전략 편집 영역에서.
/*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"}]
*/

클릭 하 여 Backtest 설정을 저장 하 여, 약간의 형식 차이점이 있습니다JavaScript/Python/C++/MyLanguage/PINE전략 코드로 백테스트 설정을 저장할 때 언어: 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"}]
*)

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"}]
*/

사용자 지정 데이터 소스

FMZ 양자 거래 플랫폼의 백테스팅 시스템은 사용자 지정 데이터 소스를 지원합니다. 백테스팅 시스템은GET사용자 지정 URL (공중 접근 가능한 URL) 를 요청하는 방법. 백테스트를 위한 외부 데이터 소스를 얻기 위해 추가 요청 매개 변수는 다음과 같습니다.

매개 변수 의미 설명
기호 기호 이름 포트 시장 데이터, 예를 들어:BTC_USDT, 선물 시장 데이터, 예를 들어:BTC_USDT.swap, 미래에셋 상시 계약금융율 데이터, 예를 들어:BTC_USDT.funding, 퓨처스 영구 계약 가격 지수 데이터, 예를 들어:BTC_USDT.index
eid 교환 예를 들어 OKX, Futures_OKX
둥글다 데이터 정확성 True는 사용자 지정 데이터 소스가 입력하는 데이터에서 특정 정밀도가 정의된다는 것을 의미합니다. FMZ 양자 거래 플랫폼 백테스팅 시스템이 사용자 지정 데이터 소스에 보내는 요청은 다음과 같이 고정됩니다.round=true
기간 K-라인 데이터 기간 (밀리 초) 예를 들어:600001분 분량입니다
깊이 깊이 레벨 1-20
무역 데이터 분할 필요 여부 true(1) / false(0)
에서 시작 시간 유닉스 시간표
종말 시대 유닉스 시간표
세부사항 기호에 대한 세부 정보를 요청 true는 사용자 지정 데이터 소스가 제공되어야한다는 것을 의미합니다. FMZ 양자 거래 플랫폼 백테스팅 시스템에서 사용자 지정 데이터 소스에 전송되는 요청은 다음과 같이 고정됩니다.detail=true
관습 이 매개 변수는 무시할 수 있습니다.

스팟 거래소 및 선물 거래소 객체의 데이터 소스가 사용자 지정 데이터 소스 (피더) 로 설정되면 백테스팅 시스템은 사용자 지정 데이터 소스 서비스에 요청을 전송합니다.

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

데이터 형식

반환 된 형식은 다음 두 가지 형식 중 하나여야 합니다. 시스템에서 자동으로 인식됩니다):

  • 시뮬레이션 레벨 Tick, 다음은 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]
        ]
    }
    
  • 보트 레벨 틱, 다음은 JSON 데이터의 예입니다: 틱 레벨 백테스트 데이터 (시장의 깊이에 대한 정보를 포함하고, 깊이 형식은[price, volume]수차례 깊이가 있을 수 있습니다.asks가격 상승 순서에서는bids가격 하락 순서)

    {
        "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]
        ]
    }
    
필드 설명
세부사항 요청된 데이터 유형에 대한 자세한 정보

통화 이름, 거래 통화, 정확성, 최소 주문량 등등 스키마. 데이터의 열의 속성을 지정합니다. 대문자 감수성이 있고 시간적 제한이 있는 배열입니다. 높은, 낮은, 닫는, 볼, 요청, 제안, 거래 데이터. 기둥 구조, 스케마에 따라 기록된 데이터. 설정.

세부 필드

필드 설명
eid 거래 ID, 점유 및 선물의
어떤 교환은 다른 효력을 가지고 있습니다.
기호 거래 상품 코드
별명 현재에 대응하는 교환의 기호
거래 상품 코드
기본 통화 거래 통화
코트화폐 지폐
마진화폐 마진 화폐
기본정확성 거래 통화 정확성
인용어정확함 가격화 통화 정확성
분량 최소 주문량
최대 최대 주문량
미노니셔널 최소 주문 금액
최대 최대 주문 금액
가격표 가격 점프
부피 주문 양의 최소 변화 값 (한 점프)
주문량)
마진수준 미래에셋자산의 레버리지 가치
계약 유형 상시계약은 다음과 같습니다.swap, 그

백테스트 시스템은 재정율과 가격 인덱스를 계속 보낼 것입니다. 요청합니다.

특별 열 속성asks, bids, trades:

필드 설명 언급
요청/입찰 [가격, 부피],...] 예를 들어,

Live Trading Level Tick데이터 예제:[[9531300, 10]]자, 이제 시작해보죠. 트레이드 시간, 방향, 가격, 규모,... 예를 들어,Live Trading Level Tick데이터 예제:[[1564315200000, 0, 9531300, 10]] |

미래에셋 거래소의 영구 계약에 대한 역 테스트를 할 때, 사용자 정의 또한 데이터 소스에는 추가적인 지원율 데이터와 가격도 필요합니다. 백테스팅 시스템은 계속 요청을 보낼 것입니다. 요청된 시장 데이터가 반환될 때만 그리고 반환 구조의 세부 필드는"contractType": "swap"키-값 쌍

백테스팅 시스템이 자금율 데이터를 받을 때, 가격지수 데이터를 계속 요청합니다.

자금 조달 비율 데이터 구조는 다음과 같습니다.

{
    "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
        ]
        // ...
    ]
}
  • 인접한 기간 사이의 간격은 8시간입니다.
  • 예를 들어, 바이낸스의 자금율은 8시간마다 업데이트됩니다. 자금율 자료는 -16795인가요? 왜냐하면 K-라인 데이터와 마찬가지로 네트워크 전송 중에 부동 소수점 정밀의 손실을 피하기 위해 데이터는 정수 유형을 사용하기 때문에, 자금 조달율 데이터는 또한 부정적일 수 있기 때문입니다.

백테스팅에서 지원율 데이터 요청의 예제 시스템은 다음과 같습니다.

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

가격지수 데이터 구조는 다음과 같습니다.


{
    "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],
        // ...
    ]
}

백테스팅에 의해 전송된 가격 지표 데이터 요청의 예 시스템은 다음과 같습니다.

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

사용자 지정 데이터 소스의 예제

데이터 소스 주소를 지정합니다.http://120.24.2.20:9090/data사용자 지정 데이터 소스 서비스 프로그램은Golang:

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

테스트 전략JavaScript예를 들어:

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

로컬 백테스트 엔진

FMZ 퀀트 트레이딩 플랫폼은JavaScript언어와Python로컬 백테스트 엔진의 언어, 백테스팅 중에 기본 K-라인 기간을 설정하는 것을 지원합니다.

백테스트 페이지 단축키

  • 전략 편집 페이지와 백테스팅 페이지 사이를 전환하는 단축키 열쇠를 사용하세요Ctrl +,다시 Backtest 페이지와 Edit Strategy 페이지로 전환합니다.Ctrl키를 누르세요,.

  • 저장 전략을 위한 단축키 열쇠를 사용하세요Ctrl + s전략을 구하기 위해서요.

  • 전략 백테스트를 시작하는 단축키 열쇠를 사용하세요Ctrl + bStart Backtest을 활성화하기 위해

백테스트 데이터 다운로드

  • 백테스팅 시스템 로그 데이터 다운로드 특정 전략을 열고 전략을 백테스트하기 위해 백테스트 페이지로 전환하십시오. 백테스트 후에 표시되는 전략의 상황 정보 열에 오른쪽 상단에있는 다운로드 테이블 버튼이 있습니다. 백테스트의 끝에 상태 열 데이터의 CSV 파일을 다운로드하기 위해 클릭하십시오.
  • 백테스팅 시스템 상태 표시줄 데이터 다운로드 특정 전략을 열고 전략을 백테스트하기 위해 백테스트 페이지로 전환합니다. 백테스트 후에 표시되는 전략의 로그 정보 열에는 오른쪽 상단에있는 다운로드 테이블 버튼이 있습니다. 그것을 클릭하여 백테스트 로그 데이터의 CSV 형식 파일을 다운로드하십시오.

백테스팅 시스템에서의 샤프 알고리즘

백테스팅 시스템에서의 샤프 알고리즘의 소스 코드:

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
    }
}
전략 편집자 전략 입력 기능