Type/to search
8
Follow
1364
Followers
Estratégia de grade simples para Python
Discussions
Created 2020-01-04 14:28:04  Updated 2024-12-15 16:03:28
 6
 5617

img

Estratégia de grade simples para Python

Não há muitas estratégias Python no Strategy Square, então aqui está uma versão Python da estratégia de grade. O princípio da estratégia é muito simples. Uma série de nós de grade são gerados em distâncias de preço fixas dentro de uma faixa de preço. Quando o mercado muda, uma ordem de compra é colocada quando o preço atinge uma posição de preço de nó de grade. Quando esta ordem é executada, uma ordem de venda para fechar a posição é colocada com base no preço da ordem pendente mais a diferença de lucro. Capture flutuações dentro de uma faixa de preço definida.

Não há necessidade de explicar os riscos da estratégia de grade. Qualquer estratégia do tipo grade é uma aposta de que os preços flutuarão dentro de uma certa faixa. Uma vez que os preços saiam da faixa da grade, perdas flutuantes sérias podem ocorrer. Portanto, o objetivo de escrever esta estratégia é fornecer uma referência para ideias de escrita de estratégias em Python ou design de programas. Esta estratégia é apenas para fins de aprendizado e negociações reais podem ser muito arriscadas.

A explicação das ideias da estratégia é escrita diretamente nos comentários do código da estratégia.

Código de estratégia

'''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) # 控制轮询频率

A principal ideia de design da estratégia é comparar a estrutura de dados da grade mantida por você.GetOrdersA lista de pedidos pendentes atual retornada pela interface. Analise as alterações nas ordens pendentes (sejam elas executadas ou não), atualize a estrutura de dados da grade e faça operações subsequentes. E as ordens pendentes não serão canceladas até que sejam executadas, mesmo que o preço se desvie. Como geralmente há picos no mercado de moeda digital, essas ordens pendentes também podem receber ordens de pico (se a bolsa tiver um limite no número de ordens pendentes pedidos, então precisa ser ajustado).

Visualização de dados de estratégia, usandoLogStatusA função exibe os dados em tempo real na barra de status.

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

Três tabelas são construídas. A primeira tabela exibe as informações de cada nó na estrutura de dados da grade atual, a segunda tabela exibe as informações de exceção e a terceira tabela exibe as informações reais de ordem pendente da bolsa.

Testes retrospectivos

img

img

Endereço da Política

Endereço da Política

A estratégia é apenas para referência, backtesting e teste. Se você estiver interessado, pode otimizá-la e atualizá-la.

Related Recommendations
Comment
All comments (4)

    撤单

    cancelOrder(arrNet[i]["price"], ORDER_TYPE_BUY) # 使用撤单函数撤单
    这个用价格为索引取消订单是什么用法?fmz的api里只展示了id,ok交易所目前的文档上也只有id或自定义id啊...

    3 years ago

    这个cancelOrder不是exchange.CancelOrder,这个是我自定义的函数。[😂]

    3 years ago

    😂 哦,我看到了 上面的def,抱歉抱歉

    3 years ago

    不错!

    5 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)