전략 광장에 있는 파이썬 전략은 많지 않지만, 여기에 파이썬 버전의 네트워크 전략이 작성되어 있습니다. 전략의 원리는 매우 간단합니다. 가격 범위 내에서 고정된 가격 거리가 일련의 네트워크 노드를 생성하고, 시장 변화가 있을 때, 가격이 네트워크 노드 가격 위치에 도달하면 구매 주문을 붙입니다. 이 주문이 거래되면, 즉, 목록의 가격에 따라 수익 이차를 더하고, 평형 판매 주문을 붙입니다. 설정된 가격 범위 내의 변동을 포착합니다.
격자 전략의 위험은 말할 필요도 없다. 어떤 격자 유형의 전략도 어떤 범위에서 가격의 변동에 속하며, 일단 가격이 격자 범위를 돌파하면 심각한 파장을 초래할 수 있다. 따라서 이 전략을 작성하는 목적은 Python 정책을 작성하는 방법이나 프로그램 설계에 대한 참고를 제공하는 것입니다. 이 전략은 학습을 위해만 사용되며 실제판에는 큰 위험이있을 수 있습니다.
전략 아이디어 설명은 전략 코드 설명서에 직접 기록되어 있습니다.
'''backtest
start: 2019-07-01 00:00:00
end: 2020-01-03 00:00:00
period: 1m
exchanges: [{"eid":"OKEX","currency":"BTC_USDT"}]
'''
import json
# 参数
beginPrice = 5000 # 网格区间开始价格
endPrice = 8000 # 网格区间结束价格
distance = 20 # 每个网格节点的价格距离
pointProfit = 50 # 每个网格节点的利润差价
amount = 0.01 # 每个网格节点的挂单量
minBalance = 300 # 账户最小资金余额(买入时)
# 全局变量
arrNet = []
arrMsg = []
acc = None
def findOrder (orderId, NumOfTimes, ordersList = []) :
for j in range(NumOfTimes) :
orders = None
if len(ordersList) == 0:
orders = _C(exchange.GetOrders)
else :
orders = ordersList
for i in range(len(orders)):
if orderId == orders[i]["Id"]:
return True
Sleep(1000)
return False
def cancelOrder (price, orderType) :
orders = _C(exchange.GetOrders)
for i in range(len(orders)) :
if price == orders[i]["Price"] and orderType == orders[i]["Type"]:
exchange.CancelOrder(orders[i]["Id"])
Sleep(500)
def checkOpenOrders (orders, ticker) :
global arrNet, arrMsg
for i in range(len(arrNet)) :
if not findOrder(arrNet[i]["id"], 1, orders) and arrNet[i]["state"] == "pending" :
orderId = exchange.Sell(arrNet[i]["coverPrice"], arrNet[i]["amount"], arrNet[i], ticker)
if orderId :
arrNet[i]["state"] = "cover"
arrNet[i]["id"] = orderId
else :
# 撤销
cancelOrder(arrNet[i]["coverPrice"], ORDER_TYPE_SELL)
arrMsg.append("挂单失败!" + json.dumps(arrNet[i]) + ", time:" + _D())
def checkCoverOrders (orders, ticker) :
global arrNet, arrMsg
for i in range(len(arrNet)) :
if not findOrder(arrNet[i]["id"], 1, orders) and arrNet[i]["state"] == "cover" :
arrNet[i]["id"] = -1
arrNet[i]["state"] = "idle"
Log(arrNet[i], "节点平仓,重置为空闲状态。", "#FF0000")
def onTick () :
global arrNet, arrMsg, acc
ticker = _C(exchange.GetTicker) # 每次获取当前最新的行情
for i in range(len(arrNet)): # 遍历所有网格节点,根据当前行情,找出需要挂单的位置,挂买单。
if i != len(arrNet) - 1 and arrNet[i]["state"] == "idle" and ticker.Sell > arrNet[i]["price"] and ticker.Sell < arrNet[i + 1]["price"]:
acc = _C(exchange.GetAccount)
if acc.Balance < minBalance : # 如果钱不够了,只能跳出,什么都不做了。
arrMsg.append("资金不足" + json.dumps(acc) + "!" + ", time:" + _D())
break
orderId = exchange.Buy(arrNet[i]["price"], arrNet[i]["amount"], arrNet[i], ticker) # 挂买单
if orderId :
arrNet[i]["state"] = "pending" # 如果买单挂单成功,更新网格节点状态等信息
arrNet[i]["id"] = orderId
else :
# 撤单
cancelOrder(arrNet[i]["price"], ORDER_TYPE_BUY) # 使用撤单函数撤单
arrMsg.append("挂单失败!" + json.dumps(arrNet[i]) + ", time:" + _D())
Sleep(1000)
orders = _C(exchange.GetOrders)
checkOpenOrders(orders, ticker) # 检测所有买单的状态,根据变化做出处理。
Sleep(1000)
orders = _C(exchange.GetOrders)
checkCoverOrders(orders, ticker) # 检测所有卖单的状态,根据变化做出处理。
# 以下为构造状态栏信息,可以查看FMZ API 文档。
tbl = {
"type" : "table",
"title" : "网格状态",
"cols" : ["节点索引", "详细信息"],
"rows" : [],
}
for i in range(len(arrNet)) :
tbl["rows"].append([i, json.dumps(arrNet[i])])
errTbl = {
"type" : "table",
"title" : "记录",
"cols" : ["节点索引", "详细信息"],
"rows" : [],
}
orderTbl = {
"type" : "table",
"title" : "orders",
"cols" : ["节点索引", "详细信息"],
"rows" : [],
}
while len(arrMsg) > 20 :
arrMsg.pop(0)
for i in range(len(arrMsg)) :
errTbl["rows"].append([i, json.dumps(arrMsg[i])])
for i in range(len(orders)) :
orderTbl["rows"].append([i, json.dumps(orders[i])])
LogStatus(_D(), "\n", acc, "\n", "arrMsg length:", len(arrMsg), "\n", "`" + json.dumps([tbl, errTbl, orderTbl]) + "`")
def main (): # 策略执行从这里开始
global arrNet
for i in range(int((endPrice - beginPrice) / distance)): # for 这个循环根据参数构造了网格的数据结构,是一个列表,储存每个网格节点,每个网格节点的信息如下:
arrNet.append({
"price" : beginPrice + i * distance, # 该节点的价格
"amount" : amount, # 订单数量
"state" : "idle", # pending / cover / idle # 节点状态
"coverPrice" : beginPrice + i * distance + pointProfit, # 节点平仓价格
"id" : -1, # 节点当前相关的订单的ID
})
while True: # 构造好网格数据结构后,进入策略主要循环
onTick() # 主循环上的处理函数,主要处理逻辑
Sleep(500) # 控制轮询频率
이 전략의 주요 설계 아이디어는 우리가 관리하는 그레이드 데이터 구조에 따라GetOrders
인터페이스가 반환하는 현재 마인드 목록. 마인드 오더의 변화를 분석 (거래 또는 그렇지 않은 경우), 그리드 데이터 구조를 업데이트하고 후속 작업을 수행하십시오. 그리고 마인드 오더는 거래가 완료 될 때까지 취소되지 않습니다. 가격 오차도 취소되지 않습니다.
전략 데이터 시각화, 사용LogStatus
이 함수는 상태 탭에서 데이터를 실시간으로 표시합니다.
tbl = {
"type" : "table",
"title" : "网格状态",
"cols" : ["节点索引", "详细信息"],
"rows" : [],
}
for i in range(len(arrNet)) :
tbl["rows"].append([i, json.dumps(arrNet[i])])
errTbl = {
"type" : "table",
"title" : "记录",
"cols" : ["节点索引", "详细信息"],
"rows" : [],
}
orderTbl = {
"type" : "table",
"title" : "orders",
"cols" : ["节点索引", "详细信息"],
"rows" : [],
}
세 개의 테이블이 구성되어 있으며, 첫 번째 테이블은 현재 격자 데이터 구조의 각 노드 정보를 보여줍니다. 두 번째 테이블은 예외 정보를 보여줍니다. 세 번째 테이블은 거래소의 실제 주문 정보를 보여줍니다.
이 전략은 레퍼런스 학습, 리테스트 테스트, 업그레이드를 최적화 할 수있는 관심사를 위한 것입니다.
천년대의 다람쥐#불출금 cancelOrder ((arrNet[i]["price], ORDER_TYPE_BUY) # 취소 함수를 사용하여 취소 이 가격에 대한 지표에서 주문을 취소하는 방법은 무엇입니까? fmz의 api는 id만 표시하고, OK 거래소의 현재 문서에는 id 또는 사용자 정의 id가 있습니다.
천년대의 다람쥐
발명가들의 수량화 - 작은 꿈이 cancelOrder는 exchange가 아닙니다. CancelOrder, 이것은 제가 사용자 정의한 함수입니다.