Не запускается код в терминале
Я только начал изучать python и слегка переделал найденный код для работы с ccxt, в результате при запуске нет совсем никакого вывода в консоли, api ключи в конфиге прописаны в чём может быть причина? Вот переделанный код
import ccxt
import time
import config
import json
import time
exchange = ccxt.ftx({
"apiKey": config.apiKey,
"secret": config.secret,
})
# параметр
beginPrice = 0.20 # Начальная цена интервала сетки # beginPrice + i * distance + pointProfit
endPrice = 0.30 # Конечная цена интервала сетки
distance = 20 # Ценовое расстояние каждого узла сетки
pointProfit = 50 # Маржа прибыли каждого узла сетки
amount = 0.01 # Количество заказов на узел сетки
minBalance = 0 # Минимальный остаток капитала на счете (при покупке)
# глобальная переменная
arrNet = []
arrMsg = []
acc = None
def FetchOrders (orderId, NumOfTimes, ordersList = []) :
for i in range(NumOfTimes) :
orders = None
if len(ordersList) == 0:
orders = exchange.fetch_open_orders()
else :
orders = ordersList
for i in range(len(orders)):
if orderId == orders[i]["id"]:
return True
time.sleep(10)
return False
def CancelOrder (price, orderType) :
orders = exchange.cancel_order('DOGE-PERP')
for i in range(len(orders)) :
if price == orders[i]["price"] and orderType == orders[i]["type"]:
exchange.cancel_order(orders[i]["id"])
def checkOpenOrders (orders, ticker) :
global arrNet, arrMsg
for i in range(len(arrNet)) :
if not FetchOrders(arrNet[i]["id"], 1, orders) and arrNet[i]["status"] == "open" :
orderId = exchange.fetch_open_orders('sell', arrNet[i]["coverPrice"], arrNet[i]["amount"], arrNet[i], ticker)
if orderId :
arrNet[i]["status"] = "closed"
arrNet[i]["id"] = orderId
else :
# Отозвать
CancelOrder(arrNet[i]["coverPrice"], 'sell')
arrMsg.append("Не удалось добавить в список!" + json.dumps(arrNet[i]))
def checkCoverOrders (orders, ticker) :
global arrNet, arrMsg
for i in range(len(arrNet)) :
if not FetchOrders(arrNet[i]["id"], 1, orders) and arrNet[i]["status"] == "closed" :
arrNet[i]["id"] = -1
arrNet[i]["status"] = "open"
def onTick () :
global arrNet, arrMsg, acc
ticker = exchange.fetch_orders() # Получаем ордера, размещенные с вашего аккаунта.
for i in range(len(arrNet)): # Просмотрите все узлы сетки в соответствии с текущим рынком, найдите место, где нужно разместить купюру, и поместите купюру.
if i != len(arrNet) - 1 and arrNet[i]["status"] == "open" and ticker['sell'] > arrNet[i]["price"] and ticker['sell'] < arrNet[i + 1]["price"]:
acc = exchange.fetch_balance()
if acc['free']['USD'] < minBalance : # Если денег не хватит, остается только выпрыгнуть и ничего не делать.
arrMsg.append("Недостаточно средств" + json.dumps(acc) + "!")
break
orderId = exchange.fetch_open_orders('buy', arrNet[i]["price"], arrNet[i]["amount"], arrNet[i], ticker) # Повесьте счет
if orderId :
arrNet[i]["status"] = "closed" # Обновите статус узлов сетки и другую информацию, если заказ успешно оплачен
arrNet[i]["id"] = orderId
else :
# Отменить заказ
CancelOrder(arrNet[i]["price"], ['buy']) # Используйте функцию отмены для отмены
arrMsg.append("Не удалось добавить в список!" + json.dumps(arrNet[i]))
time.sleep(10)
orders = exchange.create_order('DOGE-PERP', 'buy', amount, 'limit')
checkOpenOrders(orders, ticker) # Проверьте статус всех заказов на покупку и внесите изменения.
time.sleep(10)
orders = exchange.create_order('DOGE-PERP', 'sell', amount, 'limit')
checkCoverOrders(orders, ticker) # Проверьте статус всех заказов на продажу и внесите изменения.
# Ниже приводится информация в строке состояния строительства. Вы можете просмотреть документацию FMZ API.
tbl = {
"type" : "table",
"title" : "Grid state",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}
for i in range(len(arrNet)) :
tbl["rows"].append([i, json.dumps(arrNet[i])])
errTbl = {
"type" : "table",
"title" : "Record",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}
orderTbl = {
"type" : "table",
"title" : "orders",
"cols" : ["Node index", "detailed information"],
"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])])
def main (): # Выполнение политики начинается здесь
global arrNet
for i in range(int((endPrice - beginPrice) / distance)): # Цикл for строит структуру данных сетки в соответствии с параметрами. Это список, в котором хранится каждый узел сетки. Информация о каждом узле сетки следующая:
arrNet.append({
"price" : beginPrice + i * distance, # Цена этого узла
"amount" : amount, # Количество заказа
"status" : "open", # в ожидании / крышка / простаивает # Состояние узла
"coverPrice" : beginPrice + i * distance + pointProfit, # Цена закрытия узла
"id" : -1, # ID текущего заказа, относящегося к узлу
})
while True: # После построения структуры данных сетки вводится основной цикл стратегии.
onTick() # Функция обработки в основном цикле, в основном логика обработки
time.sleep(5) # Контрольная частота опроса
Вот на всякий случай оригинал кода
# parameter
beginPrice = 5000 # Grid interval start price
endPrice = 8000 # Grid interval end price
distance = 20 # Price distance of each grid node
pointProfit = 50 # Profit margin of each grid node
amount = 0.01 # Number of orders per grid node
minBalance = 300 # Minimum capital balance of account (when buying)
# global variable
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 :
# Revoke
cancelOrder(arrNet[i]["coverPrice"], ORDER_TYPE_SELL)
arrMsg.append("Failed to list!" + 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], "The node is closed and reset to idle state.", "#FF0000")
def onTick () :
global arrNet, arrMsg, acc
ticker = _C(exchange.GetTicker) # Get the latest market every time
for i in range(len(arrNet)): # Traverse all grid nodes, according to the current market, find out the location where the bill needs to be placed, and place the bill.
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 : # If the money is not enough, we can only jump out and do nothing.
arrMsg.append("Insufficient funds" + json.dumps(acc) + "!" + ", time:" + _D())
break
orderId = exchange.Buy(arrNet[i]["price"], arrNet[i]["amount"], arrNet[i], ticker) # Hang up the bill
if orderId :
arrNet[i]["state"] = "pending" # Update the status of grid nodes and other information if the order is paid successfully
arrNet[i]["id"] = orderId
else :
# Cancel the order
cancelOrder(arrNet[i]["price"], ORDER_TYPE_BUY) # Use cancellation function to cancel
arrMsg.append("Failed to list!" + json.dumps(arrNet[i]) + ", time:" + _D())
Sleep(1000)
orders = _C(exchange.GetOrders)
checkOpenOrders(orders, ticker) # Check the status of all purchase orders and deal with the changes.
Sleep(1000)
orders = _C(exchange.GetOrders)
checkCoverOrders(orders, ticker) # Check the status of all sales orders and deal with the changes.
# The following is the construction status bar information. You can view the FMZ API documentation.
tbl = {
"type" : "table",
"title" : "Grid state",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}
for i in range(len(arrNet)) :
tbl["rows"].append([i, json.dumps(arrNet[i])])
errTbl = {
"type" : "table",
"title" : "Record",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}
orderTbl = {
"type" : "table",
"title" : "orders",
"cols" : ["Node index", "detailed information"],
"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 (): # Policy execution starts here
global arrNet
for i in range(int((endPrice - beginPrice) / distance)): # The for loop constructs the data structure of the grid according to the parameters. It is a list that stores each grid node. The information of each grid node is as follows:
arrNet.append({
"price" : beginPrice + i * distance, # Price of this node
"amount" : amount, # Order quantity
"state" : "idle", # pending / cover / idle # Node state
"coverPrice" : beginPrice + i * distance + pointProfit, # Node closing price
"id" : -1, # ID of the current order related to the node
})
while True: # After the grid data structure is constructed, the main cycle of the strategy is entered
onTick() # Processing function on main loop, mainly processing logic
Sleep(500) # Control polling frequency
Основная дизайнерская идея стратегии - сравнить текущий список отложенных ордеров, возвращаемых интерфейсом GetOrders, со структурой данных сетки, которую мы поддерживаем. Анализируйте изменение заказа (транзакция или нет), обновляйте структуру данных сетки и выполняйте последующие операции. И заказы не будут отменены, пока транзакция не будет завершена, даже если цена отклонится, потому что на рынке цифровой валюты часто есть пины, эти пины также могут получать список пинов (если есть ограничение на количество всех связанных заказов в транзакции, она будет скорректирована).
Данные стратегии визуализируются, а функция LogStatus используется для отображения данных в строке состояния в реальном времени.
tbl = {
"type" : "table",
"title" : "Grid state",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}
for i in range(len(arrNet)) :
tbl["rows"].append([i, json.dumps(arrNet[i])])
errTbl = {
"type" : "table",
"title" : "Record",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}
orderTbl = {
"type" : "table",
"title" : "orders",
"cols" : ["Node index", "detailed information"],
"rows" : [],
}```