超长的、准确的样本数据
主连链回测
360度视角回测报告
WT9提供国内所有期货品种挂牌交易以来全部历史数据,不仅支持k线数据回测,且支持tick级别的模型回测。
文华财经创立于1996年,是国内四家期货交易所官方授权行情转发商,具有20多年行情转发和数据处理经验。为了保证数据准确,我们配备了一支专业的数据处理团队,从交易所的数据源到文华数据中心,再到文华客户端,在各个环节进行精准的校对和修正。
但数据检验只靠几名数据人员是无法面面俱到的,几百万用户却可以发现任何的一点小错误,文华百万数量级的用户,才是数据准确性真正的保障!
案例:超长历史k线数据回测
1、申请海量历史数据的操作方法
如下图,在主图k线上点击鼠标右键,选择补充历史数据,可以申请该合约不同周期的历史供回测使用。


2、期货合约可申请历史数据的起始时间

品种 数据起始时间 品种 数据起始时间 品种 数据起始时间 品种 数据起始时间
300股指 2010/4/16 螺纹钢 2009/3/27 PVC 2009/5/25 粳稻 2013/11/18
50股指 2015/4/16 铁矿石 2013/10/18 BR橡胶 2023/7/28 晚籼稻 2014/7/8
500股指 2015/4/16 热卷 2014/3/21 橡胶 1997/4/14 豆二 2004/12/22
1000股指 2022/7/22 不锈钢 2019/9/25 20号胶 2019/8/12 豆粕 2000/7/17
二年债 2018/8/17 线材 2018/10/16 塑料 2007/7/31 豆油 2006/1/9
五年债 2013/9/6 硅铁 2014/8/8 短纤 2020/10/12 油菜籽 2012/12/28
十年债 2015/3/20 锰硅 2014/8/8 乙二醇 2018/12/10 菜籽粕 2012/12/28
三十年债 2023/4/21 焦煤 2013/3/22 甲醇 2011/10/28 菜籽油 2007/6/8
沪金 2008/7/15 焦炭 2011/4/15 聚丙烯 2014/2/28 棕榈油 2007/10/29
沪银 2012/5/10 动力煤 2013/9/26 苯乙烯 2019/9/26 花生 2021/2/1
沪铜 1996/4/2 玻璃 2012/12/3 尿素 2019/8/9 棉花 2004/6/1
沪铝 1994/10/7 纸浆 2018/11/27 纯碱 2019/12/6 白糖 2006/1/6
沪锌 2007/3/26 纤维板 2019/12/2 对二甲苯 2023/9/15 棉纱 2017/8/18
沪铅 2011/3/24 胶合板 2013/12/6 烧碱 2023/9/15 鸡蛋 2013/11/8
沪镍 2015/3/27 原油 2018/3/26 玉米 2004/9/22 生猪 2021/1/8
沪锡 2015/3/27 燃料油 2018/7/16 豆一 2002/3/15 苹果 2017/12/22
氧化铝 2023/6/19 LU燃油 2020/6/22 淀粉 2014/12/19 红枣 2019/4/30
国际铜 2020/11/19 沥青 2013/10/9 强麦 2003/3/28 集运欧线 2023/8/18
工业硅 2022/12/22 液化气 2020/3/30 粳米 2019/8/16
碳酸锂 2023/7/21 PTA 2006/12/18 早籼稻 2009/4/20

3、为什么在【补充数据】中找不到想补充的合约周期
下载列表中所列出的合约周期是基础数据;其他周期的数据由这些基础数据合成,因此,在申请数据的时候只对基础数据做申请。

合成原则:
用tick合成的数据:逐笔回测数据。
用1秒合成的数据: 量能周期、秒周期,自定义秒周期。
用1分钟合成的数据:15min以下的周期,以及自定义分钟周期。
用15分钟合成的周期:15min,30min,1h,2h,3h,4h,自定义小时周期。
用日线合成的周期:日线及以上周期。

4、如何查看已经交割合约的历史数据
在K线图界面右键->选择历史年度合约,可以查看到历史年度合约的具体行情数据。
有别于传统的加权、主连回测算法,主连链回测是基于期货品种定期换月的特点,而专门研发的独特回测算法。其严谨的利用长期数据验证策略的方法,不再使用品种主连自身的k线数据计算信号,而是采用各个月份合约自挂牌以来的全部k线数据计算信号,规避品种主连k线数据换月跳空、新旧合约趋势相反等情况对量化计算准确性的影响。主力换月时,旧主力月份平仓,新主力根据月份合约的k线数据重新计算开仓信号。
案例:主连链回测机制详解
1、主连链回测的背景
主连k线图数据,由各个月份合约的数据拼接形成。把每一个月份合约主力期间以前的k线图砍掉,再把主力期间以后的k线数据砍掉,剩下主力期间的部分k线图,然后按照时间顺序拼接在一起,形成品种主连数据,主连k线数据全局性好,便于看盘了解品种的长期k线价格。
但是这种掐头去尾的处理机制破坏了k线趋势的连续性和完整性,造成主力月份切换时有很大的价格跳空,造成了趋势的失真,尤其是新旧主力合约的走势不一致的情况失真更加严重,不适合直接用于策略回测计算的。
为了给量化投资者提供一个更加真实、客观的回测结果,文华财经开创了主连链回测。

2、主连链回测的机制
主连链回测,不是使用你看到的品种主连k线图的数据计算信号的,而是采用主连包含的各个具体月份合约自挂牌以来的全部k线数据计算信号,规避品种主连k线数据换月跳空对量化计算准确性的影响。

适用场景
针对多个年度的主力月份合约进行连续交易的模型回测计算,用长期的历史数据验证策略的有效性。
主力换月时,回测计算的处理机制如下:
旧主力合约,清仓;
新主力合约,延续使用旧主力清仓后的资金,但是重新计算信号。
机制具体计算说明见网页:https://www.wenhua.com.cn/popwin/wh8zhulianlian.htm

3、主图上不显示信号以及原型指标线,怎么去做指标走势对比分析?
右键->回测报告->月份合约k线图,在这里对比分析指标走势,重点K线,压力,支撑线等。因为信号是用具体月份合约的k线图计算的,所以指标走势分析需要在月份k线图上进行。
主连链回测本质上是多个月份合约回测的合并,建议大家研究一个模型的时候,先在某一个具体的月份合约上做回测研究,模型在月份合约上有良好的表现后,再进行主连链回测,对模型进行长期的检测。月份合约的研究就可以在主图上做了,任意加载多个指标对比分析就方便了。
WT9基于主连链回测算法提供的回测报告,不仅包含了上百项各类统计数据,还提供了分段回测数据、分项统计、时段统计等专业回测图表,360度检测模型盈利能力及可靠性。
案例:回测报告数据计算公式详解
1、回测报告基础公式

测试天数 从回测数据开始到结束的自然日
测试周期数 从回测数据开始到结束的K线根数
信号个数 信号出现的总个数
执行信号个数 信号执行的总个数
信号消失次数 信号消失的总次数
初始资金 初始化的资金
初始资金使用率 手数*每手保证金率*第一个信号的开仓价*交易单位/初始资金
最大资金使用率 在持仓周期内(开仓保证金/当前权益)的最大值
平均资金使用率 ((开仓保证金/当前权益)求和)/持仓周期数
杠杆倍数 杠杆倍数 = 最大资金使用率 / 保证金率
回测期间最大权益 回测期间最大的权益
整个测试过程中每个周期已缴保证金+剩余可用资金+持仓浮盈所得结果中的最大值
回测期间最小权益 回测期间最小的权益
整个测试过程中每个周期已缴保证金+剩余可用资金+持仓浮盈所得结果中的最小值
最终权益 包括当前的可用资金和浮动盈亏
收益 总盈利-总亏损(已扣除手续费)
收益率 收益/初始资金
年化单利收益率 收益率/(测试天数/365)
月化单利收益率 收益率/(测试天数/30)
年化复利收益率 (最终权益/初始资金)^(365/测试天数)-1
月化复利收益率 (最终权益/初始资金)^(30/测试天数)-1
平均保证金收益率 (单次交易收益/开仓保证金)求和/交易次数
=(Σ((每次交易盈利数值-手续费)/保证金))/交易次数
扣除最大盈利后收益率 (最终权益-最大盈利-初始资金)/初始资金
扣除最大亏损后收益率 (最终权益+最大亏损-初始资金)/初始资金
夏普比率 (年化单利收益率-无风险利率)/收益率的标准离差率
计算公式:夏普比率=[E(Rp)-Rf]/σp;
其中:
E(Rp):年化单利收益率
Rf:无风险利率(大约是1.5%)
σp:收益率的标准差率(年化标准差率)=标准差率/sqrt (测试天数/365)
标准差率=标准离差/初始资金
索提诺比率 (年化单利收益率-无风险利率)/下行收益率标准差
其中:
年化单利收益率=收益率/(测试天数/365)
无风险利率=1.5%
下行收益率标准差=下行标准差率/sqrt(测试天数/365)
下行标准差率=下行标准离差/初始资金
下行标准离差=
n=交易次数
r=每次收益
=平均收益
if r<,f(t)=1
if r>=,f(t)=0
权益离散度 权益离散度=单次盈亏的平方和/交易次数,再开方
权益离散系数 权益离散系数=权益离散度/初始资金*100%
权益最大回撤 从回测开始到结束,动态权益计算出来的波段从高点到低点回撤的最大值
权益最大回撤时间 权益最大回撤出现的时间
权益最大回撤比率 (权益回撤/权益回撤时的权益)的最大值
权益最大回撤比率时间 权益最大回撤比率出现的时间
权益最长未创新高周期数 权益最长未创新高周期数
权益最长未创新高时间段 权益最长未创新高时间段
损益最大回撤 从回测开始到结束,动态损益计算出来的波段从高点到低点回撤的最大值(损益最大回撤是以持仓等于0时的资金为标准计算的)
损益最大回撤时间 损益最大回撤出现的时间
损益最大回撤比率 (损益回撤/损益回撤时的权益)的最大值
损益最大回撤比率时间 损益最大回撤比率出现的时间
损益最长未创新高周期数 损益最长未创新高周期数
损益最长未创新高时间段 损益最长未创新高时间段
本金风险率 (初始资金 - 回测期间最小权益)/初始资金
年化收益风险比率 年化单利收益率/本金风险率
胜率 (盈利次数+持平次数)/交易次数
*盈亏比率 盈利交易的平均每次盈利/亏损交易的平均每次亏损
平均每次盈利 = 总盈利/盈利交易次数
平均每次亏损 = 总亏损/亏损交易次数
*平均每次盈利 平均每次盈利交易的盈利=总盈利/总盈利次数(计算手续费)
*平均每次亏损 平均每次亏损交易的亏损=总亏损/总亏损次数(计算手续费)
*平均每次盈利/权益最大回撤 平均每次盈利/权益最大回撤
*平均每次盈利率/平均每次亏损率 平均每次盈利率/平均每次亏损率
平均每次盈利率 = SUM(单次盈利率) / 计算单次盈利率次数
平均每次亏损率 = SUM(单次亏损率)/ 计算单次亏损率次数
单次盈利率 = 上一次持仓为0到今次持仓为0期间的盈利占初始资金的百分比 (盈利/初始资金)
单次亏损率 = 上一次持仓为0到今次持仓为0期间的亏损占初始资金的百分比 (亏损/初始资金)
*平均每次收益/平均每次亏损 平均每次收益/平均每次亏损
平均每次收益 平均每笔交易的收益=(总盈利-总亏损)/ 交易笔数(总成交量的 1/2)
最大每手盈利 每手盈利的最大值(每手盈利:对于每次交易,用该次交易的盈利值除以这次交易过程中的成交手数)
最大每手亏损 每手亏损的最大值(每手亏损:对于每次交易,用该次交易的亏损值除以这次交易过程中的成交手数)
平均每手每次收益 平均每手每次交易的收益
总盈利/总亏损 总盈利/总亏损
总盈利 盈利的总和
总亏损 亏损的总和
*单次最大盈利 单次交易盈利的最大值
*单次最大亏损 单次交易亏损的最大值
单次最大盈利占比率 单次最大盈利/总盈利
单次最大亏损占比率 单次最大亏损/总亏损
收益/单次最大盈利 收益/单次最大盈利
收益/单次最大亏损 收益/单次最大亏损
*交易次数 发生交易的次数
*盈利次数 盈利的交易次数
*亏损次数 亏损的交易次数
*持平次数 持平的交易次数
*最大持续盈利次数 最大持续盈利的次数
*最大持续盈利次数出现时间 最大持续盈利的次数出现的时间
*最大持续亏损次数 最大持续亏损的次数
*最大持续亏损次数出现时间 最大持续亏损的次数出现的时间
空仓周期数 空仓的周期数
最长连续空仓周期数 最长连续空仓的周期数
*最长持仓周期数 持仓最长周期数
平均持仓周期数 平均多少根K线发生一笔交易=测试周期数/交易次数
*平均盈利持仓周期数 平均多少根K线发生一笔盈利的交易=测试周期数/盈利次数
*平均亏损持仓周期数 平均多少根K线发生一笔亏损的交易=测试周期数/亏损次数
平均持仓手数 每根K线的总持仓的累加 / 持仓周期数
最大持仓手数 在持仓周期内持仓手数最大值
平均资金使用金额 开仓保证金求和/持仓周期数
最大资金使用金额 在持仓周期内,开仓保证金额最大值
最大资金使用金额时间 在持仓周期内,最大资金使用金额的时间点
手续费 手续费合计
手续费/收益 手续费合计/收益
滑点损耗 滑点损耗合计
滑点损耗/收益 滑点损耗合计/收益
成交额 成交额合计
成交额=成交价*(开仓或者平仓手数)*交易单位
模型得分 根据盈利能力、稳定性、风险暴露、敏感度计算的综合得分

