freqtrade / freqtrade

Free, open source crypto trading bot
https://www.freqtrade.io
GNU General Public License v3.0
28.73k stars 6.16k forks source link

position mgmt (Position stacking / pyramiding) #1519

Closed yaotian closed 2 years ago

yaotian commented 5 years ago

buy or sell in several steps according to the signal.

For example as bb band strategy,

  1. buy signal: cross up low band, buy 50% position
  2. buy signal again: cross up middle band, buy another 50% position.
  3. sell signal: cross down high band, sell 50% 4, sell signal again: cross down middle band, sell 50% position.

FT supports these use cases?

gaugau3000 commented 5 years ago

@yaotian For the moment i think :

xmatthias commented 5 years ago

we have another issue already tracking position stacking #1099, which is basically asking the same (but formulated slightly different i think).

yaotian commented 5 years ago

@xmatthias this feature is very useful.

Based on my experience, A good strategy to make money successfully MUST have two reason: 1. trend (which can use indicators to make this) 2. position ( high risk price use low position, but latter it changes to low risk, it can buy more)

4oplay commented 5 years ago

Hello, lets implement this asap! this should be a freq trade bot :) @xmatthias this feature is very useful.

hroff-1902 commented 5 years ago

I'm working on it...

pantheoncap commented 5 years ago

Please leave me a mail at eqaq131@gmail.com, would like to share the approach

hroff-1902 commented 5 years ago

I'll report here.

ovidiu162000 commented 5 years ago

Also interested in this feature. Any progress on this @hroff-1902 ? Let me know if I can help in any way. Would be more than happy to assist on this.

Tamei commented 4 years ago

Is this still a thing? Would love to see this feature

hroff-1902 commented 4 years ago

yes, it's still an open issue which waits its time, we are moving step-by-step to the goal...

pnmartinez commented 4 years ago

yes, it's still an open issue which waits its time, we are moving step-by-step to the goal...

I know this may be too much to ask, but it would be awesome if you could share the roadmap, the current status, or a summary of the code yet to write.

xmatthias commented 4 years ago

I'm sorry, but we are an open source project. all of us spend our free time voluntarily working on this project - so we do not provide timing plans - as timing solely depend on the fact that some has time and interrest to work on this issue.

The status is - it is not implemented at the moment. It might be a small change - could be a big change - would need a deeper investigation first (and depends on the 2nd point below).

There are however a few unclear points to me with this issue... and i'm not sure all have a clear answer.


First of all - this will be a very dangerous setting - as many strategies (in the sample repository - but also what people develop) have a "sticking signal" problem. That means, these strategies don't buy on rsi "crossed above" 30 - but they buy on "rsi > 30" (for example).

Currently - this will mean that the strategy buys the coin - and holds it until it'll sell it, and only after that look to buy again. With this however, it would mean that the strategy buys the coin when RSI is at 31, would buy the same pair again the next candle (when RSI is at 32, ...) - basically buying the same pair until either max_open_trades is reached, or stake_amount runs out (or the signal disappears). This is very dangerous and will break a LOT of peoples strategies - as some can rely on this (it may buy late - but it'll buy once a trade-slot becomes free (because a different pair is sold).


Then - it's not clear if this should merge the trade - so you buy 100 XRP, and then buy another 100 XRP at a later point - should these 2 be merged into one position of 200 XRP - or tracked seperately as 2 trades with 100 XRP each. The benefit of the 2nd variant would be that you could then sell 30% of the 200 XRP - and another 70% at a later point - otherwise you can only sell the "sizes" that you bought initially.

This will make a difference on the implementation complexity (therefore time needed) - but changing this at a later point is not easy and is a major breaking change for everyone using this feature - so it should be "right" from the beginning (which to me, is the "merge position" approach).


In the end however, don't expect any work on this until #2183 is complete - as the current strategy interface would only allow you to buy 2 equally sized positions - but would not allow for anything dynamic.

To me personally however, this is rather low priority - and i don't see this as an important feature - as i think it'll cause more problems (see point 1) than what it can help.

pnmartinez commented 4 years ago

As usual, really thorough explanation @xmatthias, thanks. You are THE freqtrade scholar!

