GithubHelp home page GithubHelp logo

mdeverdelhan / ta4j-origins Goto Github PK

View Code? Open in Web Editor NEW
375.0 97.0 225.0 2.91 MB

A Java library for technical analysis ***Not maintained anymore, kept for archival purposes, see #192***

Home Page: https://github.com/mdeverdelhan/ta4j/issues/192

License: MIT License

Java 100.00%
java technical-analysis java-library trading trading-strategies trading-algorithms bitcoin ripple ethereum litecoin forex

ta4j-origins's Introduction


Important note

Ta4j is not maintained by Marc de Verdelhan anymore. Future PRs and issues will not be treated here. See #192 for more information. This repository is kept for archival purposes and may be used as documentation for ta4j 0.9 (which is a stable version).

The community decided to take over the project and continue to maintain it. The new repository is available at https://github.com/ta4j/ta4j.


ta4j Build Status Chat on Riot.im

Technical Analysis For Java

Ta4 main chart

Ta4j is an open source Java library for technical analysis. It provides the basic components for creation, evaluation and execution of trading strategies.

Features

  • 100% Pure Java - works on any Java Platform version 8 or later
  • More than 100 technical indicators (Aroon, ATR, moving averages, parabolic SAR, RSI, etc.)
  • A powerful engine for building custom trading strategies
  • Utilities to run and compare strategies
  • Minimal 3rd party dependencies
  • Simple integration
  • One more thing: it's MIT licensed

Maven configuration

Ta4j is available on Maven Central. You just have to add the following dependency in your pom.xml file.

<dependency>
    <groupId>eu.verdelhan</groupId>
    <artifactId>ta4j</artifactId>
    <version>0.9</version>
</dependency>

For snapshots, add the following repository to your pom.xml file.

<repository>
    <id>sonatype snapshots</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>

The current snapshot version is 0.10-SNAPSHOT.

Getting Help

The wiki is the best place to start learning about ta4j.

Of course you can ask anything via Twitter. For more detailed questions, please use the issues tracker.

Contributing to ta4j

Here are some ways for you to contribute to ta4j:

See also: the contribution policy.

ta4j-origins's People

Contributors

aster-anto avatar bukefalos avatar clydemachine avatar cu39 avatar dkcm avatar elmoe avatar gcauchis avatar lequer avatar martinklepsch avatar mdeverdelhan avatar nimo23 avatar sirolf2009 avatar team172011 avatar thecookielab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ta4j-origins's Issues

'Rule' not found

Hi
I have added ta4j 0.6 maven repository to my pom file as follows:

eu.verdelhan ta4j 0.6

Unfortunately the
"eu.verdelhan.ta4j.trading" package is not found.
Can you please help me?

Also I have never used sonatype before, can you tell me exactly what lines to paste into my pom file so that I can use your latest snapshot(in case that is the reason for the above error)/

Regards,
RR.

Update Tick.toString method

in Tick.toString method, we try to format a Decimal to a Double:

java.util.IllegalFormatConversionException: f != eu.verdelhan.ta4j.Decimal
    at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
    at java.util.Formatter$FormatSpecifier.printFloat(Formatter.java:2806)
    at java.util.Formatter$FormatSpecifier.print(Formatter.java:2753)
    at java.util.Formatter.format(Formatter.java:2526)
    at java.util.Formatter.format(Formatter.java:2455)
    at java.lang.String.format(String.java:2925)
    at eu.verdelhan.ta4j.Tick.toString(Tick.java:236)
 @Override
    public String toString() {
        return String.format("[time: %1$td/%1$tm/%1$tY %1$tH:%1$tM:%1$tS, close price: %2$f]", endTime
                .toGregorianCalendar(), closePrice);
    }

Maybe closePrice should be replaced with closePrice.toDouble().
Thanks

UnknownFormatConversionException when using toString() for SupportStrategy

When using the toString() method on a strategy that uses SupportStrategy, I'm seeing the following exception:

java.util.UnknownFormatConversionException: Conversion = 'i'

I can see that there is a %i in the toString method for SupportStrategy

@Override
    public String toString() {
        return String.format("%s suport: %i strategy: %s", this.getClass().getSimpleName(), support, strategy);
    }

Is this simply a typo? If so, what should it be?
It seems to work if I put %s instead.

%i also appear in the toString methods for

  • ResistanceStrategy
  • MaxValueStarterStrategy
  • MinValueStarterStrategy

Just let me know what it should be and I can give you a pull request.

Confusing logic/name for IndicatorOverIndicatorStrategy (?)

I always get a bit confused when using the IndicatorOverIndicatorStrategy. Perhaps it's just me, but the name IndicatorOverIndicatorStrategy suggest to me that we look at one indicator and see if it is over the other :-)

Since the input to this indicator is two indicators, it would make sense to give them in the order
new IndicatorOverIndicatorStrategy(shortSma, mediumSma)
if I want the strategy to execute when the shortSma is over the mediumSma. But the indicator works the exact opposite way, checking if the first indicator is less then the second one, so we have to give them in reverse order.

Any reason why this is the case, or is it just a legacy from tail?

ta4jexamples: question about BuyAndSellSignalsToChart.java

I have a questions about the mentioned example. In the class file is a method called 'buildChartTimeSeries':

private static org.jfree.data.time.TimeSeries buildChartTimeSeries(TimeSeries tickSeries, Indicator indicator, String name) {
org.jfree.data.time.TimeSeries chartTimeSeries = new org.jfree.data.time.TimeSeries(name);
for (int i = 0; i < tickSeries.getTickCount(); i++) {
Tick tick = tickSeries.getTick(i);
chartTimeSeries.add(new Minute(tick.getEndTime().toDate()), indicator.getValue(i).toDouble());
}
return chartTimeSeries;
}

Question: Why is the 'indicator' argument needed for this method?

You could change:
chartTimeSeries.add(new Minute(tick.getEndTime().toDate()), indicator.getValue(i).toDouble());
into:
chartTimeSeries.add(new Minute(tick.getEndTime().toDate()), tick.getClosePrice().toDouble();
because the method is called with 'ClosePriceIndicator(series)' for 'indicator'

(just to keep the method flexible?)

Cache dilemma

Given that almost all indicators are now cached I get a dilemma about removed results when using cache with a maximum tick count on a time series.

Context
A 20-ticks-long time series with a max tick count set to 3. We calculate a SMA(2) on the close prices of this series.

Problem
Calling sma.getValue(19) (i.e. most recent value). None of the SMA results have been previously cached. So we start by resizing the cache array to a size of the max tick count (i.e. 3), then we compute all the still-uncomputed values:
sma.getValue(17) needs the close prices at indexes 17 and 16. The close price indicator results are not either cached, then we look for cp.getValue(16) directly in the series (i.e. getTick(16).getClosePrice()).
--> Error: The 16-th tick is not in the series anymore (as it was removed in the setMaximumTickCount(3)).

What to do?
I don't know exactly what to do in this case. I found several solutions for now:

  1. getTick(X) where X <= (series.getEnd()-series.getMaximumTickCount()) should return the same result as getTick(series.getEnd()-series.getMaximumTickCount()+1) (i.e. the first still-in-memory tick) and should not throw any exception.

  2. getTick(X) where X <= (series.getEnd()-series.getMaximumTickCount()) should still throw an exception. This exception has to be catched in the CachedIndicator#getValue() method. A custom exception class should be used. This is the solution which has been currently chosen (without the custom exception for now).

  3. getTick(X) where X <= (series.getEnd()-series.getMaximumTickCount()) should still throw an exception. The CachedIndicator class could detect by itself if a tick has already been removed. Then it could avoid trying to getTick() it.

Typical enter rule parameters to test for intra day

Hi, I recently saw ta4j. First of all thanks for contributing and sharing. I wanted to test out some of the indicators in India NSE market for intra day. Was trying with the moving momentum example which has been shared. However my enter rule was not getting satisfied. I might be missing something. I was taking a 10 second interval. In that interval I am finding open, close, high, low and traded volume. With that 10 second data I am creating a tick and adding to a time series. I initialized time series with maximum 100 ticks. Wanted to check if I am configuring it right.

Possible update for TimeSeries.run()

Currently, when running TimeSeries.run(strategy), the tradingRecord does not record the entry price for the trade ( with the use of operate(i) ), it always return Decimal.NAN. So the StopLossRule and the StopGainRule never actually work when used like that.
Now that you have TradingRecord.enter() and TradingRecord.exit(), is it possible to pass the trade amount and store the entry price when running the strategy?

Something along those line?

    public TradingRecord run(Strategy strategy, OrderType orderType, Decimal amount) {

        log.trace("Running strategy: {} (starting with {})", strategy, orderType);
        TradingRecord tradingRecord = new TradingRecord(orderType);

        for (int i = beginIndex; i <= endIndex; i++) {
            // For each tick in the sub-series...
            if (strategy.shouldEnter(i, tradingRecord)) {
                tradingRecord.enter(i, amount, ticks.get(i).getClosePrice());
            }
            if (strategy.shouldExit(i, tradingRecord)) {
                tradingRecord.exit(i, amount, ticks.get(i).getClosePrice());
            }
        }
// ....

Thank you for the consideration.

RSI Divide by zero issue

Hi,

Perhaps I'm misunderstanding how to use things here, but when I do the following:

closePriceIndicator = new ClosePriceIndicator(timeSeries);
rsiIndicator = new RSIIndicator(closePriceIndicator, 5);

Then proceed to call "getValue();" I get:

rsiIndicator.getValue(0); // 0;
rsiIndicator.getValue(1); // Divide by zero exception.

The data in my closePriceIndicator is fine and works as expected. I'm expecting values between 0 and 100 that correspond to the RSI Values at the respective dates.

I'm using the jar from maven central: ta4j-0.5

Thanks!

VWAP, MVWAP, TWAP, TMA and WMA

Not sure if they are implemented and I'm just not seeing them, but I would be interest in seeing these indicators implemented.

Sense of Decimal class?

I don't understand the purpose of the Decimal class: what is the benefit of using decimal numbers instead of timeseries data?

How to get a TradingRecord when using chooseBest() ?

It's been a while since I used ta4j, and I've spent some time getting my application up to date with 0.8-SNAPSHOT.
One thing we had before is Decision, which could be used when evaluating multiple strategies, something along these lines:

List<Strategy> strats = new ArrayList<Strategy>();

strats.add(...);

TotalProfitCriterion criterion = new TotalProfitCriterion();
Decision dec = criterion.chooseBest(series, strats);
dec.evaluateCriterion()

You would then know the criterion value for the chosen strategy.

My understanding is that Decision has now been replaced (kinda) by TradingRecord.
I was wondering if it's possible to get a TradingRecord when using chooseBest(), without rerunning the strategy returned by chooseBest() ?

I'm currently doing something along these lines, which means that the chosen strategy is executed twice; once when evaluating it against the other strategies, and then again to get a TradingRecord:

TotalProfitCriterion criterion = new TotalProfitCriterion();
Strategy strategy = criterion.chooseBest(series, strats);

TradingRecord tradingRecord = series.run(strategy);
criterion.calculate(series, tradingRecord);

Is there any way of avoiding executing the strategy twice in order to get a TradingRecord?

Time scale in time series

The problem I am facing is that I want to show weekly charts in my web page, but I am downloading data from a provider which only returns daily data. It would be nice if you could create the TimeSeries with daily data and then call to a function which would return weekly data instead of daily.

Improve Decimal performances

Following #19 I would like to improve the performance of the Decimal class.

I think the internal BigDecimal could be replaced by a less memory-and-cpu-expensive thing. It can be achieved by reducing the abilities of these decimal numbers. Thus:

  • The maximum scale can be 16.
  • The maximum precision can be 32.
  • For now we don't need more math operations than the Decimal class is already providing.

Division by zero in updated WalkForward example

When running the updated WalkForward example with release 0.5, I'm now seeing:

Exception in thread "main" java.lang.ArithmeticException: Division by zero
    at java.math.BigDecimal.divide(BigDecimal.java:1669)
    at eu.verdelhan.ta4j.TADecimal.dividedBy(TADecimal.java:117)
    at eu.verdelhan.ta4j.indicators.trackers.RSIIndicator.relativeStrength(RSIIndicator.java:66)
    at eu.verdelhan.ta4j.indicators.trackers.RSIIndicator.getValue(RSIIndicator.java:47)
    at eu.verdelhan.ta4j.indicators.trackers.RSIIndicator.getValue(RSIIndicator.java:34)
    at eu.verdelhan.ta4j.strategies.SupportStrategy.shouldEnter(SupportStrategy.java:57)
    at eu.verdelhan.ta4j.strategies.CombinedBuyAndSellStrategy.shouldEnter(CombinedBuyAndSellStrategy.java:52)
    at eu.verdelhan.ta4j.strategies.AndStrategy.shouldEnter(AndStrategy.java:51)
    at eu.verdelhan.ta4j.strategies.AbstractStrategy.shouldOperate(AbstractStrategy.java:37)
    at eu.verdelhan.ta4j.TimeSeries.run(TimeSeries.java:235)
    at eu.verdelhan.ta4j.TimeSeries.run(TimeSeries.java:219)
    at ta4jexamples.walkforward.WalkForward.main(WalkForward.java:80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Add caching mechanism to all indicators

As performances dramatically decreased since I added TADecimals I plan to generalize the cache system which exists in the CachedIndicator class to all indicators (and not only the recursive ones).

I plan to use the Guava library to do that (see note below). It seems to provide local caching with an interesting variety of expiration behaviors.
A first version could be a simple replacement of the internal logic of the CachedIndicator class using a Guava CacheLoader. Then 2 questions arise:

  • What should be the eviction/removal policy? For now I thank about size-based eviction with an arbitrary size of 100 entries per indicator. But maybe there is a more intelligent strategy.
  • As the cache can be considered as an enhanced map, what should be the keys? If the values are the results returned by the Indicator#getValue(int index), it seems relevant to use the index integer as the key. But what if I remove the first entry of a TimeSeries (as I plan to add the possibility)? Then all the cached value would be shifted compared to the series indexes, which is a problem. No idea for now, maybe we could address this last issue later.

Note: I don't like to add a dependency like Guava to use only one of its features. In the future our usage of Guava should be extended to, at least, null and preconditions checkings

Missing 'Period timePeriod' in full Tick constructor

Hello, this is the first time I send an issue, let me know if this is not the right place:

In the complete Tick constructor, the period is always set to days(1). I need to be able to set the period in the constructor as the same time as the prices. Yet I cannot override the field as it is set to private.

public Tick(DateTime endTime, Decimal openPrice, Decimal highPrice, Decimal lowPrice, Decimal closePrice, Decimal volume) {
        this.timePeriod = Period.days(1);
        ...

could we have instead

public Tick(DateTime endTime, Period timePeriod, Decimal openPrice, Decimal highPrice, Decimal lowPrice, Decimal closePrice, Decimal volume) {
        this.timePeriod = timePeriod;
        ...

Incorrect EMA calculation

There is discrepancy in EMA calculation formula in class: eu.verdelhan.ta4j.indicators.trackers.EMAIndicator

Current formula : return ((indicator.getValue(index).doubleValue() - emaPrev) * multiplier()) + emaPrev;

With Correction : return indicator.getValue(index).doubleValue() * multiplier() + emaPrev * (1-multiplier());

How to create timeseries with only close prices?

HI,
I have a mysql database with close prices of several stocks.
They are daily close prices
I want to create a timeseries, but your example shows only how to do it with csv files.
Can you please help me with this?

P.s: Congratulations on building a wonderful library.
Regards,
Bhargav.

Parabolic SAR

Hallo,

I am wondering whether there are some problems in the parabolic SAR indicator.

I compare the results with what I got in the MT4 platform. There apparently more flip point according to your calculation. Therefore, could you double chk your implementation?

Cheers,

Question: Quickstart example

I was trying to get the Quickstart example working so I created a project with that class as well as CsvTradesLoader. The below gist is the csv I was using, also I commented out the "Cutomizing our strategy" (lines 59-65) section of Quickstart to make things a little simpler. If the strategy is to trade when the SMA lines cross I would have expected to see a few trades come out, but I didnt. Below is the output I saw. I couldn't understand what is going on in HistoryRunner.run().

First close price: 175.17 12:00 03/02/2014
true
Number of slices: 54
Number of trades for our strategy: 0
Number of trades for reference strategy: 0
Total profit for our strategy: 1.0
Total profit for reference strategy: 1.0

https://gist.github.com/kmulvey/11211604

Google graph of the same data:

https://www.google.com/finance?chdnp=1&chdd=1&chds=1&chdv=1&chvs=maximized&chdeh=0&chfdeh=0&chdet=1398252600348&chddm=29716&chls=IntervalBasedLine&q=NYSEARCA:IVV&ntsp=0&ei=H6RXU5ibHsOr6QGQzAE

Runner class OperationType

When Runner class is used without OperationType it should take the first matching buy or sell action instead of always buying first and selling subsequently. The other constructor wherein we can set the OperationType may not suffice since in certain trading scenario we may NOT have preference for going long or short initially and it should be driven by whichever condition is met first.

Contributing enhancements?

Hi,
i created a bit of code:

  • a trailing stop loss indicator
  • a class to flexibly convert between common objects of ta4j (jfree-timeseries, ta4j-timeseries, ticklists, indicators etc.)

I think about contributing the code to the project after some more testing, what do you think?

If ok:

  • in which packages would you store the code?
  • for the testing of the conversion class i use some real world tick series with different frequencies. Do you have a standard set of time series to test new code or should i also contribute them with the corresponding tests?
  • do you have a policy to handle new dependencies to ta4j? For the conversion class it would be needed to add org.apache.commons.math3.stat.* and org.jfree.data.time.*

Best regards,
E.

BB indicators’ multiplier K to be variable

I am planning to edit BB upper/lower indicators for their multiplier (usually called K) to be variable. Currently K is hard-coded as Decimal.TWO. ref1 ref2

Two ways of implemantation:

  1. Creating a new abstract class for BB upper/lower and implement properties onto it.
  2. Implementing new prop on each of them independently.

Opt 1 is rather OOP and DRY approach but the name of new abstract is another question for me.
Opt 2 is viable for simple classes like them, though not DRY.

I would appreciate any suggestion from maitainer.

Improve strategy building engine

The current strategy building engine is a mess.
It comes with several problems, of which:

  • There is no simple way of building an entry strategy independently of an exit strategy.
  • In some case we may use entry rules in exit strategy (and reciprocally), the engine doesn't allow this easily.
  • For each strategy provided by ta4j we don't know, a priori, if it's a more-entry strategy, a more-exit one, or a both one.

I plan to refactor all the strategy building engine. I would keep the strategy concept but they would be constructed with an entry rule and an exit rule. Each rule will be truly independent of each other.

Question regarding EMAIndicator Calculation

Hi,

Just a quick question, why does the EMAIndicator use an SMAIndicator when the index is less than the input timeframe?

Reference:
Line 52: EMAIndicator.java

Thanks!

Keep up the great work

Performance enhancements?

Just wondering if you are aware of any possible performance improvements that could be implemented, but that you haven't had time to look into yet?
I haven't looked in detail into the new code using TADecimal, and I haven't performed any detailed measurements, but it when backtesting multiple strategies at once it feels like the cost of improved accuracy is a severe decrease in performance overall.

HMA Indicator

To create a new Indicator for Hull Median Average:

The formula is:

WMA(2*WMA(PRICE, n/2) - WMA(PRICE, n), sqrt(n))

and WMA(PRICE, n) is defined as

( PRICE * n + PRICE(1) * n-1 + ... PRICE(n-1) * 1) / ( n * (n + 1) / 2 )

Performance issues with recursive methods

Hi,

I just recently started looking at ta4j, and I really like the look of it so far. However I've been wondering how come performance seems pretty slow even for operations that should be pretty simple. After poking around in the code I realize that there are recursive calls being used in different indicators. Perhaps there is a good reason for this, but it looks to me like this is really killing the performance. Perhaps I'm using the components in the wrong way, but I built almost all of my code on top of the given examples.

For the sake of discussion I'll refer to the MovingMomentumStrategy from ta4j as an example, the code is fairly straightforward.

ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
EMAIndicator shortEma = new EMAIndicator(closePrice, 9);
EMAIndicator longEma = new EMAIndicator(closePrice, 26);

IndicatorOverIndicatorStrategy shortEmaAboveLongEma = new IndicatorOverIndicatorStrategy(longEma, shortEma);

So we use a ClosePriceIndicator combined with two EMAIndicators to create a IndicatorOverIndicatorStrategy.

To determine if a trade should be initiated, the following statement is ran IndicatorOverIndicatorStrategy.

@Override
public boolean shouldEnter(int index) {
    return (first.getValue(index) < second.getValue(index));
}

getValue() in this case will be the recursive function in EMAIndicator.

@Override
public Double getValue(int index) {
        if (index + 1 < timeFrame) {
            return new SMAIndicator(indicator, timeFrame).getValue(index);
        }
        if(index == 0) {
            return indicator.getValue(0).doubleValue();
        }
        double emaPrev = getValue(index - 1).doubleValue();
        return ((indicator.getValue(index).doubleValue() - emaPrev) * multiplier()) + emaPrev;
}

Since this metod takes index as the only parameter, it will calculate the value of the EMAIndicator for the entire timeseries up until the current tick for EVERY call to the method.

I tried adding a static counter to see the result for MovingMomentumStrategy, and getValue() get called more than 73 million times.

Now I'm not that familiar with the arithmetic behind the indicators, but
wouldn't it be possible to just calculate the indicators once for the entire timeseries and get a huge performance increase?

Tick.inPeriod() bug?

I have a lot of recorded ticks (price + volume), and sometimes a few have exactly the same timestamp.

For this example, I want all my ticks to be collected within a TA4J Tick instance with period 1 second.

I use this code to round off my timestamp to nearest second:
new_ts = ((ts + 500) / 1000) * 1000;

I keep track of lastTick, to see if this new tick is on the same second as last, and if so, I call addTrade instead.

if (lastTick != null && lastTick.inPeriod(d)) {
        lastTick.addTrade(tradeAmount, tradePrice);
        return lastTick;
    }
    else {
        Tick newTick = new Tick(Period.seconds(1), d);
        lastTick = newTick;
            newTick.addTrade(tradeAmount, tradePrice);      
            series.addTick(newTick);
    return newTick;
    }

Now the problem:
inPeriod() returns false if endTime is equal or less to the given timestamp. Since all ticks within a second will end up having the same ts, inPeriod() must return true.

My fix was:

public boolean inPeriod(DateTime timestamp) {
    return timestamp != null
            && !timestamp.isBefore(beginTime)
            /* bugfix that works for me: endTime is included in period! */
            &&  (timestamp.isEqual(endTime) || timestamp.isBefore(endTime));
}

Is this the wrong way to "fix" the problem that will cause unwanted sideeffects later? Is it better if I "clean" my data and concatenate all ticks to a single tick or....what? Please guide me.

StopLossRule does not work

Hello, I am not able to make the StopLossRule work.
For example

ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
RSIIndicator rsiIndicator = new RSIIndicator(closePrice, 40);
Rule entryRule = new CrossedUpIndicatorRule(rsiIndicator, Decimal.valueOf(60));
Rule exitRule = new StopLossRule(closePrice, Decimal.valueOf("1"));

does give me zero trades, it does not get out of trade even at real series where stop loss rules are satisfied. Also tried with

Rule exitRule = new StopLossRule(closePrice, Decimal.ONE);

and getting zero trades.
Thank you

Question: Do we have a strategy to exit after x number of ticks?

We have the NotTooFast strategy which waits for a number of ticks between enter and exit, and then exists according to the given strategy. Do we currently have anything for the opposite, e.i.
enter and then after x number of ticks, or according to the provided strategy if it happens before x number of ticks?

Make 'Tick' serializable

The 'Tick' object is very central to the whole process, but it is not serializable. This means that it could not, for example, be natively serialized and sent over a message bus, such as Rabbit MQ.

I solved this problem myself by extending Tick and making it JSON-marshallable, using Jackson, but do you think it is reasonable for Tick object itself, in Ta4j to also be serializable?

I'm happy to do a PR (with tests) if you think this is worthwhile.

Regards,
James

What about specialized strategies?

For longterm investing there is often a period of time when you just need a buying strategy or a selling strategy - not both at the same time. What about offering specialized strategies for buying and selling seperately with just one argument for the rule set in the constructor?

EMAIndicator Unknown Stack Overflow

I've been using this for a little while, and everything runs perfectly on my backtests. However, I've been performing preliminary tests for live trading, and consistently receive a stack overflow error for the EMAIndicator.

Exception in thread "Timer-0" java.lang.StackOverflowError
    at java.lang.Class.getSimpleName(Class.java:1306)
    at eu.verdelhan.ta4j.indicators.CachedIndicator.getValue(CachedIndicator.java:78)
    at eu.verdelhan.ta4j.indicators.trackers.EMAIndicator.calculate(EMAIndicator.java:58)
    at eu.verdelhan.ta4j.indicators.trackers.EMAIndicator.calculate(EMAIndicator.java:33)
    at eu.verdelhan.ta4j.indicators.CachedIndicator.getValue(CachedIndicator.java:83)
    at eu.verdelhan.ta4j.indicators.trackers.EMAIndicator.calculate(EMAIndicator.java:58)
    at eu.verdelhan.ta4j.indicators.trackers.EMAIndicator.calculate(EMAIndicator.java:33)

Note that I have a task that runs at a fixed interval to process all incoming trades and submit a tick to the trader.

A little bit more. I have set the maximum tick count for the time series to 225, which is more than needed for the EMAIndicator I have configured on a 26 tick period. The longest indicator I have is a 200 period SMAIndicator.

In all likelihood this is an error that is probably in my implementation, however, I've been trouble shooting for hours, and have come up empty handed. I was hoping you might have some advice.

Previously when I was attempting to fix this, I was sending ticks that had zero trades in them, and I have now prevented those from being sent to the trader. This is done as per the CsvTradesLoader.java example.

Tests failing in JDK8

Failed tests: toStringMethod(eu.verdelhan.ta4j.analysis.criteria.AbstractAnalysisCriterionTest): expected:<'[Average ]Profit'> but was:<'[]Profit'>

Forbid to create a sub-series from a series with a maximum tick count

Creating a sub-series from an original series with a maximum tick count results in weird behaviors around getTickCount() calls.
Mainly 2 causes:

  • the maximum tick count is not always forwarded.
  • the internal list of ticks is shared between orginal series and sub-series.

E.g.:

seriesWith5Ticks.setMaximumTickCount(2);
TimeSeries subSeriesWith3Ticks = seriesWith5Ticks.subseries(0, 2);
subSeriesWith3Ticks.setMaximumTickCount(1); // Such a weird state?!!

Solution: We need to forbid any subseries() call if a maximum tick count has been set. Partly revert this commit.

Note: Special case for previously created sub-series when setting the maximum tick count.

question: When buy/sell

Hi
I have a little understanding problem.

I thought that strategy.shouldEnter(endIndex) is for buy. But, I think my thought is not correct. strategy.shouldEnter(endIndex) is for sell. Correct?

Average gain and average loss with memory.

There are two ways of calculating average gain and average loss.

Without memory:
Average Gain = Sum of Gains over the past period / period
Average Loss = Sum of Losses over the past period / period

With memory:
Average Gain = [(previous Average Gain) x (period -1) + current Gain] / period
Average Loss = [(previous Average Loss) x (period - 1) + current Loss] / period

http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi

Is there any plan to add an option to use the indicator with memory?

TimeSeries length or size

Hey,
First of all - thanks for the great work! Love this project - have it embedded in the myopentrader engine for quite some time.

I noticed that you never return the length/size of the timeSeries? In a lot of cases, I need to convert my data into a timeSeries, but I am only interested in the last one or two elements (without knowing, how many ticks are within one timeSeries at a time). I forked your repository, to add the
public int size() {
return ticks.size();
}
to the TimeSeries class. Did u not add it because it may contain stale data during caching?

Thanks :)
Stephan

Mocks for users?

Mock classes inside eu.verdelhan.ta4j.mocks package are useful for ta4j users to test their custom indicators and analysis criteria or to learn things in trial and error, while they're unavailable since mocks reside in src/test/java.

How about moving them to src/main/java ?

About common interface for TimeSeries and Indicator<Decimal>

The library now contains TimeSeries and Indicator. They both offer access to values by index. So, they actually provide the same functionality.

AnalysisCriterion inferface is very good because it offers an easy way to write different implementations for different criteria. However, the AnalysisCriterion always requires TimeSeries to calculate values.

I would like to use AnalysisCriterion to calculate values from some Indicators. I think creating a common interface for both TimeSeries and Indicator would simplify the code and make it easier to use. I could e.g. calculate total profit using either average or close values by just creating a new indicator. I might also want to calculate AnalysisCriterion from a couple of indicators, e.g. an analysis criterion would include two risk-related indicators.

E.g. AnalysisCriterion could be called by
double calculate(CommonTimeSeriesIndicatorInterface interface, List trades);

MaxValueStarterStrategy

Suggest adding a new strategy that enters when an indicator's value is less than a threshold (see code snippet below). Happy to implement the feature if you like.

@OverRide
public boolean shouldEnter(final int index) {
return (indicator.getValue(index).doubleValue() < start);
}

Strategy compatible?

So I'm looking over porting a multi-symbol, multi trade with hedging strategy to see if I can backtest. Until now it's been impossible to backtest due to the fact it hedges on multiple symbols. Do you think I could use this library to record this succesfully? in Both backtesting and Live trading?

This is kind of the list of things I need to find a way for it to do:

  1. Send out multiple buys and sell orders (up to 6, each could be a different trade/rule). Which ever buy or sell side gets triggered, an "exit" trade gets made, and then adjust dynamically to different "take profit" targets as the market/tick series move.
  2. Have a way to cancel/reset the trades and re-send them out. Eg. initial trades are sent at X distance from current market price, these trades cancelled after 30 minutes of inactivity, new trades are sent out at X distance from the "new current market price".
  3. Once a designed level of Loss or profit has been achieved, send out immediate close orders for all trades (all 6 or however many are open).
  4. IF an initial trade reach a desired level of loss, trigger to open a hedge on a different symbol. (I"m guessing this would require to make a new time series for the hedging strategy on the new hedge symbol that either runs simultaneously, or is activated when the "hedging" is triggered through an IF statement. The hedging strategy and time series would need to "sync" up with the original strategy to know when to activate/deactivate. The trades generated would also be recorded with the initial strategy somehow!
  5. The P&L should record successfully if all this works, but my concern would be live trading. Where should I insert the trade recording? Seems like I'd want the broker to send a "trade confirmation" and upon the broker "confirming" the trade was executed, then I would enter the trade into the traderecord and continue with the strategy?
  • Do all these things seem feasible? If so, any examples you have that are closest?

I became interested in this library, because I was looking for some API that had all the indicators I use to determine trading rules, without having to program them all myself :) like 3 different Moving averages, crosses over different time periods etc.

Right now, I was just basically planning to model a FIX engine simulator, have it send all the market data to the strategy, and dummy make a trade confirmation. Then record the trading record and evaluate the results after, but this TA library seems useful for backtesting as well.

(Attaching a screenshot, so u can see what kind of strategy I'm looking at, the main purpose for this GUI was just to monitor, stop/start the strategy with optional "kill" buttons for positions and hedging strategy separately.)
strategyscreenie

Error in standard deviation calculation

The PR #23 noticed an error in the Standard Deviation indicator.

The fix should be something like:

@Override
protected TADecimal calculate(int index) {
    TADecimal standardDeviation = TADecimal.ZERO;
    TADecimal average = sma.getValue(index);
    final int startIndex = Math.max(0, index - timeFrame + 1);
    for (int i = startIndex; i <= index; i++) {
        TADecimal pow = indicator.getValue(i).minus(average).pow(2);
        standardDeviation = standardDeviation.plus(pow);
    }
    standardDeviation = standardDeviation.dividedBy(TADecimal.valueOf(index-startIndex)); // +1 or -1 or not
    return standardDeviation.sqrt();
}

Tests also have to be updated.

See also http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:standard_deviation_volatility

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.