如何实现一些简单的算法单
<h4><strong>简要说明</strong></h4>
<ul>
<li>常见的算法单有TWAP、VWAP、扫盘口等,下面以一种扫盘口算法单来进行举例说明。</li>
<li>本例的扫盘口算法:用于将一笔大单拆分成一系列小单。用户设置的参数有:盘口深度、盘口比例、总委托数量、单笔最大委托数量、委托价格类型。程序每次委托时,委托数量小于单笔最大委托数量,也小于对手盘口深度已内的总委托数量*盘口比例的数量,以委托价格类型进行委托,隔一段时间后,撤掉还未成交的部分,再采用之前的方式进行第二笔子单的委托,直到吃完总委托数量为止。</li>
</ul>
<h4><strong>示例代码</strong></h4>
<pre><code>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#例:扫盘口算法:用于将一笔大单拆分成一系列小单。用户设置的参数有:盘口深度、盘口比例、总委托数量、单笔最大委托数量、委托价格类型。程序每次委托时,委托数量小于单笔最大委托数量,也小于对手盘口深度已内的总委托数量*盘口比例的数量,以委托价格类型进行委托,隔一段时间后,撤掉还未成交的部分,再采用之前的方式进行第二笔子单的委托,直到吃完总委托数量为止。
from ths_api import *
import numpy as np
import time
import pandas as pd
#显示所有列
pd.set_option('display.max_columns', None)
#显示所有行
pd.set_option('display.max_rows', None)
code = '002622'
bors = 'buy'
zwtsl = 10000 #总目标委托数量
pksd = 2 #盘口深度
pkbl = 0.01 #盘口比例
dbsx = 100000 #单笔上限委托数量
wtjg = 'dsj3' #委托价格类型
ymsl = 0 #记录程序的已买数量
ys = 2 #大致的每笔委托延时时长,单位:秒。
list_cjsl = [] #记录每笔子单的成交数量
htbh_zd = [] #记录子单的合同编号
api = hq.ths_hq_api()
quote = api.reg_quote(code)
if bors == 'buy':
list_pksl = ['a1_v', 'a2_v', 'a3_v', 'a4_v', 'a5_v']
else:
list_pksl = ['b1_v', 'b2_v', 'b3_v', 'b4_v', 'b5_v']
while ymsl < zwtsl:
api.wait_update()
pksl = 0 #记录当前的盘口深度内的委托数量
for i in range(0, pksd):
pksl = pksl + quote[code][list_pksl[i]]
print('盘口:', pksl * pkbl)
sx = min(pksl * pkbl, dbsx)
print('限制:', sx)
wtsl0 = np.random.randint(int(sx/300)+1, int(sx/100)+2) * 100
if zwtsl - (ymsl + wtsl0) < 0:
wtsl0 = zwtsl - ymsl
ret = xd.cmd('%s %s %s %s' % (bors, code, wtjg, str(wtsl0)))
print(ret)
time.sleep( 1 ) #给之后的查询当日委托表留出委托表的更新时间
time.sleep(ys + np.random.randint(0, int(ys/3)+1)) #延时10~20s内的某一随机时间后,继续下一笔子单的委托
htbh_zd.append(ret['htbh'])
#撤单之前未成交的子单委托
df = xd.order_to_dataframe(xd.g_fullorder)
df0 = df[df['htbh'] == htbh_zd[-1]]
dic = df0.set_index('htbh').T.to_dict() #转化为以合同编号为键的dict格式
wtsl0 = dic[ret['htbh']]['wtsl']
cjsl0 = dic[ret['htbh']]['cjsl']
cxsl0 = dic[ret['htbh']]['cxsl']
if wtsl0 == cjsl0 + cxsl0:
pass
else:
print('核对是否完全成交', cjsl0, cxsl0, wtsl0)
ret = xd.cmd('cancel -h %s -notip' % df0.iloc[0]['htbh'])
print('撤单数量:%.2f' % (wtsl0 - cxsl0 - cjsl0))
#计算当前子单的总成交数量:
ymsl = 0
for i in htbh_zd:
ymsl = ymsl + df[df['htbh'] == i].iloc[0]['cjsl']
for i in htbh_zd:
list_cjsl.append(df[df['htbh'] == i].iloc[0]['cjsl'])
print('拆单后每单的成交数量列表:', list_cjsl)</code></pre>
<h4><strong>运行结果</strong></h4>
<p>程序输出如下,由最后输出的从全量委托表读取的各子单成交数量列表求和可验证,总成交数量等于设置的总目标委托数量。</p>
<pre><code>盘口: 2176.0
限制: 2176.0
tips=您的买入委托已成功提交,合同编号:1272365148。
{'retMsg': '您的买入委托已成功提交,合同编号:1272365148。', 'htbh': '1272365148', 'retCode': '0'}
[2019-11-19 09:51:11.148] [14684][367369776]等待数据更新...
tips=send buy code:002622 price:3.03 amount:2000
[2019-11-19 09:51:13.348] [14684][367369776] 实时数据更新 = ['002622']
盘口: 2145.0
限制: 2145.0
tips=您的买入委托已成功提交,合同编号:1272398407。
{'retMsg': '您的买入委托已成功提交,合同编号:1272398407。', 'htbh': '1272398407', 'retCode': '0'}
tips=您的撤单委托已成功提交,合同编号:1272398407。
核对是否完全成交 600 0 2000
撤单数量:1400.00
'''
备注:之后输出类似,由于数量较多,不在此列出。
'''
拆单后每单的成交数量列表: [2200, 600, 0, 0, 0, 0, 0, 1000, 0, 100, 0, 1900, 0, 0, 0, 0, 1900, 100, 0, 2000, 200]</code></pre>