I will further look into this in the mid-term: I am very interested in the possibility of opening several trades of the same pair, "no-merging" style.

As always, will update you all if I get somewhere.

gring0-cripto commented 3 years ago

just a question, can we buy at the stoploss ? per example, bought BTC at 10$, dropped 10%, now it's in 9$, can we make FT buy more there ? instead of selling at 10% loss ? like open another position or something ? ending with 2 BTC instead of 1

xmatthias commented 3 years ago

at the moment, freqtrade does not support position staking, so no, you cannot do that.

Aphris-Karu commented 3 years ago

watching though with this feature request being two years old do you have any idea how much longer before it is available?

xmatthias commented 3 years ago

Freqtrade is an open source project. Everyone contributing spends their free time voluntarily working on this project - so we do not provide timing plans - as timing solely depend on the fact that some has time and interrest to work on this issue.

elja commented 3 years ago

IMO writing a code is not a big deal for many people. However, without knowing the topic it's really hard to implement such features. If anyone has a detailed idea of how it should work (something like a user story) it shouldn't be hard to code. Personally, I would like to see an ability to create DCA bots based on freqtrade. I've been thinking if we can make it work similar to https://www.tradingview.com/pine-script-docs/en/v4/essential/Strategies.html. But it has so many features like risk management or OCA groups.

As I understand we should think about 'sticky' signal problem and it's better to merge positions, so we need to create something like a 'position manager' that should keep info about multiple trades done, total position, current profit, etc. Moreover, it's better for the position manager to have the ability to work with shorts and longs at the same time, or maybe we should have two separate instances there? Regarding a sticky signal - I have no idea how to better handle it. In my strategy, I'm working with EMA crossing and 30m timeframe and it's also can generate buy signals multiple times. My brains are simply not there when I think about it - I don't like the idea of having a state somewhere to prevent this from happening, maybe there is an elegant solution. Or maybe we need to send a signal once per candle? BTW having strategies with indicators like RSI > 30 is not an issue, just because it's simply up to you if you want to use pyramiding or not, and if you do - please make sure that your strategy written correctly for pyramiding.

Anyways If anyone understands what steps should be done in order to complete it then just share it, just share any good ideas and thoughts. I really hope that it will help a lot.

yohplala commented 3 years ago

IMO writing a code is not a big deal for many people. [...]

Hi there, Just to say that I share your optimism. I plan in the future to get my hands into freqtrade.

Interested in this DCA stuff, I am only commenting the 'sticky signal' trouble raised by @xmatthias . I don't know freqtrade code, so this comment is probably worthless, but I think this trouble is not one, i.e. it does not exist.

In my own use case, and in the use case of the very first post of this ticket, there is an order (buy or sell) each time for a different condition. In the 1st post:

Only commenting this aspect at the moment. Bests

xmatthias commented 3 years ago

As mentioned above - the "combine position" is a decision - for some usecases, a combined position is better, for others, separate trades would be beneficial (both opinions are present in this thread iirc).

There's 2 "sticking signal" problems that need addressing.

While you can "blame" the 2nd case on the strategy (it causes sticking signals) - the first one MUST be addressed for sure.

The big problem with "write a user story" is that it should capture all cases - which is quite difficult to do as everyone tries to work on this differently. If you think you can give that a try - please go for it - either in this issue, or with a new issue linking to this (to keep the spec at the top of the issue). Obviously, once it's specd (we know what we expect / need) - it's easy to implement ... it's this "spec" part that is quite tedious and difficult to do.

