[TOC]
금융시장의 급속한 발전과 양적 거래의 보편화로 인해 점점 더 많은 거래자가 자동화 전략에 의존하기 시작하였다. 이 과정에서 전략 간의 통신과 조정은 특히 중요해졌다. FMZ (quantitative trading platform) 는 효율적인 거래 전략 실제 디스크 통신 프로토콜을 제공함으로써 거래자가 전략의 원활한 연동과 실시간 데이터 공유를 구현하도록 돕는다.
이 기사에서는 FMZ 플랫폼의 거래 전략 실제 디스크 간 통신 프로토콜에 대해 자세히 살펴보고, 그것의 설계 개념, 기능 특징 및 실제 응용에서의 장점을 소개합니다. 우리는 자세한 사례 분석을 통해 이 프로토콜을 사용하여 효율적이고 안정적인 전략 통신을 달성하고 거래 전략의 실행력과 수익 성과를 향상시키는 방법을 보여줍니다.
FMZ의 양적 거래에 대해 처음 접한 애호가이든, 경험이 많은 전문 프로그래머이든, 이 글은 당신에게 귀중한 통찰력과 실용적인 운영 지침을 제공 할 것입니다. 함께 FMZ의 강력한 기능을 탐구하여 효율적인 통신 프로토콜을 통해 전략 간 협력을 구현하고 거래 효율성을 높이고 시장 기회를 포착하는 방법을 알아보자.
이러한 요구 시나리오들은 FMZ 거래 전략 실제 디스크 간 통신 프로토콜의 실제 응용에서의 여러 가능성과 장점을 보여줍니다. 효과적인 전략 간 통신을 통해 거래자는 복잡한 시장 환경에 더 잘 대처하고 거래 전략을 최적화하고 거래 효율성과 수익을 향상시킬 수 있습니다.
디스크 A와 디스크 B가 상호작용할 수 있기를 바란다는 것만으로도, 겉으로 보기에는 간단하다. 그러나 다양한 세부사항들이 통신 프로토콜을 사용해서 협의해야 하는 것이 있는데, FMZ는 몇 가지 비교적 인기있는 통신 프로토콜을 포장했다.
mqtt / nats / amqp / kafka
통신 구조는 다음과 같습니다.
FMZ 플랫폼에서 이러한 프로토콜을 적용할 때 mqtt / nats / amqp / kafka로 간단하게 이해할 수 있습니다.Dial()
함수에서, 사용Dial()
함수들은 메시지 배포, 구독 등 동작을 수행한다. 이 배포된 메시지는 프로토콜의 서버 텐트 에이전트 (?? 接) 를 통해 구독자의 디스크에 전달된다. 따라서 먼저 프로토콜의 서버를 실행해야 한다. 예시를 위해, 우리는 다음 예제에서 다양한 프로토콜 서버 텐트 미러 배포를 사용한다.
다이얼 함수가 있는 API 문서 섹션:https://www.fmz.com/syntax-guide#fun_dial
도커 미러를 배포하기 전에 먼저 도커 소프트웨어를 설치하는 것을 기억하십시오.
다음에는 FMZ가 지원하는 통신 프로토콜의 응용을 함께 탐구하고 실천해보자.
MQTT (Message Queuing Telemetry Transport) 는 낮은 대역폭, 높은 지연, 또는 신뢰할 수 없는 네트워크 환경에 특히 적합한 가벼운 메시지 전송 프로토콜이다. 1999년에 IBM의 앤디 스탠퍼드-클라크와 아르렌 닉퍼가 제안하여 ISO 표준 (ISO/IEC PRF 20922) 이 되었다.
MQTT 프로토콜의 주요 특징: 게시/구독 모드
우리는 MQTT 프로토콜을 지원하는 소프트웨어를 사용하는 도커 미러 (eclipse-mosquitto mirror) 를 사용하여 MQTT 프록시 서버를 배포하기 때문에 미리 도커를 설치하고 후속 내용은 설명하지 않습니다.
미러 배포 명령어를 실행하기 전에 우리는 대리 서버 프로파일을 작성해야 합니다.mosquitto.conf
。
# 配置端口号及远程访问IP
listener 1883 0.0.0.0
# 设置匿名访问
allow_anonymous true
그리고 배포 명령어를 실행합니다:
docker run --rm -p 1883:1883 -v ./mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
프록시 서버가 실행되면 다음과 같은 것이 표시됩니다.
1723012640: mosquitto version 2.0.18 starting
1723012640: Config loaded from /mosquitto/config/mosquitto.conf.
1723012640: Opening ipv4 listen socket on port 1883.
1723012640: mosquitto version 2.0.18 running
그리고 나서 우리는 전략을 테스트하고 실행할 수 있습니다.
var conn = null
function main() {
LogReset(1)
var robotId = _G()
Log("当前实盘robotId:", robotId)
conn = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
if (!conn) {
Log("通信失败!")
return
}
for (var i = 0; i < 10; i++) {
// 写入
var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()
conn.write(msg)
Log("向testQueue写入消息:", msg)
// 读取
Log("read:", conn.read(1000), "#FF0000")
Sleep(1000)
}
}
function onexit() {
conn.close()
Log("关闭conn")
}
전략 코드는 주로 다이얼 함수를 사용한다:
Dial("mqtt://127.0.0.1:1883?topic=test_topic")
다이얼 함수의 문자열 변수 시작mqtt://
프로토콜 이름, 이어서 경청 주소, 포트, ▲ 기호 "?" 다음 가입/공개 주체의 이름, 여기서 테스트 주체의 이름은 다음과 같습니다.test_topic
。
이 전략은 게시물, 구독 및 실행 테스트를 위해 다음과 같습니다.
또한 두 개의 실제 디스크를 사용하여 서로 가입하거나 주제 정보를 게시할 수 있습니다. 우리는 nats 프로토콜의 연습 섹션에서 이러한 예제를 사용하지만 다른 프로토콜에서는 이러한 방법을 설명하지 않습니다.
NATS의 프로토콜은 간단한, 텍스트 기반의 릴리스/서브스크립션 스타일의 프로토콜이다. 클라이언트는 gnatsd (NATS 서버) 에 연결되고 gnatsd와 통신하며, 통신은 일반적인 TCP/IP 서식어를 기반으로 하며, 매우 작은 작업 세트를 정의하고, 라인 교환을 표시한다. 전통적인, 이진 메시지 형식을 사용하는 메시지 통신 시스템과는 달리, 텍스트 기반의 NATS 프로토콜을 사용하여 클라이언트가 쉽게 구현할 수 있으며, 여러 프로그래밍 언어 또는 스크립트 언어를 편리하게 선택할 수 있습니다.
각 조약은 각기 다른 특성을 가지고 있으며, 구체적인 문서, 자료를 살펴볼 수 있습니다.
Nats 프로토콜 서버를 배포합니다:
docker run
name nats rm -p 4222:4222 -p 8222:8222 nats http_port 8222 auth admin
이 도커 명령은 자동으로 nats 이미지를 다운로드하고 실행합니다. 포트 4222는 클라이언트가 액세스하려는 포트입니다.
Listening for client connections on 0.0.0.0:4222
Server is ready
nats 서버미러가 시작되고, 포트 4222를 감시합니다.
우리는 두 가지 정책을 만들 필요가 있습니다. (실용 디스크) A 정책과 B 정책이라고 이름 붙여서, 두 가지 정책의 코드는 기본적으로 동일합니다. FMZ 플랫폼에서 가장 쉽게 사용할 수있는 자바스크립트 언어를 사용하여 작성됩니다.
전략 A
var connPub = null
var connSub = null
function main() {
var robotId = _G()
Log("当前实盘robotId:", robotId)
connPub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotA")
if (!connPub) {
Log("通信失败!")
return
}
connSub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotB")
if (!connSub) {
Log("通信失败!")
return
}
while (true) {
connPub.write("robotA发布的消息,robotId: " + robotId + ", time:" + _D())
var msgRead = connSub.read(10000)
if (msgRead) {
Log("msgRead:", msgRead)
}
LogStatus(_D())
Sleep(10000)
}
}
function onexit() {
connPub.close()
connSub.close()
}
전략 B
var connPub = null
var connSub = null
function main() {
var robotId = _G()
Log("当前实盘robotId:", robotId)
connPub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotB")
if (!connPub) {
Log("通信失败!")
return
}
connSub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotA")
if (!connSub) {
Log("通信失败!")
return
}
while (true) {
connPub.write("robotB发布的消息,robotId: " + robotId + ", time:" + _D())
var msgRead = connSub.read(10000)
if (msgRead) {
Log("msgRead:", msgRead)
}
LogStatus(_D())
Sleep(10000)
}
}
function onexit() {
connPub.close()
connSub.close()
}
이 두 가지 전략은 기본적으로 동일하지만 서로 게시, 구독, 구독 주제, 게시 주제, 게시 정보는 다릅니다.
예를 들어, 전략 B:
1, 사용Dial()
함수 클라이언트 연결 서버 대상 생성connPub
이 글은 이 부분의 게시물을 통해 공개되었습니다.
var connPub = 다이얼127.0.0.1:4222?topic=pubRobotB”)
다이얼 함수의 변수 문자열, 시작nats://
이 문서는 NATS 프로토콜을 사용하는 것을 나타냅니다.admin
도커 미러를 배포할 때 설정되는 간단한 확인 정보입니다.auth admin
, "@127.0.0.1:4222
그리고 마지막으로, 게시물 / 구독 주제:topic=pubRobotB
참고로 이전 주소와 사이에는 "
2, 사용Dial()
함수 클라이언트 연결 서버 대상 생성connSub
이 글은 이 주제에 대한 뉴스 구독을 위한 것입니다.
var connSub = 다이얼127.0.0.1:4222?topic=pubRobotA”)
그 차이점은topic=pubRobotA
다른 전략 A를 구독해야 하기 때문에 다른 전략 A를 구독해야 합니다pubRobotA
。
정책 A의 구독, 게시 연결 개체의 생성 및 사용은 위에서 설명한 것과 동일합니다.
전략 A 실행
전략 B 실행
이렇게 하면 A 디스크와 B 디스크 사이에 상호 구독, 메시지 발송, 통신을 하는 간단한 nats 프로토콜 응용 사례가 구현된다.
비동기 통신에서는 메시지가 즉시 수신자에게 도착하지 않고, 하나의 컨테이너에 저장되며, 특정 조건이 충족되면 메시지는 컨테이너에 의해 수신자에게 전송됩니다. 이 컨테이너는 메시지 큐어입니다. 이 기능을 수행하려면 양쪽과 컨테이너와 그 구성 요소가 통일된 협약과 규칙을 준수해야합니다. AMQP는 이러한 프로토콜입니다.
각 조약은 각기 다른 특성을 가지고 있으며, 구체적인 문서, 자료를 살펴볼 수 있습니다.
amqp 프로토콜 서버를 배포합니다:
docker run
rm hostname my-rabbit name rabbit -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=q -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3-관리
도커 미러를 배포할 때 자동으로 배포를 다운로드하고 완료하면 다음과 같이 표시됩니다.
2024-08-06 09:02:46.248936+00:00 [info] <0.9.0> Time to start RabbitMQ: 15569 ms
서버 이미지 배포가 완료되면 테스트 예제 테스트를 작성합니다.
var conn = null
function main() {
LogReset(1)
var robotId = _G()
Log("当前实盘robotId:", robotId)
conn = Dial("amqp://q:admin@127.0.0.1:5672/?queue=robotA_Queue")
if (!conn) {
Log("通信失败!")
return
}
for (var i = 0; i < 10; i++) {
// 读取
Log("read:", conn.read(1000), "#FF0000")
// 写入
var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()
conn.write(msg)
Log("向testQueue写入消息:", msg)
Sleep(1000)
}
}
function onexit() {
conn.close()
Log("关闭conn")
}
amqp 프로토콜을 사용하는 큐는 게시된 메시지가 큐에 영구적으로 존재한다는 것을 주목해야 합니다. 예를 들어, 위의 예제 코드를 실행하는 동안 큐에 10개의 메시지가 쓰여집니다. 다음으로 두 번째 실행을 할 때 첫 번째 입력된 메시지가 다시 읽혀집니다. 그림은 다음과 같습니다:
스크린에서 빨간색 화살표가 가리키는 두 개의 로그 메시지가 시간이 일치하지 않는 것을 볼 수 있습니다. 빨간색으로 표시된 것은 정책 코드가 처음 실행될 때 큐에 쓰인 읽기 메시지가므로입니다.
이 특징에 따라 몇 가지 요구 사항이 실현될 수 있다. 예를 들어: 전략 리얼 디스크가 다시 시작되면, 초기화 컴퓨팅 등의 작업을 위해 큐에서 기록된 시장 데이터를 여전히 얻을 수 있다.
아파치 카프카 (Apache Kafka) 는 실시간으로 추출하고 처리하기 위해 최적화된 스트림 데이터의 분산 데이터 저장소이다. 스트림 데이터는 수천 개의 데이터 소스에서 지속적으로 생성되는 데이터를 의미합니다. 일반적으로 데이터 기록이 동시에 전송 될 수 있습니다. 스트림 플랫폼은 이러한 지속적인 스트림 데이터를 처리해야하며 순서대로 단계적으로 처리해야합니다.
카프카는 사용자에게 세 가지 주요 기능을 제공합니다.
카프카는 주로 데이터 흐름에 적응하는 실시간 스트림 데이터 파이프 및 응용 프로그램을 구축하는 데 사용됩니다. 그것은 메시지 송수신, 저장 및 스트림 처리 기능을 결합하여 역사 및 실시간 데이터를 저장할 수 있습니다.
카프카 대리인을 배포하는 도커 이미지:
docker run --rm --name kafka-server --hostname kafka-server -p 9092:9092 -p 9093:9093 \
-e KAFKA_CFG_NODE_ID=0 \
-e KAFKA_CFG_PROCESS_ROLES=controller,broker \
-e KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 \
-e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 \
-e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT \
-e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-server:9093 \
-e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER \
bitnami/kafka:latest
테스트 코드를 사용하여 테스트:
var conn = null
function main() {
LogReset(1)
var robotId = _G()
Log("当前实盘robotId:", robotId)
conn = Dial("kafka://localhost:9092/test_topic")
if (!conn) {
Log("通信失败!")
return
}
for (var i = 0; i < 10; i++) {
// 写入
var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()
conn.write(msg)
Log("向testQueue写入消息:", msg)
// 读取
Log("read:", conn.read(1000), "#FF0000")
Sleep(1000)
}
}
function onexit() {
conn.close()
Log("关闭conn")
}
이제 우리는 다이얼 함수에서 카프카 프로토콜을 사용하여 메시지를 게시하고 가입하는 방법을 살펴보겠습니다.
Dial("kafka://localhost:9092/test_topic")
다른 몇 가지 프로토콜과 마찬가지로, 프로토콜 이름은 시작됩니다.localhost:9092
◎ 다음으로 "/"를 간격으로 사용 하 여, 다음 가입/공개 주제를 작성, 여기 테스트 주제가 설정 됩니다.test_topic
。
테스트 결과: