好库网 好库网首页 | 我的好库
区块链专栏

文章分类

Ta4j Num接口The Num Interface

发布者:blockchain
发布日期:2021-2-21 22:36:00   更新日期:2021-2-23 19:13:00
阅读次数:83
评分:4.80
介绍:Ta4j支持使用不同类型进行Indicator或中进行的基本计算BarSeries。这意味着您可以编写自己的Num接口实现,也可以在现有实现之间进行选择。
正文:

什么是Num?

从版本0.12开始,Ta4j支持使用不同类型进行Indicator或中进行的基本计算BarSeries这意味着您可以编写自己的Num接口实现,也可以在现有实现之间进行选择。目前,有两个可用的现有实现:(PrecisionNum默认)和DoubleNum顾名思义,可用的实现使用不同的类型(代理)进行算术计算。DoubleNum采用了double原始的和PrecisionNum使用BigDecimal的计算类。以下代码段说明了它们的区别:

加上操作DoubleNum

@Override
public Num plus(Num augend) {
    return augend.isNaN() ? NaN : new DoubleNum(delegate + ((DoubleNum)augend).delegate);
}

加上操作PrecisionNum

public Num plus(Num augend) {
    return augend.isNaN() ? NaN : new BigDecimalNum(delegate.add(((BigDecimalNum)augend).delegate, MATH_CONTEXT));
}

查看用法示例中的相应部分,以了解如何使用NumBaseBarSeries

选择正确的Num实施

为算术运算支持不同数据类型的主要目的是技术分析中的相反目标。一方面,性能是高频交易或大数据分析中的关键因素,另一方面,加密货币和货币价值的一般处理要求的算法基于诸如或的二进制浮点类型例如,以下使用简单代码片段将打印出意外的结果:doublefloatdouble

System.out.println(1.0 - 9*0.1)

输出将0.0999999999999999998不等于0.1。这不是错误,而是尝试在二进制数字系统中表示十进制值的结果。不可能精确地以double或float表示0.1(或其他任何负的10的幂)使用这些数据类型,您只能近似使用这种十进制值。在许多情况下,这种表示可能就足够了,您会说“四舍五入到最后一分将为我提供正确的值”,但请注意,.9999万亿美元大约等于1万亿美元。您能把差额存入我的银行帐户吗?

正确的方式来解决这个问题的方法是使用BigDecimalintlong货币计算。这并不意味着双打永远不能用于此目的。基于指标仅使用货币值作为输入但进一步的计算和结果不具有货币维度这一事实,Double的53个有效位(〜16个十进制数字)通常足以满足那些仅要求准确性的事情。 您必须了解您的应用程序,并且应该研究目标并告知自己哪种数据类型实现最适合您。

PrecisionNum

使用BigDecimal作为delgatePrecisionNum实现,可以表示精确到32位小数的任何十进制值。它可用于进行高度精确的计算并与需要大量小数位表示的加密货币一起使用。如果创建,则是默认实现对于某些需要快速进行运算或大量计算的目的,您可能注意到由于实现了性能瓶颈NumNumBaseBarSeriesNum

BarSeries series_1 = new BaseBarSeriesBuilder().build() // implicit initialize BarSeries with PrecisionNum
BarSeries series_2 = new BaseBarSeriesBuilder().withNumType(PrecisionNum::valueOf).build() // explicit initialize BarSeries with PrecisionNum

DoubleNum

在发现有关的缺点之后DoubleNum,请注意,它可以使您的Ta4j应用程序大幅提升性能。您可以按如下方式BaseBarSeries使用DoubleNum

BarSeries series_3 = new BaseBarSeriesBuilder().withNumType(DoubleNum::valueOf).build() // explicit initialize BarSeries with DoubleNum

 

设计和其他可能的实现

如果要编写自己的实现,则Num只需让您的类实现Num接口即可:

public class MyNum implements Num {
    // Override interface functions...
}

例如,您可以使用integerlong作为代理来解决性能与准确性的问题。现有的替代方法BigDecimal可能是Decimal4j

特别注意需要以下Num接口原型

public Function<Number, Num> function(); // required from every class that implements Num..

此函数必须返回一个java.util.Function对象,该对象允许用户和库的其他类将任何Number扩展类(例如Double,Integer,BigDecimal等)转换为Num实现。

现有的实现DoubleNumBigDecimalNum提供静态函数以将转换Number为相应的Num实现类:

    /**
     * Returns a {@code Num} version of the given {@code Number}.
     * Warning: This method turns the number into a string first
     * @param val the number
     * @return the {@code Num}
     */
    public static BigDecimalNum valueOf(Number val) {
        return new BigDecimalNum(val.toString());
    }

function()返回此静态valueOf()函数的lamba表达式以下代码片段显示了BigDecimalNum如何在方法参考的function()帮助下覆盖函数

    @Override
    public Function<Number, Num> function() {
        return BigDecimalNum::valueOf;
    }

处理数字

BarSeries并且Bar需要对此Function对象的引用,该引用能够将任何对象转换Number为所需的Num实现。因此,您必须在Bar手动创建时传递此函数

// The bar object has to transform the intput into Num with help of the given function
Bar bar = new BaseBar(ZonedDateTime.now(),1,3,1,1,1,BigDecimalNum::valueOf);

BarSeries也需要此Function解决此问题的最简单方法是使用SeriesBuilder并将条形数据直接添加到BarSeries:

BarSeries series = new BaseBarSeries.SeriesBuilder().withName("mySeries").build(); // the builder uses BigDecimalNum as default

ZonedDateTime endTime = ZonedDateTime.now();
// add bar data directly. It will be transformed automatically to Num implementation of BarSeries
series.addBar(endTime, 105.42, 112.99, 104.01, 111.42, 1337); 
series.addBar(endTime.plusDays(1), 111.43, 112.83, 107.77, 107.99, 1234);
series.addBar(endTime.plusDays(2), 107.90, 117.50, 107.90, 115.42, 4242);

您可以使用以下功能通过构建器确定Num转换FunctionwithNumTypeOf(function)

BarSeries series = new BaseBarSeries.SeriesBuilder().withName("mySeries").withNumTypeOf(DoubleNum::valueOf).build();


请注意,实例化BarSeries具有特定Num实现的实例后就无法将另一个Num实现中的数据添加到中BarSeries

BarSeries series = BaseBarSeries.SeriesBuilder().build() // implicit initialize with PrecisionNum
series.addTrade(DoubleNum.valueOf(volume), DoubleNum.valueOf(bid)); // try to add DoubleNum values
// throws ClassCastException: org.ta4j.core.num.DoubleNum
// cannot be cast to org.ta4j.core.num.PrecisionNum

评论 [发表评论]
账号 密码 还没帐号呢,现在注册一个?

免责声明:好库网所展示的信息由买卖双方自行提供,其真实性、准确性和合法性由信息发布人负责。好库网不提供任何保证,并不承担任何法律责任。