거래 전략 개발 경험

저자:선함, 2019-09-05 11:49:31, 업데이트: 2023-11-07 20:48:06

img

이 문서의 목적은 전략 개발에 대한 몇 가지 경험과 몇 가지 팁을 설명하는 것입니다. 이는 독자가 거래 전략 개발의 핵심 사항을 신속하게 파악 할 수 있도록합니다.

어떤 전략 설계에서 비슷한 세부 사항을 발견하면 즉시 합리적인 해결책을 찾을 수 있습니다.

우리는 FMZ 퀀트 플랫폼을 설명, 테스트 및 연습의 예로 사용합니다.

전략 프로그래밍 언어 우리는 자바스크립트를 사용할 것입니다

트레이딩 타겟은 블록체인 자산 시장 (BTC, ETH 등) 을 대상으로 합니다.

데이터 수집 및 처리

일반적으로 전략 논리에 따라 다음과 같은 다른 인터페이스를 사용하여 시장 데이터를 얻을 수 있습니다. 대부분의 전략 논리는 시장 데이터에 의해 구동됩니다. (물론 고정 투자 전략과 같은 일부 전략은 가격 데이터를 신경 쓰지 않습니다.)

  • GetTicker: 실시간 틱 코팅을 받습니다. 일반적으로 현재 최신 가격을 빠르게 얻기 위해 사용 됩니다.

  • '그트데프스' (GetDepth) 는 주문번호부에서 주문 깊이를 얻습니다. 일반적으로 주문 포스트 깊이의 각 계층의 가격과 미뤄진 주문의 크기를 얻기 위해 사용됩니다. 헤지 전략, 시장 제작 전략 등에 사용됩니다.

  • GetTrade: 시장의 최신 거래 기록을 얻습니다. 일반적으로 짧은 시기의 시장 행동을 분석하고 시장의 미세한 변화를 분석하는 데 사용됩니다. 일반적으로 고주파 전략 및 알고리즘 전략에 사용됩니다.

  • GetRecords: 시장 K-라인 데이터를 얻는다. 일반적으로 트렌드 추적 전략 및 지표를 계산하는 데 사용됩니다.

결함 허용

전략 수립 시, 초보자는 보통 다양한 오류를 무시하고 직관적으로 전략의 각 부분의 결과가 확립되었다고 믿는다. 그러나 이것은 사실이 아니다. 전략 프로그램의 운영에서 시장 데이터를 요청할 때, 당신은 다양한 예기치 않은 상황에 직면할 것이다.

예를 들어, 일부 시장 인터페이스는 실행되지 않은 데이터를 반환합니다.

var depth = exchange.GetDepth()

// depth.Asks[0].Price < depth.Bids[0].Price "Selling 1" price is lower than "buying 1" price, this situation cannot exist on the market.
// Because the selling price is lower than the buying price, the order must have been executed.
// depth.Bids[n].Amount = 0 Order book buying list "nth" layer, order quantity is 0
// depth.Asks[m].Price = 0 Order book selling list "mth" layer, the order price is 0

또는 바로 exchange.GetDepth() 는 null값을 반환합니다.

이런 이상한 상황이 많이 있습니다. 따라서 이러한 예측 가능한 문제를 처리해야합니다. 이러한 처리 방식은 오류 용인 처리라고합니다.

오류를 처리하는 일반적인 방법은 데이터를 폐기하고 다시 얻는 것입니다.

예를 들어:

function main () {
     while (true) {
         onTick()
         Sleep(500)
     }
}

function GetTicker () {
     while (true) {
         var ticker = exchange.GetTicker()
         if (ticker.Sell > ticker.Buy) { // Take the example of fault-tolerant processing that detects whether the "Selling 1" price is less than the "Buying 1" price.
                                               // Exclude this error, the current function returns "ticker".
             Return ticker
         }
         Sleep(500)
     }
}

function onTick () {
     var ticker = GetTicker() // Make sure the "ticker" you get doesn't exist the situation that "Selling 1" price is less than the "Buying 1" price.
     // ... specific strategy logic
}

