18

最も近い指定された間隔 (この場合は金融市場のティック サイズ) に丸める必要がある BigDecimal 計算結果があります。

例: 価格 [ティック サイズ] -> 四捨五入された価格

100.1 [0.25] -> 100
100.2 [0.25] -> 100.25
100.1 [0.125] -> 100.125
100.2 [0.125] -> 100.25

ありがとう。

更新: Java/BigDecimal 用語に翻訳された schnaader のソリューション:

price = price.divide(tick).setScale(0, RoundingMode.HALF_UP).multiply(tick)
4

3 に答える 3

14

目盛りのサイズを正規化してから、通常の丸め方法を使用できます。

100.1 [0.25] -> * (1/0.25) -> 400.4 [1]  -> round -> 400 -> / (1/0.25) -> 100
100.2 [0.25] -> * (1/0.25) -> 400.8 [1] -> round -> 401 -> / (1/0.25) -> 100.25

したがって、次のようになります。

Price = Round(Price / Tick) * Tick;

また、BigDecimals に正しい丸めモードを設定する必要があるように見えることにも注意してください。たとえば、BigDecimal Docsを参照してください。したがって、これを正しく設定し、コードの正確性を確認するためのテストを作成する必要があります。

于 2009-03-13T08:49:16.960 に答える
2

これは、 「株価を最も近いティック サイズに丸める」に関連しています。

schnaader から提供された回答は正しいですが、不足していることがいくつかあります。

  • まず、株価に四捨五入が必要かどうかを確認する必要があります。不要な丸めは、小数部分を台無しにします。
  • 次に、除算関数ArithmeticException中に発生する可能性のある処理も必要ですBigDecimal

これが私の解決策です。それを説明するにはとても時間がかかります。雰囲気をつかむために、いくつかのサンプルで試してみることをお勧めします。関数を探しますroundTick()

import static java.math.RoundingMode.HALF_UP;

import java.math.BigDecimal;

/**
 * Utility class for stock price related operations.
 */
public final class PriceFormatter {

    public static final float DELTA = 0.0001f;

    private PriceFormatter() {
    }

    /**
     * Rounds the price to the nearest tick size.
     *
     * @param price    price
     * @param tickSize tick size
     * @return price rounded to the nearest tick size
     */
    public static final float roundTick(final float price, final float tickSize) {
        if (tickSize < DELTA) {
            return price;
        }

        if (!isRoundingNeeded(price, tickSize)) {
            return price;
        }

        final BigDecimal p = new BigDecimal(price);
        final BigDecimal t = new BigDecimal(tickSize);

        final BigDecimal roundedPrice = p.divide(t, 0, HALF_UP).multiply(t);

        return roundedPrice.floatValue();
    }

    /**
     * Checks whether price needs rounding to the nearest tick size.
     *
     * @param price    price
     * @param tickSize tick size
     * @return true, if rounding is needed; false otherwise
     */
    public static final boolean isRoundingNeeded(final float price, final float tickSize) {
        final int mult = calculateTickMultiplier(tickSize);
        final int mod = (int) (tickSize * mult);
        final float reminder = (((price * mult) % mult) % mod);
        final boolean needsRounding = reminder > DELTA;
        return needsRounding;
    }

    public static final int calculateTickMultiplier(final float tickSize) {
        int result = 1;
        while (((tickSize * result) < 1) || (((tickSize * result) - (int) (tickSize * result)) > DELTA)) {
            result *= 10;
        }

        return result;
    }

}
于 2020-04-24T18:36:13.553 に答える
1
p= p - p % t + ((p % t < t / 2) ? 0.0 : t);

// ここで、p= 価格、t= ティックの増分

于 2013-12-06T01:44:42.480 に答える