8
Follow
1364
Followers
Python版冰山委托策略
Created 2020-03-06 15:26:43 Updated 2025-06-24 11:21:21
2
4238
Python版冰山委托策略
本期文章,带来两个移植的经典策略:冰山委托(买入/卖出)。策略移植自发明者量化交易平台经典策略JavaScript版冰山委托,策略地址:https://www.fmz.com/strategy/188435 。
引用JavaScript版本策略介绍:
冰山委托指的是投资者在进行大额交易时,为避免对市场造成过大冲击,将大单委托自动拆为多笔委托,根据当前的最新买一/卖一价格和客户设定的价格策略自动进行小单委托,在上一笔委托被全部成交或最新价格明显偏离当前委托价时,自动重新进行委托。
很多交易所的交易页面都自带冰山委托工具,有着丰富的功能,不过如果想根据自身需求,定制一些功能或者改动一些功能,就需要更加灵活的工具了。发明者量化交易平台很好的解决了这个问题。策略广场上Python策略不多,一些希望使用Python语言编写交易工具、策略的交易者需要参考范例。因此,就把经典的冰山委托策略移植为Python版。
Python版冰山委托 - 买入 策略代码及注释
import random # 导入随机数库
def CancelPendingOrders(): # CancelPendingOrders 函数作用是取消当前交易对所有挂单。
while True: # 循环检测,调用GetOrders 函数,检测当前挂单,如果orders 为空数组,即len(orders) 等于0,说明订单全部取消了,可以退出函数,调用return 退出。
orders = _C(exchange.GetOrders)
if len(orders) == 0 :
return
for j in range(len(orders)): # 遍历当前挂单数组,调用取消订单的函数CancelOrder,逐个取消挂单。
exchange.CancelOrder(orders[j]["Id"])
if j < len(orders) - 1: # 除了最后一个订单,每次都执行Sleep 让程序等待一会儿,避免撤单过于频繁。
Sleep(Interval)
LastBuyPrice = 0 # 设置一个全局变量,记录最近一次买入的价格。
InitAccount = None # 设置一个全局变量,记录初始账户资产信息。
def dispatch(): # 冰山委托逻辑的主要函数
global InitAccount, LastBuyPrice # 引用全局变量
account = None # 声明一个变量,记录实时获取的账户信息,用于对比计算。
ticker = _C(exchange.GetTicker) # 声明一个变量,记录最近行情。
LogStatus(_D(), "ticker:", ticker) # 在状态栏输出时间,最新行情
if LastBuyPrice > 0: # 当LastBuyPrice大于0时,即已经委托开始时,执行if条件内代码。
if len(_C(exchange.GetOrders)) > 0: # 调用exchange.GetOrders 函数获取当前所有挂单,判断有挂单,执行if条件内代码。
if ticker["Last"] > LastBuyPrice and ((ticker["Last"] - LastBuyPrice) / LastBuyPrice) > (2 * (EntrustDepth / 100)): # 检测偏离程度,如果触发该条件,执行if内代码,撤单。
Log("偏离过多, 最新成交价:", ticker["Last"], "委托价", LastBuyPrice)
CancelPendingOrders()
else :
return True
else : # 如果没有挂单,证明订单完全成交了。
account = _C(exchange.GetAccount) # 获取当前账户资产信息。
Log("买单完成, 累计花费:", _N(InitAccount["Balance"] - account["Balance"]), "平均买入价:", _N((InitAccount["Balance"] - account["Balance"]) / (account["Stocks"] - InitAccount["Stocks"]))) # 打印交易信息。
LastBuyPrice = 0 # 重置 LastBuyPrice为0
BuyPrice = _N(ticker["Buy"] * (1 - EntrustDepth / 100)) # 通过当前行情和参数,计算挂单价格。
if BuyPrice > MaxBuyPrice: # 判断是否超过参数设置的最大价格
return True
if not account: # 如果 account 为 null ,执行if 语句内代码,重新获取当前资产信息,复制给account
account = _C(exchange.GetAccount)
if (InitAccount["Balance"] - account["Balance"]) >= TotalBuyNet: # 判断买入所花费的总钱数,是不是超过参数设置。
return False
RandomAvgBuyOnce = (AvgBuyOnce * ((100.0 - FloatPoint) / 100.0)) + (((FloatPoint * 2) / 100.0) * AvgBuyOnce * random.random()) # 随机数 0~1
UsedMoney = min(account["Balance"], RandomAvgBuyOnce, TotalBuyNet - (InitAccount["Balance"] - account["Balance"]))
BuyAmount = _N(UsedMoney / BuyPrice) # 计算买入数量
if BuyAmount < MinStock: # 判断买入数量是否小于 参数上最小买入量限制。
return False
LastBuyPrice = BuyPrice # 记录本次下单价格,赋值给LastBuyPrice
exchange.Buy(BuyPrice, BuyAmount, "花费:¥", _N(UsedMoney), "上次成交价", ticker["Last"]) # 下单
return True
def main():
global LoopInterval, InitAccount # 引用 LoopInterval, InitAccount 全局变量
CancelPendingOrders() # 开始运行时,取消所有挂单
InitAccount = _C(exchange.GetAccount) # 初始记录 开始时的账户资产
Log(InitAccount) # 打印初始账户信息
if InitAccount["Balance"] < TotalBuyNet: # 如果初始时资产不足,则抛出错误,停止程序
raise Exception("账户余额不足")
LoopInterval = max(LoopInterval, 1) # 设置LoopInterval至少为1
while dispatch(): # 主要循环,不停调用 冰山委托逻辑函数 dispatch ,当dispatch函数 return false 时才停止循环。
Sleep(LoopInterval * 1000) # 每次循环都暂停一下,控制轮询频率。
Log("委托全部完成", _C(exchange.GetAccount)) # 当循环执行跳出时,打印当前账户资产信息。
Python版冰山委托 - 卖出
可以尝试,读一下「Python版冰山委托 - 卖出」的代码,策略逻辑和买入的是一样的,只有略微差别。
import random
def CancelPendingOrders():
while True:
orders = _C(exchange.GetOrders)
if len(orders) == 0:
return
for j in range(len(orders)):
exchange.CancelOrder(orders[j]["Id"])
if j < len(orders) - 1:
Sleep(Interval)
LastSellPrice = 0
InitAccount = None
def dispatch():
global LastSellPrice, InitAccount
account = None
ticker = _C(exchange.GetTicker)
LogStatus(_D(), "ticker:", ticker)
if LastSellPrice > 0:
if len(_C(exchange.GetOrders)) > 0:
if ticker["Last"] < LastSellPrice and ((LastSellPrice - ticker["Last"]) / ticker["Last"]) > (2 * (EntrustDepth / 100)):
Log("偏离过多,最新成交价:", ticker["Last"], "委托价", LastSellPrice)
CancelPendingOrders()
else :
return True
else :
account = _C(exchange.GetAccount)
Log("买单完成,累计卖出:", _N(InitAccount["Stocks"] - account["Stocks"]), "平均卖出价:", _N((account["Balance"] - InitAccount["Balance"]) / (InitAccount["Stocks"] - account["Stocks"])))
LastSellPrice = 0
SellPrice = _N(ticker["Sell"] * (1 + EntrustDepth / 100))
if SellPrice < MinSellPrice:
return True
if not account:
account = _C(exchange.GetAccount)
if (InitAccount["Stocks"] - account["Stocks"]) >= TotalSellStocks:
return False
RandomAvgSellOnce = (AvgSellOnce * ((100.0 - FloatPoint) / 100.0)) + (((FloatPoint * 2) / 100.0) * AvgSellOnce * random.random())
SellAmount = min(TotalSellStocks - (InitAccount["Stocks"] - account["Stocks"]), RandomAvgSellOnce)
if SellAmount < MinStock:
return False
LastSellPrice = SellPrice
exchange.Sell(SellPrice, SellAmount, "上次成交价", ticker["Last"])
return True
def main():
global InitAccount, LoopInterval
CancelPendingOrders()
InitAccount = _C(exchange.GetAccount)
Log(InitAccount)
if InitAccount["Stocks"] < TotalSellStocks:
raise Exception("账户币数不足")
LoopInterval = max(LoopInterval, 1)
while dispatch():
Sleep(LoopInterval)
Log("委托全部完成", _C(exchange.GetAccount))
策略运行
策略逻辑并不复杂,策略执行时,根据策略参数、当时行情价格,动态的挂单、撤单。当交易金额/币数达到、接近参数设置数量时,策略停止。策略代码非常简单,适合初学。有兴趣的同学可以加以改造,设计成适合自己交易方式的策略。
策略为教学性质,实盘慎用。
Related Recommendations
Research on Binance Futures Multi-currency Hedging Strategy Part 3Research on Binance Futures Multi-currency Hedging Strategy Part 2Research on Binance Futures Multi-currency Hedging Strategy Part 1Crocodile line trading system Python versionJavaScript version SuperTrend strategyIntroducing FMZ Quant data science research environmentParabolic Steering SAR and Price High and Low Point StrategyTeach you how to let an old strategy docking the websocket quotes interfaceSimilarities and differences between commodity futures and cryptocurrency exchanges APIMulti-level percentage take profit strategy



