Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: trade-dependent indicators #757

Closed
wants to merge 17 commits into from

Conversation

MarcDahlem
Copy link
Contributor

@MarcDahlem MarcDahlem commented May 7, 2021

Fixes #742.

Changes proposed in this pull request:

  • Allow trade based indicators, which can easily calculate their values by using the last executed trade

  • Added a break even indicator based on the last executed entry position

  • added an entry with related ticket number(s) to the unreleased section of CHANGES.md

@MarcDahlem MarcDahlem changed the base branch from master to develop May 7, 2021 12:30
@MarcDahlem MarcDahlem changed the title WIP: Feature/position indicators WIP: Feature/trade indicators May 7, 2021
@MarcDahlem MarcDahlem marked this pull request as ready for review May 7, 2021 17:34
@MarcDahlem MarcDahlem changed the title WIP: Feature/trade indicators Feature: trade-dependent indicators May 7, 2021
@MarcDahlem MarcDahlem mentioned this pull request May 7, 2021
2 tasks
@nimo23 nimo23 mentioned this pull request May 13, 2021
1 task
Copy link
Member

@team172011 team172011 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reservation against this indicator type. Similar to #761 why should we mix up Trades and indicators? Wouldn't a Rule be the place for such a decisions? In a Rule you have access to the TradingRecord of the current run. Having access to a TradingRecord in an Indicator means that you have to create another Strategy with Rules and Indicators and so on just to apply this TradingRecord to this indicator. There may be special cases for this, but I am not sure if ta4j should support this by default and within the current architecture of this framework

CHANGELOG.md Outdated
@@ -17,6 +17,8 @@ Changelog for `ta4j`, roughly following [keepachangelog.com](http://keepachangel
- :tada: **Enhancement** Added possibility to use CostModels when backtesting with the BacktestExecutor
- :tada: **Enhancement** added Num#zero, Num#one, Num#hundred
- **Example** added a json serialization and deserialization example of BarSeries using google-gson library
- :tada: **Enhancement** Implemented an (abstract) TradeBasedIndicator, which can perform calculations based on the last trade
- :tada: **Enhancement** Implemented a BreakEvenIndicator, which returns the needed break even regarding the last trade according to given transaction fees
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change Implemented ... to Added ...

Copy link
Contributor Author

@MarcDahlem MarcDahlem May 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reservation against this indicator type. Similar to #761 why should we mix up Trades and indicators? Wouldn't a Rule be the place for such a decisions? In a Rule you have access to the TradingRecord of the current run. Having access to a TradingRecord in an Indicator means that you have to create another Strategy with Rules and Indicators and so on just to apply this TradingRecord to this indicator. There may be special cases for this, but I am not sure if ta4j should support this by default and within the current architecture of this framework

Mhm, not sure if that can be handled in Rules. If you have any ideas how to do it, I'm open to every suggestion.

I use the trade-based indicator quite much in my trading bot.
Examples:

  • Break even indicator
    • --> if break even is reached, the exit criterion of the strategy is changed (needs only true and false)
    • --> place an order 2% above the break even (needs the concrete value/Num of the break even for every trade. Thats why it is an "calculator"(Indicator) and not a "condition"(Rule))
  • Lowest/highest since last sell
  • Restart of rules/conditions after a sell
    • --> example: Buy if EMA(20)>EMA(200). Sell on 2% gain. Without a "reset", the bot would directly buy again if the EMA(20) is still over EMA(200).
  • BuyPrice-Indicator --> Indicator which holds the buy price during the lifetime of a trade
  • IsBuyPhase indicator ..> true if in BuyPhase and false if not
  • ...

If it is an indicator, other indicators and rules can easily depend on it.
For example TransformIndicator.muplitply(breakEvenIndicator, 1.04) directly contains the value which is 4% above the break even in EVERY Buy-Phase. new OverIndicatorRule(closePrice, breakEven) is true if the break even is reached...No need to handle multiple indicators, swich rules, swich strategies, adapt indicators... The only thing that must be handled is storing TradingRecords in my bot on every real executed trade on the market while it is running.

And those indicators can easily be used also in backtesting. They are really powerful!

@nimo23
Copy link
Contributor

nimo23 commented May 16, 2021

Wouldn't a Rule be the place for such a decisions? In a Rule you have access to the TradingRecord of the current run.

Yes, I also think you should create a new Rule instead of an Indicator. Because Indicator is linked with Bars and nothing else. I will look to create a new PR CriterionRule which is an improvement over #761. Maybe this CriterionRule is also sufficent for your use case. If not, please create a new Rule and call it BreakEvenRule.

@nimo23
Copy link
Contributor

nimo23 commented May 16, 2021

After rethinking, I guess, such trade based decisions would not be solely possible with a Rule because we need the already executed TradingRecord (till the observed index) to look for. We need to add Indicators within Rules to determine if the Rule is satisfied. That's why we could make use of the CriterionIndicator (from #761) within a Rule (but a Rule cannot replace the CriterionIndicator). In this context, this also means that it would not be easily possible to replace the TradeBasedIndicator with a Rule.

To demonstrate this, look at the following code which ought to replace the CriterionIndicator with a CriterionRule:

/**
 * Criterion rule.
 * 
 * <p>
 * Satisfied when the AnalysisCriterion satisfies a required criterion value.
 */
public class CriterionRule extends AbstractRule {

    private final BarSeries barSeries;
    private final AnalysisCriterion criterion;
    private final Num requiredCriterionValue;

    /**
     * @param barSeries              the bar series
     * @param criterion              the criterion to get the calculated criterion
     *                               value on a bar index
     * @param requiredCriterionValue the required criterion value to test against
     *                               the calculated criterion value
     */
    public CriterionRule(BarSeries barSeries, AnalysisCriterion criterion, Num requiredCriterionValue) {
        this.barSeries = barSeries;
        this.criterion = criterion;
        this.requiredCriterionValue = requiredCriterionValue;
    }

    @Override
    public boolean isSatisfied(int index, TradingRecord tradingRecord) {
        boolean satisfied = false;
        if (tradingRecord == null || tradingRecord.getPositions().isEmpty()) {
            satisfied = false;
        } else {
            Num calculatedCriterionValue = criterion.calculate(barSeries, tradingRecord);
            satisfied = criterion.betterThan(calculatedCriterionValue, requiredCriterionValue)
                    || calculatedCriterionValue.isEqual(requiredCriterionValue);
        }
        traceIsSatisfied(index, satisfied);
        return satisfied;
    }
}

You see that the tradingRecord cannot be filled without another rule or indicator. That's also the case for this TradeBasedIndicator - you cannot replace it solely by a Rule.

I think this TradeBasedIndicator (and the CriterionIndicator) has its need. Because currently, it is impossible to create a decision solely by a TradingRecord.

@team172011
Copy link
Member

I think we have to distinguish between different use cases: live trading (e.g. implementing a bot) and backtesting. So far the only use case for AnalysisCriterions in ta4j has been backtesting.

  • After creating one or several Strategies you can execute them and get the results in form of TradingReports. After that you can analyze results by using AnalysisCriterions. It makes no sense here to have a backtesting run with Indicators that depend on an AnalysisCriterion and this criterion depends on a TradingRecord (that needs to be the result of another run?).

  • For live trading once could imagine use cases where you need access to the TradingRecord and the (current) value of an AnalysisCriterion and where you want to implement logic that modifies the TradingRecord and so on. If you are using it in a trading bot for live trading this is also fine, but there is no general concept for using it together within an Indicator and/or AnalysisCriterions during a session.

We cannot add trade based indicators or criterion based indicators to this lib just because you are using it during live trading in a specific situation. It will get confusing for the user if we mix things up this way.
I am open for improvement or extension for more live trading support in ta4j. But first we need a general and separated concept for live trading that can be discussed.

@MarcDahlem
Copy link
Contributor Author

MarcDahlem commented May 16, 2021

For the moment, I dont need Crtierion.

I personally need Indicators, which can calculate their current value according the the current trade state.
Especially LowestSinceLastExit and BreakEven and BuyPrice are very important indicators for me.
I need them especially during backtesting!

For live-trading I could workaround that by replacing my complete strategy with new indicators and rules as soon as a position changed.

But for Backtesting, I need calculators, which change if the last position is opened, closed or there is no last position. (And here I cannot change the complete Strategy and indicators, because Backtesting would not work). There are simple features like wait at least 200 ticks after an exit. Or get the current buy price in running open positions to calculate borders for gain and loss accordingly.

Its no problem for me if you are not interested in this (in my opinion very useful) indicator and dont want to merge it into your project.

--> PR closed

@MarcDahlem MarcDahlem closed this May 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants