code / 交易执行 /tradecoin.py
tradequant's picture
Upload 59 files
7ec53ba
import asyncio
import math
import datetime
import time
import pandas as pd
from binance.client import Client
from pymongo import MongoClient
# 函数说明
# get_exchange_info():获取当前交易对信息,包括交易对精度、限价单最大值、挂单最小值等。
# get_order_book(symbol, limit=100):获取指定交易对的深度信息,包括卖五、买五等信息。
# get_account(recvWindow=60000):获取当前账户信息,包括余额、冻结资金等。
# get_avg_price(symbol):获取指定交易对最新的平均价格。
# get_open_orders(symbol=None, recvWindow=60000):获取当前账户的所有未成交的订单信息,可以指定交易对。
# cancel_order(symbol, orderId=None, origClientOrderId=None, newClientOrderId=None, recvWindow=60000):取消指定订单,可以通过订单ID或客户端自定义ID来取消。
# get_order(symbol, orderId=None, origClientOrderId=None, recvWindow=60000):获取指定订单的信息,可以通过订单ID或客户端自定义ID来查询。
# get_all_orders(symbol, orderId=None, startTime=None, endTime=None, limit=500, recvWindow=60000):获取当前账户在指定交易对下的所有订单信息。
# # 币安的api配置(主网)
# api_key = "0jmNVvNZusoXKGkwnGLBghPh8Kmc0klh096VxNS9kn8P0nkAEslVUlsuOcRoGrtm"
# api_secret = "PbSWkno1meUckhmkLyz8jQ2RRG7KgmZyAWhIF0qPdCJrmDSFxoxGdMG5gZeYYCgy"
# 创建Binance客户端
# client = Client(api_key, api_secret)
# 币安的api配置(现货测试网)
api_key = "I5To2CwMIp74EB6zkulpwo4eioWPrYyp4JwBDLBR6QFNHalQUnm595ZEy3Z3JWzK"
api_secret = "37DJ4aGGfTTLuNtKHQC7p8IMRN3fx0kM5QY0iZGqFwZ9GDeBfi3YUF3FHCngInH3"
# 创建Binance客户端
client = Client(api_key, api_secret, testnet=True)
# 连接MongoDB数据库
dbclient = MongoClient(
"mongodb://wth000:[email protected]:27017/dbname?authSource=wth000")
db = dbclient["wth000"]
name = "COIN"
collectionbuy = db[f"order买入{name}"]
collectionsell = db[f"order卖出{name}"]
collectionbalance = db[f"order余额{name}"]
money = 1000 # 设置每一批的下单金额
holdday = 1 # 设置持仓周期
waittime = 5 # 设置下单间隔,避免权重过高程序暂停,目前来看5比较好
buy_limit_money = 12 # 设置买单的最小下单金额,不得低于12否则无法成交
sell_limit_money = 12 # 设置卖单的最小下单金额,不得低于12否则无法成交
cancelrate = 5 # 设置撤单速率,每下多少轮次的订单,撤销一次订单
stoprate = 0.0005 # 设置停止下单的价格偏离
async def sell_all(): # 市价卖出所有代币
# 获取账户余额
balances = client.get_account()["balances"]
for balance in balances:
try:
asset = balance["asset"]
free_balance = float(balance["free"])
locked_balance = float(balance["locked"])
total_balance = free_balance + locked_balance
if asset != "USDT" and total_balance > 0:
symbol = asset + "USDT"
# 执行市价卖单
client.order_market_sell(
symbol=symbol,
quantity=total_balance
)
print(f"卖出{asset}成功!")
except Exception as e:
print(f"buy发生bug: {e}")
continue
async def buy(buy_symbol, money):
balances = client.get_account()["balances"] # 获取现货账户资产余额
for balance in balances:
if balance["asset"] == "USDT":
usdt_balance = float(balance["free"])
print("USDT余额:", usdt_balance)
buymoney = 0 # 累计买入金额
buyvalue = 0 # 累计买入量
error_count = 0
for n in range(1, 86400):
try:
# 暂停5秒,等待撤单
await asyncio.sleep(waittime)
buy_symbol_info = client.get_symbol_info(buy_symbol)
# 针对现货市场的精度设置
buy_price_precision = buy_symbol_info["filters"][0]["minPrice"]
buy_price_precision = abs(
int(math.log10(float(buy_price_precision))))
buy_precision = buy_symbol_info["filters"][1]["minQty"]
buy_precision = abs(int(math.log10(float(buy_precision))))
buy_tickSize = float(buy_symbol_info["filters"][0]["tickSize"])
buy_stepSize = float(buy_symbol_info["filters"][1]["minQty"])
while True:
await asyncio.sleep(waittime)
# 实时获取当前卖一和买一价格
buy_depth = client.get_order_book(symbol=buy_symbol, limit=5)
print(buy_depth)
buy_ask_price_1 = float(buy_depth["asks"][0][0])
buy_ask_value_1 = float(buy_depth["asks"][0][1])
buy_bid_price_1 = float(buy_depth["bids"][0][0])
buy_bid_value_1 = float(buy_depth["bids"][0][1])
buy_ave = client.get_avg_price(symbol=buy_symbol)[
"price"] # 获取交易标的的一分钟均价
# 计算最佳买单和最佳卖单
buy_target_price = round(
(buy_ask_price_1+buy_bid_price_1)/2, buy_price_precision)
buy_quantity = round(round(
buy_limit_money/buy_target_price / buy_stepSize) * buy_stepSize, buy_precision)
if ((float(buy_target_price)/float(buy_ave)) <= 1+stoprate) & ((float(buy_target_price)/float(buy_ave)) >= 1-stoprate):
# 上涨的时候会抬升目标价,如果目标价抬升的偏离均价千分之一就暂停下单
break
buy_order = client.create_order(
symbol=buy_symbol,
side=Client.SIDE_BUY,
type=Client.ORDER_TYPE_LIMIT,
quantity=float(buy_quantity),
price=float(buy_target_price),
timeInForce="GTC" # “GTC”(成交为止),“IOC”(立即成交并取消剩余)和“FOK”(全部或无)
) # 限价成交
print(f"buy第{n}次下单", "交易标的", buy_symbol, "目标价格", buy_target_price,
"买一价:", buy_bid_price_1, "买一量:", buy_bid_value_1,
"卖一价:", buy_ask_price_1, "卖一量:", buy_ask_value_1,
"数量精度:", buy_precision, "数量步长:", buy_stepSize,
"价格精度:", buy_price_precision, "价格步长:", buy_tickSize,
"下单信息:", buy_order)
collectionbuy.insert_one({
"日期": datetime.datetime.now().strftime("%Y-%m-%d"),
"orderId": int(buy_order["orderId"]),
"symbol": buy_symbol,
"time": int(time.time()),
"quantity": float(buy_order["origQty"]),
"buy_quantity": None,
"buy_price": float(buy_order["price"]),
"buy_precision": int(buy_precision),
"buy_price_precision": int(buy_price_precision),
"buy_tickSize": float(buy_tickSize),
"buy_stepSize": float(buy_stepSize),
"status": "pending",
"目标买入金额": money,
"当前下单批次": n,
})
if n % cancelrate == 0:
try:
for buy_cancel_order in collectionbuy.find({"status": "pending"}):
buy_cancel_symbol = buy_cancel_order["symbol"]
buy_cancel_order_id = buy_cancel_order["orderId"]
# 撤销订单
buy_result = client.cancel_order(
symbol=buy_cancel_symbol, orderId=buy_cancel_order_id)
print(f"撤销订单{buy_cancel_order_id}成功buy:{buy_result}")
# 暂停5秒,等待撤单
await asyncio.sleep(waittime)
except Exception as e:
print(f"撤销订单{buy_cancel_order_id}失败buy{e}")
# 每10秒更新一次订单状态
try:
# 获取当日已完成的订单
start_time = int(
(datetime.datetime.now() - datetime.timedelta(days=1)).timestamp() * 1000)
all_orders = client.get_all_orders(
symbol=buy_symbol, startTime=start_time)
# 遍历已完成的订单
for all_order in all_orders:
all_order_id = all_order["orderId"]
# 已成交订单
collectionbuy.update_one(
{"orderId": all_order_id},
{"$set": {
"buy_price": float(all_order["price"]),
"buy_quantity": float(all_order["executedQty"]),
"status": all_order["status"],
}}
)
buymoney += float(all_order["price"]) * \
float(all_order["executedQty"])
buyvalue += float(all_order["executedQty"])
print(f"待下单金额:{buymoney}", f"今日买入量:{buyvalue}",
"历史成交订单更新sell", all_order)
except Exception as e:
print(f"发生异常:{e}")
if buymoney >= money*0.995:
collectionbalance.insert_one(
{
"日期": datetime.datetime.now().strftime("%Y-%m-%d"),
"symbol": buy_symbol,
"买入金额": buymoney,
"买入数量": buyvalue,
"卖出金额": None,
"卖出数量": None,
}
)
break
except Exception as e:
# 错误次数加1,并输出错误信息
error_count += 1
print(f"buy发生bug: {e}")
continue
# 输出异常次数
print(f"buy共出现{error_count}次异常")
async def sell(sell_symbol):
try:
balancevalue = list(collectionbalance.find({"symbol": sell_symbol, "日期": (datetime.datetime.now(
) - datetime.timedelta(days=holdday)).strftime("%Y-%m-%d"), "symbol": sell_symbol}))
balancevalue = [b["买入数量"] for b in balancevalue][-1]
# 列表索引不能是字符串
print("需卖出数量", sell_symbol, balancevalue)
sellmoney = 0 # 累计卖出金额
sellvalue = 0 # 累计卖出量
error_count = 0
for n in range(1, 86400):
try:
# 暂停5秒,等待撤单
await asyncio.sleep(waittime)
sell_symbol_info = client.get_symbol_info(sell_symbol)
# 针对现货市场的精度设置
sell_price_precision = sell_symbol_info["filters"][0]["minPrice"]
sell_price_precision = abs(
int(math.log10(float(sell_price_precision))))
sell_precision = sell_symbol_info["filters"][1]["minQty"]
sell_precision = abs(int(math.log10(float(sell_precision))))
sell_tickSize = float(
sell_symbol_info["filters"][0]["tickSize"])
sell_stepSize = float(sell_symbol_info["filters"][1]["minQty"])
while True:
# 实时获取当前卖一和买一价格
sell_depth = client.get_order_book(
symbol=sell_symbol, limit=5)
print(sell_depth)
sell_ask_price_1 = float(sell_depth["asks"][0][0])
sell_ask_value_1 = float(sell_depth["asks"][0][1])
sell_bid_price_1 = float(sell_depth["bids"][0][0])
sell_bid_value_1 = float(sell_depth["bids"][0][1])
sell_ave = client.get_avg_price(symbol=sell_symbol)[
"price"] # 获取交易标的的一分钟均价
# 计算最佳买单和最佳卖单
sell_target_price = round(
(sell_ask_price_1+sell_bid_price_1)/2, sell_price_precision)
sell_quantity = round(round(
sell_limit_money/sell_target_price / sell_stepSize) * sell_stepSize, sell_precision)
if ((float(sell_target_price)/float(sell_ave)) <= 1+stoprate) & ((float(sell_target_price)/float(sell_ave)) >= 1-stoprate):
# 卖出的时候会砸低目标价,如果目标价砸低的偏离均价千分之一就暂停下单
break
sell_order = client.create_order(
symbol=sell_symbol,
side=Client.SIDE_SELL,
type=Client.ORDER_TYPE_LIMIT,
quantity=float(sell_quantity),
price=float(sell_target_price),
timeInForce="GTC" # “GTC”(成交为止),“IOC”(立即成交并取消剩余)和“FOK”(全部或无)
) # 限价成交
print(f"sell第{n}轮下单", "交易标的", sell_symbol, "目标价格", sell_target_price,
"买一价:", sell_bid_price_1, "买一量:", sell_bid_value_1,
"卖一价:", sell_ask_price_1, "卖一量:", sell_ask_value_1,
"数量精度:", sell_precision, "数量步长:", sell_stepSize,
"价格精度:", sell_price_precision, "价格步长:", sell_tickSize,
"下单信息:", sell_order)
collectionsell.insert_one({
"日期": datetime.datetime.now().strftime("%Y-%m-%d"),
"orderId": int(sell_order["orderId"]),
"symbol": sell_symbol,
"time": int(time.time()),
"quantity": float(sell_order["origQty"]),
"sell_quantity": None,
"sell_price": float(sell_order["price"]),
"sell_precision": int(sell_precision),
"sell_price_precision": int(sell_price_precision),
"sell_tickSize": float(sell_tickSize),
"sell_stepSize": float(sell_stepSize),
"status": "pending",
"目标卖出数量": balancevalue,
"当前下单批次": n,
})
if n % cancelrate == 0:
try:
for sell_cancel_order in collectionsell.find({"status": "pending"}):
sell_cancel_symbol = sell_cancel_order["symbol"]
sell_cancel_order_id = sell_cancel_order["orderId"]
# 撤销订单
sell_result = client.cancel_order(
symbol=sell_cancel_symbol, orderId=sell_cancel_order_id)
print(
f"撤销订单{sell_cancel_order_id}成功sell:{sell_result}")
# 暂停5秒,等待撤单
await asyncio.sleep(waittime)
except Exception as e:
print(f"撤销订单{sell_cancel_order_id}失败sell{e}")
# 每10秒更新一次订单状态
try:
# 获取当日已完成的订单
start_time = int(
(datetime.datetime.now() - datetime.timedelta(days=1)).timestamp() * 1000)
all_sell_orders = client.get_all_orders(
symbol=sell_symbol, startTime=start_time)
# 遍历已完成的订单
for all_sell_order in all_sell_orders:
all_sell_order_id = all_sell_order["orderId"]
# 已成交订单
collectionsell.update_one(
{"orderId": all_sell_order_id},
{"$set": {
"sell_price": float(all_sell_order["price"]),
"sell_quantity": float(all_sell_order["executedQty"]),
"status": all_sell_order["status"],
}}
)
sellmoney += float(all_sell_order["price"]) * float(
all_sell_order["executedQty"])
sellvalue += float(all_sell_order["executedQty"])
print(f"待下单金额:{sellmoney}", f"今日买入量:{sellvalue}",
"历史成交订单更新sell", all_sell_order)
except Exception as e:
print(f"发生异常:{e}")
if sellvalue >= balancevalue*0.995:
collectionbalance.update_one(
{"symbol": sell_symbol, "日期": (datetime.datetime.now(
) - datetime.timedelta(days=holdday)).strftime("%Y-%m-%d")},
{"$set": {
"卖出金额": sellmoney,
"卖出数量": sellvalue,
}}
)
break
except Exception as e:
# 错误次数加1,并输出错误信息
error_count += 1
print(f"sell发生bug: {e}")
continue
# 输出异常次数
print(f"sell共出现{error_count}次异常")
except Exception as e:
print(e)
async def clearn():
limit = 10000
for collection in [collectionbuy, collectionsell, collectionbalance]:
if collection.count_documents({}) >= limit:
oldest_data = collection.find().sort([("日期", 1)]).limit(
collection.count_documents({})-limit)
ids_to_delete = [data["_id"] for data in oldest_data]
collection.delete_many({"_id": {"$in": ids_to_delete}})
print(f"{collection}数据清理成功")
async def get_buy_symbols():
buy_symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT", "TRXUSDT"]
time.sleep(10)
return buy_symbols
async def get_sell_symbols():
sell_symbols = pd.DataFrame(list(collectionbuy.find({"日期": (
datetime.datetime.now() - datetime.timedelta(days=holdday)).strftime("%Y-%m-%d")})))
sell_symbols = sell_symbols["symbol"].copy(
).drop_duplicates().tolist() # 获取所有不重复的交易标的
time.sleep(10)
return sell_symbols
async def main():
tasks = []
try:
sell_symbols = await get_sell_symbols()
for sell_symbol in sell_symbols:
tasks.append(asyncio.create_task(sell(sell_symbol)))
except Exception as e:
print(e)
time.sleep(10800) # 之前的卖出委托执行三个小时后执行买入委托
try:
buy_symbols = await get_buy_symbols()
for buy_symbol in buy_symbols:
tasks.append(asyncio.create_task(buy(buy_symbol, money)))
except Exception as e:
print(e)
tasks.append(asyncio.create_task(clearn()))
await asyncio.gather(*tasks)
if __name__ == "__main__":
# sell_all()
asyncio.run(main())