注:对于盈利、亏损的计算,带有*的是都是以从开仓到持仓为0算一次交易计算盈亏,未标注*的是按照一开一平来计算盈亏。

2、分项统计数据计算公式

收益/风险:
点击展开
(1)损益曲线图:策略的累计盈亏曲线,反映一段时间内平仓盈亏累加值的波动,每完整的交易一次计算一次损益值
(2)权益曲线图:反映某一个时点的权益波动情况,每根K线都动态的统计一次权益数值
(3)损盈分布图:根据距离平均盈亏的离散程度分析交易的整体盈利情况
(4)损盈直方图:统计落入盈亏净值区间内的次数,对比盈利和亏损能力
(5)权益回撤直方图:统计落入某一回撤区间的次数,反映权益回撤的金额分布
(6)连续亏损次数:统计连续亏损的次数,投资者可结合自身对风险的承受能力综合考量策略的稳定性

浮动盈亏:
点击展开
(1)权益面积图:对比权益的高点位置和权益波动,直观的查看权益回撤的幅度
(2)浮盈面积图:对比权益面积图,分析浮盈波动情况
(3)浮亏面积图:对比权益面积图,分析浮亏波动变化
(4)浮盈分布图:根据距离平均浮盈的离散程度分析交易的浮盈极值和整体盈利状态
(5)浮亏分布图:根据距离平均浮动亏损值的离散程度分析浮亏的极值和整体亏损情况
(6)浮盈直方图:统计落在指定浮盈区间内的交易次数,分析策略的盈利能力
(7)浮亏直方图:统计落在固定浮亏区间内的交易次数,分析策略的亏损程度

阶段分析:
点击展开
(1)月度统计:统计当月交易的盈亏和成本大小
(2)日统计:统计当日的交易的盈亏和成本大小

效率分析:
点击展开
(1)总效率分布图:以做多为例,买在最低点卖在最高点视效率为100%,按交易价格折算每次交易的效率
(2)建仓效率分布图:以做多为例,买在最低点即为最佳入场点,效率为100%,再按实际入场点折算每次建仓的效率
(3)平仓效率分布图:以做多为例,卖在最高点即为最佳出场点,效率为100%,再按实际出场点折算每次平仓的效率

损盈分析:
点击展开
(1)胜率分析:统计不同盈利百分比下的胜率分布
(2)盈利分析:统计一定盈利范围内的盈利次数
(3)亏损分析:统计一定亏损范围内的亏损次数
(4)回撤分析:按回撤比例分析权益回撤幅度
可视化回测平台
仿真撮合机制
可视化的盘口算法模型回测平台,能够同时展示tick数据变化、持仓信息、挂单详情、以及权益曲线变化过程,并提供360度视角的多维度回测报告。
案例:盘口模型回测过程详解
第一步:点击左侧【回测】标签,双击要回测的订单流模型,可进入订单流策略回测界面,可点击鼠标右键,切换回测日期,并设置回测速度倍数。


第二步:系统开始进行回测计算,可视化的回测界面,包含了Tick图形变化,持仓列表、挂单列表以及权益曲线。


Tick图画线机制:
红色实线:买开挂单价位;
绿色实线:卖开挂单价位;
红色虚线:买平挂单价位;
绿色虚线:卖平挂单价位。

第三步:可点击鼠标右键,选择查看模型回测报告、回测交易明细、回测运行日志。

WT9的仿真撮合机制,既考虑到了委托价等于对手价时,对手盘挂单量不足,部分成交的情况,同时,当委托价等于排队价时,还会计算挂单成交比例,按比例撮合成交,完美虚拟真实交易过程。
案例:仿真撮合机制计算公式详解
订单流策略回测采用交易所的行情数据作为撮合基础,模型回测报告、回测交易明细均使用如下算法统计交易结果和相关数据。

仿真撮合机制:
成交条件:买委托价>最新价 或 卖委托价<最新价,全部成交;
委托价=最新价=买一价 或 委托价=最新价=卖一价,部分成交*。
成交价格:最新价。
*注:部分成交手数=委托手数*成交比例(买成交比例=现手/买一量,卖成交比例=现手/卖一量,成交手数向上取整)
模型信号算法交易
手动下单算法交易
WT9支持模组单元调用算法交易组件,使用算法交易策略控制交易过程,根据盘口情况智能拆单,不仅支持主动、被动型算法策略,还支持更加高效的综合型算法交易策略。能够提高交易效率,降低冲击成本,还能隐匿机构交易行为,防止下单对趋势产生影响。
案例:根据盘口挂单自动分批策略
1、算法交易接管模组信号实现方式
策略模型加载到模组运行时,可选择算法下单组件,系统提供了常用的几种模型信号处理组件,也支持编写自定义算法组件。

组件一号:
(1)委托方式:开仓对价,平仓市价。
(2)平仓信号:先撤未成交开仓挂单,按实际持仓手数平仓。
(3)反手信号:平仓成交后发开仓委托。

组件二号:
(1)委托方式:开仓排队价,平仓对价且市价追价。
(2)平仓信号:先撤未成交开仓挂单,按实际持仓手数平仓。
(3)反手信号:平仓成交后发开仓委托。

组件三号:
(1)委托方式:开仓对价,平仓对价。
(2)平仓信号:先撤未成交开仓挂单,按实际手数平仓。
(3)反手信号:平仓成交后发开仓委托。
(4)智能分批:根据盘口挂单智能分批下单。


2、智能分批算法组件的基本逻辑
可先使用F_FreshSig函数刷新信号,然后使用IF语句根据信号种类添加不同的处理机制,系统支持使用For循环遍历委托,支持数组,记录成交手数,并按照指定价格和手数发送委托。

根据盘口挂单智能分批部分核心源码:
	If(F_FreshSig() == 1) //如果刷新到新信号
		{
			COD = F_SigCode(); //信号合约
			SGM = F_SigVol(); //信号手数
			SGFLG = 1; //已出现新信号
		}
	For X = 0 To BKN - 1 //遍历买开委托
		{
			If(BKFLG[X] > 0) //如果有买开委托
			{
				BKCM[X] = F_OrderFilledLot(BKID[X]); //买开成交手数
				If(F_OrderStatus(BKID[X]) == Enum_Filled && BRP >= BKSM[X]) //如果买开委托成交
				{
					If(BKFLG[X] == 1) //如果是BK信号买开委托
					{
						Commentary("【买开:买开委托" + Text(X + 1) + "成交】");
					}
					Else If(BKFLG[X] == 2) //如果是BPK信号买开委托
					{
						Commentary("【买平开:买开委托" + Text(X + 1) + "成交】");
					}
					Else If(BKFLG[X] == 3) //如果是SP信号买开委托
					{
						Commentary("【卖平:买开委托" + Text(X + 1) + "成交】");
					}
					BKFLG[X] = 0; //买开标志归0
					BKDEL[X] = 0; //买开撤单标志归0
					BKOFLG[BKDX[X]] = 0; //买开挂单标志归0
				}
				Else If(F_OrderStatus(BKID[X]) == Enum_Canceled) //如果买开委托已撤
				{
					If(BKDEL[X] == 1) //如果是追价撤单
					{
						If(BKFLG[X] == 1) //如果是BK信号买开委托
						{
							Commentary("【买开:买开委托" + Text(X + 1) + "已撤】");
						}
						Else If(BKFLG[X] == 2) //如果是BPK信号买开委托
						{
							Commentary("【买平开:买开委托" + Text(X + 1) + "已撤】");
						}
						Else If(BKFLG[X] == 3) //如果是SP信号买开委托
						{
							Commentary("【卖平:买开委托" + Text(X + 1) + "已撤】");
						}
						BKM[X] = BKM[X] - BKCM[X]; //买开委托手数
						If(BKM[X] > 0) //如果买开委托手数大于0
						{
							BKP[X] = BKZP; //买开委托价格
							If(BKFLG[X] == 1) //如果是BK信号买开委托
							{
								Commentary("【买开:买开委托" + Text(X + 1) + "追价】");
							}
							Else If(BKFLG[X] == 2) //如果是BPK信号买开委托
							{
								Commentary("【买平开:买开委托" + Text(X + 1) + "追价】");
							}
							Else If(BKFLG[X] == 3) //如果是SP信号买开委托
							{
								Commentary("【卖平:买开委托" + Text(X + 1) + "追价】");
							}
							Commentary("【盘口数据:卖一价=" + Text(ASKP) + ",卖一量=" + Text(ASKV) + "】");
							Commentary("【盘口数据:买一价=" + Text(BIDP) + ",买一量=" + Text(BIDV) + "】");
							Commentary("【买开委托:买开价格=" + Text(BKP[X]) + ",买开手数=" + Text(BKM[X]) + "】");
							BKID[X] = COD.A_SendOrder(Enum_Buy,Enum_Entry,BKM[X],BKP[X]); //发出买开委托
							BKT[X] = NOW; //买开委托时间
						}
					}
					Else If(BKDEL[X] == 2 || BKDEL[X] == 3 || BKDEL[X] == 4) //如果是平仓信号撤单
					{
						If(BKDLF == 1) //如果是SP信号撤单
						{
							Commentary("【卖平:买开委托" + Text(X + 1) + "已撤】");
						}
						Else If(BKDLF == 2) //如果是SPK信号撤单
						{
							Commentary("【卖平开:买开委托" + Text(X + 1) + "已撤】");
						}
						BKDM = BKDM + BKM[X] - BKCM[X]; //买开撤单手数
						BKDP = IIF(BKDP == 0,BKP[X],Min(BKDP,BKP[X])); //买开重发价格
						BKFLG[X] = 0; //买开标志归0
					}
					BKDEL[X] = 0; //买开撤单标志归0
				}
				Else If(F_OrderStatus(BKID[X]) == Enum_Declared || F_OrderStatus(BKID[X]) == Enum_FillPart) //如果买开委托挂单
				{
					If(BKDEL[X] == 0) //如果未撤单
					{
						If(ZJFLG == 1 && TimeDiff(BKT[X],NOW) >= ZJT && BKP[X] != RLP) //如果满足撤单条件
						{
							If(BKFLG[X] == 1) //如果是BK信号买开委托
							{
								Commentary("【买开:买开委托" + Text(X + 1) + "撤单】");
							}
							Else If(BKFLG[X] == 2) //如果是BPK信号买开委托
							{
								Commentary("【买平开:买开委托" + Text(X + 1) + "撤单】");
							}
							Else If(BKFLG[X] == 3) //如果是SP信号买开委托
							{
								Commentary("【卖平:买开委托" + Text(X + 1) + "撤单】");
							}
							COD.F_DeleteOrder(F_OrderContractNo(BKID[X])); //撤掉买开委托挂单
							BKDEL[X] = 1; //已发出撤掉买开委托挂单
						}
					}
					Else If(BKDEL[X] == 3) //如果是平仓信号撤单
					{
						If(BKDLF == 1) //如果是SP信号撤单买开委托
						{
							Commentary("【卖平:买开委托" + Text(X + 1) + "撤单】");
						}
						Else If(BKDLF == 2) //如果是SPK信号买开委托
						{
							Commentary("【卖平开:买开委托" + Text(X + 1) + "撤单】");
						}
						COD.F_DeleteOrder(F_OrderContractNo(BKID[X])); //撤掉买开委托挂单
						BKDEL[X] = 4; //已发出撤掉买开委托挂单
					}
				}
				Else If(F_OrderStatus(BKID[X]) == Enum_Deleted) //如果买开委托废单
				{
					If(BKFLG[X] == 1) //如果是BK信号买开委托
					{
						Commentary("【买开:买开委托" + Text(X + 1) + "废单】");
					}
					Else If(BKFLG[X] == 2) //如果是BPK信号买开委托
					{
						Commentary("【买平开:买开委托" + Text(X + 1) + "废单】");
					}
					Else If(BKFLG[X] == 3) //如果是SP信号买开委托
					{
						Commentary("【卖平:买开委托" + Text(X + 1) + "废单】");
					}
					BKFLG[X] = 0; //买开标志归0
					BKDEL[X] = 0; //买开撤单标志归0
				}
			}
		}
						
