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

FMZ API 지침

저자:제로, 제작: 2020-04-20 10:19:00, 업데이트: 2023-04-12 14:44:56

sted IP 주소는10.0.3.15 }


#### exchange.SetTimeout(...)

```exchange.SetTimeout(Millisecond)```, in which the parameter **Millisecond** is a millisecond value.

Only for the ```rest``` protocol, it is used to set the time-out period for ```rest``` requests, and it takes effect only by setting it once.
For example: ```exchange.SetTimeout(3000)```, set the timeout time of the ```rest``` request of the exchange object ```exchange```, if it exceeds 3 seconds, timeout will return ```null```.

Note:
* The parameter ```Millisecond``` is millisecond, and 1,000 milliseconds equals 1 second. 
* Only need to set once.
* Only for the **rest** protocol.
* ```SetTimeout``` is not a global function, but an exchange object method. 

### Special Requirements for C++ Written Strategies   
The main difference between ```C++``` written strategy and ```JavaScript``` written strategy is the returned data differences of **FMZ API** interface. For example, the ```exchange.GetTicker()``` function.

- JavaScript
```exchange.GetTicker()``` returns an object if the call succeeds, or returns ```null``` if the call fails (due to the exchange server problems or network problems, etc.).

```javascript
function main() {
    var ticker = exchange.GetTicker()
    // Determine if the call to "exchange.GetTicker" function failed, and return "null" when it failed
    if (ticker){
        Log(ticker)
    }
}
  • C++exchange.GetTicker()호출이 성공하면 객체를 반환합니다. 호출이 실패하면 반환된 객체는 여전히 객체입니다.Valid.

    void main() {
        auto ticker = exchange.GetTicker();
        // Determine if the call to "exchange.GetTicker()" function failed and if the "Valid" attribute of the returned object is "false"
        if (ticker.Valid) {
            Log(ticker);
        }
    }
    

그 사이의 차이점main()기능C++작성된 전략과main()표준 C11의 함수: 이 값의 반환 값은C++프로그램 입력 함수main()C11은int의 종류.C++FMZ 플랫폼에 작성된 전략, 전략의 시작 기능은 또한 기능입니다main(), 하지만 이 두 가지는 같은 함수가 아닙니다, 단지 같은 이름을 가지고 있습니다. FMZ 플랫폼에서, 반환 값은main()기능C++전략은void type.

void main() {
    // Use "Test" function to test
    if (!Test("c++")) {
        // Show an exception to stop the program
        Panic("Please download the latest-versioned docker");
    }

    // Determine if the return of all objects is valid with "Valid" 
    LogProfitReset();
    LogReset();
    Log(_N(9.12345, 2));
    Log("use _C", _C(exchange.GetTicker), _C(exchange.GetAccount));
}

자바스크립트 특수 사항

자바스크립트 언어 이유로 (자바스크립트 언어 내장 문자열 지원ascii그리고utf-16데이터 손실을 방지하기 위해, 단지 인코딩), 그것은 인코딩 할 수 없는 문자열을 만났을 때, 그것은 반환ArrayBuffer문자열 매개 변수를 전달할 수 있는 모든 API 인터페이스는ArrayBuffer type.

자바스크립트 멀티 스레딩

그것은 정말로 다중 스레딩 기능을 지원JavaScript언어 전략 시스템 하단에서, 포함: 사용자 정의 실행 기능의 동시 실행; 동시 스레드 간의 통신 지원, 동시 스레드 및 메인 스레드 사이의 통신 지원; 저장, 스레드 환경에서 변수 공유 및 기타 기능. 그것은 단지 라이브 거래 환경에서 사용을 지원합니다. 지금까지 참조하십시오:https://www.fmz.com/bbs-topic/9974.

힌트

__Thread(function, arguments...)function는 동시 실행되는 스레드를 생성합니다. 스레드 실행 함수 (단독된 환경으로 실행) 를 제외한 다른 변수에 대한 직접 참조를 지원하지 않습니다. 외부 변수에 대한 참조가 컴파일되지 않습니다. 다른 클로저 함수에 대한 참조도 지원되지 않습니다. 플랫폼의 모든 API는 스레드 내부에서 호출 될 수 있지만 다른 사용자 정의 함수는 호출 될 수 없습니다. 매개 변수function함수 참조 또는 익명 함수일 수 있습니다. 매개 변수arguments이 지표의 매개 변수function함수 (실제 입력된 매개 변수)arguments...여러 매개 변수를 전달할 수 있다는 것을 의미합니다. 반환 값: 스레드 ID.

function testFunc(n) {
    Log("Execute the function testFunc, parameter n:", n)
}

function main() {
    var testThread1 = __Thread(function () {
        Log("Executes an anonymous function with no parameters.")
    })

    var testThread2 = __Thread(testFunc, 10)   // parameter n : 10
    
    __threadJoin(testThread1)                  // You can use the __threadJoin function to wait for concurrent threads to complete
    __threadJoin(testThread2)                  // If you don't wait for the execution of testThread1 and testThread2 to complete, the main thread will automatically release the concurrent thread after the execution is completed first, and terminate the execution function of the concurrent thread
}

그것은 호출 방법을 지원__Thread([function, arguments...], [function, arguments...], ...)즉, 여러 개의 스레드 실행 함수는 생성된 스레드에서 순차적으로 실행됩니다.

function threadTestFuncA(a) {
    Log(a)
    threadTestFuncC(4)
    
    // The threadTestFuncC function can be called, but the threadTestFuncB function cannot be called

    // this.d
    Log(d)
}

function threadTestFuncB(b) {
    Log(b)
    threadTestFuncC(2)

    this.d = 5
}

function main() {
    // Execute the threadTestFuncB function first, and then execute the threadTestFuncA function
    // threadTestFuncC will not be executed automatically, but it can be called by other thread execution functions
    var threadId = __Thread([threadTestFuncA, 3], [threadTestFuncB, 1], ["function threadTestFuncC(c) {Log(c)}"])
    __threadJoin(threadId)
}

동시 실행 기능은__Thread이 예제에서 이 함수는 역 순서로 실행됩니다Log프린트 함수1 ~ 5다른 스레드 실행 함수들 사이에서 공유 변수를 지원합니다. 예를 들어,this.d위의 예제에서 변수를 할당 할 수 있습니다threadTestFuncB기능 및 사용threadTestFuncA함수 문자열을 전달하는 것을 지원합니다."function threadTestFuncC(c) {Log(c)}"위 예제에서, 스레드가 이 방법으로 외부 함수와 라이브러리들 (imported) 에 함수 호출을 실행할 수 있게 해줍니다.

외부 라이브러리를 가져오기 위한 구체적인 사용 예는 다음과 같습니다.

function ml(input) {
    const net = new brain.NeuralNetwork();
    net.train([
        { input: [0, 0], output: [0] },
        { input: [0, 1], output: [1] },
        { input: [1, 0], output: [1] },
        { input: [1, 1], output: [0] },
    ]);
    return net.run(input);
}

function main() {
    Log(__threadJoin(__Thread([ml, [1, 0]], [HttpQuery("https://unpkg.com/brain.js")])))
}

__threadPeekMessage

__threadPeekMessage(threadId, timeout)함수는 스레드 통신 채널에서 데이터를 읽습니다, 파라미터threadIdID가 반환되는__Thread()함수, 매개 변수를 설정threadId로 표시되는 스레드에서 전송된 데이터를 수신하는 것을 의미합니다. 0로 설정되면, 현재 주요 함수인 메인 스레드에서 전송된 데이터를 수신하는 것을 의미합니다 (패라미터 는 0으로 설정되어 있으며, 이는 동시 스레드 실행 함수에서만 지원됩니다.)timeout이 매개 변수에서 설정된 밀리초 수에 따라 차단 및 대기하는 타임 아웃 설정입니다.timeout설정되어 있습니다-1, 그것은 채널의 전송 스레드가 실행을 완료하고 데이터가 없을 때, 채널의 데이터가 수신 될 때까지 차단하고 기다립니다.__threadPeekMessage함수는 즉시 null 값을 반환합니다. 반환 값: 수신된 데이터.

프로그램을 작성할 때, 스레드 막착 문제에 주의를 기울여야 합니다. 다음 예는 실행 함수 사이의 통신입니다.testFunc생성되는 동행 스레드 및main주요 스레드의 기능과 스레드 실행 기능testFunc먼저 처형될 것입니다.

function testFunc() {
    for(var i = 0 ; i < 5 ; i++) {                // 0 ~ 5, after sending to the main thread 5 times, the execution of the thread function is completed, and the __threadPeekMessage function in the main function fetches all the data, it will not block again, and returns a null value immediately
        __threadPostMessage(0, i)                 // Send data to the main thread
        var msg = __threadPeekMessage(0, -1)      // Listen for data from the main thread
        Log("from main msg:", msg)
        Sleep(500)
    }
    Log("testFunc execution is complete")
}

function main() {
    var testThread = __Thread(testFunc)           // Create a thread with an Id of 1 
    
    for (var i = 0 ; i < 10 ; i++) {
        __threadPostMessage(1, i)                 // Send data to the thread whose Id is 1, that is, the thread that executes the testFunc function in this example
        var msg = __threadPeekMessage(1, -1)      // Listen to the data sent by the thread whose Id is 1, that is, the data sent by the thread that executes the testFunc function in the example
        Log("from testFunc msg:", msg)
        Sleep(500)
    }
}

__threadPostMessage

__threadPostMessage(threadId, data)함수는 스레드 통신 채널에 데이터를 기록, 매개 변수threadIdID가 반환되는__Thread()함수, 매개 변수를 설정threadId로 표시된 스레드에 데이터를 전송하는 것을 의미하며, 가 0로 설정되면,

스레드에 데이터를 전송하는 것을 의미합니다. 즉, 현재 주요 함수 (패라미터 는 0로 설정되어 있으며, 이는 동시 스레드 실행 함수에서만 지원됩니다.)
data값, 문자열, 부엘 값, 객체, 배열 및 다른 유형의 데이터를 전달할 수 있습니다. 이 함수는 반환 값이 없습니다.

그 때__threadPostMessage이 함수는 스레드의 실행 함수에서 신호와 데이터를 보내기 위해 호출되면 메시지 이벤트도 생성됩니다.EventLoop()메시지 알림을 수신하는 기능.

function testFunc() {
    for(var i = 0 ; i < 10 ; i++) {
        Log("post msg, i:", i)
        __threadPostMessage(0, {msg: "testFunc", i: i})
        Sleep(100)
    }
}

function main() {
    var testThread = __Thread(testFunc)
    
    for (var i = 0 ; i < 10 ; i++) {
        var e = EventLoop()
        Log("e:", e)
        // e: {"Seq":1,"Event":"thread","Index":1,"Nano":1677745512064773600,"Deleted":0,"Symbol":"","Ticker":{"Info":null,"High":0,"Low":0,"Sell":0,"Buy":0,"Last":0,"Volume":0,"OpenInterest":0,"Time":0}}
        if (e.Event == "thread") {
            var msg = __threadPeekMessage(testThread, -1)
            Log("msg:", msg, "#FF0000")
        }
        Sleep(500)
    }
    
    var retThreadJoin = __threadJoin(testThread)
    Log("retThreadJoin:", retThreadJoin)
}

__thread참여

__threadJoin(threadId, timeout)이 함수는 정해진 ID를 가진 스레드가 시스템 리소스를 종료하고 복구하도록 기다리는 데 사용됩니다.threadIdID가 반환되는__Thread()함수와 매개 변수timeout스레드 종료를 기다리는 시간 정렬입니다. 시간 정렬되지 않은 경우 스레드 실행 종료까지 기다리는 것을 의미합니다. 반환 값: 타입은 실행 결과를 나타내는 객체입니다. 시간이 종료되면 반환합니다.undefined.

수익 가치 구조, 예를 들어:

{
    "id":1,                 // Thread Id
    "terminated":false,     // Whether the thread is terminated forcibly
    "elapsed":2504742813,   // The running time of the thread (nanoseconds)
    "ret": 123              // The return value of the thread function
}

__thread 종료

__threadTerminate이 함수는 스레드를 강제로 종료하고 생성된 스레드가 사용하는 하드웨어 자원을 풀기 위해 사용됩니다.threadIdID가 반환되는__Thread()함수. 반환 값: 실행 결과를 나타내는 부엘 값.

function testFunc() {
    for(var i = 0 ; i < 10 ; i++) {
        Log("i:", i)
        Sleep(500)
    }
}

function main() {
    var testThread = __Thread(testFunc)
    
    var retThreadTerminate = null 
    for (var i = 0 ; i < 10 ; i++) {
        Log("main i:", i)
        if (i == 5) {
            retThreadTerminate = __threadTerminate(testThread)
        }
        Sleep(500)
    }
    
    Log("retThreadTerminate:", retThreadTerminate)
}

__threadGetData

__threadGetData(threadId, key), 이 함수는 스레드 사이에 공유된 변수에 액세스하는 데 사용됩니다. 스레드가 실행되지 않은 경우 데이터가 유효합니다.__threadJoin기능 (성공한 출출을 기다리고)__threadTerminate함수 (강제로 스레드를 종료). 파라미터threadId스레드 ID, 그리고 매개 변수key저장된 키의 이름입니다.key-value값 반환: 값에 대응하는 키 값을 반환keykey-value pair.

threadId0은 주 가닥을 나타냅니다 (즉, 가닥이main함수 위치) 를 사용할 수 있습니다.__threadId()현재 스레드의 Id를 얻기 위해 함수, 매개 변수를 설정threadId현재 스레드 ID에, 그리고 스레드 실행 함수에서 현재 스레드에 저장된 변수를 읽기 위해 그것을 사용할 수 있습니다. 당신은 또한 지정된 ID의 스레드 환경에서 변수를 읽을 수 있습니다.

function main() {
    var t1 = __Thread(function() {
        Sleep(2000)
        var id = __threadId()                                                   // Get the Id of the current thread
        Log("id:", id, ", in testThread1 print:", __threadGetData(id, "msg"))   // Retrieve the key value corresponding to the key name msg in the current thread, i.e. "testThread2"
        Log("id:", 2, ", in testThread1 print:", __threadGetData(2, "msg"))     // Read the key value corresponding to the key name msg in the thread with thread Id 2, i.e. 99
    })

    var t2 = __Thread(function(t) {
        __threadSetData(t, "msg", "testThread2")                                // Set a key-value pair to the thread with Id t1 (Id 1), with the key name msg and the key value "testThread2"
        __threadSetData(__threadId(), "msg", 99)                                // Set the key-value pair in the current thread (Id is 2) with the key name msg and the key value 99
        __threadSetData(0, "msg", 100)                                          // Set up a key-value pair in the main thread, with the key name msg and the key value 100
    }, t1)
    
    __threadJoin(t1)   // You can check the __threadJoin(threadId, timeout) function, which is used to wait for the end of thread execution
    Log("in main, get msg:", __threadGetData(0, "msg"))
}

__threadSet데이터

__threadSetData(threadId, key, value), 스레드 환경에서 변수를 저장하는 데 사용됩니다.threadId스레드 ID, 매개 변수key저장된 키의 이름입니다.key-value쌍, 그리고 매개 변수value이 함수는 반환값이 없습니다.

threadId0은 주 가닥을 나타냅니다 (즉, 가닥이main함수가 위치하고 있습니다.) 를 사용할 수 있습니다__threadId()현재 스레드의 ID를 얻기 위한 함수입니다.value삭제할 수 있는 지정되지 않은 방법key. 스레드 간의 공유 변수에 대한 상호 액세스를 지원합니다. 스레드가 실행되지 않은 경우 데이터가 유효합니다.__threadJoin기능 (성공한 출출을 기다리고)__threadTerminate함수 (강제로 스레드를 종료). 매개 변수 값value일련화 가능한 변수여야 합니다.

function testFunc() {
    var id = __threadId()                  // Get the current thread Id
    __threadSetData(id, "testFunc", 100)   // Stored in the current thread environment
    __threadSetData(0, "testFunc", 99)     // Stored in the main threaded environment
    Log("testFunc execution is complete")
}

function main() {
    // threadId is 1, the created thread with threadId 1 will be executed first, as long as the thread resources are not recycled, the variables stored locally in the thread will be valid
    var testThread = __Thread(testFunc)
    
    Sleep(1000)

    // Output in main, get testFunc: 100
    Log("in main, get testFunc:", __threadGetData(testThread, "testFunc"))

    // Output in main, get testFunc: 99
    Log("in main, get testFunc:", __threadGetData(0, "testFunc"))

    // Delete the testFunc key-value pair in the thread environment with Id testThread
    __threadSetData(testThread, "testFunc")

    // After deleting and reading again, the __threadGetData function returns undefined
    Log("in main, get testFunc:", __threadGetData(testThread, "testFunc"))
}

_threadId

__threadId(), 매개 변수 없이 현재 스레드의 Id를 얻기 위해 사용 됩니다. 반환 값:threadId현재 스레드.

function testFunc() {
    Log("in testFunc, __threadId():", __threadId())
}

function main() {
    __Thread(testFunc)

    // If the execution of the main thread is completed, the created child thread will stop executing, so here Sleep(1000), wait for 1 second
    Sleep(1000)
    Log("in main, __threadId():", __threadId())
}

지원 wasm 인코딩

이 지역에서는JavaScript언어 전략에서, wasm 파일의 스 코드는 로드, 인스턴스화, 그리고 실행될 수 있습니다.JavaScript코드, 그것은 특정 속도 이점을 가지고 있습니다.

wasm.parseModule

wasm.parseModule(data), 이 hex 문자열 모델을 분석합니다.data매개 변수 는 hex 문자열 로 변환 된 wasm 인코딩입니다. 반환 값: wasm 모델 객체를 반환, 참조 할 수 있습니다전략 예제.

예를 들어, 다음 C++ 함수 코드는 wasm 코드로 컴파일되고,data매개 변수wasm.parseModule(data) function.

// Recursive Algorithm for Fibonacci Numbers
int fib(int f) {
    if (f < 2) return f;
    return fib(f - 1) + fib(f - 2);   
}

wasm.buildInstance

wasm.buildInstance(module, opt), 이것은 wasm 모델 인스턴스를 만듭니다.module매개 변수는 wasm 모델이고,opt파라미터 는 wasm 인스턴스 프로그램에 할당 된 스택 공간을 설정하는 데 사용되는 구성 정보입니다. 반환 값: wasm 모델 인스턴스를 반환합니다.

opt매개 변수 설정 예제:

{
    stack_size: 65*1024*1024,
}

callFunction

callFunction(funcName, param1, ...), wasm 모델 인스턴스의 메소드로, wasm 모델 인스턴스에서 함수를 실행하는 데 사용됩니다.funcName매개 변수는 실행될 함수의 이름이고,param1매개 변수는 함수를 실행할 때 전달되는 매개 변수입니다 (매개 변수에 의해 지정된)funcName).

블록체인

FMZ 퀀트 트레이딩 플랫폼은web3체인에 대한 계약,defi쉽게 교환합니다.

이더리움

구성

FMZ 퀀트 트레이딩 플랫폼에서 Ethereum 체인에 스마트 계약의 메소드 호출을 구현하기 위해 전략 코드를 작성합니다.exchange.IO기능. 먼저, FMZ 퀀트 트레이딩 플랫폼에서 액세스 노드를 구성합니다. 액세스 노드는 자체 구축 노드 또는 제3자 서비스를 사용할 수 있습니다.infura.

이 페이지에서 교환FMZ 양자 거래 플랫폼, 프로토콜을 선택: 암호화폐, 그리고 교환을 선택Web3설정Rpc Address(접속 노드의 서비스 주소) 그리고Private Key(비밀 키). 그것은 개인 키의 현지 배포를 지원합니다, 참조핵심 안전].

ABI 등록

표준인 계약을 호출ERC20메소드 등록이 필요하지 않으며 직접 호출할 수 있습니다. 표준 계약 이외의 다른 메소드 호출은 ABI 콘텐츠를 등록해야합니다:exchange.IO("abi", tokenAddress, abiContent). 계약의 ABI 컨텐츠를 얻기 위해, 당신은 결과를 필드만 채용하여 다음 URL을 사용할 수 있습니다.

https://api.etherscan.io/api?module=contract&action=getabi&address=0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

이더리움 RPC 호출 방법

두 번째 매개 변수가exchange.IO함수는"eth", 당신은 노드 서버에 사용할 수 있는 RPC 방법을 직접 호출할 수 있습니다, 예를 들어:

  • 지갑에 있는 ETH 잔액을 검색합니다

    function main() {
        // "owner" needs to be replaced with a specific wallet address
        // "latest" parameter labels for string position: 'latest', 'earliest' or 'pending', please refer to https://eth.wiki/json-rpc/API#the-default-block-parameter
        // The return value ethBalance is a hexadecimal string: 0x9b19ce56113070
        var ethBalance = exchange.IO("api", "eth", "eth_getBalance", "owner", "latest")
    
        // ETH has a precision unit of 1e18
        var ethDecimal = 18
    
        // Because of the JavaScript language precision, it is necessary to use the system underlying encapsulated function BigInt, BigDecimal to process.
        // Convert ethBalance to readable quantity, 0x9b19ce56113070 to 0.043656995388076145.
        Log(Number((BigDecimal(BigInt(ethBalance))/BigDecimal(Math.pow(10, ethDecimal))).toString()))
    }
    
  • ETH 송금

    function mian() {
        // ETH has a precision unit of 1e18
        var ethDecimal = 18
    
        // Number of transfers, readable quantity e.g. 0.01 ETH
        var sendAmount = 0.01
    
        // Because of the JavaScript language precision, it is necessary to use the system underlying encapsulated function BigInt, BigDecimal to process, and converts readable quantities into data for processing on the chain.
        var toAmount = (BigDecimal(sendAmount)*BigDecimal(Math.pow(10, ethDecimal))).toFixed(0)
        
        // "toAddress" is the address of the recipient's ETH wallet at the time of the transfer, which needs to be filled in specifically, and toAmount is the number of transfers.
        exchange.IO("api", "eth", "send", "toAddress", toAmount)
    }
    
  • 물음 가스 가격

    function toAmount(s, decimals) {
        return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString())
    }  
    
    function main() {
        var gasPrice = exchange.IO("api", "eth", "eth_gasPrice")
        Log("gasPrice:", toAmount(gasPrice, 0))   // 5000000000 , in wei (5 gwei)
    }
    
  • 질의 eth_estimate가스

    function toAmount(s, decimals) {
        // The toAmount function can convert the hex-encoded value to a decimal value
        return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString())
    }  
    
    function main() {
        // Encoding the call to the approve method
        var data = exchange.IO("encode", "0x111111111117dC0aa78b770fA6A738034120C302", "approve", "0xe592427a0aece92de3edee1f18e0157c05861564", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
        Log("data:", data)
        var gasPrice = exchange.IO("api", "eth", "eth_gasPrice")
        Log("gasPrice:", toAmount(gasPrice, 0))
        var obj = {
            "from" : "0x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",   // walletAddress
            "to"  : "0x111111111117dC0aa78b770fA6A738034120C302",
            "gasPrice" : gasPrice,
            "value" : "0x0",
            "data" : "0x" + data,
        }
        
        var gasLimit = exchange.IO("api", "eth", "eth_estimateGas", obj)
        Log("gasLimit:", toAmount(gasLimit, 0))
        Log("gas fee", toAmount(gasLimit, 0) * toAmount(gasPrice, 0) / 1e18)
    }
    

코딩 지원

기능exchange.IO가결된encode함수 호출 인코딩을 반환할 수 있는 방법hex문자열 형식을 참조할 수 있습니다.Uniswap V3 트레이딩 클래스 라이브러리 템플릿특정 용도로unwrapWETH9이 방법은 예를 들어 다음과 같이 사용됩니다.

function main() {
    // Main network address of ContractV3SwapRouterV2: 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
    // To call the unwrapWETH9 method, you need to register the ABI first, omit the registration here.
    // "owner" represents the wallet address, it needs to fill in the specific, 1 represents the number of unwrapping, unwrap a WETH into ETH
    var data = exchange.IO("encode", "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "unwrapWETH9(uint256,address)", 1, "owner")
    Log(data)
}

전화할 때exchange.IO("encode",...)함수, 만약 두 번째 매개 변수 (string type) 가0x, 이는 암호화된 (encode(smart contract) 로 시작되지 않으면0x, 그것은 지정된 타입 순서를 코드화하는 데 사용됩니다.abi.encodesolidity다음 예제를 참조하십시오.

function main() {
    var x = 10 
    var address = "0x02a5fBb259d20A3Ad2Fdf9CCADeF86F6C1c1Ccc9"
    var str = "Hello World"
    var array = [1, 2, 3]
    var ret = exchange.IO("encode", "uint256,address,string,uint256[]", x, address, str, array)   // uint i.e. uint256 , the type length needs to be specified on FMZ
    Log("ret:", ret)
    /*
    000000000000000000000000000000000000000000000000000000000000000a    // x
    00000000000000000000000002a5fbb259d20a3ad2fdf9ccadef86f6c1c1ccc9    // address
    0000000000000000000000000000000000000000000000000000000000000080    // offset of str
    00000000000000000000000000000000000000000000000000000000000000c0    // offset of array
    000000000000000000000000000000000000000000000000000000000000000b    // the length of str
    48656c6c6f20576f726c64000000000000000000000000000000000000000000    // str data
    0000000000000000000000000000000000000000000000000000000000000003    // the length of the array
    0000000000000000000000000000000000000000000000000000000000000001    // array the first data
    0000000000000000000000000000000000000000000000000000000000000002    // array the second data
    0000000000000000000000000000000000000000000000000000000000000003    // array the third data
    */
}

튜플 또는 튜플을 포함하는 타입의 순차적 인코딩을 지원합니다:

function main() {
    var types = "tuple(a uint256,b uint8,c address),bytes"
    var ret = exchange.IO("encode", types, {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }, "0011")
    Log("encode: ", ret)
}

이 유형의 순서는tuple그리고bytes, 그래서 두 개의 매개 변수를 호출할 때 전달해야 합니다exchange.IOencode:

    1. 타입에 대응하는 변수tuple:
    {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }
    

    전달된 매개 변수는 또한 구조와 유형의tuple, 그 정의에 따라types파라미터:tuple(a uint256, b uint8, c address).

    1. 타입에 대응하는 변수bytes:
    "0011"
    

배열 또는 배열을 포함하는 타입의 순차적 인코딩을 지원합니다.

function main() {
    var path = ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7"]   // ETH address, USDT address
    var ret = exchange.IO("encode", "address[]", path)
    Log("encode: ", ret)
}

EncodePacked를 지원합니다.

예를 들어, DEX 방법을 호출 할 때Uniswap V3, 당신은 교환 경로와 같은 매개 변수를 전달해야합니다, 그래서 당신은encodePackaged작업:

function main() {
    var fee = exchange.IO("encodePacked", "uint24", 3000)
    var tokenInAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
    var tokenOutAddress = "0x6b175474e89094c44da98b954eedeac495271d0f"
    var path = tokenInAddress.slice(2).toLowerCase()
    path += fee + tokenOutAddress.slice(2).toLowerCase()
    Log("path:", path)
}

디코딩 지원

데이터 처리는 코딩을 지원할 뿐만 아니라 (encode하지만 또한 디코딩 (decode) 를 사용exchange.IO("decode", types, rawData)수행 할 수 있습니다decode operation.

function main() {
    // register SwapRouter02 abi
    var walletAddress = "0x398a93ca23CBdd2642a07445bCD2b8435e0a373f"
    var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
    var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]`
    exchange.IO("abi", routerAddress, abi)   // abi only uses the contents of the local exactOutput method, the full abi can be searched on the Internet

    // encode path
    var fee = exchange.IO("encodePacked", "uint24", 3000)
    var tokenInAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    var tokenOutAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"
    var path = tokenInAddress.slice(2).toLowerCase()
    path += fee + tokenOutAddress.slice(2).toLowerCase()
    Log("path:", path)

    var dataTuple = {
        "path" : path, 
        "recipient" : walletAddress, 
        "amountOut" : 1000, 
        "amountInMaximum" : 1, 
    }
    // encode SwapRouter02 exactOutput 
    var rawData = exchange.IO("encode", routerAddress, "exactOutput", dataTuple)
    Log("method hash:", rawData.slice(0, 8))   // 09b81346
    Log("params hash:", rawData.slice(8))

    // decode exactOutput params
    var decodeRaw = exchange.IO("decode", "tuple(path bytes,recipient address,amountOut uint256,amountInMaximum uint256)", rawData.slice(8))
    Log("decodeRaw:", decodeRaw)
}

