[TOC] 이 튜토리얼은 API 도입, 백테스트, 차트 및 기타를 포함한 전략 작성에 대한 기본 지식을 포함합니다. 이 기본 튜토리얼을 배운 후 사용자는 기본 API를 능숙하게 사용하고 안정적인 봇 전략을 작성할 수 있습니다. 튜토리얼을 배우기 전에, 사용 방법을 배워야합니다.FMZ 퀀트 플랫폼을 시작하세요.
구 버전의 튜토리얼:FMZ 퀀트 (FMZ.COM) 전략 작성 설명서 2.0 (교습); 이 튜토리얼에는 많은 게시물 인덱스가 있는데, 읽어보시기 바랍니다.
프로그램 트레이딩 (Program Trading) 은 프로그램을 사용하여 API를 통해 플랫폼과 연결하여 설계 의도에 따라 자동 구매 및 판매 또는 기타 기능을 달성하는 것을 의미합니다. API는 응용 프로그램 프로그래밍 인터페이스를 나타냅니다.
현재 암호화폐 플랫폼에는 REST 및 Websocket의 두 가지 주요 인터페이스 프로토콜이 있습니다. REST 프로토콜이 데이터를 획득할 때마다 한 번 액세스해야합니다. 예를 들어 시뮬레이션 플랫폼
{"data:{"buy":"11351.73","high":"11595.77","last":"11351.85","low":"11118.45","open":"11358.74","quoteVol":"95995607137.00903936","sell":"11356.02","time":1565593489318,"vol":"3552.5153"}}
이 방법으로, 거래 쌍 BTC_USDT의 최신 시장 코트를 따르는 거래가
FMZ 퀀트 거래 플랫폼은 모든 플랫폼의 REST 인터페이스를 캡슐화하고 통일된 호출 방식과 통일된 데이터 형식을 사용하여 전략 작성을 단순하고 일반화합니다. 웹소켓은 FMZ 플랫폼에서 쉽게 지원 할 수 있으며 다음 튜토리얼에서 자세히 소개 될 것입니다.
FMZ 플랫폼 API 문서의 대부분의 부분은 자바스크립트를 예로 사용하지만, 캡슐화 때문에 서로 다른 언어들 사이에 거의 차이가 없으며 문법 문제에만 주의를 기울여야 합니다.
파이썬은 다양한 버전을 가지고 있기 때문에, 프로그램 초에 지정될 수 있습니다.#!Python2
그리고#!Python3
. 자바스크립트는 최근 ES6 문법을 업그레이드했으며, 관심있는 사람들은 그것에 대해 배울 수 있습니다. 동일한 기능을 가진 파이썬과 자바스크립트 코드는 아래에 표시됩니다. 문법 차이만 있음을 알 수 있으므로 API 문서는 자바스크립트의 예제만 제공하며, 이 튜토리얼은 또한 파이썬의 특수 사용 사례를 고려할 것입니다.
#python code
def main():
while True:
Log(exchange.GetAccount().Balance)
Sleep(2000)
#the corresponding Js code
function main(){
while(true){
Log(exchange.GetAccount().Balance)
Sleep(2000)
}
}
FMZ 퀀트 플랫폼은
전략 프로그램은 코드 명령어에서 실행되는 정상적인 프로그램과 동일합니다. 특별한 부분은
특수 동작을 가진 다른 기능들은 다음과 같이 표시됩니다.
function onTick(){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
//write the strategy logic here, and it will be called ever 6 seconds
}
function main(){
while(true){
onTick()
Sleep(6000)
}
}
이전 예제에서 네트워크 액세스 오류가 발생하면 전략이 직접 중단 될 수 있습니다. 자동 재부팅과 유사한 전략을 원하고 멈추지 않을 경우 bot 전략에서
function onTick(){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
//write the strategy logic here, and it will be called ever 6 seconds
}
function main(){
try{
while(true){
onTick()
Sleep(6000)
}
}catch(err){
Log(err)
}
}
플랫폼 관련 API를 호출할 때 플랫폼과 거래 쌍을 지정해야 합니다.exchange
예를 들어, 어떤exchange.GetTicker()
이
FMZ 퀀트 플랫폼은 여러 exchanges
배열을 나타낼 수 있습니다.exchanges[0]
그리고exchanges[1]
...그리고 그 다음으로, 보트를 만들 때 덧셈 순서에 따라.BTC_USDT
, 이전
물론, 우리가 많은 거래 쌍을 운영한다면, 이 방법은 매우 불편할 것입니다. 이 상황에서, 우리는 SetCurrency를 사용하여 거래 쌍을 전환할 수 있습니다.exchange.SetCurrency("BTC_USDT")
이 경우, 거래 쌍은exchange
되죠BTC_USDT
, 거래 쌍을 변경하기 위한 다음 호출까지 유효합니다.참고로 백테스트는 최근 거래 쌍을 전환하는 것을 지원합니다.아래는 구체적인 예입니다.
var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT"]
var buyValue = 1000
function main(){
for(var i=0;i<symbols.length;i++){
exchange.SetCurrency(symbols[i])
var ticker = exchange.GetTicker()
var amount = _N(buyValue/ticker.Sell, 3)
exchange.Buy(ticker.Sell, amount)
Sleep(1000)
}
}
이전 예제에서 언급했듯이, 시장 인터페이스는 일반적으로 모든 사람이 액세스 할 수있는 공개 인터페이스입니다. 일반적인 시장 인터페이스는: GetTicker, GetDepth, GetRecords 및 GetTrades입니다. 시장 코트는 거래 판단을 내리는 전략의 기초입니다. 나중에 하나씩 소개 할 것입니다. 직접
각 인터페이스는 일반적으로Info
필드, 플랫폼에서 반환 된 원래 데이터 문자열을 대표하고 추가 정보를 보충하는 데 사용할 수 있습니다. 사용 전에 분석해야합니다. 자바스크립트는JSON.parse()
, 파이썬은 json 라이브러리를 사용합니다.Time
이 필드는 요청의 시간표를 나타냅니다. 이는 지연을 판단하는 데 사용될 수 있습니다.
보트에서 어떤 API를 사용할 때, 액세스 실패하고 돌아올 수 있습니다null
, 그리고 파이썬은 반환None
. 이 때 사용중인 데이터는 오류를 보고하여 봇이 멈추게 됩니다. 그래서 오류 용도는 매우 중요합니다. 이 튜토리얼에서는 오류 용도를 특별히 소개합니다.
GetTicker는 아마도 가장 일반적으로 사용되는 인터페이스입니다. 마지막으로 실행 된 가격, 구매1 가격 및 판매1 가격 및 최신 거래량 등을 찾을 수 있습니다. 주문을하기 전에 실행 된 가격을 틱어 정보에 따라 결정할 수 있습니다. 봇 반환의 예:{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}
.
function main() {
var ticker = exchange.GetTicker()
Log(ticker) //return ticker in the debugging tool, and you can see the specific result
Log('Last time executed price:',ticker.Last, 'Buy1 price:', ticker.Buy)
}
대기 중인 주문의 깊이 정보를 얻기 위해 GetDepth를 사용한다. GetTicker에는 구매 1과 판매 1가격이 포함되어 있지만, 더 깊은 대기 중인 주문을 검색하려면 이 인터페이스를 사용하여 일반적으로 200개의 대기 중인 주문을 상하하하하하하 확인할 수 있다. 이 인터페이스를 사용하여 쇼크 가격을 계산할 수 있다. 아래는 실제 반환 결과이다. 그 중,
{
"Info":null,
"Asks":[
{"Price":5866.38,"Amount":0.068644},
{"Price":5866.39,"Amount":0.263985},
......
]
"Bids":[
{"Price":5865.13,"Amount":0.001898},
{"Price":5865,"Amount":0.085575},
......
],
"Time":1530241857399
}
Ask & Bids에 GetDepth를 사용하는 예제:
function main() {
var depth = exchange.GetDepth()
Log('Buy 1 price:', depth.Bids[0].Price, 'Sell 1 price:', depth.Asks[0].Price)
}
GetRecords는 가장 일반적으로 사용되는 인터페이스 중 하나이며, 다양한 지표를 계산하는 기초가 되는 장기간에 걸쳐 가격 정보를 반환 할 수 있습니다. K-라인 기간이 지정되지 않으면 bot을 추가 할 때 기본 기간을 사용하는 것을 의미합니다. K-라인 길이는 지정 할 수 없으며 시간이 지남에 따라 계속 증가 할 것입니다. 최대 수는 2000이며 첫 번째 호출에서 숫자는 약 200입니다. 마지막 K-라인은 최신 K-라인이기 때문에 시장 코팅이 변경됨에 따라 데이터가 변경됩니다. 첫 번째 K-라인은 가장 오래된 데이터입니다.
exchange.SetMaxBarLen(Len)
처음으로 획득한 K-라인의 수를 설정할 수 있습니다 (일부 플랫폼에서 지원됩니다) 그리고 최대 K-라인 수를 설정할 수 있습니다.예를 들어:exchange.SetMaxBarLen(500)
.
GetRecords는 PERIOD_M1: 1 분, PERIOD_M5: 5 분, PERIOD_M15: 15 분, PERIOD_M30: 30 분, PERIOD_H1: 1 시간 및 PERIOD_D1: 1 일과 같은 기간을 지정할 수 있습니다. 특정 사용은exchange.GetRecords(PERIOD_M1)
. 최신 도커를 업그레이드 한 후, 기간의 두 번째 숫자를 매개 변수로 전달하는 기간 사용자 정의를 지원합니다. 1 분 수준의 사용자 정의는 1 분 K 라인에 따라 합성되며, 1 분 이하의 K 라인은 GetTrades (()) 를 통해 합성되며, 상품 선물은 틱에 따라 합성됩니다.다른 대문자 변수들도 있습니다.PERIOD_M1
이 튜토리얼에서. 그들은 FMZ의 기본 글로벌 변수입니다. 당신이 관심이 있다면, 당신은 자신의 특정 값을 직접 로그 할 수 있습니다..
반환 데이터 예제:
[
{"Time":1526616000000,"Open":7995,"High":8067.65,"Low":7986.6,"Close":8027.22,"Volume":9444676.27669432},
{"Time":1526619600000,"Open":8019.03,"High":8049.99,"Low":7982.78,"Close":8027,"Volume":5354251.80804935},
{"Time":1526623200000,"Open":8027.01,"High":8036.41,"Low":7955.24,"Close":7955.39,"Volume":6659842.42025361},
......
]
반복된 K-라인 예제:
function main(){
var close = []
var records = exchange.GetRecords(PERIOD_H1)
Log('total bars: ', records.length)
for(var i=0;i<records.length;i++){
close.push(records[i].Close)
}
return close
}
GetTrades는 특정 시간 범위 내에서 거래 데이터를 얻습니다 (당신의 자신의 거래 데이터가 아닙니다), 일부 플랫폼에서 지원되지 않습니다. 일반적으로 사용되지 않으며 API 문서의 자세한 소개를 확인할 수 있습니다.
이 인터페이스는 계정과 관련이 있으므로 직접 얻을 수 없습니다. 그들을 얻기 위해서는 API-KEY를 사용하여 서명해야합니다. FMZ 플랫폼의 통일 자동 배경 처리 후에 직접 사용할 수 있습니다.
계정 정보를 얻기 위해 GetAccount을 사용한다. 가장 일반적으로 사용되는 인터페이스 중 하나로서, 충분한 잔액을 피하기 위해 주문을 하기 전에 호출되어야 한다. 반환 결과는 다음과 같다:{"Stocks":0.38594816,"FrozenStocks":0,"Balance":542.858308,"FrozenBalance":0,"Info":{}}
여기서 BTC_USDT
,
반환 결과는 지정된 거래 쌍의 결과이며 거래 계좌의 다른 통화의 정보는
현재 거래 쌍의 총 가치를 지속적으로 인쇄하는 봇:
function main(){
while(true){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
var price = ticker.Buy
var stocks = account.Stocks + account.FrozenStocks
var balance = account.Balance + account.FrozenBalance
var value = stocks*price + balance
Log('Account value is: ', value)
LogProfit(value)
Sleep(3000)//sleep 3000ms(3s), A loop must has a sleep, or the rate-limit of the exchange will be exceed
//when run in debug tool, add a break here
}
}
구매 주문. 호출 방법에는exchange.Buy(Price, Amount)
그리고exchange.Buy(Price, Amount, Msg)
이 방법들은 대기 중인 주문입니다. 주문이 즉시 완전히 실행될 수 없는 경우, 미완성 주문이 생성됩니다. 주문이 성공적으로 배치되면 주문 id가 반환됩니다.null
주문이 실패하면 반환됩니다. 주문 상태를 검색하는 데 사용됩니다.
만약 당신이 시장 가격에 구매 주문을 하고 싶다면, exchange.Buy(-1, 0.5)
거래 쌍이ETH_BTC
일부 플랫폼은 시장 주문을 지원하지 않으며 선물 백테스트도 하지 않습니다.
일부 플랫폼은 가격과 금액에 대한 정밀 요구 사항이 있습니다. 정밀 기능으로 제어 할 수 있습니다._N()
선물 거래에서,
해당 가격에 도달하면 구매하는 예:
function main(){
while(true){
var ticker = exchange.GetTicker()
var price = ticker.Sell
if(price >= 7000){
exchange.Buy(_N(price+5,2), 1, 'BTC-USDT')
break
}
Sleep(3000)//Sleep 3000ms
}
Log('done')
}
판매 주문. 매개 변수는 exchange.Sell(-1, 0.2)
시장 가격에 0.2ETH를 판매하는 것을 의미합니다.
이 공통 인터페이스가 메소드를 호출할 때exchange.GetOrder(OrderId)
, Type
그리고 주문의 실제 가치Status
FMZ는 이러한 값을 표현하기 위해 글로벌 상수를 사용합니다. 예를 들어, FMZ는Status
완료되지 않은 주문의 값은 0이고,ORDER_STATE_PENDING
. 이 모든 글로벌 상수는 문서에서 볼 수 있습니다... 반환 결과:
{
"Id":125723661, //Order id
"Amount":0.01, //Order ammount
"Price":7000, //Order price
"DealAmount":0, //Executed amount
"AvgPrice":0, //executed average price
"Status":0, //0: not completely executed; 1: executed; 2: canceled
"Type":1,//Order type; 0: buy order; 1: sell order
"ContractType":"",//contract type, used in futures trading
"Info":{} //the platform returns the raw information
}
}
특정 금액의 화폐를 구매하는 전략:
function main(){
while(true){
var amount = exchange.GetAccount().Stocks
var ticker = exchange.GetTicker()
var id = null
if(5-amount>0.01){
id = exchange.Buy(ticker.Sell, Math.min(5-amount,0.2))
}else{
Log('Job completed')
return //return the main function, bot will stop
}
Sleep(3000) //Sleep 3000ms
if(id){
var status = exchange.GetOrder(id).Status
if(status == 0){ //Here you can aslo use "status == ORDER_STATE_PENDING" to judge
exchange.CancelOrder(id)
}
}
}
}
GetOrder는 현재 거래 쌍의 모든 미완성 주문 목록을 얻습니다. 미완성 주문이 없으면 빈 배열을 반환합니다.
현재 거래 쌍의 모든 오더를 취소하는 예제:
function CancelAll(){
var orders = exchange.GetOrders()
for(var i=0;i<orders.length;i++){
exchange.CancelOrder(orders[i].Id) // cancel order by orderID
}
}
function main(){
CancelAll()
while(true){
//do something
Sleep(10000)
}
}
주문 ID에 따르면 주문을 취소합니다.exchange.CancelOrder(OrderId)
. 취소가 성공하면 true를 반환합니다. 그렇지 않으면 false를 반환합니다.
암호화폐의 경우 선물 거래는 스팟 거래와 다르다. 스팟 거래의 위의 기능은 선물 거래에도 적용되며 단일 선물 거래는 자체 기능을 가지고 있다. 암호화폐 선물의 프로그램 거래를 수행하기 전에 웹 사이트의 수동 작업에 익숙하고 오픈, 클로즈, 크로즈, 격리, 레버리지, 클로즈 이익과 손실, 부동 수익, 마진 및 기타 개념, 그에 따른 계산 공식과 같은 기본 개념을 이해해야합니다. 해당 튜토리얼은 다양한 선물 플랫폼에서 찾을 수 있으며 스스로 배워야합니다.
영구 계약은 선물 계약과 비슷하지만, 차이점은 동시에 긴 포지션과 짧은 포지션을 보유하는 개념이 없다는 것입니다.
플랫폼이 OKEX와 Huobi의 선물과 스팟을 지원하는 경우 해당 플랫폼 인터페이스에서
선물 거래의 첫 번째 단계는 거래 할 계약을 설정하는 것입니다. 예를 들어 OKEX 선물을 취하면 봇 또는 백테스팅을 만들 때 BTC 거래 쌍을 선택하고 코드에서 주간, 다음 주 또는 분기 계약을 설정해야합니다. 설정되지 않으면 요청됩니다.invalid contract type
. 현금 거래 쌍과 달리 선물 계약은 종종 BTC와 같은 거래 통화를 마진으로 사용합니다. 거래 쌍에 BTC를 추가하는 것은 일반적으로 BTC_USD 거래 쌍을 대표합니다. USDT를 마진으로 사용하는 선물 계약이 있다면 BTC_USDT 거래 쌍을 추가하기 위해 봇을 만들 필요가 있습니다. 예를 들어, 바이낸스 OKEX 퓨처스와 같은 영구 계약은 암호화 마진과 USDT 마진 계약을 모두 가지고 있습니다.거래 쌍을 설정 한 후, 영구, 주간, 다음 주 등과 같은 특정 계약 유형을 설정해야합니다. 계약을 설정 한 후 시장 코팅, 구매 및 판매 등의 작업을 수행 할 수 있습니다.
바이낸스, OKEX, HuobiDM 등은 암호화 마진과 USDT 마진 계약을 모두 가지고 있으며, 봇을 추가하고 계약을 설정할 때 구별해야합니다. 구체적인 설정은 다음과 같습니다.
//OKEX Futures
exchange.SetContractType("swap") // set to perpetual contract
exchange.SetContractType("this_week") // set to weekly contract
exchange.SetContractType("next_week") // set to next week contract
exchange.SetContractType("quarter") // set to quarterly contract
//HuobiDM
exchange.SetContractType("this_week") // set to weekly contract
exchange.SetContractType("next_week") // set to next week contract
exchange.SetContractType("quarter") // set to quarterly contract
exchange.SetContractType("swap") // set to perpetual contract
//Binance Futures
exchange.SetContractType("swap") // set to perpetual contract, and notice that crypto-margined and USDT-margined contracts are all in the perpetual contract
exchange.SetContractType("quarter") // set to quarterly contract
exchange.SetContractType("next_quarter") // set to next quarter contract
//BitMEX
exchange.SetContractType("XBTUSD") // set to perpetual contract
exchange.SetContractType("XBTM19") // the contract settled at a specific time; for more details, please log in BitMEX to check each contract code
//GateIO
exchange.SetContractType("swap") // set to perpetual contract, and do not set the default as swap perpetual contract
//Deribit
exchange.SetContractType("BTC-27APR18") // the contract settled at a specific time; for more details, please log in Deribit to check out
현재 위치 정보 목록을 얻기 위해, OKEX (OKCOIN) 선물은 얻을 계약 유형을 지정하는 매개 변수에 통과 할 수 있습니다. 빈 목록을 반환[]
, 만약 포지션이 없다면. 포지션 정보는 다음과 같이 반환됩니다. 거래 쌍과 결합하여 분석해야하는 많은 특정 정보가 있습니다.
데이터 타입 | 변수 이름 | 설명 |
---|---|---|
물체 | 정보 | 플랫폼이 반환하는 원시 구조 |
번호 | 마진 레벨 | 레버리지 크기; OKCoin은 10 또는 20이며, OK 선물의 교차 포시는 10 (결정) 을 반환합니다. 원시 API를 지원하지 않습니다. |
번호 | 금액 | 포지션 금액; OKCoin은 계약 금액을 나타냅니다. (1분의 정수) |
번호 | 얼어붙은 금액 | 동결된 지점 금액 |
번호 | 가격 | 지점 평균 가격 |
번호 | 마진 | 얼어붙은 마진 |
번호 | 수익 | 재화 선물: 시장에 지점의 이익과 손실; 암호화폐: 암호화폐 단위: BTC/LTC, 전통적인 선물 단위: RMB (참고:OKCoin 선물의 크로스 포지션의 경우, 포지션의 이익과 손실이 아니라 실현 된 이익과 손실을 의미합니다. 격리된 위치 하에서는 포지션의 이익과 손실을 의미합니다.) |
const | 종류 | PD_LONG는 긴 포지션 (CTP는 포지션을 닫기 위해 |
문자열 | 계약 유형 | 재화 선물은 계약 코드이고 주식은 |
function main(){
exchange.SetContractType("this_week");
var position = exchange.GetPosition();
if(position.length>0){ //especially pay attention to judging the length of position before call, or an error will occur
Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type,"ContractType:", position[0].ContractType)
}
}
우선, 레버리지 크기를 설정해야 합니다. 호출 방법:exchange.SetMarginLevel(10)
exchange.SetDirection(Direction)
, 이는 오픈 포지션과 클로즈 포지션에 해당합니다.선물과 달리, 영구 계약이 동시에 긴 및 짧은 개념을 포함하지 않는 경우, 즉 단일 포지션은 허용되지 않습니다. 당신이 긴 포지션에 짧은 오픈을 운영 할 때, 긴 포지션은 자동으로 닫힐 것입니다, 그래서 당신은 단지 설정해야합니다buy
그리고sell
. 그것은 양방향 위치를 지원하는 경우, 당신은 설정해야closebuy
, closesell
.특정 관계:
운영 | SetDirection 매개 변수 | 질서 를 정하는 기능 |
---|---|---|
오픈 롱 포지션 | 교환.SetDirection ( |
교환.구입() |
롱 포지션 닫기 | 교환.SetDirection (( |
교환.판매. |
오픈 쇼트 포지션 | 교환.SetDirection (( |
교환.판매. |
마이너 포지션 | 교환.SetDirection (( |
교환.구입() |
마지막으로, 오픈 및 클로즈 포지션에 대한 특정 코드가 있습니다. 배치 된 주문의 양은 플랫폼에 따라 다릅니다. 예를 들어, Huobi 선물은 계약량 수를 기반으로하며 한 계약은 100 미국 달러입니다. 선물 백테스트가 시장 주문을 지원하지 않는다는 점에 유의하십시오.
function main(){
exchange.SetContractType("this_week") // for example, set OKEX futures to weekly contract
price = exchange.GetTicker().Last
exchange.SetMarginLevel(10) // set to 10 times of leverage
exchange.SetDirection("buy") // set the order type as buy long
exchange.Buy(price+10, 20) // set contract quantity as 20 orders
pos = exchange.GetPosition()
Log(pos)
Log(exchange.GetOrders()) // check out if there is any unfinished order
exchange.SetDirection("closebuy"); // if it is a perpetual contract, directly set exchange.SetDirection("sell")
exchange.Sell(price-10, 20)
}
다음과 같이 전체 폐쇄 포지션의 구체적인 전략 예를 제시하십시오.
function main(){
while(true){
var pos = exchange.GetPosition()
var ticker = exchange.GetTicekr()
if(!ticker){
Log('not able to obtain ticker')
return
}
if(!pos || pos.length == 0 ){
Log('no position')
return
}
for(var i=0;i<pos.length;i++){
if(pos[i].Type == PD_LONG){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closebuy')
exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
}
if(pos[i].Type == PD_SHORT){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closesell')
exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
}
}
var orders = exchange.Getorders()
Sleep(500)
for(var j=0;j<orders.length;j++){
if(orders[i].Status == ORDER_STATE_PENDING){
exchange.CancelOrder(orders[i].Id)
}
}
}
}
암호화폐 레버리지 거래는 코드에 있는 레버리지 계좌로 전환해야 합니다. 다른 부분은 스팟 거래와 동일합니다.
사용exchange.IO("trade_margin") 는 레버리지 계정 모드로 전환합니다. 주문을 하고 계정 자산을 얻는 것은 레버리지 플랫폼의 인터페이스에 액세스합니다. 사용exchange.IO("trade_normal") 로 정상 계정으로 전환합니다.
지원되는 플랫폼:
재화 선물 거래와 암호화폐 선물 거래는 상당히 다르다. 우선, 재화 선물 거래 시간은 매우 짧지만 암호화폐는 24시간 동안 거래된다; 재화 선물의 프로토콜은 일반적으로 사용되는 REST API가 아니다; 재화 선물의 거래 빈도와 미결 주문 금액은 제한되어 있지만, 암호화폐 선물은 매우 느슨하다. 따라서 재화 선물 거래를 할 때 특별한 주의가 필요한 점이 많고, 수동 조작에 풍부한 경험을 가진 사람들에게 권장된다. FMZ는 현재 재화 선물 시뮬레이션 봇을 지원하고 있으며, 참조할 수 있다:https://www.fmz.com/bbs-topic/325상품 선물 회사를 추가하기 위해:https://www.fmz.com/bbs-topic/371
상품 선물은 2019년 6월 투명감독을 시행했으며, 개별 프로그램에서는 개인 사용자가 계정을 개설하여 선물 브로커의 허가 코드를 신청해야 합니다. (특정 애플리케이션 정보 템플릿은 위
FMZ Quant 플랫폼 구조의 장점으로 인해 사용자는 또한 여러 개의 선물 브로커 계정을 추가하고 다른 상품 선물 프로그램 거래 소프트웨어가 완료 할 수없는 몇 가지 기능을 구현 할 수 있습니다.https://www.fmz.com/bbs-topic/1184
우선, 24시간 거래가 아니기 때문에 로그인 작업이 필요하기 때문에 거래 전에 링크 상태를 판단해야 합니다.exchange.IO("status")
이true
, 이는 플랫폼에 성공적인 연결을 표시합니다. 로그인이 성공하지 않을 때 API가 호출되면, 로그인이 되지 않습니다. 전략이 시작 된 후, 로그인 할 수 있는 특정 시간을 제공하여, _C(exchange.SetContractType,"MA888")
, 성공적인 로그인을 보장합니다.
상품 선물의 시장 코트 인수 및 거래 코드는 암호화폐 선물과 동일합니다. 여기서 차이점과 주의가 필요한 점을 소개합니다.
function main(){
_C(exchange.SetContractType,"MA888") //If you do not log in successfully, you cannot subscribe to the contract, so better to try again
while(true){
if(exchange.IO("status")){
var ticker = exchange.GetTicker()
Log("MA888 ticker:", ticker)
LogStatus(_D(), "Already connected with CTP !")//_D obtain event
} else {
LogStatus(_D(), "Not connected with CTP !")
Sleep(1000)
}
}
}
거래에 대 한 재화 선물 라이브러리를 사용 하는 것이 좋습니다 (이 나중에 설명 될 것 이다), 코드는 이 시간 매우 간단 하 게 될 것 이다, 그리고 지루 한 세부 사항 을 처리 할 필요 가 없습니다.https://www.fmz.com/strategy/57029
function main() {
// Use the CTA strategy framework of commodity futures library
$.CTA(Symbols, function(st) {
var r = st.records
var mp = st.position.amount
var symbol = st.symbol
/*
"r" represents K-line, "mp" indicates the position amount of the current variety; positive number means long position, negative number means short position, and 0 means no position; "symbol" is the variety name
if the return value is n:
n = 0 : full close positions (no matter now they are long or short)
n > 0 : if right now long positions are held, add n long positions; if now they are short positions, close n short posiitons; if n is over the position amount right now, reverse to open long positions
n < 0 : if right now short positions are held, add n short positions; if now they are long positions, close n long posiitons; if -n is over the position amount right now, reverse to open short positions
*/
if (r.length < SlowPeriod) {
return
}
var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod));
if (mp <= 0 && cross > ConfirmPeriod) {
Log(symbol, "Golden Cross Period", cross, "the moment position", mp);
return Lots * (mp < 0 ? 2 : 1)
} else if (mp >= 0 && cross < -ConfirmPeriod) {
Log(symbol, "Death Cross Period", cross, "the moment position", mp);
return -Lots * (mp > 0 ? 2 : 1)
}
});
}
재화 선물은 CTP 프로토콜을 사용하며, 모든 시장 코팅과 주문 실행은 변경 후에야 알릴 것이며, 주문, 계정 및 포지션에 대한 질의는 활성 질의입니다. 따라서 이벤트 기반의 고주파 전략 작성에 적합합니다.GetTicker
, GetDepth
그리고GetRecords
, 모든 최신 데이터를 얻기 위해 데이터를 캐시해야합니다. 데이터가 없으면 데이터가있을 때까지 기다립니다. 따라서 전략이
만약 당신이 시장 코트를 얻을 때마다 데이터를 얻고 싶다면, 그것은 오래된 데이터라고 하더라도, 당신은 시장 코트의 즉각적인 업데이트 모드로 전환할 수 있습니다exchange.IO("mode", 0)
. 이 시점에서 전략은 이벤트에 의해 구동되어 작성될 수 없으며, 빠른 무한 루프를 피하기 위해 exchange.IO("mode", 1)
기본 캐시 모드로 다시 전환합니다.
단일 계약을 실행할 때 기본 모드를 사용하십시오. 그러나 여러 계약이있는 경우 계약 중 하나가 시장 코트를 업데이트하지 않아 시장 코트를 얻는 인터페이스 차단이 발생할 수 있으며 다른 계약의 코트 업데이트도 얻을 수 없습니다. 이 문제를 해결하기 위해 즉각 업데이트 모드를 사용할 수 있지만 고주파 전략을 작성하는 것이 불편합니다. 이 시점에서 명령과 코트를 푸시하는 이벤트 푸시 모드를 사용할 수 있습니다. 설정 방법은exchange.IO("wait")
여러 교환 대상이 추가되면, 재화 선물에서 드문 경우, 당신은 사용할 수 있습니다exchange.IO("wait_any")
, 그리고 반환된
시장 트릭 변화의 추진:{Event:"tick", Index: platform index (in the order of the platforms added in the bot), Nano: event of nanosecond-level time, Symbol: contract name}
주문 추진:{Event:"order", Index:Exchange index, Nano:Event of nanosecond-level time, Order:Order information (same as GetOrder)}
이 때, 전략 구조는 다음과 같이 쓸 수 있습니다.
function on_tick(symbol){
Log("symbol update")
exchange.SetContractType(symbol)
Log(exchange.GetTicker())
}
function on_order(order){
Log("order update", order)
}
function main(){
while(true){
if(exchange.IO("status")){ //Judge the link status
exchange.IO("mode", 0)
_C(exchange.SetContractType, "MA888")//Subscribe to MA; only the subscription request for the first time is ture, and the later ones are program switches, which do not consume time
_C(exchange.SetContractType, "rb888")//Subscribe to rb
while(true){
var e = exchange.IO("wait")
if(e){
if(e.event == "tick"){
on_tick(e.Symbol)
}else if(e.event == "order"){
on_order(e.Order)
}
}
}
}else{
Sleep(10*1000)
}
}
}
또한 재화 선물과 암호화폐 플랫폼의 차이점에도 유의하십시오. 예를 들어,
exchange.IO("기기"): 그것은 사전 형태로 플랫폼 {계약 이름: 세부 사항}에 있는 모든 계약의 목록을 반환하고, 단지 봇을 지원합니다.exchange.IO("프로덕트"): 플랫폼 {계약 이름: 세부 사항}에 있는 모든 항목의 목록을 사전 형태로 반환하고, 봇만 지원합니다.exchange.IO("구독"): 플랫폼에서 사전 형태로 구독된 시장 코트를 반환하고, 봇만 지원합니다.
이ContractType
전통적인 CTP 선물의 경우, 대문자 민감한 계약 ID를 참조합니다.exchange.SetContractType("au1506")
. 계약이 성공적으로 설정된 후, 최소 구매 금액, 서비스 수수료, 배송 시간 등 계약의 자세한 정보를 반환합니다. 여러 계약에 가입할 때, 가입 요청이 실제로 전송되는 첫 번째 시간 만이며, 그 다음 거래 쌍은 코드 수준에서 전환됩니다. 시간이 걸리지 않습니다. 주요 연속 계약은 MA888과 같은 코드 888, 연속 비율 계약은 MA000과 같은 000입니다. 888과 000은 백테스트만 지원하는 가상 계약 거래이며 실제 봇은 시장 코트를 지원합니다.하지만 MyLanguage는 메인 컨트랙트를 운영할 수 있고, 이 프로그램은 자동으로 포지션을 변경합니다. 즉, 비 메인 포지션을 닫고 메인 포지션에 새로운 포지션을 개설합니다.
실패 로그인은 계약을 설정할 수 없습니다, 하지만 즉시 반환, 그래서 당신은 CTP 로그인이 완료 된 것을 알 수 있도록 다시 시도 할 수 있습니다. 성공적인 로그인 후, 그것은 계약을 설정하는 데 시간을 소비하지 않습니다, 그리고 실제 네트워크 액세스가 없습니다.
SetDirection
네 개의 매개 변수를 얻을 수 있습니다.buy, closebuy, sell, closesell
재화 선물은 더 많은closebuy_today
그리고closesell_today
, 현재 포지션의 폐쇄를 나타냅니다.closebuy/ closesell
, 어제 포지션의 폐쇄를 나타냅니다. 상하이 선물 거래소의 종류만 오늘 포지션과 어제 포지션으로 나뉘어서 서비스 수수료에 영향을 줄 수 있으므로 어제 포지션의 폐쇄에 우선 순위를 부여해야합니다. CTP 전통적인 선물의 경우 두 번째 매개 변수를 각각
운영 | SetDirection 매개 변수 | 질서 를 정하는 기능 |
---|---|---|
오픈 롱 포지션 | 교환.SetDirection ( |
교환.구입() |
롱 포지션 닫기 | 교환.SetDirection (( |
교환.판매. |
오픈 쇼트 포지션 | 교환.SetDirection (( |
교환.판매. |
마이너 포지션 | 교환.SetDirection (( |
교환.구입() |
다음 예는 특정 폐쇄 위치 함수입니다. 이 예가 너무 간단하다는 점에 유의하십시오. 또한 거래 시간 내에 있는지, 완전히 채우지 않은 경우 대기 주문을 다시 시도하는 방법, 최대 주문 부피가 무엇인지, 빈도가 너무 높는지, 슬라이딩 가격 또는 시장 가격과 같은 경우를 고려해야합니다. 참조를 위해만,그것은 실제 봇에서 포지션을 열고 닫는 제안 플랫폼의 라이브러리 패키지입니다:https://www.fmz.com/strategy/12961라이브러리 섹션에는 구체적인 소개가 있으며 라이브러리의 소스 코드를 연구하는 것도 좋습니다.
function Cover(contractType, amount, slide) {
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType != contractType) {
continue;
}
var depth = _C(e.GetDepth);
if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) {
exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");
exchange.Sell(depth.Bids[0]-slide, amount, contractType, positions[i].Type == PD_LONG ? "Close today" : "Close yesterday", 'Bid', depth.Bids[0]);
} else {
exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
exchange.Buy(depth.Asks[0]+slide, amount, contractType, positions[i].Type == PD_SHORT ? "Close today" : "Close yesterday", 'Ask', depth.Asks[0]);
}
}
}
재화 선물은 사용자 정의 주문 유형을 지원합니다. (보트 지원, 백테스트 지원은 아닙니다.)
exchange.SetDirection("buy_ioc");
exchange.SetDirection("sell_gtd-20170111")
특정 후속자:
기본 설정으로, 상품 선물 브로커에서 열리는 인터페이스는 모두 CTP 인터페이스입니다. 필요한 경우, 그들은 Esunny 인터페이스로 대체 될 수 있습니다. FMZ의 캡슐화를 통해 호출 방법은 동일합니다. 차이점은 계정, 주문 및 포지션이 모두 푸시 모드에 있기 때문에 도커는 이러한 데이터를 로컬로 유지하며, 실제로 요청을 하지 않고 해당 인터페이스를 호출 할 때 즉시 돌아올 것입니다.
에스니 프로토콜 사용자 지정 주문 유형은:
봇 인터페이스에서 로그 레코드를 로그하면 문자열 뒤에 문자 Log('Push to WeChat@')
.
로그 색상 또한 사용자 정의 할 수 있습니다.Log('this is a log in red font #ff0000')
.
#ff0000
RGB 색상의 열여섯 자리, 모든 로그 파일이 도커가 위치한 디렉토리의 봇의 SqLit 데이터베이스에 저장되어 있으며, 데이터베이스 소프트웨어로 다운로드하여 열 수 있으며 백업 및 복원 (데이터베이스 이름과 봇 id가 동일) 를 복사하는 데 사용할 수 있음을 나타냅니다.
수익을 기록하고, 보트 인터페이스에서 수익 곡선을 그리며, 보트가 재시작된 후에 유지될 수 있습니다. 호출 방법:LogProfit(1000)
이 매개 변수가LogProfit
이득이 될 필요는 없고, 어떤 숫자일 수도 있고, 직접 작성해야 합니다.
로그가 먼저 저장되고 지속적으로 갱신될 것이기 때문에, 보트 상태가 정보를 저장하기 위한 것이 아니라 표시하기 위해만 필요한 경우,LogStatus
함수.LogStatus
문자열입니다. 이 문자열은 테이블 정보를 표현하는 데도 사용될 수 있습니다.
특정 실제 봇 위치 표시 테이블의 예:
var table = {type: 'table', title: 'position information', cols: ['Column1', 'Column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]};
LogStatus('`' + JSON.stringify(table) + '`'); // After serialization, JSON will be added the character "'" on both sides, which is regarded as a comlpex messag format (now supporting tables)
LogStatus('The first line information\n`' + JSON.stringify(table) + '`\nthe third line information'); // the table information can be displayed in multiple lines
LogStatus('`' + JSON.stringify([table, table]) + '`'); // Multiple tables are supported to be displayed at the same time, which will be displayed in one group by TAB
LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n'); // Multiple tables are displayed up and down by arrangement
그 매개 변수는 밀리 초인 수입니다.Sleep(1000)
모든 플랫폼의 제한된 액세스 주파수 때문에, 수면 시간은 일반적인 전략에서 무한 루프에 추가되어야 합니다.
로봇이 다시 시작되면 프로그램이 다시 시작됩니다._G
매우 편리하고 실용적이며 JSON 시리즈화된 내용을 저장할 수 있습니다._G
함수는onexit()
, 그래서 전략이 멈출 때마다 필요한 정보가 자동으로 저장됩니다.
더 많은 포맷 된 데이터를 저장하려면 _G 함수가 적합하지 않습니다.