3、是否需要编写多个信号处理组件绑定多个策略模型
具有相同信号处理方式和算法拆单需求的多个策略模型,可以绑定同一个信号处理组件。每个模型单元独立运行,互不影响。
使用算法交易策略替代手动下单控制交易过程。通过对持仓信息、挂单信息,成交回报,委托回报等信息的监控,实现了对交易过程的精细化控制。成交效率高,对市场变化反应迅速,降低冲击成本。
案例1:手动下单+智能分批算法
对于大资金客户,是否有下单单量大,唯恐惊扰行情趋势的困扰?是否有欲拉动行情却缕缕付出了大量成本的困扰?这里我们以此为例通过手动下单调用算法交易的方式介绍两个案例来解决你的困扰。

策略1:通过算法根据买卖量,自动拆分大单

交易思路解析:
1、取得手动下单的合约、手数、买卖方向、开平方向;自设委托价格。
2、如果为开仓:
(1)如果为买入开仓:
分批买入,取盘口卖一量*1/2与剩余下单手数比较,取数量较小值根据盘口卖一价买入,第一批成交后,再委托第二批,直至完全成交后退出算法。
(2)如果为卖出开仓:
分批卖出,取盘口买一量*1/2与剩余下单手数比较,取数量较小值根据盘口买一价卖出,第一批成交后,再委托第二批,直至完全成交后退出算法。
3、如果为平仓:
(1)如果为买入平仓:
分批处理同买入开仓。
(2)如果为卖出平仓:
分批处理同卖出开仓。

源码实现:
	Vars
	Global_String AID; //账号
	Global_String COD; //合约编码
	Numeric P; //数值比例
	Numeric SH; //上海合约标志
	Numeric BSF; //买卖方向
	Numeric EEF; //开平方向
	Numeric BIDP,ASKP; //买卖一价
	Numeric BIDV,ASKV; //买卖一量
	Numeric BRP0,BRP1,BRP; //多头可用持仓
	Numeric SRP0,SRP1,SRP; //空头可用持仓
	Numeric OPFLG; //模型处理标志
	Global_Numeric VLM; //交易手数
	Global_Numeric KPFLG; //委托处理标志
	Global_Numeric BKDFLG; //买开处理标志
	Global_Numeric SKDFLG; //卖开处理标志
	Global_Numeric BPDFLG; //买平处理标志
	Global_Numeric SPDFLG; //卖平处理标志
	Global_Numeric BKID,SKID; //开仓委托
	Global_Numeric BKFLG,SKFLG; //开仓标志
	Global_Numeric BKM,SKM; //开仓委托手数
	Global_Numeric BKP,SKP; //开仓委托价格
	Global_Numeric BPID0,BPID1,BPID; //买平委托
	Global_Numeric SPID0,SPID1,SPID; //卖平委托
	Global_Numeric BPFLG0,BPFLG1,BPFLG; //买平标志
	Global_Numeric SPFLG0,SPFLG1,SPFLG; //卖平标志
	Global_Numeric BPM0,BPM1,BPM; //买平委托手数
	Global_Numeric SPM0,SPM1,SPM; //卖平委托手数
	Global_Numeric BPP0,BPP1,BPP; //买平委托价格
	Global_Numeric SPP0,SPP1,SPP; //卖平委托价格
	Begin
	//------------------------委托获取------------------------//
	If(1) //委托获取
	{
		If(KPFLG == 0) //如果未开启委托处理
		{
			AID = M_GetTradeAccount(0); //账号
			COD = M_GetTradeContract(); //合约编码
			BSF = M_GetTradeBuySell(); //买卖方向
			EEF = M_GetTradeEntryExit(); //开平方向
			VLM = M_GetTradeVol(); //交易手数
			If(VLM > 0 && COD.A_IsExchangeOpen() == 1) //如果交易手数大于0,且当前状态是开盘
			{
				If(BSF == Enum_Buy && EEF == Enum_Entry) //如果是买开方向
				{
					Commentary("【" + COD + "做多:手动买开" + Text(VLM) + "手!】");
					BKDFLG = 1; //开启买开处理
				}
				Else If(BSF == Enum_Sell && EEF == Enum_Exit) //如果是卖平方向
				{
					Commentary("【" + COD + "平多:手动卖平" + Text(VLM) + "手!】");
					SPDFLG = 1; //开启卖平处理
				}
				Else If(BSF == Enum_Sell && EEF == Enum_ExitToday) //如果是卖平今方向
				{
					Commentary("【" + COD + "平今多:手动卖平" + Text(VLM) + "手!】");
					SPDFLG = 2; //开启卖平今仓处理
				}
				Else If(BSF == Enum_Sell && EEF == Enum_Entry) //如果是卖开方向
				{
					Commentary("【" + COD + "做空:手动卖开" + Text(VLM) + "手!】");
					SKDFLG = 1; //开启卖开处理
				}
				Else If(BSF == Enum_Buy && EEF == Enum_Exit) //如果是买平方向
				{
					Commentary("【" + COD + "平空:手动买平" + Text(VLM) + "手!】");
					BPDFLG = 1; //开启买平处理
				}
				Else If(BSF == Enum_Buy && EEF == Enum_ExitToday) //如果是买平今方向
				{
					Commentary("【" + COD + "平今空:手动买平" + Text(VLM) + "手!】");
					BPDFLG = 2; //开启买平今仓处理
				}
				KPFLG = 1; //开启委托处理
			}
		}
		If(KPFLG == 1 && COD.A_IsExchangeOpen() == 1) //如果已开启委托处理,且当前状态是开盘
		{
			OPFLG = 1; //开启模型处理
		}
	}
	//------------------------变量赋值------------------------//
	If(OPFLG == 1) //变量赋值
	{
		P = 0.5; //数值比例
		BIDP = COD.Price("Bid1"); //买一价
		ASKP = COD.Price("Ask1"); //卖一价
		BIDV = COD.Price("BidVol1"); //买一量
		ASKV = COD.Price("AskVol1"); //卖一量
		SH = COD.A_IsSHCode(); //上海合约标志
		BRP = COD.A_BuyRemainPosition(); //多头可用持仓
		SRP = COD.A_SellRemainPosition(); //空头可用持仓
		If(SH == 1) //如果是上期所合约
		{
			BRP0 = COD.A_TodayBuyRemainPosition(); //多头今仓可用持仓
			SRP0 = COD.A_TodaySellRemainPosition(); //空头今仓可用持仓
			BRP1 = BRP - BRP0; //多头老仓可用持仓
			SRP1 = SRP - SRP0; //空头老仓可用持仓
		}
	}
	//------------------------成交判断------------------------//
	If(OPFLG == 1) //成交判断
	{
		If(BKFLG == 1) //如果有买开委托
		{
			If(F_OrderStatus(BKID) == Enum_Filled) //如果买开委托成交
			{
				Commentary("【" + COD + "做多:买开委托成交!】");
				VLM = VLM - BKM; //交易手数
				BKFLG = 0; //买开标志归0
			}
		}
		If(SH == 1) //如果是上期所合约
		{
			If(SPFLG0 == 1) //如果有卖平今仓委托
			{
				If(F_OrderStatus(SPID0) == Enum_Filled) //如果卖平今仓委托成交
				{
					Commentary("【" + COD + "平多:卖平今仓委托成交!】");
					VLM = VLM - SPM0; //交易手数
					SPFLG0 = 0; //卖平今仓标志归0
				}
			}
			If(SPFLG1 == 1) //如果有卖平老仓委托
			{
				If(F_OrderStatus(SPID1) == Enum_Filled) //如果卖平老仓委托成交
				{
					Commentary("【" + COD + "平多:卖平老仓委托成交!】");
					VLM = VLM - SPM1; //交易手数
					SPFLG1 = 0; //卖平老仓标志归0
				}
			}
		}
		Else //如果非上期所合约
		{
			If(SPFLG == 1) //如果有卖平委托
			{
				If(F_OrderStatus(SPID) == Enum_Filled) //如果卖平委托成交
				{
					Commentary("【" + COD + "平多:卖平委托成交!】");
					VLM = VLM - SPM; //交易手数
					SPFLG = 0; //卖平标志归0
				}
			}
		}
		If(SKFLG == 1) //如果有卖开委托
		{
			If(F_OrderStatus(SKID) == Enum_Filled) //如果卖开委托成交
			{
				Commentary("【" + COD + "做空:卖开委托成交!】");
				VLM = VLM - SKM; //交易手数
				SKFLG = 0; //卖开标志归0
			}
		}
		If(SH == 1) //如果是上期所合约
		{
			If(BPFLG0 == 1) //如果有买平今仓委托
			{
				If(F_OrderStatus(BPID0) == Enum_Filled) //如果买平今仓委托成交
				{
					Commentary("【" + COD + "平空:买平今仓委托成交!】");
					VLM = VLM - BPM0; //交易手数
					BPFLG0 = 0; //买平今仓标志归0
				}
			}
			If(BPFLG1 == 1) //如果有买平老仓委托
			{
				If(F_OrderStatus(BPID1) == Enum_Filled) //如果买平老仓委托成交
				{
					Commentary("【" + COD + "平空:买平老仓委托成交!】");
					VLM = VLM - BPM1; //交易手数
					BPFLG1 = 0; //买平老仓标志归0
				}
			}
		}
		Else //如果非上期所合约
		{
			If(BPFLG == 1) //如果有买平委托
			{
				If(F_OrderStatus(BPID) == Enum_Filled) //如果买平委托成交
				{
					Commentary("【" + COD + "平空:买平委托成交!】");
					VLM = VLM - BPM; //交易手数
					BPFLG = 0; //买平标志归0
				}
			}
		}
	}
	//------------------------委托处理------------------------//
	If(OPFLG == 1) //委托处理
	{
		If(BKDFLG == 1) //如果已开启买开处理
		{
			If(BKFLG == 0) //如果没有买开委托
			{
				BKM = Min(Ceiling(P * ASKV,1),VLM); //买开委托手数
				If(BKM > 0) //如果买开委托手数大于0
				{
					BKP = ASKP; //买开委托价格
					Commentary("【" + COD + "做多:公式买开" + Text(BKM) + "手!】");
					Commentary("【" + COD + "做多:买开委托发出!】");
					BKID = COD.A_SendOrder(Enum_Buy,Enum_Entry,BKM,BKP,AID); //发出买开委托
					BKFLG = 1; //已发出买开委托
				}
				Else If(BKM == 0) //如果买开委托手数等于0
				{
					Commentary("【" + COD + "做多:买开委托完成!】");
					Exit(); //退出公式
				}
			}
		}
		If(SPDFLG > 0) //如果已开启卖平处理
		{
			If(SPFLG0 == 0 && SPFLG1 == 0 && SPFLG == 0) //如果没有卖平委托
			{
				SPM = Min(Ceiling(P * BIDV,1),VLM); //卖平委托手数
				If(BRP > 0 && SPM > 0) //如果有多头可用持仓,且卖平委托手数大于0
				{
					If(SH == 1) //如果是上期所合约
					{
						If(SPDFLG == 2) //如果是卖平今仓处理
						{
							If(BRP0 > 0) //如果有多头今仓可用持仓
							{
								SPM0 = Min(BRP0,SPM); //卖平今仓委托手数
								SPP0 = BIDP; //卖平今仓委托价格
								Commentary("【" + COD + "平多:公式卖平今仓" + Text(SPM0) + "手!】");
								Commentary("【" + COD + "平多:卖平今仓委托发出!】");
								SPID0 = COD.A_SendOrder(Enum_Sell,Enum_ExitToday,SPM0,SPP0,AID); //发出卖平今仓委托
								SPFLG0 = 1; //已发出卖平今仓委托
							}
							Else If(BRP0 == 0) //如果没有多头今仓可用持仓
							{
								Commentary("【" + COD + "平多:卖平委托完成!】");
								Exit(); //退出公式
							}
						}
						Else If(SPDFLG == 1) //如果是卖平处理
						{
							If(BRP1 > 0) //如果有多头老仓可用持仓
							{
								SPM1 = Min(BRP1,SPM); //卖平老仓委托手数
								SPP1 = BIDP; //卖平老仓委托价格
								Commentary("【" + COD + "平多:公式卖平老仓" + Text(SPM1) + "手!】");
								Commentary("【" + COD + "平多:卖平老仓委托发出!】");
								SPID1 = COD.A_SendOrder(Enum_Sell,Enum_Exit,SPM1,SPP1,AID); //发出卖平老仓委托
								SPFLG1 = 1; //已发出卖平老仓委托
							}
							Else If(BRP1 == 0) //如果没有多头老仓可用持仓
							{
								Commentary("【" + COD + "平多:卖平委托完成!】");
								Exit(); //退出公式
							}
						}
					}
					Else //如果非上期所合约
					{
						SPM = Min(BRP,SPM); //卖平委托手数
						SPP = BIDP; //卖平委托价格
						Commentary("【" + COD + "平多:公式卖平" + Text(SPM) + "手!】");
						Commentary("【" + COD + "平多:卖平委托发出!】");
						SPID = COD.A_SendOrder(Enum_Sell,Enum_Exit,SPM,SPP,AID); //发出卖平委托
						SPFLG = 1; //已发出卖平委托
					}
				}
				Else If(BRP == 0 || SPM == 0) //如果没有多头可用持仓,或卖平委托手数等于0
				{
					Commentary("【" + COD + "平多:卖平委托完成!】");
					Exit(); //退出公式
				}
			}
		}
		If(SKDFLG == 1) //如果已开启卖开处理
		{
			If(SKFLG == 0) //如果没有卖开委托
			{
				SKM = Min(Ceiling(P * BIDV,1),VLM); //卖开委托手数
				If(SKM > 0) //如果卖开委托手数大于0
				{
					SKP = BIDP; //卖开委托价格
					Commentary("【" + COD + "做空:公式卖开" + Text(SKM) + "手!】");
					Commentary("【" + COD + "做空:卖开委托发出!】");
					SKID = COD.A_SendOrder(Enum_Sell,Enum_Entry,SKM,SKP,AID); //发出卖开委托
					SKFLG = 1; //已发出卖开委托
				}
				Else If(SKM == 0) //如果卖开委托手数等于0
				{
					Commentary("【" + COD + "做空:卖开委托完成!】");
					Exit(); //退出公式
				}
			}
		}
		If(BPDFLG > 0) //如果已开启买平处理
		{
			If(BPFLG0 == 0 && BPFLG1 == 0 && BPFLG == 0) //如果没有买平委托
			{
				BPM = Min(Ceiling(P * ASKV,1),VLM); //买平委托手数
				If(SRP > 0 && BPM > 0) //如果有空头可用持仓,且买平委托手数大于0
				{
					If(SH == 1) //如果是上期所合约
					{
						If(BPDFLG == 2) //如果是买平今仓处理
						{
							If(SRP0 > 0) //如果有空头今仓可用持仓
							{
								BPM0 = Min(SRP0,BPM); //买平今仓委托手数
								BPP0 = ASKP; //买平今仓委托价格
								Commentary("【" + COD + "平空:公式买平今仓" + Text(BPM0) + "手!】");
								Commentary("【" + COD + "平空:买平今仓委托发出!】");
								BPID0 = COD.A_SendOrder(Enum_Buy,Enum_ExitToday,BPM0,BPP0,AID); //发出买平今仓委托
								BPFLG0 = 1; //已发出买平今仓委托
							}
							Else If(SRP0 == 0) //如果没有空头今仓可用持仓
							{
								Commentary("【" + COD + "平空:买平委托完成!】");
								Exit(); //退出公式
							}
						}
						Else If(BPDFLG == 1) //如果是买平处理
						{
							If(SRP1 > 0) //如果有空头老仓可用持仓
							{
								BPM1 = Min(SRP1,BPM); //买平老仓委托手数
								BPP1 = ASKP; //买平老仓委托价格
								Commentary("【" + COD + "平空:公式买平老仓" + Text(BPM1) + "手!】");
								Commentary("【" + COD + "平空:买平老仓委托发出!】");
								BPID1 = COD.A_SendOrder(Enum_Buy,Enum_Exit,BPM1,BPP1,AID); //发出买平老仓委托
								BPFLG1 = 1; //已发出买平老仓委托
							}
							Else If(SRP1 == 0) //如果没有空头老仓可用持仓
							{
								Commentary("【" + COD + "平空:买平委托完成!】");
								Exit(); //退出公式
							}
						}
					}
					Else //如果非上期所合约
					{
						BPM = Min(SRP,BPM); //买平委托手数
						BPP = ASKP; //买平委托价格
						Commentary("【" + COD + "平空:公式买平" + Text(BPM) + "手!】");
						Commentary("【" + COD + "平空:买平委托发出!】");
						BPID = COD.A_SendOrder(Enum_Buy,Enum_Exit,BPM,BPP,AID); //发出买平委托
						BPFLG = 1; //已发出买平委托
					}
				}
				Else If(SRP == 0 || BPM == 0) //如果没有空头可用持仓,或买平委托手数等于0
				{
					Commentary("【" + COD + "平空:买平委托完成!】");
					Exit(); //退出公式
				}
			}
		}
	}
	End
						

通过右上方菜单【运行】->【算法交易运行池】->【算法交易下单】,调出算法交易下单界面,按下图所示方法实现手动下单调用算法交易:


注:①如果再次下单,会再次加载该模型,不会直接在前一个算法交易模型中继续执行。
②如果模型中含有函数Exit(),则模型执行完毕后会自动退出。

策略2:拉动行情,每次自动把买盘吃光,将行情往上拉,反之亦然

交易思路解析:
1、取值手动下单的合约、手数、买卖方向、开平方向;自设委托价格。
2、如果为开仓:
(1)如果为买入开仓:
分批买入,取盘口卖一量与剩余下单手数比较,取数量较小值根据盘口卖一价买入。
如果盘口卖一价变化,撤单并重新委托,取盘口卖一量与该批剩余下单手数比较,取数量较小值根据盘口卖一价买入,直至完全成交完全成交后退出算法。
(2)如果为卖出开仓:
分批卖出,取盘口买一量与剩余下单手数比较,取数量较小值根据盘口买一价卖出。
如果盘口买一价变化,撤单并重新委托,取盘口买一量与该批剩余下单手数比较,取数量较小值根据盘口买一价卖出,直至完全成交完全成交后退出算法。
3、如果为平仓:
(1)如果为买入平仓:
分批处理同买入开仓。
(2)如果为卖出开仓:
分批处理同卖出开仓。

源码实现:
	Vars
	Global_String AID; //账号
	Global_String COD; //合约编码
	Numeric SH; //上海合约标志
	Numeric BSF; //买卖方向
	Numeric EEF; //开平方向
	Numeric BIDP,ASKP; //买卖一价
	Numeric BIDV,ASKV; //买卖一量
	Numeric BRP0,BRP1,BRP; //多头可用持仓
	Numeric SRP0,SRP1,SRP; //空头可用持仓
	Numeric OPFLG; //模型处理标志
	Global_Numeric VLM; //交易手数
	Global_Numeric KPFLG; //委托处理标志
	Global_Numeric BKDFLG; //买开处理标志
	Global_Numeric SKDFLG; //卖开处理标志
	Global_Numeric BPDFLG; //买平处理标志
	Global_Numeric SPDFLG; //卖平处理标志
	Global_Numeric BKID,SKID; //开仓委托
	Global_Numeric BKFLG,SKFLG; //开仓标志
	Global_Numeric BKDEL,SKDEL; //开仓撤单标志
	Global_Numeric BKCM,SKCM; //开仓成交手数
	Global_Numeric BKM,SKM; //开仓委托手数
	Global_Numeric BKP,SKP; //开仓委托价格
	Global_Numeric BPID0,BPID1,BPID; //买平委托
	Global_Numeric SPID0,SPID1,SPID; //卖平委托
	Global_Numeric BPFLG0,BPFLG1,BPFLG; //买平标志
	Global_Numeric SPFLG0,SPFLG1,SPFLG; //卖平标志
	Global_Numeric BPDEL0,BPDEL1,BPDEL; //买平撤单标志
	Global_Numeric SPDEL0,SPDEL1,SPDEL; //卖平撤单标志
	Global_Numeric BPCM0,BPCM1,BPCM; //买平成交手数
	Global_Numeric SPCM0,SPCM1,SPCM; //卖平成交手数
	Global_Numeric BPM0,BPM1,BPM; //买平委托手数
	Global_Numeric SPM0,SPM1,SPM; //卖平委托手数
	Global_Numeric BPP0,BPP1,BPP; //买平委托价格
	Global_Numeric SPP0,SPP1,SPP; //卖平委托价格
	Begin
	//------------------------委托获取------------------------//
	If(1) //委托获取
	{
		If(KPFLG == 0) //如果未开启委托处理
		{
			AID = M_GetTradeAccount(0); //账号
			COD = M_GetTradeContract(); //合约编码
			BSF = M_GetTradeBuySell(); //买卖方向
			EEF = M_GetTradeEntryExit(); //开平方向
			VLM = M_GetTradeVol(); //交易手数
			If(VLM > 0 && COD.A_IsExchangeOpen() == 1) //如果交易手数大于0,且当前状态是开盘
			{
				If(BSF == Enum_Buy && EEF == Enum_Entry) //如果是买开方向
				{
					Commentary("【" + COD + "做多:手动买开" + Text(VLM) + "手!】");
					BKDFLG = 1; //开启买开处理
				}
				Else If(BSF == Enum_Sell && EEF == Enum_Exit) //如果是卖平方向
				{
					Commentary("【" + COD + "平多:手动卖平" + Text(VLM) + "手!】");
					SPDFLG = 1; //开启卖平处理
				}
				Else If(BSF == Enum_Sell && EEF == Enum_ExitToday) //如果是卖平今方向
				{
					Commentary("【" + COD + "平今多:手动卖平" + Text(VLM) + "手!】");
					SPDFLG = 2; //开启卖平今仓处理
				}
				Else If(BSF == Enum_Sell && EEF == Enum_Entry) //如果是卖开方向
				{
					Commentary("【" + COD + "做空:手动卖开" + Text(VLM) + "手!】");
					SKDFLG = 1; //开启卖开处理
				}
				Else If(BSF == Enum_Buy && EEF == Enum_Exit) //如果是买平方向
				{
					Commentary("【" + COD + "平空:手动买平" + Text(VLM) + "手!】");
					BPDFLG = 1; //开启买平处理
				}
				Else If(BSF == Enum_Buy && EEF == Enum_ExitToday) //如果是买平今方向
				{
					Commentary("【" + COD + "平今空:手动买平" + Text(VLM) + "手!】");
					BPDFLG = 2; //开启买平今仓处理
				}
				KPFLG = 1; //开启委托处理
			}
		}
		If(KPFLG == 1 && COD.A_IsExchangeOpen() == 1) //如果已开启委托处理,且当前状态是开盘
		{
			OPFLG = 1; //开启模型处理
		}
	}
	//------------------------变量赋值------------------------//
	If(OPFLG == 1) //变量赋值
	{
		BIDP = COD.Price("Bid1"); //买一价
		ASKP = COD.Price("Ask1"); //卖一价
		BIDV = COD.Price("BidVol1"); //买一量
		ASKV = COD.Price("AskVol1"); //卖一量
		SH = COD.A_IsSHCode(); //上海合约标志
		BRP = COD.A_BuyRemainPosition(); //多头可用持仓
		SRP = COD.A_SellRemainPosition(); //空头可用持仓
		If(SH == 1) //如果是上期所合约
		{
			BRP0 = COD.A_TodayBuyRemainPosition(); //多头今仓可用持仓
			SRP0 = COD.A_TodaySellRemainPosition(); //空头今仓可用持仓
			BRP1 = BRP - BRP0; //多头老仓可用持仓
			SRP1 = SRP - SRP0; //空头老仓可用持仓
		}
	}
	//------------------------成交判断------------------------//
	If(OPFLG == 1) //成交判断
	{
		If(BKFLG == 1) //如果有买开委托
		{
			If(F_OrderStatus(BKID) == Enum_Filled) //如果买开委托成交
			{
				Commentary("【" + COD + "做多:买开委托成交!】");
				VLM = VLM - BKM; //交易手数
				BKFLG = 0; //买开标志归0
				BKDEL = 0; //买开撤单标志归0
			}
			Else If(F_OrderStatus(BKID) == Enum_Canceled) //如果买开委托已撤
			{
				Commentary("【" + COD + "做多:买开委托已撤!】");
				BKCM = F_OrderFilledLot(BKID); //买开成交手数
				If(BKCM > 0) //如果买开委托部分成交
				{
					BKM = BKM - BKCM; //买开委托手数
					VLM = VLM - BKCM; //交易手数
				}
				BKM = Min(ASKV,BKM); //买开委托手数
				If(BKM > 0) //如果买开委托手数大于0
				{
					BKP = ASKP; //买开委托价格
					Commentary("【" + COD + "做多:公式买开" + Text(BKM) + "手!】");
					Commentary("【" + COD + "做多:买开委托追价!】");
					BKID = COD.A_SendOrder(Enum_Buy,Enum_Entry,BKM,BKP,AID); //发出买开委托
				}
				BKDEL = 0; //买开撤单标志归0
			}
			Else If(F_OrderStatus(BKID) == Enum_Declared || F_OrderStatus(BKID) == Enum_FillPart) //如果买开委托挂单
			{
				If(ASKP != BKP && BKDEL == 0) //如果卖一价不等于买开委托价格,且未撤单
				{
					Commentary("【" + COD + "做多:买开委托撤单!】");
					F_DeleteOrder(F_OrderContractNo(BKID)); //撤掉买开委托挂单
					BKDEL = 1; //已发出撤掉买开委托挂单
				}
			}
		}
		If(SH == 1) //如果是上期所合约
		{
			If(SPFLG0 == 1) //如果有卖平今仓委托
			{
				If(F_OrderStatus(SPID0) == Enum_Filled) //如果卖平今仓委托成交
				{
					Commentary("【" + COD + "平多:卖平今仓委托成交!】");
					VLM = VLM - SPM0; //交易手数
					SPFLG0 = 0; //卖平今仓标志归0
					SPDEL0 = 0; //卖平今仓撤单标志归0
				}
				Else If(F_OrderStatus(SPID0) == Enum_Canceled) //如果卖平今仓委托已撤
				{
					Commentary("【" + COD + "平多:卖平今仓委托已撤!】");
					SPCM0 = F_OrderFilledLot(SPID0); //卖平今仓成交手数
					If(SPCM0 > 0) //如果卖平今仓委托部分成交
					{
						SPM0 = SPM0 - SPCM0; //卖平今仓委托手数
						VLM = VLM - SPCM0; //交易手数
					}
					SPM0 = Min1(BRP0,BIDV,SPM0); //卖平今仓委托手数
					If(BRP0 > 0 && SPM0 > 0) //如果有多头今仓可用持仓,且卖平今仓委托手数大于0
					{
						SPP0 = BIDP; //卖平今仓委托价格
						Commentary("【" + COD + "平多:公式卖平今仓" + Text(SPM0) + "手!】");
						Commentary("【" + COD + "平多:卖平今仓委托追价!】");
						SPID0 = COD.A_SendOrder(Enum_Sell,Enum_ExitToday,SPM0,SPP0,AID); //发出卖平今仓委托
					}
					SPDEL0 = 0; //卖平今仓撤单标志归0
				}
				Else If(F_OrderStatus(SPID0) == Enum_Declared || F_OrderStatus(SPID0) == Enum_FillPart) //如果卖平今仓委托挂单
				{
					If(BIDP != SPP0 && SPDEL0 == 0) //如果买一价不等于卖平今仓委托价格,且未撤单
					{
						Commentary("【" + COD + "平多:卖平今仓委托撤单!】");
						F_DeleteOrder(F_OrderContractNo(SPID0)); //撤掉卖平今仓委托挂单
						SPDEL0 = 1; //已发出撤掉卖平今仓委托挂单
					}
				}
			}
			If(SPFLG1 == 1) //如果有卖平老仓委托
			{
				If(F_OrderStatus(SPID1) == Enum_Filled) //如果卖平老仓委托成交
				{
					Commentary("【" + COD + "平多:卖平老仓委托成交!】");
					VLM = VLM - SPM1; //交易手数
					SPFLG1 = 0; //卖平老仓标志归0
					SPDEL1 = 0; //卖平老仓撤单标志归0
				}
				Else If(F_OrderStatus(SPID1) == Enum_Canceled) //如果卖平老仓委托已撤
				{
					Commentary("【" + COD + "平多:卖平老仓委托已撤!】");
					SPCM1 = F_OrderFilledLot(SPID1); //卖平老仓成交手数
					If(SPCM1 > 0) //如果卖平老仓委托部分成交
					{
						SPM1 = SPM1 - SPCM1; //卖平老仓委托手数
						VLM = VLM - SPCM1; //交易手数
					}
					SPM1 = Min1(BRP1,BIDV,SPM1); //卖平老仓委托手数
					If(BRP1 > 0 && SPM1 > 0) //如果有多头老仓可用持仓,且卖平老仓委托手数大于0
					{
						SPP1 = BIDP; //卖平老仓委托价格
						Commentary("【" + COD + "平多:公式卖平老仓" + Text(SPM1) + "手!】");
						Commentary("【" + COD + "平多:卖平老仓委托追价!】");
						SPID1 = COD.A_SendOrder(Enum_Sell,Enum_Exit,SPM1,SPP1,AID); //发出卖平老仓委托
					}
					SPDEL1 = 0; //卖平老仓撤单标志归0
				}
				Else If(F_OrderStatus(SPID1) == Enum_Declared || F_OrderStatus(SPID1) == Enum_FillPart) //如果卖平老仓委托挂单
				{
				If(BIDP != SPP1 && SPDEL1 == 0) //如果买一价不等于卖平老仓委托价格,且未撤单
				{
					Commentary("【" + COD + "平多:卖平老仓委托撤单!】");
					F_DeleteOrder(F_OrderContractNo(SPID1)); //撤掉卖平老仓委托挂单
					SPDEL1 = 1; //已发出撤掉卖平老仓委托挂单
				}
				}
				}
				}
				Else //如果非上期所合约
				{
				If(SPFLG == 1) //如果有卖平委托
				{
				If(F_OrderStatus(SPID) == Enum_Filled) //如果卖平委托成交
				{
				Commentary("【" + COD + "平多:卖平委托成交!】");
				VLM = VLM - SPM; //交易手数
				SPFLG = 0; //卖平标志归0
				SPDEL = 0; //卖平撤单标志归0
				}
				Else If(F_OrderStatus(SPID) == Enum_Canceled) //如果卖平委托已撤
				{
				Commentary("【" + COD + "平多:卖平委托已撤!】");
				SPCM = F_OrderFilledLot(SPID); //卖平成交手数
				If(SPCM > 0) //如果卖平委托部分成交
				{
					SPM = SPM - SPCM; //卖平委托手数
					VLM = VLM - SPCM; //交易手数
				}
				SPM = Min1(BRP,BIDV,SPM); //卖平委托手数
				If(BRP > 0 && SPM > 0) //如果有多头可用持仓,且卖平委托手数大于0
				{
					SPP = BIDP; //卖平委托价格
					Commentary("【" + COD + "平多:公式卖平" + Text(SPM) + "手!】");
					Commentary("【" + COD + "平多:卖平委托追价!】");
					SPID = COD.A_SendOrder(Enum_Sell,Enum_Exit,SPM,SPP,AID); //发出卖平委托
				}
				SPDEL = 0; //卖平撤单标志归0
				}
				Else If(F_OrderStatus(SPID) == Enum_Declared || F_OrderStatus(SPID) == Enum_FillPart) //如果卖平委托挂单
				{
				If(BIDP != SPP && SPDEL == 0) //如果买一价不等于卖平委托价格,且未撤单
				{
					Commentary("【" + COD + "平多:卖平委托撤单!】");
					F_DeleteOrder(F_OrderContractNo(SPID)); //撤掉卖平委托挂单
					SPDEL = 1; //已发出撤掉卖平委托挂单
				}
				}
				}
				}
				If(SKFLG == 1) //如果有卖开委托
				{
				If(F_OrderStatus(SKID) == Enum_Filled) //如果卖开委托成交
				{
				Commentary("【" + COD + "做空:卖开委托成交!】");
				VLM = VLM - SKM; //交易手数
				SKFLG = 0; //卖开标志归0
				SKDEL = 0; //卖开撤单标志归0
				}
				Else If(F_OrderStatus(SKID) == Enum_Canceled) //如果卖开委托已撤
				{
				Commentary("【" + COD + "做空:卖开委托已撤!】");
				SKCM = F_OrderFilledLot(SKID); //卖开成交手数
				If(SKCM > 0) //如果卖开委托部分成交
				{
				SKM = SKM - SKCM; //卖开委托手数
				VLM = VLM - SKCM; //交易手数
				}
				SKM = Min(BIDV,SKM); //卖开委托手数
				If(SKM > 0) //如果卖开委托手数大于0
				{
				SKP = BIDP; //卖开委托价格
				Commentary("【" + COD + "做空:公式卖开" + Text(SKM) + "手!】");
				Commentary("【" + COD + "做空:卖开委托追价!】");
				SKID = COD.A_SendOrder(Enum_Sell,Enum_Entry,SKM,SKP,AID); //发出卖开委托
				}
				SKDEL = 0; //卖开撤单标志归0
				}
				Else If(F_OrderStatus(SKID) == Enum_Declared || F_OrderStatus(SKID) == Enum_FillPart) //如果卖开委托挂单
				{
				If(BIDP != SKP && SKDEL == 0) //如果买一价不等于卖开委托价格,且未撤单
				{
				Commentary("【" + COD + "做空:卖开委托撤单!】");
				F_DeleteOrder(F_OrderContractNo(SKID)); //撤掉卖开委托挂单
				SKDEL = 1; //已发出撤掉卖开委托挂单
				}
				}
				}
				If(SH == 1) //如果是上期所合约
				{
				If(BPFLG0 == 1) //如果有买平今仓委托
				{
				If(F_OrderStatus(BPID0) == Enum_Filled) //如果买平今仓委托成交
				{
				Commentary("【" + COD + "平空:买平今仓委托成交!】");
				VLM = VLM - BPM0; //交易手数
				BPFLG0 = 0; //买平今仓标志归0
				BPDEL0 = 0; //买平今仓撤单标志归0
				}
				Else If(F_OrderStatus(BPID0) == Enum_Canceled) //如果买平今仓委托已撤
				{
				Commentary("【" + COD + "平空:买平今仓委托已撤!】");
				BPCM0 = F_OrderFilledLot(BPID0); //买平今仓成交手数
				If(BPCM0 > 0) //如果买平今仓委托部分成交
				{
					BPM0 = BPM0 - BPCM0; //买平今仓委托手数
					VLM = VLM - BPCM0; //交易手数
				}
				BPM0 = Min1(SRP0,ASKV,BPM0); //买平今仓委托手数
				If(SRP0 > 0 && BPM0 > 0) //如果有空头今仓可用持仓,且买平今仓委托手数大于0
				{
					BPP0 = ASKP; //买平今仓委托价格
					Commentary("【" + COD + "平空:公式买平今仓" + Text(BPM0) + "手!】");
					Commentary("【" + COD + "平空:买平今仓委托追价!】");
					BPID0 = COD.A_SendOrder(Enum_Buy,Enum_ExitToday,BPM0,BPP0,AID); //发出买平今仓委托
				}
				BPDEL0 = 0; //买平今仓撤单标志归0
				}
				Else If(F_OrderStatus(BPID0) == Enum_Declared || F_OrderStatus(BPID0) == Enum_FillPart) //如果买平今仓委托挂单
				{
				If(ASKP != BPP0 && BPDEL0 == 0) //如果卖一价不等于买平今仓委托价格,且未撤单
				{
					Commentary("【" + COD + "平空:买平今仓委托撤单!】");
					F_DeleteOrder(F_OrderContractNo(BPID0)); //撤掉买平今仓委托挂单
					BPDEL0 = 1; //已发出撤掉买平今仓委托挂单
				}
				}
				}
				If(BPFLG1 == 1) //如果有买平老仓委托
				{
				If(F_OrderStatus(BPID1) == Enum_Filled) //如果买平老仓委托成交
				{
				Commentary("【" + COD + "平空:买平老仓委托成交!】");
				VLM = VLM - BPM1; //交易手数
				BPFLG1 = 0; //买平老仓标志归0
				BPDEL1 = 0; //买平老仓撤单标志归0
				}
				Else If(F_OrderStatus(BPID1) == Enum_Canceled) //如果买平老仓委托已撤
				{
				Commentary("【" + COD + "平空:买平老仓委托已撤!】");
				BPCM1 = F_OrderFilledLot(BPID1); //买平老仓成交手数
				If(BPCM1 > 0) //如果买平老仓委托部分成交
				{
					BPM1 = BPM1 - BPCM1; //买平老仓委托手数
					VLM = VLM - BPCM1; //交易手数
				}
				BPM1 = Min1(SRP1,ASKV,BPM1); //买平老仓委托手数
				If(SRP1 > 0 && BPM1 > 0) //如果有空头老仓可用持仓,且买平老仓委托手数大于0
				{
					BPP1 = ASKP; //买平老仓委托价格
					Commentary("【" + COD + "平空:公式买平老仓" + Text(BPM1) + "手!】");
					Commentary("【" + COD + "平空:买平老仓委托追价!】");
					BPID1 = COD.A_SendOrder(Enum_Buy,Enum_Exit,BPM1,BPP1,AID); //发出买平老仓委托
				}
				BPDEL1 = 0; //买平老仓撤单标志归0
				}
				Else If(F_OrderStatus(BPID1) == Enum_Declared || F_OrderStatus(BPID1) == Enum_FillPart) //如果买平老仓委托挂单
				{
				If(ASKP != BPP1 && BPDEL1 == 0) //如果卖一价不等于买平老仓委托价格,且未撤单
				{
					Commentary("【" + COD + "平空:买平老仓委托撤单!】");
					F_DeleteOrder(F_OrderContractNo(BPID1)); //撤掉买平老仓委托挂单
					BPDEL1 = 1; //已发出撤掉买平老仓委托挂单
				}
				}
				}
				}
				Else //如果非上期所合约
				{
				If(BPFLG == 1) //如果有买平委托
				{
				If(F_OrderStatus(BPID) == Enum_Filled) //如果买平委托成交
				{
					Commentary("【" + COD + "平空:买平委托成交!】");
					VLM = VLM - BPM; //交易手数
					BPFLG = 0; //买平标志归0
					BPDEL = 0; //买平撤单标志归0
				}
				Else If(F_OrderStatus(BPID) == Enum_Canceled) //如果买平委托已撤
				{
					Commentary("【" + COD + "平空:买平委托已撤!】");
					BPCM = F_OrderFilledLot(BPID); //买平成交手数
					If(BPCM > 0) //如果买平委托部分成交
					{
						BPM = BPM - BPCM; //买平委托手数
						VLM = VLM - BPCM; //交易手数
					}
					BPM = Min1(SRP,ASKV,BPM); //买平委托手数
					If(SRP > 0 && BPM > 0) //如果有空头可用持仓,且买平委托手数大于0
					{
						BPP = ASKP; //买平委托价格
						Commentary("【" + COD + "平空:公式买平" + Text(BPM) + "手!】");
						Commentary("【" + COD + "平空:买平委托追价!】");
						BPID = COD.A_SendOrder(Enum_Buy,Enum_Exit,BPM,BPP,AID); //发出买平委托
					}
					BPDEL = 0; //买平撤单标志归0
				}
				Else If(F_OrderStatus(BPID) == Enum_Declared || F_OrderStatus(BPID) == Enum_FillPart) //如果买平委托挂单
				{
					If(ASKP != BPP && BPDEL == 0) //如果卖一价不等于买平委托价格,且未撤单
					{
						Commentary("【" + COD + "平空:买平委托撤单!】");
						F_DeleteOrder(F_OrderContractNo(BPID)); //撤掉买平委托挂单
						BPDEL = 1; //已发出撤掉买平委托挂单
					}
				}
			}
		}
	}
	//------------------------委托处理------------------------//
	If(OPFLG == 1) //委托处理
	{
		If(BKDFLG == 1) //如果已开启买开处理
		{
			If(BKFLG == 0) //如果没有买开委托
			{
				BKM = Min(ASKV,VLM); //买开委托手数
				If(BKM > 0) //如果买开委托手数大于0
				{
					BKP = ASKP; //买开委托价格
					Commentary("【" + COD + "做多:公式买开" + Text(BKM) + "手!】");
					Commentary("【" + COD + "做多:买开委托发出!】");
					BKID = COD.A_SendOrder(Enum_Buy,Enum_Entry,BKM,BKP,AID); //发出买开委托
					BKFLG = 1; //已发出买开委托
				}
				Else If(BKM == 0) //如果买开委托手数等于0
				{
					Commentary("【" + COD + "做多:买开委托完成!】");
					Exit(); //退出公式
				}
			}
		}
		If(SPDFLG > 0) //如果已开启卖平处理
		{
			If(SPFLG0 == 0 && SPFLG1 == 0 && SPFLG == 0) //如果没有卖平委托
			{
				SPM = Min(BIDV,VLM); //卖平委托手数
				If(BRP > 0 && SPM > 0) //如果有多头可用持仓,且卖平委托手数大于0
				{
					If(SH == 1) //如果是上期所合约
					{
						If(SPDFLG == 2) //如果是卖平今仓处理
						{
							If(BRP0 > 0) //如果有多头今仓可用持仓
							{
								SPM0 = Min(BRP0,SPM); //卖平今仓委托手数
								SPP0 = BIDP; //卖平今仓委托价格
								Commentary("【" + COD + "平多:公式卖平今仓" + Text(SPM0) + "手!】");
								Commentary("【" + COD + "平多:卖平今仓委托发出!】");
								SPID0 = COD.A_SendOrder(Enum_Sell,Enum_ExitToday,SPM0,SPP0,AID); //发出卖平今仓委托
								SPFLG0 = 1; //已发出卖平今仓委托
							}
							Else If(BRP0 == 0) //如果没有多头今仓可用持仓
							{
								Commentary("【" + COD + "平多:卖平委托完成!】");
								Exit(); //退出公式
							}
						}
						Else If(SPDFLG == 1) //如果是卖平处理
						{
							If(BRP1 > 0) //如果有多头老仓可用持仓
							{
								SPM1 = Min(BRP1,SPM); //卖平老仓委托手数
								SPP1 = BIDP; //卖平老仓委托价格
								Commentary("【" + COD + "平多:公式卖平老仓" + Text(SPM1) + "手!】");
								Commentary("【" + COD + "平多:卖平老仓委托发出!】");
								SPID1 = COD.A_SendOrder(Enum_Sell,Enum_Exit,SPM1,SPP1,AID); //发出卖平老仓委托
								SPFLG1 = 1; //已发出卖平老仓委托
							}
							Else If(BRP1 == 0) //如果没有多头老仓可用持仓
							{
								Commentary("【" + COD + "平多:卖平委托完成!】");
								Exit(); //退出公式
							}
						}
					}
					Else //如果非上期所合约
					{
						SPM = Min(BRP,SPM); //卖平委托手数
						SPP = BIDP; //卖平委托价格
						Commentary("【" + COD + "平多:公式卖平" + Text(SPM) + "手!】");
						Commentary("【" + COD + "平多:卖平委托发出!】");
						SPID = COD.A_SendOrder(Enum_Sell,Enum_Exit,SPM,SPP,AID); //发出卖平委托
						SPFLG = 1; //已发出卖平委托
					}
				}
				Else If(BRP == 0 || SPM == 0) //如果没有多头可用持仓,或卖平委托手数等于0
				{
					Commentary("【" + COD + "平多:卖平委托完成!】");
					Exit(); //退出公式
				}
			}
		}
		If(SKDFLG == 1) //如果已开启卖开处理
		{
			If(SKFLG == 0) //如果没有卖开委托
			{
				SKM = Min(BIDV,VLM); //卖开委托手数
				If(SKM > 0) //如果卖开委托手数大于0
				{
					SKP = BIDP; //卖开委托价格
					Commentary("【" + COD + "做空:公式卖开" + Text(SKM) + "手!】");
					Commentary("【" + COD + "做空:卖开委托发出!】");
					SKID = COD.A_SendOrder(Enum_Sell,Enum_Entry,SKM,SKP,AID); //发出卖开委托
					SKFLG = 1; //已发出卖开委托
				}
				Else If(SKM == 0) //如果卖开委托手数等于0
				{
					Commentary("【" + COD + "做空:卖开委托完成!】");
					Exit(); //退出公式
				}
			}
		}
		If(BPDFLG > 0) //如果已开启买平处理
		{
			If(BPFLG0 == 0 && BPFLG1 == 0 && BPFLG == 0) //如果没有买平委托
			{
				BPM = Min(ASKV,VLM); //买平委托手数
				If(SRP > 0 && BPM > 0) //如果有空头可用持仓,且买平委托手数大于0
				{
					If(SH == 1) //如果是上期所合约
					{
						If(BPDFLG == 2) //如果是买平今仓处理
						{
							If(SRP0 > 0) //如果有空头今仓可用持仓
							{
								BPM0 = Min(SRP0,BPM); //买平今仓委托手数
								BPP0 = ASKP; //买平今仓委托价格
								Commentary("【" + COD + "平空:公式买平今仓" + Text(BPM0) + "手!】");
								Commentary("【" + COD + "平空:买平今仓委托发出!】");
								BPID0 = COD.A_SendOrder(Enum_Buy,Enum_ExitToday,BPM0,BPP0,AID); //发出买平今仓委托
								BPFLG0 = 1; //已发出买平今仓委托
							}
							Else If(SRP0 == 0) //如果没有空头今仓可用持仓
							{
								Commentary("【" + COD + "平空:买平委托完成!】");
								Exit(); //退出公式
							}
						}
						Else If(BPDFLG == 1) //如果是买平处理
						{
							If(SRP1 > 0) //如果有空头老仓可用持仓
							{
								BPM1 = Min(SRP1,BPM); //买平老仓委托手数
								BPP1 = ASKP; //买平老仓委托价格
								Commentary("【" + COD + "平空:公式买平老仓" + Text(BPM1) + "手!】");
								Commentary("【" + COD + "平空:买平老仓委托发出!】");
								BPID1 = COD.A_SendOrder(Enum_Buy,Enum_Exit,BPM1,BPP1,AID); //发出买平老仓委托
								BPFLG1 = 1; //已发出买平老仓委托
							}
							Else If(SRP1 == 0) //如果没有空头老仓可用持仓
							{
								Commentary("【" + COD + "平空:买平委托完成!】");
								Exit(); //退出公式
							}
						}
					}
					Else //如果非上期所合约
					{
						BPM = Min(SRP,BPM); //买平委托手数
						BPP = ASKP; //买平委托价格
						Commentary("【" + COD + "平空:公式买平" + Text(BPM) + "手!】");
						Commentary("【" + COD + "平空:买平委托发出!】");
						BPID = COD.A_SendOrder(Enum_Buy,Enum_Exit,BPM,BPP,AID); //发出买平委托
						BPFLG = 1; //已发出买平委托
					}
				}
				Else If(SRP == 0 || BPM == 0) //如果没有空头可用持仓,或买平委托手数等于0
				{
					Commentary("【" + COD + "平空:买平委托完成!】");
					Exit(); //退出公式
				}
			}
		}
	}
	End
							

通过右上方菜单【运行】->【算法交易运行池】->【算法交易下单】,调出算法交易下单界面,按下图所示方法实现手动下单调用算法交易:


注:①如果再次下单,会再次加载该模型,不会直接在前一个算法交易模型中继续执行。
②如果模型中含有函数Exit(),则模型执行完毕后会自动退出。
案例二:手动下单+多账号分批算法
算法交易也支持多账号智能分批,既可以对多个账号进行分组,设定不同的委托手数倍率,也可以根据对手盘情况实时计算每一批的总手数,实现多账号智能分批、统一管理。
例如:
我们有三个交易账号需要同时开仓,三个交易账号的委托手数倍率分别为1、1.5、2.5。我们可在多账号下单界面中勾选要参与交易的账号,并设定好下单倍率。


我们可以一键对这三个账号一起进行智能分批下单。
首先,要求每批的总手数不超过盘口对手盘量的20%。首批三个账户按照1 : 1.5 :2.5的比例进行下单。
其次,任何一个账号第一批成交以后(三个账号不一定同时都成交),第二批委托数量为对手盘量的20%乘以该账号的比例,直到全部成交。
最后,任何一个账号如3秒未全部成交,则执行追价策略确保成交。
这样既保证了总手数不对趋势造成影响,也同时完成了三个账号的分批建仓。

代码如下:
	Vars
	Global_StringArray AID; //账号
	Global_String COD; //合约编码
	Numeric X; //循环变量
	Numeric T; //时间间隔
	Numeric P; //数值比例
	Numeric BSF; //买卖方向
	Numeric EEF; //开平方向
	Numeric VLM; //交易手数
	Numeric NOW; //当前时间
	Numeric ASKP; //卖一价
	Numeric ASKV; //卖一量
	Numeric ODFLG; //挂单判断标志
	Numeric OPFLG; //模型处理标志
	Global_Numeric ADN; //账号数量
	Global_Numeric TP; //下单总倍数
	Global_Numeric KPFLG; //委托处理标志
	Global_Numeric BKDFLG; //买开处理标志
	Global_NumericArray NP; //下单倍数
	Global_NumericArray BKID; //买开委托
	Global_NumericArray BKFLG; //买开标志
	Global_NumericArray BKDEL; //买开撤单标志
	Global_NumericArray BKSM; //买开总手数
	Global_NumericArray BKM; //买开委托手数
	Global_NumericArray BKP; //买开委托价格
	Global_NumericArray BKT; //买开委托时间
	Begin
	//------------------------委托获取------------------------//
	If(1) //委托获取
	{
		If(KPFLG == 0) //如果未开启委托处理
		{
			ADN = M_GetTradeAccountNum; //账号数量
			COD = M_GetTradeContract(); //合约编码
			BSF = M_GetTradeBuySell(); //买卖方向
			EEF = M_GetTradeEntryExit(); //开平方向
			VLM = M_GetTradeVol(); //交易手数
			For X = 0 To ADN - 1 //遍历账号
			{
				AID[X] = M_GetTradeAccount(X); //账号
				NP[X] = M_GetTradeOrderRatio(X);//下单倍数
				BKSM[X] = NP[X] * VLM; //买开总手数
				TP = TP + NP[X]; //下单总倍数
			}
			If(VLM > 0 && COD.A_IsExchangeOpen() == 1)//如果交易手数大于0,且当前状态是开盘
			{
				If(BSF == Enum_Buy && EEF == Enum_Entry)//如果是买开方向
				{
					Commentary("【" + COD +"做多:手动买开" + Text(VLM) + "手!】");
					BKDFLG = 1;//开启买开处理
				}
				KPFLG = 1; //开启委托处理
			}
		}
		If(KPFLG == 1 && COD.A_IsExchangeOpen() == 1) //如果已开启委托处理,且当前状态是开盘
		{
			OPFLG = 1; //开启模型处理
		}
	}
	//------------------------变量赋值------------------------//
	If(OPFLG == 1) //变量赋值
	{
		T = 3; //时间间隔
		P = 0.2; //数值比例
		NOW = CurrentTime(); //当前时间
		ASKP = COD.Price("Ask1"); //卖一价
		ASKV = COD.Price("AskVol1"); //卖一量
	}
	//------------------------成交判断------------------------//
	If(OPFLG == 1) //成交判断
	{
		For X = 0 To ADN - 1 //遍历账号
		{
			If(BKFLG[X] == 1) //如果有买开委托
			{
				If(F_OrderStatus(BKID[X]) == Enum_Filled)//如果买开委托成交
				{
					Commentary("【" + COD + "做多:买开委托成交!" + AID[X] + "】");
					BKFLG[X] = 0;//买开标志归0
					BKDEL[X] = 0;//买开撤单标志归0
				}
				Else If(F_OrderStatus(BKID[X]) == Enum_Canceled) //如果买开委托已撤
				{
					Commentary("【" + COD + "做多:买开委托已撤!" + AID[X] + "】");
					If(F_OrderFilledLot(BKID[X]) > 0) //如果买开委托部分成交
					{
						BKM[X] = BKM[X] - F_OrderFilledLot(BKID[X]); //买开委托手数
					}
					If(BKM[X] > 0) //如果买开委托手数大于0
					{
						BKP[X] = ASKP; //买开委托价格
						Commentary("【" + COD + "做多:买开委托追价!" + AID[X] + "】");
						BKID[X] = COD.A_SendOrder(Enum_Buy,Enum_Entry,BKM[X],BKP[X],AID[X]); //发出买开委托
						BKT[X] = NOW; //买开委托时间
					}
					BKDEL[X] = 0; //买开撤单标志归0
				}
				Else If(F_OrderStatus(BKID[X]) == Enum_Declared || F_OrderStatus(BKID[X]) == Enum_FillPart) //如果买开委托挂单
				{
					If(BKDEL[X] == 0) //如果未撤单
					{
						If(TimeDiff(BKT[X],NOW) >= T) //如果时间间隔T秒
						{
							Commentary("【" + COD + "做多:买开委托撤单!" + AID[X] + "】");
							COD.F_DeleteOrder(F_OrderContractNo(BKID[X]),AID[X]); //撤掉买开委托挂单
							BKDEL[X] = 1; //已发出撤掉买开委托挂单
						}
					}
				}
			}
		}
		ODFLG = 1; //挂单判断标志初始化
		For X = 0 To ADN - 1 //遍历账号
		{
			If(BKFLG[X] == 1 || BKSM[X] > 0) //如果有买开委托,或有剩余买开手数
			{
				ODFLG = 2; //存在买开委托挂单
			}
		}
		If(ODFLG == 1) //如果没有买开委托
		{
			Commentary("【" + COD + "做多:买开委托完成!】");
			BKDFLG = 0; //买开处理标志归0
			Exit(); //退出公式
		}
	}
	//------------------------委托处理------------------------//
	If(OPFLG == 1) //委托处理
	{
		If(BKDFLG == 1) //如果已开启买开处理
		{
			For X = 0 To ADN - 1 //遍历账号
			{
				If(BKFLG[X] == 0) //如果没有买开委托
				{
					If(TP > 0) //如果已取得下单总倍数
					{
						BKM[X] = Min(Floor((NP[X] / TP) * P * ASKV),BKSM[X]); //买开委托手数
					}
					If(BKM[X] > 0) //如果买开委托手数大于0
					{
						BKP[X] = ASKP; //买开委托价格
						Commentary("【" + COD + "做多:公式买开" + Text(BKM[X]) + "手!" + AID[X] + "】");
						Commentary("【" + COD + "做多:买开委托发出!" + AID[X] + "】");
						BKID[X] = COD.A_SendOrder(Enum_Buy,Enum_Entry,BKM[X],BKP[X],AID[X]); //发出买开委托
						BKSM[X] = BKSM[X] - BKM[X]; //买开总手数自减买开处理手数
						BKT[X] = NOW; //买开委托时间
						BKFLG[X] = 1; //已发出买开委托
					}
				}
			}
		}
	}
	End
						
