2017-03-16 102 views
0

使用股票报价我需要找到具有以下输入参数的范围:查找股票报价范围

价格步骤:尽可能降低价格变动。步骤= 0.01意味着报价可以是100.01,100.1,但不是100.015。对于'大'股可以是> 1。

范围内的步数。步骤= 10意味着我需要10次最低价格变动。像[100.1; 100.2)需要调整时间间隔以尽量减少移动,所以不需要[100.015; 100.15)可能的时间间隔。

输入引号任何双(6个位数后,就足够了),可能会或可能不会遵守价格一步规则(例如,从股市的直接价值服从,但平均值不)。显然,报价应该是间隔的。我尝试了不同的方法,但都失败了。

范围是相当简单:

public class Range<T extends Comparable> { 
    private T from = null; 
    private T to = null; 

    public Range(T from, T to) { 
     this.from = from; 
     this.to = to; 
    } 

    public T getFrom() { 
     return from; 
    } 

    public T getTo() { 
     return to; 
    } 

    @SuppressWarnings("unchecked") 
    public boolean contains(T value) { 
     return from.compareTo(value) <= 0 && to.compareTo(value) > 0; 
    } 

    @Override 
    public String toString() { 
     return "Range{" + 
       "from=" + from + 
       ", to=" + to + 
       '}'; 
    } 
} 


protected static Range<Double> getRangeFromPrice(double pips, int step, double price) { 
    BigDecimal modifier = new BigDecimal(pips * step).setScale(6, BigDecimal.ROUND_HALF_DOWN); 
    BigDecimal begin = new BigDecimal(price).divide(modifier, 0, BigDecimal.ROUND_HALF_DOWN).multiply(modifier); 
    return new Range<>(begin.doubleValue(), begin.add(modifier).doubleValue()); 
} 

此功能的大部分时间,例如对于点数= 0.01和步长= 10

  1. 价= 132范围{从= 132.0,以= 132.1}确定
  2. 价格= 132.01范围从{= 132.0,为= 132.1}确定
  3. 价格= 132.1范围从{= 132.1,为= 132.2}确定
  4. 价格= 132.15范围从{= 132.2,为= 132.3} < - ERROR,价格不在间隔

我尝试不同的舍入策略,但它们都失败(在一个实例中或另外的)。现在我完全没有想法。我怎样才能自动选择舍入策略?

回答

0

考虑:

Decimal STEP = 0.1; // floating-point 0.1 is always imprecise. 
Decimal shifted = price/step; // make steps integral. 
Decimal left = trunc(price) * step; // always ≤ price. 
Decimal right = trunc(price + 1) * step; // always > left. 
return Range(left, right); 
0
protected static Range<Double> getRangeFromPrice(double step, int count, double price) { 
    BigDecimal modifier = new BigDecimal(count * step).setScale(Common.PRICE_RESOLUTION, BigDecimal.ROUND_HALF_UP); 
    BigDecimal div = new BigDecimal(price).divide(modifier, Common.PRICE_RESOLUTION, BigDecimal.ROUND_HALF_EVEN).setScale(0, BigDecimal.ROUND_FLOOR); 
    BigDecimal begin = div.multiply(modifier); 
    Range<Double> ret = new Range<>(begin.doubleValue(), begin.add(modifier).doubleValue()); 

    assert ret.contains(price); 
    return ret; 
} 

我解决了原来的问题用下面的代码。价格应该不是真的双倍,我在数据库中使用数字(19,6),但是在应用程序中,我使用double,因为BigDecimal相当慢。 如果您想使用双倍,则需要额外的舍入。

此代码通过我的单元测试。