订单(order)有效性检查是交易系统一个重要的基础功能。当一个订单从柜台进入交易系统后,会经历几十项不同规则的检查,主要涉及订单自身的合法性、以及当时交易系统和合约的状态、权限等等不同的领域。
其中一个典型的检查是,价格是否是最小变动价位(tick)的整数倍。这是之前介绍价格波动带时提到的合约价格不连续的问题的延伸。
报价单位:指数点 最小变动价位:0.2点合约乘数:每点300元
以上述合约表中的描述来说,因为tick=0.2,我们会在某些交易软件的五档行情表中看到类似这样的价格列表:
来源:
https://www.wenhuacaijing.hk/wenti/174.html
那么,这个问题就转换成了一个简单的数学问题:如何判断一个数是另外一个数的倍数?
JAVA BigDecimal的实现
import java.math.BigDecimal; public class TickCheckRule { public boolean checkTick(BigDecimal price, BigDecimal tick) throws Exception { if (pareTo(BigDecimal.ZERO)==0) throw new Exception("tick should not be ZERO"); //取余 BigDecimal number= price.remainder(tick); if(pareTo(BigDecimal.ZERO) == 0) { return true; } else return false; } }package com.github.tdd.finance;
然后写几个用例来测试一下
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.math.BigDecimal; import static org.assertj.core.api.Assertions.assertThat; public class TestTick { TickCheckRule rule = new TickCheckRule(); @Test public void tickShouldNotBeZero(){ BigDecimal price = BigDecimal.valueOf(2.3); BigDecimal tick = new BigDecimal("0"); Assertions.assertThrows(Exception.class, () -> { rule.checkTick(price,tick); }); } @Test public void NotTickVerySmallRemainder() throws Exception { BigDecimal price = new BigDecimal("100.10000001"); BigDecimal tick = new BigDecimal("0.1"); assertThat(rule.checkTick(price,tick)).isFalse(); } @Test public void DividedByTick() throws Exception { BigDecimal price = new BigDecimal("0.10"); BigDecimal tick = new BigDecimal("0.1"); assertThat(rule.checkTick(price,tick)).isTrue(); } @Test public void notValidEndless() throws Exception { BigDecimal price = new BigDecimal("4"); BigDecimal tick = new BigDecimal("3"); assertThat(rule.checkTick(price,tick)).isFalse(); } }package com.github.tdd.finance;
那么问题来了,在现实中代码是用C++编写,并没有使用类似BigDecimal的库来专门处理数学运算。我们来看看接口说明文档中的实际价格定义。以CTP交易接口为例,
TThostFtdcPriceType PriceTick; ///本次结算价 TThostFtdcPriceType SettlementPrice; ///涨停板价 TThostFtdcPriceType UpperLimitPrice; ///跌停板价 TThostFtdcPriceType LowerLimitPrice;///最小变动价位
而这些价格的基础类型定义是
///TFtdcPriceType是一个价格类型 ///////////////////////////////////////////////////////////////////////// typedef double TThostFtdcPriceType;/////////////////////////////////////////////////////////////////////////
可以看到价格是一个double类型的浮点数。
/
JAVA Double版本
if (isZero(tick)==0) throw new Exception("tick should not be ZERO"); //判断是否能整除, double number= price %tick; if(isZero(number) == 0) { return true; } else return false; } private int isZero(double x){ double EPSINON = 0.000000001; if (( x >= -EPSINON ) && ( x <= EPSINON )) { return 0; } return -1; }public boolean checkTick(double price, double tick) throws Exception {
写个用例测试一下
public void NotTickVerySmallRemainder() throws Exception { String price ="100.100001"; String tick="0.1"; assertThat(rule.checkTick(price,tick)).isFalse(); }@Test
小节
本文简要介绍了价格是tick整数倍的判断
如果觉得《判断非负整数是否是3的倍数_价格是最小变动价位(tick)整数倍检查》对你有帮助,请点赞、收藏,并留下你的观点哦!