组合回测
组合参数优化
WT9软件以Tick精准历史回测为基础,可进行多品种、多策略、多周期任意组合的测试。还提供风险分析、盈利分析、相关性分析等分析工具,从多个角度解析组合的内在逻辑,寻求优化策略,搭建最优投资组合。
案例1:批量回测工具操作手册
1、一篮子合约批量回测
用同一个策略模型对一篮子合约进行批量回测,筛选最佳交易合约。回测后每一个合约都生成一份独立的回测报告和独立的资金曲线图,投资者点击合约名称可切换回测报告分析,简化操作步骤。


2、一篮子模型批量回测
用多个策略模型对同一合约进行批量回测,筛选适合该合约的交易策略。软件提供每个策略的回测报告,分项统计图表、时段统计图表,以及k线图供分析,且支持一键加入到模组运行。


案例2:组合回测分析工具使用方法
1、组合回测操作步骤




2、组合资金曲线计算方式


权益资金曲线,记录每根K线上的权益波动;
损益曲线,记录平仓盈亏累加值的波动,每完整交易一次则统计一次;
收益曲线,展示模型的累计收益情况(浮盈+累计平仓盈亏-手续费);
净值曲线,刨除出入金对组合的收益影响,展示组合的真实盈利效果;
显示保证金占比,在资金曲线图下方显示保证金占比柱状图,便于分析资金占用情况,调控资金分配;
资金详细信息,记录每根K线上的组合资金概况和组合中所有策略的具体交易信息。

3、风险分析工具的使用
风险分析工具提供了净值、收益回测曲线,并支持设定回撤阈值,统计回撤幅度、持续天数、恢复天数等数据。


回撤贡献度分析,对每个模型进行打分,回撤贡献度分数越高说明回撤越小,贡献越大。


回撤贡献度得分算法:
每个策略在每个时点上比较,回撤值最大的得1分,次之得2分,以此类推。每个策略总分就是每个时点得分之和。如在某一个时点上,策略A的回撤大,策略B的回撤小,那么策略A得1分,策略B得2分。每个时点上都会计算得分,策略A和策略B的得分分别加和就是各自的总得分。得分高说明策略的回撤小,贡献大。
注:回撤值=回撤前的最大权益-当前权益

回撤比贡献度得分算法:
回撤比贡献度以每个时点的最大回撤比(最大回撤/最大回撤前的最大权益)做比较,计算各个点的得分之后加起来计算总得分。

4、盈利分析工具的使用
盈利分析图表对每个策略盈利状况(盈利贡献度=策略盈利/组合总盈利),分析组合成员的盈利贡献度大小。


注:组合盈利小于0时,盈利分析图不显示盈利贡献度百分比,只显示具体盈利数值。

5、相关性分析工具的使用
组合回测提供相关性分析,统计策略收益率的相关性大小,分析组合的风险分散效果。方便用户根据策略的相关性强弱,调整组合成员,优化模型结构,分散组合风险。

WT9不仅支持单策略的参数优化,还提供了基于遗传规划算法的组合参数优化,通过设定初始种群、最大遗传代数、参考标准等参数,可对策略组合进行参数优化,自动计算最优参数,制定最优定参计划。
案例:组合参数优化操作步骤
1、在组合回测窗口,点击左下角【组合参数优化】按钮。


2、选择需要进行参数优化的模型,设定初始种群、最大遗产代数、参考标准,系统将自动机计算计算次数,以及启用的线程数。


3、计算结果支持排序,或右键保存到备用参数组中。
模组分区资金管理
运行单元资金管理
WT9模组会根据模型的实盘交易数据,绘制出每个模组分区的收益曲线和权益曲线。当一只资管产品的各个交易账号加载到同一个分区交易时,分区综合收益/权益曲线,就是该产品的收益/权益曲线。还支持出入金管理,可展现产品历史出入金记录及资金变动情况,方便实时关注产品的真实盈亏和权益变化。
案例:模组分区出入金管理
在模组的运行单元中点击鼠标右键,可选择资金管理功能。


分区资金管理模块提供了该分区综合收益曲线和综合权益曲线,且可以选择显示全部资金账号收益或N个资金账号的收益。


资金管理名称解释:
分区初始资金:可设置初始资金,用于计算综合权益。
分区出入金:可选择出入金日期,并进行出入金操作,系统会记录历史出金情况,并展示在综合权益曲线中。
模组还提供每个模组单元的权益、收益率、回撤比数据,可以在模型的运行过程中,了解每一个模型的资金分配情况和权益变化,及时发现运行效果不理想或已经失效的模型,灵活调整投资组合,提高组合收益,降低投资风险;各个运行单元独立的头寸计算,也是后期投入资金不断增加,制定资金再分配计划的保障。
案例:运行单元策略优选
在模组的运行单元中点击鼠标右键,可选择资金管理功能。


分区资金管理模块提供了在该分区下所有单元的初始资金、出入金、权益、收益率、回撤等统计数据。


资金管理名词解释:
单元初始资金:可设置单元的初始资金。
单元出入金:可选择出入金日期,并进行出入金操作,系统会记录单元历史出金情况。
单元运行报告:可查看当前单元到当前交易日的回测报告,该报告基于理论数据计算,评估单元最新交易情况。
策略加密运行
模组运行监控
WT9支持对策略设置查看密码,以及加密输出执行副本,在策略编辑以及模型运行过程中,都无法直接查看策略源码,保证策略的安全性。
案例:模型加密运行过程详解
在模型编辑界面,可点击【设置】,选择设置查看密码,输入密码以后,该模型在编辑和加载运行时,都不会显示模型源码,保证策略安全运行。


模型加载以后,只能看到信号和运行结果,不显示模型源码。

模组是基金经理的模型运行管理操作页面,也是交易员监控模型运行状态的工具。可随时查看每一个模型的运行日志,持仓、成交情况,当模型出现挂单、不成交的情况时,可以一键手动追价或加减仓,保证模型顺利运行。
案例:模组运行监控界面详解


模组运行界面名词解释:
单元:模组中每个运行的模型称为单元。
分区:多个运行单元可分配到同一工作区内,进行分区管理。
监控k线图:显示该模型数据合约的k线图,支持显示模型信号、理论资金曲线、原型指标线,右键支持重新计算历史信号,或清除历史信号重新计算。
模型参数:显示模型参数,并支持手动修改参数并启用新参数重新计算。
交易合约:支持查看数据合约、交易合约,并支持修改交易合约。
源码:显示策略模型源码,支持设置查看密码,隐藏交易源码。
撤单/手动追价:当模型委托不成交产生挂单时,可以手动撤单,或者进行追价。
导入现有持仓:单元持仓小于理论持仓且实际账户中有持仓时,可在模组里点击“导入现有持仓”按钮,将实际账户中已有的持仓带入到模组中。
加仓/减仓:支持手动对该模组单元进行加仓、减仓操作。
平移到新合约:用于换月移仓操作,将旧主力合约平仓以后,点击“平移到新合约”按钮,选择新主力合约,系统延续模型单元的资金,在新主力合约上重新计算信号并继续交易。
运行日志:显示该模型单元的运行日志。
成交列表/持仓列表:显示该模型单元的成交情况和当前持仓情况。
持仓匹配校验
产品申购/赎回管理
当盘中遇到电脑、网络及其他交易环境故障引起的模组运行中断,信号没有有效执行的情况时,需要对模组单元持仓手动进行调整。T9软件提供持仓匹配校验功能,可一键校验各个合约的理论持仓和账户实际持仓是否匹配,并支持批量手动补单、批量算法补单。
案例:模组持仓匹配校验及补单操作流程
如下图,点击持仓匹配校验按钮可一键查询模组中合约理论持仓、单元持仓与实际账户持仓的匹配情况,便于及时手动处理。


1、手动单独处理
单元持仓小于理论持仓且实际账户中有持仓时,可在模组里点击“导入现有持仓”按钮,将实际账户中已有的持仓带入到模组中,完成持仓匹配。模组会根据输入的价格和持仓数量计算权益,后续对导入的持仓按策略信号执行平仓操作。


2、批量处理
可点击批量手动补仓或批量算法补仓按钮,系统根据每个模组单元的实际情况,按照选择的价格或算法交易策略,自动批量补仓。

模组支持产品申购/赎回辅助处理,针对手动资金管理的场景,以及用模型做自动资金管理的场景都有对应的支持。
案例:产品申购/赎回处理流程
1、手动资金管理产品申购/赎回操作方法
当某一只资管产品进行申购/赎回管理时,只需在多账号管理界面,修改账号组中产品账户的下单倍率,即可自动变更此产品账户全部运行单元的交易手数,运行单元会自动从下一个开仓指令开始使用新的手数交易。


2、自动资金管理产品申购赎回操作方法
在模型里写了资金头寸函数实现按理论资金比例下单的情况下,当一只资管产品需要进行申购/赎回时,可在资金管理界面,对该产品的运行单元进行出入金操作,后续的开仓指令,模型会根据调整后的资金重新计算下单手数。对于各个运行单元的当前持仓需要进行辅助的手动处理:申购时可手动点击“加仓”按钮,进行加仓交易;赎回时可点击“减仓”按钮,进行减仓交易。

© 上海文华财经资讯股份有限公司   ICP证号:沪B2-20110035