with the current interface, the bot would simply buy another stake (up to X positions per pair?) for every buy signal. There would be no differentiation between signals (if it's buy - buy another X for pair) - and i don't think there should be, either.

As mentioned above, don't expect any work on this until #2183 is complete (or at least defined) - as the current strategy interface would only allow you to buy 2 equally sized positions - but would not allow for anything dynamic. Maybe ##3886 would suffice - but that's not mergable (almost all files changed in the meantime) - so maybe start on reimplementing that based on the current codebase?


You also mention shorts ... while changes should not prevent shorts - adding both at the same time will not work (it would become a huge PR, which is impossible to review and I'd have therefore to reject - simply because guaranteeing that it won't break existing behavior would become impossible / very difficult).

yohplala commented 3 years ago

@qkum

What does mean?

  • sell condition 1 & 2: idem

Hi, it means similar logic than buy condition 1 & 2. I phrased this comment to highlight that each order (buy or sell) has its own specific trigger condition. It is supposed to comment on @xmatthias' clarification of multi-order triggering in this sentence:

this will be a very dangerous setting - as many strategies (in the sample repository - but also what people develop) have a "sticking signal" problem. [...] That means, these strategies don't buy on rsi "crossed above" 30 - but they buy on "rsi > 30" (for example). With this however, it would mean that the strategy buys the coin when RSI is at 31, would buy the same pair again the next candle (when RSI is at 32, ...)

The thing (that I have in mind and that is probably not implemented) is that the strategy I am focusing on (and proven to be more successful with DCA thanks to backtrader) is that each order (buy or sell) has:

So once condition 1 triggers, amount 1 is bought for order 1, and even if the condition remains valid the next candle, no more is bought. Amount 2 for order 2 is bought only if condition 2 triggers.

Ok, I am aware this is only blablabla, it does not help much, and the thing to do is to get ones' hands inside the code :) I am sorry, at the moment, it is not part of my short term priorities :)

aayush-jain18 commented 3 years ago

I am interested in the pyramiding feature, I can contribute to the implementation. If there are ideas on how to proceed towards implementing it.

xmatthias commented 3 years ago

@aayush-jain18 Please look at the issues labeled with "good first issue" to get started.

This will require quite extensive knowledge about the internals of the bot.

d4fuQQ commented 3 years ago

oh shoot, it took me a while to figure out there is no position stacking in demo/live mode, although I was building a strategy based on this.

I got the strategy running in backtesting very smoothly actually and was just wondering recently why there are almost no trades in demo mode ....

Well, nevertheless I would like to share this positive experience during backtesting and perhaps it also helps to solve some of the complications you'd be facing implementing position stacking (?): image

plus the corresponding backtesting results image

At least I'm really happy with how the bot handles the buy & sell logic during backtesting (where blue arrows indicated a complete trade & black arrows just orders that are not sold yet i.e. "buy 'n hold" or "force_sell"). As you can see, it's basically closing the most recent order(s) at first and then, subsequently, the other ones.

@ the "sticking signal" problems:

There's 2 "sticking signal" problems that need addressing.

* a buy-signal is active throughout a candle (so multiple buys should not happen)

* a buy-signal is active for more than one candle (e.g. rsi>30)

While you can "blame" the 2nd case on the strategy (it causes sticking signals) - the first one MUST be addressed for sure.

I do, however, include certain price changes (as part of the buy condition from signals) which are always checked before an order is triggered and which would prevent the bot from buying several times during one interval, I guess.

If it deosn't help, well, sorry for the spam — at least count me in rooting for this issue 😃

xmatthias commented 3 years ago

it's pretty clear that this can have benefits for strategies that are specifically tailored for this.

It's however still a risk for strategies that are working fine now (but which suffer from the "sticking signal" problem.

I do, however, include certain price changes (as part of the buy condition from signals) which are always checked before an order is triggered and which would prevent the bot from buying several times during one interval, I guess.

The same as above applies here. Backtesting only checks for buys once - live will check for buys potentially throughout the whole candle - potentially causing quite many buys during one candle.

Finnance-analyst commented 3 years ago

Hi there,

I just started with the bot (testing for a week) and got same idea as I looked on graphs that sometimes there are much better positions after initial buy, so I thought

  1. if there would be condition/s for max open trades per pair(I would prefer 2 max 3),

  2. for trigger something like: don't buy unless buy signal is lower then prior position by at least 10%

  3. for sell those positions I don't care if they are sold at same time or separately => if 1st position is in green automatically 2nd position is in green, maybe in case of ROI trigger it could be separated (to protect some gains and than repeat), in case of sell signal together if it means less codding

4 . and also as some financial insurance: have a whitelist for coins where this option can be switched on, I don't want to buy some sh*di coin which is dropping more and more

Great work!! Thanks

toddabraham commented 3 years ago

Probably already studied, but here's a good article explaining the strategy manual traders use. An important point to keep in mind, buying an asset that is in decline can be a very dangerous strategy to follow as the position will not recover should the asset continue to lose value. The idea is to keep adding to the position while continued strength is shown.

https://www.investopedia.com/articles/trading/09/pyramid-trading.asp

devilsinthedetail commented 3 years ago

Just to give some more context for this, the 3commas bot uses 6 additional variables for this.

Edit: Also note that there is no need to create additional signals. Its just buying X times more of asset XYZ when it dropped Y% after buy signal

JHDE commented 3 years ago

While it is difficult and risky to do position stacking on the same pair, would it be possible to do position stacking on different pairs?

For example:

In the strategy:

xmatthias commented 3 years ago

@JHDE i don't see how this is position stacking (which makes it irrelevant for this issue). It's compounding (utilizing prior profits) - which is easily possible by reading the documentation.

krisligara commented 3 years ago

some other approach I've seen :

if after buy, buy signal is still present or being generated (for the current time) while no sell signal (roi, stop loss, or sell signal from strategies) then buy again with a ratio of previous buy

the amount and average could be merged and an average will be calculated for those open position example :

1st buy at 1 coin at $100, so now 1C=$100 2nd buy at 1 coin at $90, so now 2C=$190 or 1C=$95

then you can use the 1C=$95 to see if gain or loss depending on current market price. for instance if market current is 1C=$100, then you are at 5% gain if you sell.

variables needed for configuration will be :

enable or disable? how many stacks? how big of a ratio of the stacks compare to the 1st base buy order? (1 will be the same as previous order, 0.5 will be half previous order etc.)

hope this can work.

since for highly fluctuating asset, sometimes its better to do small base order, complemented by several small order VS doing One large order.

ghost commented 3 years ago

There is a way to do multiple buys of the same pair: This code in freqtradebot.py in method enter_positions(self) avoids rebuy of the same pair:

      # Remove pairs for currently opened trades from the whitelist
        for trade in Trade.get_open_trades():
            if trade.pair in whitelist:
                whitelist.remove(trade.pair)
                logger.debug('Ignoring %s in pair whitelist', `trade.pair)

Remove this code or use boolean value to enable/disable the loop.

Then add this code at the end of method execute_entry() in freqtradebot.py to avoid instant rebuy:

        # Lock pair for one candle to prevent immediate rebuys
            self.strategy.lock_pair(trade.pair, datetime.now(timezone.utc),
                                    reason='Auto lock')`

Then use the methods inside the strategy to find out which pairs to buy and at what price.

To buy again after a buy signal simply use something like this in populate_buy_trend: dataframe['my_buy_signal'] | dataframe['my_buy_signal'].shift(delay_candles)

Then define variables for how many pairs to trade, how many trades per pair, for example: max_open_pairs = 2 max_trades_per_pair = 2 (in config.json: max_open_trades has to be max_open_pairs * max_trades_per_pair) Then in confirm_trade_entry something like this:

    def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
                            time_in_force: str, current_time: datetime, **kwargs) -> bool:
        max_open_pairs = 2
        max_trades_per_pair = self.config['max_open_trades'] / max_open_pairs

        open_trades = Trade.get_open_trades()
        open_pairs = []
        trade_count = 0

        for trade in open_trades:
            # store open pairs
            if not trade.pair in open_pairs:
                open_pairs.append(trade.pair)
            # count the trades for this pair
            if trade.pair == pair:
                trade_count+=1

        if trade_count >= max_trades_per_pair:
            # dont buy more than n times the same
            self.lock_pair(pair, until=datetime.now(timezone.utc) + timedelta(minutes=20), reason='Trades per pair limit')
            return False

        if len(open_pairs) >= max_open_pairs:
            # dont't trade more than n pairs
            if not pair in open_pairs:
                self.lock_pair(pair, until=datetime.now(timezone.utc) + timedelta(minutes=20), reason='Open pairs limit')
                return False

        return True

I am using lock_pair because it seemed the most easy way to me, but might not be very efficient - maybe using PairList and temporarily add/remove pairs to whitelist after a buy or sell is better here.

Current problems/questions with this approach are:

xmatthias commented 3 years ago

@incrementby1 Please don't post missleading, hacky solutions that heavily depend on your strategy, and will probably cause other people losses, as they'll try to implement it without fully understanding this method and what it entails. To protect other, inexperienced users from this, i've hidden your comment.

If you're interrested in having this feature, best submit a pull request (ideally including tests, documentation). That way we can properly evaluate it, test it, and determine how to make it work properly.

I will not support custom hacks in issues and i think your approach has potentially more issues than you think it does - so it may work with your particular strategy, but cannot be applied safely on a wider scale.

I also think that a "merging" approach would be better - as it'll provide more flexibility and real position management capability (you can sell 20% of a position, not "whatever i bought).

@everyone This thread is long enough, i don't think additional opinions will help. If you're looking to help, best with an implementation / Pull request proposal.

krisligara commented 3 years ago

@xmatthias : yes, I will ask maybe if he will make PR, then we can discuss it there instead of waking up this ol' zombie thread. @incrementby1 I see, maybe you should make a branch/pull request then. see if we can attack it and maybe yield something useful. it needs a few more things :

  1. an option in config file enable or disable
  2. need to do a merge of current traded based on pairs and recalculate average cost in it, so that strategies, roi and stoploss will work properly. and maybe the entire value of the Pair need to be made as special #ID in the database for exit_positions() to work on.
  3. store that value for future cycle.
  4. for exit considerations : there will be a need to specify another function to sell this type of trade, like what @xmatthias said, which is either an option to do part sell (defined by total value divided by a number to make it easier, since if we give % to people they might input weird % that won't completely liquidate leaving leftover coins, which in turn, require the bot to have another function to sell leftovers :)). or just do a clean exit position selling all of that Pair which have been bought by the bot.

@xmatthias I'm sorry for resurrecting this thread, it's just that I felt sincerely with how the crypto market is going, this type of high frequency trading capability is needed. it will enable taking position in short-term uncertainty and hedge against it.

Thank You 👍 this project is awesome, I regret I have just learned about it.

riodda commented 2 years ago

Hi guys, really thanks for this great open source project ! I would like to really give me opinion on postion stacking or DCA, I come from 2 years of trading in this way and i have to say that position stacking or DCA is in credibly profitable for cryptos that have very good ups and downs. I would really encourage the community to have a position stacking feature. I think that just enabling a newer buy when a newer buy signal is received would make the trick. Also another important aspect is position scaling like: base buy is 10, scaling factor is 1.1 so:

First buy signal is postion is open with10, Second buy signal Position is increased by 101.1 so the new position ia 21.1 Third buy signal the potition is increased by (21.1+10)1.1 and so on.... Then a table of the coefficent for the position is needed as well like:

BUY COEFF 1 1.1 2 1.1 3 1.1 .... 7 1.1 8 0.25 9 0

In this way you can control the maxium amount of capital you use and you can even decide how much level you can go down, and then stop accumulation and just wait.

The other feature that is very importan is a thersold deviation that can be a table as well, if buy signal AND price below thersold deviation, same for SELL. This allow to control the capital and brings down the average buy price. In this way instead of getting creazy for spotting the best signal we just focus on indentifying market dips and market peaks DCA and thersolds on buy and sells will make the rest. This is an example of what i mean:

image As you can see at BUY n°4 the position size increasing has pushed the everage price so down that the first market bounce was enough to have a gain and a sell, and you can notice that the sell sinal happen at a lower value than the first buy signal.

xmatthias commented 2 years ago

Averaging into a position is currently in progress in #6079. This will not cover the sell side - and i think that'll take another while - as that includes quite some additional complications.

umutrcc commented 2 years ago

hello, is dca active now, I wonder how we can use it, I think there is work on it?

xataxxx commented 2 years ago

Ability to buy multiple orders within a single trade has been implemented in develop branch via #6079 and we can DCA now using a new callback adjust_trade_position. Multiple sell orders are currently not implemented, but are planned.

qkum commented 2 years ago

Ability to buy multiple orders within a single trade has been implemented in develop branch via #6079 and we can DCA now using a new callback adjust_trade_position. Multiple sell orders are currently not implemented, but are planned.

great news

thanks for working on this must-have feature🥇

(in a modular & logical form hopefully)