다른 예측 가능한 오류 용인 프로세스에도 비슷한 접근 방식을 사용할 수 있습니다.

디자인 원칙은 전략 논리를 이끌어내기 위해 잘못된 논리를 절대 사용할 수 없다는 것입니다.

K선 데이터 사용

K 라인 데이터 획득, 호출:

var r = exchange.GetRecords()

얻은 K 직선 데이터는 다음과 같은 배열입니다.

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

각 커리 브래시에는 시간, 오픈 가격, 최고 가격, 최저 가격, 종료 가격, 그리고 볼륨이 포함되어 있습니다.

이것은 K선 바입니다. 일반적인 K선 데이터는 이동 평균, MACD 등과 같은 지표를 계산하는 데 사용됩니다.

K-라인 데이터는 매개 변수 (무료 데이터) 로 전달되고, 그 다음 지표 매개 변수는 지표 데이터의 함수를 계산하기 위해 설정됩니다.

FMZ Quant 양적 거래 플랫폼에는 많은 지표 기능이 있습니다.

예를 들어, 우리는 이동 평균 지표를 계산합니다. 통과된 K-선 데이터의 주기에 따라, 우리는 해당 주기의 이동 평균을 계산합니다.

예를 들어, 통과 K-라인 데이터 (한 K-라인 바는 하루를 나타냅니다), 일일 평균 라인을 계산합니다. 같은 것, 통과 평균 지표 함수의 K-라인 데이터가 1 시간 주기가라면 계산 된 지표는 1 시간 이동 평균입니다.

보통 우리는 지표를 계산할 때 문제를 무시합니다. 만약 제가 5일 이동평균 지표를 계산하고 싶다면, 먼저 매일 K-라인 데이터를 준비합니다.

var r = exchange.GetRecords(PERIOD_D1) // Pass parameters to the "GetRecords" function "PERIOD_D1" specifies the day K line to be acquired.
                                       // Specific function using method can be seen at: https://www.fmz.com/api#GetRecords

매일 K-라인 데이터로 이동평균 지표를 계산할 수 있습니다. 5일 이동평균을 계산하고 싶다면,

var ma = TA.MA(r, 5) // "TA.MA()" is the indicator function used to calculate the moving average indicator. The first parameter sets the daily K-line data r just obtained.
                             // The second parameter is set to 5. The calculated 5-day moving average is the same as the other indicators.

우리는 잠재적인 문제를 간과했습니다. 만약 K선 데이터의 K선 바의 수가 5보다 작다면, 유효한 5일 이동평균을 계산하기 위해 어떻게 할 수 있을까요?

답은 당신이 할 수 있는 게 없다는 겁니다.

왜냐하면 이동 평균 지표는 K-라인 바의 특정 수의 폐쇄 가격의 평균이기 때문입니다.

img

따라서, K-라인 데이터와 지표 함수를 사용하여 지표 데이터를 계산하기 전에, K-라인 데이터에 있는 K-라인 바의 수가 지표 계산 조건 (지표 매개 변수) 을 만족하는지 여부를 결정해야 한다.

5일 이동평균을 계산하기 전에 먼저 확인해야 합니다.

function CalcMA () {
     var r = _C(exchange.GetRecords, PERIOD_D1) // _C() is a fault-tolerant function, the purpose is to avoid r being null, you can get more information at: https://www.fmz.com/api#_C
     if (r.length > 5) {
         Return TA.MA(r, 5) // Calculate the moving average data with the moving average indicator function "TA.MA", return it as a function return value.
     }

     Return false
}

function main () {
     var ma = CalcMA()
     Log(ma)
}

img

백테스트 표시:

[null,null,null,null,4228.7,4402.9400000000005, ... ]

계산된 5일 이동평균 지표를 볼 수 있습니다. 첫 4개는 0이 됩니다. 왜냐하면 K선 바의 수가 5개 미만이기 때문에 평균을 계산할 수 없습니다. 5번째 K선 바에 도달하면 계산할 수 있습니다.