이 예제에서는encodePacked1차 운영 기간path패러미터 처리,exactOutput나중에 암호화 해야 하는 방법 호출은path매개 변수입니다.encode의 방법exactOutput라우팅 계약은 하나의 매개 변수만 있고 매개 변수 유형은tuple방법exactOutput이름은0x09b81346, 결과를 해독하는decodeRaw에 의해exchange.IO ("decode",...)방법, 그리고 변수와 일치dataTuple.

개인 키를 전환할 수 있는 지원

개인 키를 전환하여 여러 지갑 주소를 작동하는 것을 지원합니다. 예를 들어:

function main() {
    exchange.IO("key", "Private Key")   // "Private Key" represents the private key string, which needs to be filled in specifically
}

스마트 컨트랙트를 호출하는 방법

첫 번째 매개 변수exchange.IO함수는:"api"이 호출은 연장 호출입니다.exchange.IOfunction는 호출될 스마트 계약의 주소입니다.

호출된 메소드가payable매개 변수 이름의 다음에 이식 ETH 값을 추가해야 합니다exchange.IO함수), 이는 숫자 타입이거나 문자열 형태로 값을 전달할 수 있습니다.multicall방법Uniswap V3다음 내용은 일부 스마트 계약 방법 호출의 예입니다:

  • 소수

    decimals방법은constant방법ERC20생성하지 않는gas소비량, 그리고 특정 데이터의 정밀 데이터를 검색 할 수 있습니다.token.decimals매개 변수는 없습니다. 반환 값:token.

    function main(){
        var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"    // The contract address of the token, in the example the token is 1INCH
        Log(exchange.IO("api", tokenAddress, "decimals"))                  // Query, print 1INCH tokens with precision index of 18
    }
    
  • 보조금

    allowance방법은constant방법ERC20생성하지 않는gas소비, 그리고 그것은 특정의 허가된 양을 검색 할 수 있습니다.token특정 계약 주소allowance이 방법은 2개의 매개 변수를 통과해야 합니다. 첫 번째는 지갑 주소이고 두 번째는 승인 주소입니다. 반환 값:token.

    function main(){
        // The contract address of the token, in the example the token is 1INCH
        var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"            
    
        // For example, the query yields 10000000000000000000000, divided by the precision unit of the token 1e18, the current exchange object bound to the wallet to the spender address authorized 1 1INCH.
        Log(exchange.IO("api", tokenAddress, "allowance", "owner", "spender"))   
    }
    

    owner: 지갑 주소는 예제에서 문자열 owner로 대체됩니다. 실제 사용에서는 주소를 채워야 합니다.spender: 허가 계약 주소는 문자열에 의해 대체됩니다. 실제 사용에서, 당신은 예를 들어 주소를 구체적으로 채워야 합니다.Uniswap V3 router v1.

  • 승인

    approve이 방법은constant방법ERC20생성하는gas소비를 허용하는 데 사용됩니다.token계약 주소로 거래 금액approve이 방법은 2개의 매개 변수를 통과해야 합니다. 첫번째는 승인될 주소이고 두번째는 승인된 금액입니다.txid.

    function main(){
        // The contract address of the token, in the example the token is 1INCH
        var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"   
    
        // The hexadecimal string of the authorization amount: 0xde0b6b3a7640000 , the corresponding decimal string: 1e18 , 1e18 divided by the precision unit of the token, i.e. 1 token amount, so this refers to the authorization of one token.
        Log(exchange.IO("api", tokenAddress, "approve", "spender", "0xde0b6b3a7640000"))  
    }
    

    spender: 허가 계약의 주소는, 예를 들어 문자열에 의해 대체됩니다Uniswap V3 router v1 address. 0xde0b6b3a7640000: 여기 hexadecimal 문자열을 사용하여 표시 된 권한의 수는 decimal 값에 해당합니다.1e18,token예제에서의 정밀 단위 (즉, 1e18) 는 1을 낸다.token authorized.

    세 번째 매개 변수는exchange.IO함수가 전달됩니다 방법 이름approve, 이 또한 형태로 작성 될 수 있습니다methodId, 예를 들어: 0x571ac8b0. 또한 approve(address,uint256) 과 같은 전체 표준 메소드 이름을 쓸 수 있습니다.

  • 복수 호출

    multicall이 방법은 일정한 방법이 아닙니다Uniswap V3, 이것은 생성gas소비 및 여러 가지 방법으로 토큰을 교환하는 데 사용됩니다.multicall메소드는 매개 변수를 전달하는 여러 메소드를 가질 수 있습니다. 자세한 내용은 메소드를 포함하는 ABI에 문의할 수 있습니다. 메소드를 호출하기 전에 ABI를 등록해야합니다. 반환 값:txid.

    구체적인 예제multicall방법 호출, 대중을 참조하십시오Uniswap V3 트레이딩 클래스 라이브러리 템플릿우리 플랫폼의

    위조코드는 몇 가지 세부 사항을 설명하기 위해 사용됩니다.

    exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data)
    

    ContractV3SwapRouterV2: Uniswap V3의 라우터 v2 주소value: ETH의 양을 전송, 0으로 설정tokenIn거래 거래에 사용되는 토큰은 ETH가 아닙니다.deadline: 설정할 수 있습니다(new Date().getTime() / 1000) + 36001시간 동안 유효합니다.data: 수행될 포장 작업의 데이터.

    또한gasLimit/gasPrice/nonce메소드 호출을 설정하는 경우, 우리는 다시 설명하기 위해 위조 코드를 사용합니다:

    exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data, {gasPrice: 123456, gasLimit: 21000})
    

    매개 변수를 설정할 수 있습니다{gasPrice: 11, gasLimit: 111, nonce: 111}당신의 특정 필요에 따라, 매개 변수는exchange.IO함수를 빼낼 수 있습니다nonce그리고 시스템 기본값을 사용하거나 설정하지 않습니다gasLimit/gasPrice/nonce그리고 모든 시스템 기본값을 사용하세요.

    이 예제에서,stateMutability안쪽multicall(uint256,bytes[])방법은payable, 그리고value매개 변수를 입력해야 합니다.stateMutability":"payable"이 부분의 본문은ABI.exchange.IO함수는 요구되는 매개 변수를stateMutability속성ABI등록 된 경우stateMutability속성은nonpayable, 매개 변수value전달할 필요가 없습니다.

일반적인 함수 호출

  1. 교환 객체에 의해 구성된 지갑의 주소를 얻습니다.
function main() {
    Log(exchange.IO("address"))         // Print the wallet address of the private key configured on the exchange object.
}
  1. 블록체인 RPC 노드를 전환하세요.
function main() {
    var chainRpc = "https://bsc-dataseed.binance.org"
    e.IO("base", chainRpc)    // Switch to BSC chain
}

표시기 기능

표시기 함수를 호출할 때, 당신은 추가해야 합니다TA.또는talib.접두어

표시기 함수를 호출하는 예제talib도서관 및TA라이브러리

function main(){
    var records = exchange.GetRecords()
    var macd = TA.MACD(records)
    var atr = TA.ATR(records, 14)

    // Print the last row of indicator values
    Log(macd[0][records.length-1], macd[1][records.length-1], macd[2][records.length-1])
    Log(atr[atr.length-1])

    // Print all indicator data, and JavaScript written strategies have integrated a talib library on FMZ Quant Trading platform 
    Log(talib.MACD(records))
    Log(talib.MACD(records, 12, 26, 9))
    Log(talib.OBV(records))

    // The talib library can also be passed in an array of numbers, which can be passed in order. For example: OBV (Records [Close], Records [Volume]) requires the parameters of the two arrays, including "Close" and "Volume"
    Log(talib.OBV([1,2,3], [7.1, 6.2, 3, 3]))

    // You can also directly pass in the "records" array containing the "Close" and "Volume" attribute
    Log(talib.OBV(records))
    Log(TA.Highest(records, 30, 'High'))
    Log(TA.Highest([1,2,3,4], 0))
}
# Python needs to install the talib library separately 
import talib
def main():
    r = exchange.GetRecords()
    macd = TA.MACD(r)
    atr = TA.ATR(r, 14)
    Log(macd[0][-1], macd[1][-1], macd[2][-1])
    Log(atr[-1])

    # For Python, the system extends the attributes of the array returned by GetRecords, and adds "Open", "High", "Low", "Close" and "Volume" to facilitate the call of the functions in the talib library
    Log(talib.MACD(r.Close))
    Log(talib.MACD(r.Close, 12, 26, 9))
    Log(talib.OBV(r.Close, r.Volume))

    Log(TA.Highest(r, 30, "High"))
    Log(TA.Highest([1, 2, 3, 4], 0))
void main() {
    auto r = exchange.GetRecords();
    auto macd = TA.MACD(r);
    auto atr = TA.ATR(r, 14);
    Log(macd[0][macd[0].size() - 1], macd[1][macd[1].size() - 1], macd[2][macd[2].size() - 1]);
    Log(atr[atr.size() - 1]);

    Log(talib.MACD(r));
    Log(talib.MACD(r, 12, 26, 9));
    Log(talib.OBV(r));

    Log(TA.Highest(r.Close(), 30));
}

다음 매개 변수의 데이터는 함수로 얻은 모든 데이터입니다.exchange.GetRecords(Period)- 그래요 길이를 주의하십시오records, 길이가 지표 함수의 매개 변수 계산 요구 사항을 충족하지 않으면 유효하지 않은 값이 반환됩니다.

TA - 일반적으로 사용되는 지표 라이브러리

TAFMZ 퀀트 트레이딩 플랫폼의 지표 라이브러리는 일반적으로 사용되는 지표 알고리즘을 최적화하여JavaScript, Python그리고cpp 오픈 소스 TA 라이브러리 코드.

MACD - 컨버전스 및 디버전스의 이동 평균

TA.MACD(data, fast period, slow period, signal period)(12, 26, 9) 의 기본 기간 매개 변수와 함께[DIF, DEA, MACD] respectively.

function main(){
    // You can fill in different k-line periods, such as PERIOD_M1, PERIOD_M30 and PERIOD_H1...
    var records = exchange.GetRecords(PERIOD_M15)
    var macd = TA.MACD(records, 12, 26, 9)
    // You can see from the log that three arrays are returned, corresponding to DIF, DEA, MACD
    Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
}
def main():
    r = exchange.GetRecords(PERIOD_M15)
    macd = TA.MACD(r, 12, 26, 9)
    Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
void main() {
    auto r = exchange.GetRecords(PERIOD_M15);
    auto macd = TA.MACD(r, 12, 26, 9);
    Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2]);
}

KDJ - 스토카스틱 지표

TA.KDJ(data, period 1, period 2, period 3), (9, 3, 3) 의 기본 기간 매개 변수와 함께(K, D, J) respectively.

function main(){
    var records = exchange.GetRecords(PERIOD_M15)
    var kdj = TA.KDJ(records, 9, 3, 3)
    Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
}
def main():
    r = exchange.GetRecords(PERIOD_M15)
    kdj = TA.KDJ(r, 9, 3, 3)
    Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
void main() {
    auto r = exchange.GetRecords();
    auto kdj = TA.KDJ(r, 9, 3, 3);
    Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]);
}

RSI - 상대적 강도 지수