K-line 업데이트를 판단하는 팁

우리가 전략을 작성할 때, 종종 이러한 시나리오가 있습니다. 예를 들어, 전략은 각 K-라인 사이클이 완료되면 어떤 연산을 처리하거나 어떤 로그를 인쇄해야 합니다.

이러한 기능을 어떻게 구현할 수 있을까요? 프로그래밍 경험이 없는 초보자에게는 문제가 될 수 있습니다. 여기 우리는 해결책을 제공합니다.

K-라인 바 사이클이 완료되었다는 판단 방법. 우리는 K-라인 데이터의 시간 속성에서 시작할 수 있습니다. K-라인 데이터를 얻을 때마다, 우리는이 K-라인 데이터의 마지막 K-라인 바의 시간 속성을 변화하는지 아닌지 판단합니다. 변경되면 새로운 K-라인 바가 생성되었음을 의미합니다 (새로 생성된 K-라인 바의 이전 K-라인 바 사이클이 완료되었음을 증명합니다), 변화가 없다면 새로운 K-라인 바가 생성되지 않았다는 것을 의미합니다 (현행 마지막 K-라인 바 사이클은 아직 완료되지 않았습니다).

그래서 우리는 K-라인 데이터의 마지막 K-라인 바의 시간을 기록하는 변수가 필요합니다.

var r = exchange.GetRecords()
var lastTime = r[r.length - 1].Time // "lastTime" used to record the last K-line bar time.

실제로는 일반적으로 다음과 같습니다.

function main () {
     var lastTime = 0
     while (true) {
         var r = _C(exchange.GetRecords)
         if (r[r.length - 1].Time != lastTime) {
             Log ("New K-line bar generated")
             lastTime = r[r.length - 1].Time // Be sure to update "lastTime", this is crucial.

             // ... other processing logic
             // ...
         }

         Sleep(500)
     }
}

img

당신은 백테스트에서 볼 수 있습니다, K 라인 사이클은 매일로 설정됩니다exchange.GetRecordsfunction가 호출되고, 백테스트에 따라 설정된 K 라인 사이클이 기본 매개 변수입니다.) 새로운 K 라인 바가 표시될 때마다 로그를 인쇄합니다.

숫자 값 계산

  • 교환 인터페이스에 액세스하는 데 소요되는 시간을 계산

만약 당신이 특정 표시 또는 전략이 거래소 인터페이스에 액세스하는 데 걸리는 시간에 대한 통제를 원한다면, 당신은 다음 코드를 사용할 수 있습니다:

function main () {
     while (true) {
         var beginTime = new Date().getTime()
         var ticker = exchange.GetTicker()
         var endTime = new Date().getTime()

         LogStatus(_D(), "GetTicker() function time-consuming:", endTime - beginTime, "millisecond")
         Sleep(1000)
     }
}

간단히 말해서, 시간표는GetTicker이 함수는 호출 전 시간표에서 빼어내고 경험한 밀리 초의 수를 계산합니다.GetTicker실행부터 반환까지

  • Math.min / Math.max을 사용하여 값의 상단 및 하단 한도를 제한합니다

예를 들어, 판매 주문을 하는 과정에서 판매 주문의 금액은 계좌에 있는 동전 수보다 크지 않아야 합니다. 왜냐하면 그것이 계좌에 있는 동전 수보다 많으면 순서가 오류를 일으킬 것이기 때문입니다.

우리는 이것을 이렇게 제어합니다.

예를 들어, 우리는 0.2 코인을 단축 판매할 계획입니다.

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

이렇게 하면 주문 수가 계좌에 있는 코인 수를 초과하지 않을 수 있습니다.

같은 이유로,Math.max값의 하단 한도를 보장하는 데 사용됩니다.

  • 보통 어떤 장면에 적용되나요?

일반적으로 일반적인 거래소는 특정 거래 쌍에 대한 최소 전송 주문 제한을 가지고 있습니다. 최소 금액보다 낮으면 주문이 거부됩니다. 이것은 또한 프로그램 실패를 유발합니다.

BTC가 보통 0.01의 최소 주문 양을 가지고 있다고 가정합니다.

트레이딩 전략은 때때로 0.01보다 작은 주문 양을 초래할 수 있습니다. 그래서 우리는 사용할 수 있습니다Math.max최소한의 주문량을 보장하기 위해서요.

  • 주문량, 가격 정확성 통제

정밀도는_N()기능 또는SetPrecision function.

SetPrecision()함수는 한 번만 설정해야 하며, 순서 양과 가격 값의 소수점은 자동으로 시스템에서 줄여집니다.

_N()함수는 특정 값에 대한 소수점 단축 (정밀 제어) 을 수행하는 것입니다.

예를 들어:

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

π의 값은 소수점으로 줄이고, 소수점 2개가 예약되어 있습니다.

자세한 내용은 API 문서를 참조하십시오.

일부 논리 설정

  • 타이밍, 특정 기간 동안 어떤 작업을 수행

이러한 메커니즘을 사용하여 타임 스탬프 탐지 방법을 사용하여 예정된 작업이 실행된 마지막 시간의 타임 스탬프를 빼고 현재 타임 스탬프를 결정하고 실시간으로 경과 시간을 계산할 수 있습니다. 경과 시간이 특정 설정된 시간 길이를 초과하면. 그 후에 새로운 작업이 수행됩니다.

예를 들어, 고정 투자 전략에서 사용되죠.

var lastActTime = 0
var waitTime = 1000 * 60 * 60 * 12 // number of milliseconds a day
function main () {
     while (true) {
         var nowTime = new Date().getTime()
         if (nowTime - lastActTime > waitTime) {
             Log ("Execution Fixed")
             // ... specific fixed investment operation, buying operation.


             lastActTime = nowTime
         }

         Sleep(500)
     }
}

이것은 간단한 예입니다.

  • 전략에 대한 자동 회수 메커니즘 설계

FMZ 양을 사용함_G()저장 함수를 종료하면 저장 진행을 종료하고 자동 복구 상태를 다시 시작하는 전략을 설계하는 것이 편리합니다.

var hold = {
     Price : 0,
     Amount : 0,
}

function main () {
     if (_G("hold")) {
         var ret = _G("hold")
         hold.price = ret.price
         hold.amount = ret.amount
         Log("restore hold:", hold)
     }

     var count = 1
     while (true) {
         // ... strategy logic
         // ... In the strategy operation, it is possible that when opening a position, then assign the position price of the open position to "hold.price", and the amount of open positions is assigned to "hold.amount" to record the position information.

         hold.price = count++ // simulate some values
         hold.amount = count/10 // Simulate some values

         Sleep(500)
     }
}

function onexit () { // Click the stop button on the robot to trigger the execution of this function. After the execution, the robot stops.
     _G("hold", hold)
     Log("save hold:", JSON.stringify(hold))
}

img

이 자료들은hold로봇이 멈추는 때마다 객체가 저장됩니다. 그리고 데이터가 다시 시작될 때마다 데이터가 읽히고hold정지 전 상태로 복원됩니다.

물론 위의 예는 간단한 예입니다. 실제 거래 전략에서 사용되는 경우 전략에 복원해야 할 주요 데이터 (일반적으로 계정 정보, 위치, 이익 가치, 거래 방향 등) 에 따라 설계되어야합니다.

또한, 당신은 또한 복원하기 위해 몇 가지 다른 조건을 설정할 수 있습니다.

이것은 거래 전략을 개발하는 몇 가지 팁입니다, 그리고 나는 그것이 초보자 도움이 될 수 있기를 바랍니다!

실습 훈련은 자기 자신을 향상시키는 가장 빠른 방법입니다. 여러분 모두에게 행운을 빌겠습니다.


관련

더 많은