TA.RSI(data, period), 14의 기본 기간 매개 변수와 함께, 1차원 배열을 반환합니다.

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var rsi = TA.RSI(records, 14)
    Log(rsi)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    rsi = TA.RSI(r, 14)
    Log(rsi)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto rsi = TA.RSI(r, 14);
    Log(rsi); 
}

ATR - 평균 실제 변동성

TA.ATR(data, period); ATR ((data, period), 기본 기간 매개 변수 14로 1차원 배열을 반환합니다.

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var atr = TA.ATR(records, 14)
    Log(atr)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    atr = TA.ATR(r, 14)
    Log(atr)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto atr = TA.ATR(r, 14);
    Log(atr);
}

OBV - 균형 부피

TA.OBV(data)1차원 배열을 반환합니다.

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var obv = TA.OBV(records)
    Log(obv)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    obv = TA.OBV(r)
    Log(obv)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto obv = TA.OBV(r);
    Log(obv);
}

MA - 이동 평균

TA.MA(data, period); MA ((data, period), 기본 기간 매개 변수 9로 1차원 배열을 반환합니다.

function main(){
    var records = exchange.GetRecords(PERIOD_M30)
    var ma = TA.MA(records, 14)
    Log(ma)
}
def main():
    r = exchange.GetRecords(PERIOD_M30)
    ma = TA.MA(r, 14)
    Log(ma)
void main() {
    auto r = exchange.GetRecords(PERIOD_M30);
    auto ma = TA.MA(r, 14);
    Log(ma);
}

EMA - 기하급수적 이동 평균

TA.EMA(data, period)지수 평균 지표로 기본 기간 매개 변수는 9이고, 1차원 배열을 반환합니다.

function main(){
    var records = exchange.GetRecords()
    // Determine if the number of K-line bars meets the requirement of the indicator calculation period 
    if (records && records.length > 9) {
        var ema = TA.EMA(records, 9)          
        Log(ema)
    }
}
def main():
    r = exchange.GetRecords()
    if r and len(r) > 9:
        ema = TA.EMA(r, 9)
        Log(ema)
void main() {
    auto r = exchange.GetRecords();
    if(r.Valid && r.size() > 9) {
        auto ema = TA.EMA(r, 9);
        Log(ema);
    }
}

BOLL - 볼링거 밴드

TA.BOLL(data, period, multiplier); BOLL ((데이터, 기간, 곱) 는 볼링거 밴드 지표로, 기본 매개 변수 (20, 2) 를 가지고, 두 차원 배열을 반환, 즉[Upline, Midline, Downline].

function main() {
    var records = exchange.GetRecords()
    if(records && records.length > 20) {
        var boll = TA.BOLL(records, 20, 2)
        var upLine = boll[0]
        var midLine = boll[1]
        var downLine = boll[2]
        Log(upLine)
        Log(midLine)
        Log(downLine)
    }
}
def main():
    r = exchange.GetRecords()
    if r and len(r) > 20:
        boll = TA.BOLL(r, 20, 2)
        upLine = boll[0]
        midLine = boll[1]
        downLine = boll[2]
        Log(upLine)
        Log(midLine)
        Log(downLine)
void main() {
    auto r = exchange.GetRecords();
    if(r.Valid && r.size() > 20) {
        auto boll = TA.BOLL(r, 20, 2);
        auto upLine = boll[0];
        auto midLine = boll[1];
        auto downLine = boll[2];
        Log(upLine);
        Log(midLine);
        Log(downLine);
    }
}

악어 - 악어 표시기

TA.Alligator(data, mandible period, tooth period, upper lip period); 알리거터 ((데이터, 턱 기간, 치아 기간, 윗 입술 기간) 는 알리거터 지표, 기본 매개 변수 (13,8,5) 와 함께, 그리고 두 차원 배열을 반환, 즉[Mandible, Teeth, Upper Lip].

CMF - Chaikin 현금 흐름

TA.CMF(data, period); CMF ((데이터, 기간) 는 Chaikin 돈 흐름 지표, 기본 기간 매개 변수 20와 함께, 1차원 배열을 반환합니다.

최고 - 기간 최고 가격

TA.Highest(data, period, attribute), 가장 최근의 기간 (현행 바를 제외한) 의 최대 값을 반환합니다.TA.Highest(records, 30, 'High')만약period0이면 모든 바를 의미합니다.attribute정해지지 않은 경우, 데이터는 일반 배열로 간주되며, 가격을 반환합니다 (값 유형).

최저 - 기간 최저 가격

TA.Lowest(data, period, attribute), 가장 최근의 기간 (현행 바를 제외한) 의 최소 값을 반환합니다.TA.Highest(records, 30, 'Low')만약period0은 모든 바를 의미합니다. 속성이 지정되지 않으면 데이터는 일반 배열로 간주되며 가격 (값 유형) 이 반환됩니다.

의 사용TA.Highest(...)그리고TA.Lowest(...)C++이 전략은Highest그리고Lowest함수들은 각각 2개의 매개 변수를 가지고 있고 첫 번째 매개 변수는auto r = exchange.GetRecords()함수, 그래서 당신은 방법의 호출해야 합니다r특정 속성 데이터를 전달하기 위해, 예를 들어:r.Close()클로즈 가격 데이터Close, High, Low, Open, Volume그냥r.Close().

C++예를 들어:

void main() { 
    Records r;
    r.Valid = true;
    for (auto i = 0; i < 10; i++) {
        Record ele;
        ele.Time = i * 100000;
        ele.High = i * 10000;
        ele.Low = i * 1000;
        ele.Close = i * 100;
        ele.Open = i * 10;
        ele.Volume = i * 1;
        r.push_back(ele);
    }

    for(int j = 0; j < r.size(); j++){
        Log(r[j]);
    }

    // Note: if the first parameter passed in is not r, you need to call "r.Close()"
    auto highest = TA.Highest(r.Close(), 8);   
    Log(highest);                     
}

첨부된 제3자 라이브러리

자바스크립트

C++

예제

  • JavaScript도서관http://mathjs.org/

    function main() {
        Log(math.round(math.e, 3))                // 2.718
        Log(math.atan2(3, -3) / math.pi)          // 0.75
        Log(math.log(10000, 10))                  // 4
        Log(math.sqrt(-4))                        // {"mathjs":"Complex","re":0,"im":2}   
    }
    

    http://mikemcl.github.io/decimal.js/

    function main() {
        var x = -1.2
        var a = Decimal.abs(x)
        var b = new Decimal(x).abs()
        Log(a.equals(b))                           // true  
    
        var y = 2.2
        var sum = Decimal.add(x, y)
        Log(sum.equals(new Decimal(x).plus(y)))

더 많은