DeviaVir / zenbot

Zenbot is a command-line cryptocurrency trading bot using Node.js and MongoDB.
MIT License
8.21k stars 2.04k forks source link

Zenbot always makes losses in live mode #1059

Closed code4passion closed 5 years ago

code4passion commented 6 years ago

System information

Describe the problem

For me bot makes profit in simulation and paper mode. But in live trade it always looses money. Buys high and sells low. The strategy used is trend_ema.

There was a similar issue open some time back which got closed without resolving.

I understand that the simulation/paper mode gives more profit in general, but i am making consistent losses in live mode.

Questions: -Is anyone making profits in live mode? -Any possible reasons for this behaviour?

DeviaVir commented 6 years ago

linking to https://github.com/DeviaVir/zenbot/issues/189

code4passion commented 6 years ago

-Is anyone making profits in live mode?I asked this question multiple times in our forum and noone answered. I am asking this, coz if everyone is making losses then we know that there is something wrong in the code and we need to fix it. I remember that one guy had asked to revert the buy and sell signal.

adrianocr commented 6 years ago

@DeviaVir I think most of us are aware of that issue but is anything being done about it? Anyone make any progress on improving it? No matter which strategy I try (even after simulating first) it always buys at something like 0.0075 and then sells at like 0.0069. It's a loss on 95% of the trades it initiates.

P.s. I understand my question comes off a little bit like a crazy person asking to speak to the manager, but I promise that's not my intention. It isn't a negative "is anything being done about this?!" and simply curiosity on my part about whether this is being worked on.

datafj commented 6 years ago

I found the same.

The difference between paper trading with live trading is that in live trading your buy / sell order will almost never get filled when it first initiated, because the exchange will always match other people's orders who are posted before you.

Check my question: https://github.com/DeviaVir/zenbot/issues/1018

blevok commented 6 years ago

Orders not getting filled when doing maker orders does explain not making trades consistently, but i think there's more to it than that. I can't look too deeply into it because i'm a JS noob, but looking at config options, some logic seems to be backwards. For example, these options:

// sell if price drops below this % of bought price (0 to disable) c.sell_stop_pct = 0 // buy if price surges above this % of sold price (0 to disable) c.buy_stop_pct = 0

So buy when the price goes above the last sell, and sell when it goes below the buy? Seems like setting these to a positive value basically ensures loss in day trading (probably good for swing trading though). But even without setting those, a lot of the strategies look like they send the opposite signal they should be sending. I've seen it look like this in a lot of my recent ETH tests: 979 sell 980 sell 981 buy 982 buy 979 sell 978 sell 980 buy

So it seems like it's doing the exact opposite that it should be doing, however, simply reversing the signals doesn't really work like it would seem it should in many situations. And setting the max sell loss isn't a solution because there are times when it's wise to sell at a loss just to be able to keep trading, which should erase the losses over time.

I think part of the solution might be more fine grained control of global buy/sell rules. The addition of options like the two above which work the opposite would add logical buy/sell conditions, but the opposite still needs to exist to allow for selling at a loss when necessary. So they would need to work together somehow, probably requiring additional options to determine when it's okay to sell at a loss.

But the strategies would be working against these rules, so there are more fundamental issues than just adding some configuration options.

Another option that would probably be beneficial is a max sell loss total, because it can keep selling at a loss that is within your configured percentage over and over, making your total loss basically unlimited, despite the configured limit.

datafj commented 6 years ago

Did you read DeviaVir's link? There is a fix for always reversed signal. See "krilson commented on Jun 23, 2017" in that link.

evseevnn-zz commented 6 years ago

@DeviaVir Same problem. In config max_sell_loss_pct: 0.1 That started after pulling changes from repository

blevok commented 6 years ago

Ah, well i did try reversing the signals in some strategies, but i didn't try trend_ema or a few others since i wasn't getting reliably opposite results.

code4passion commented 6 years ago

@blevok I think setting c.sell_stop_pct > 0 is good because it will minimize ur losses. Example the bought did buy a price X hoping it will go up, but price dipped. Now the bot should not hold anymore.As soon as it makes > 0.1% loss it should sell.

The question is why the discrepancy between simulation/paper and live trade. I understand that in live trade there are many other factors, the order might not get fulfilled. But if can minimize that using 'maker' order. This will solve the problem during buy as we will always buy low. But Selling might still be issue. But i assume that the bot should atleast win sometimes(make profit on trade of a buy sell pair).

blevok commented 6 years ago

I definitely agree with the concept of the sell stop, but the problem is that it can sell at the same loss over and over, and eventually see massive loss. Plus, with it buying when the price goes up, it'll just lose on every single trade when things are moving sideways. I ran a sim with it set at 0.3 for one of those buy high/sell low strategies, without crippling it via config, and i saw a 75% loss in 5 days. An aggregate sell stop would be helpful in preventing that.

And as for pushing orders through, yes the maker option can almost completely resolve that issue, but the issue i've found is that when trading the top coins, there often isn't enough short term volatility to account for the fees, so it still results in a loss. I think the solution may be another reversal of logic.

// % to mark down buy price for orders c.markdown_buy_pct = 0 // % to mark up sell price for orders c.markup_sell_pct = 0

I can't imagine why i would want to mark down buys, and mark up sells. That just ensures my order always gets left behind. But if i could do the opposite, that would always put my order right next to the spread, which should often result in it being filled almost instantly. Does this make sense or am i missing something?

rountrey commented 6 years ago

This is going to be long so bear with me.

First, I am not done with my testing, yet. I have finished doing 90 day tests on eight strategies and have five or six left to go. Everything is in a spreadsheet with different buy/sell pct, options, periods, and so on. But they all start at the same time, which means my buy/hold result is the same for all of them (+17%). By the way, all my testing has been on gdax.LTC-USD.

But I have been running two bots for over a week. Both are running RSI --period=5m --oversold_rsi=40 --overbought_rsi=75 --buy_pct=100 --sell_pct=100. One is on poloniex.XRP-USDT, the other is gdax.LTC-USD. They were both started within a minute of each other and so far my vs. buy/hold is -2.91 for gdax (still above profit/loss pct) and +8.61% for poloniex. I think there are a lot of key factors to look at when you lose money, the biggest is what the market is doing during your trading period. There's been times where I started losing and was very tempted in killing the bot and starting over at a lower price to see what happens. I did that when I live tested trend_ema, and now I am resisting.

I found out about the trend_ema issue, reversed the signals and it messed up all the simulations. Funny. So, I ended up copying it and now I have "trend_ema_sim" and trend_ema_live" strategies. So, there's one tip/fix for you.

I also ran across the threads that have issues with the max_sell_loss_pct=0. Where using 0 will allow it to sell at a loss. Some were putting 0.1 to minimize the loss, but I found a fix for that. Use a negative number and it will force it to sell at a profit. If max_sell_loss_pct=1 allows to sell at -1%, then max_sell_loss_pct=-1 changes it to +1%.I think the main key is not to use a max_sell_loss_pct=0. I have found an issue in doing this and it will not do an initial buy if all you have is asset and no currency. I fixed this by setting a limit order on the market's website while the bot was running. It caught it, calculated it and everything kicked off like normal.

I have also found that -1 or -1.5 works well in most cases, -2 is iffy, and any less than that will pretty much prevent it from trading very often and the vs. buy/hold is in the red.

Those are my tips. Once you have stopped the bot from selling at a loss, either through the max_sell_loss_pct trick, reversing the signals on trend_ema, or both, all you have to do is be patient. I'd love for a lot of my sims to be real, especially when one of them pulled 900% above buy/hold.

Lastly, you have to think of this as a long term thing, whether you just hold coin or use zenbot. THIS IS NOT A GET RICH QUICK THING!! I look at it like this, say next year whatever I have goes up 200%, zenbot just helped me push that a little higher at 243%

code4passion commented 6 years ago

@rountrey

I found out about the trend_ema issue, reversed the signals and it messed up all the simulations. Funny. So, I ended up copying it and now I have "trend_ema_sim" and trend_ema_live" strategies. So, there's one tip/fix for you

Did u reverse the singals of buy/ sell as mentioned in https://github.com/DeviaVir/zenbot/issues/189 ? Or did u reverse and then also use negative values for max_loss_pct?

Overall i dont think what you mentioned in the comment is related to the bug i have reported. You are setting max_sell_loss_pct to negative or 0 or very less value , In that case u will always win the trade and make profit. That works for me too. But i dont want to enable this setting.

rountrey commented 6 years ago

Did u reverse the singals of buy/ sell as mentioned in #189 ? Or did u reverse and then also use negative values for max_loss_pct?

I copied the strategy and reversed the signals to have it ready if I decide to use it live. Other than a small test with $10 for a couple days (live trading), I have not run it consistently. It did work, though. With the original, it sold at a loss, and the reversed sold at a gain.

I have not (re)done trend_ema simulations, yet, that strategy was my first run of testing and moved on to other strategies after I found the reverse signal thread. I will be testing the max_loss_pct when I get back to it, just like I've done with the rest.

As for simulations, normally, I test max_loss_pct=0 first with a lot of other options that I change, then I run those same options with a -1. If that does better I will also run -0.5 and -1.5, maybe move to -2, -but that's rare.

Overall i dont think what you mentioned in the comment is related to the bug i have reported.

Maybe not, but it's something I found that can help prevent you from losing money until it gets fixed. It may be a crutch but at least you can keep moving forward.

To be clear, I am running sims on all strategies, some have been more than 100 times with all the options I've changed. Some have lost more than won, but with changing that max_loss_pct value to the negative changed a lot of them. Some of them actually lost, like trendline. At max_loss_pct=0 I got 8.08% above buy/hold, with max_loss_pct=-1 I got -0.44% with other options being the same.

Getting all the sims done is my main goal. The more data I have, the better I can calculate what will have the best return. I suggest you do the same, too. It's tempting to jump in and go for it, and I said I am trading live, but I'm using the rsi strategy and that one seemed to be safest. Nothing big, nothing too risky. I'm only playing with $50, and with the current drop on LTC and XRP, I've lost about 20%. That's the market, though, not the bot.

Kontsnor commented 6 years ago

Checkout this commit I found on a random fork: https://github.com/jaroschek/zenbot/commit/1912baae69fd155f33aa087c10f9a5195006ad78#diff-a41b519e7979a713e894ef8d1b3fe568

It seems like this guy found it in the engine.

code4passion commented 6 years ago

I saw the latest code in this repo and the code is as following. The following condition looks good to me. Your comments?


 if (s.buy_stop && s.period.close > s.buy_stop) {
              stop_signal = 'buy'
              console.log(('\nbuy stop triggered at ' + pct(s.last_trade_worth) + ' trade worth\n').red)
 }

Also logic to calculate looks buy_stop_pct good

if (so.buy_stop_pct) {
            s.buy_stop = n(price).add(n(price).multiply(so.buy_stop_pct / 100)).value()
          }
blevok commented 6 years ago

Yeah buy_stop_pct is good. I've tested it, and when the strategy allows the price to drop, it tries to buy. But in most of my testing so far, it doesn't have the chance. It still buys before it hits it, because the strategy tells it to, which is expected of course. But what i don't like is when it buys above the last sell price, very soon after selling, like seconds sometimes. I've yet to test a strategy that doesn't make bad moves like that sometimes (actually very often in some cases).

About setting max_sell_loss_pct to zero or negative, it works, but i don't think that's a solution. You get stuck holding coins that might not sell for a while, and meanwhile there's lots of ups and downs happening below that you're not getting in on. In order to keep trading, it's necessary to sometimes sell at a loss.

But still, using the configurable limits is just fighting against the strategy. That's where the real problem is i think. Ideally, it shouldn't even be necessary to set any of the limits in the configuration file, or at least very few, just to prevent absolute doomsday. The strategy should be making smart buys that have a good chance of recovering quickly, or at least not making obvious bad buys. A good strategy is the real solution, but i think most that we have now aren't suited to trading when there isn't huge volatility.

edit: Also i want to note that i've seen some promising results with the new bollinger strategy. I haven't tested it very long, but it seems to make much fewer bad buys then the other popular strategies.

adrianocr commented 6 years ago

How is it that there's so much activity and apparent usage of Zenbot yet live trading isn't working well? Have some people figured out what the rest of haven't -- how to make it work correct in live mode? Unless it's mostly being used for simulating (which I doubt).

laloch commented 6 years ago

The stop loss logic is still severely broken. It doesn't take into account whether the last trade was 'buy' or 'sell'. It doesn't take into account whether another order was already placed. Especially if you use both sell_stop and buy_stop with low percentages simultaneously, you can see funny things like this:

2018-01-17 15:00:00  2.16300 IOT-USD   -1.31%    55819   --- 31     +8.42%    4.01233413 IOT   946.83 USD   -4.45%  +13.53%
2018-01-17 15:03:00  2.18000 IOT-USD   +0.78%    46880    -- 36     buying    4.01233413 IOT   946.83 USD   -4.45%  +12.65%
2018-01-17 15:06:00  2.14990 IOT-USD   -1.39%    39201   --- 32     bought  433.13768327 IOT     9.46 USD   -5.94%  +12.44%

sell stop triggered at -3.31% trade worth

2018-01-17 15:09:00  2.11000 IOT-USD   -1.86%  141.67k   --- 27    selling  433.13768327 IOT     9.46 USD   -7.67%  +12.46%

buy stop triggered at -3.48% trade worth

2018-01-17 15:12:00  2.17970 IOT-USD   +3.30%  181.03k    -- 42     buying    4.33137684 IOT   911.84 USD   -7.88%   +8.62%
2018-01-17 15:15:00  2.16000 IOT-USD   -0.91%    91524    -- 40     bought  417.65381163 IOT     9.11 USD   -8.88%   +8.42%
2018-01-17 15:18:00  2.13390 IOT-USD   -1.21%    74084    -- 37     -2.20%  417.65381163 IOT     9.11 USD   -9.97%   +8.43%

These races can even push the engine to a state in which it is stuck in buying/selling state indefinitely doing nothing. They can also dramatically distort simulation results. I'm evaluating the following patch right now. It eases the pain a bit, but it's incomplete and doesn't really solve the problem. Even with the patch applied, once you hit the sell_stop, the engine will never trigger buy_stop until the next regular trade is made and vice versa.

diff --git a/lib/engine.js b/lib/engine.js
index d4aedfa..fbbd9f2 100644
--- a/lib/engine.js
+++ b/lib/engine.js
@@ -157,7 +157,7 @@ module.exports = function container (get, set, clear) {
         s.last_trade_worth = last_trade.type === 'buy' ? (s.period.close - last_trade.price) / last_trade.price : (last_trade.price - s.period.close) / last_trade.price
         if (!s.acted_on_stop) {
           if (last_trade.type === 'buy') {
-            if (do_sell_stop && s.sell_stop && s.period.close < s.sell_stop) {
+            if (do_sell_stop && !s.buy_order && s.last_trade_worth > 0 && s.sell_stop && s.period.close < s.sell_stop) {
               stop_signal = 'sell'
               console.log(('\nsell stop triggered at ' + pct(s.last_trade_worth) + ' trade worth\n').red)
             }
@@ -171,7 +171,7 @@ module.exports = function container (get, set, clear) {
             }
           }
           else {
-            if (s.buy_stop && s.period.close > s.buy_stop) {
+            if (s.buy_stop && !s.sell_order && s.last_trade_worth < 0 && s.period.close > s.buy_stop) {
               stop_signal = 'buy'
               console.log(('\nbuy stop triggered at ' + pct(s.last_trade_worth) + ' trade worth\n').red)
             }
laloch commented 6 years ago

I forgot to post the following evidence of the above statements:

2018-01-17 12:00:00  2.06800 IOT-USD   -4.67%  155.33k  ---- 25     buying    4.25706205 IOT  1001.10 USD   +0.99%  +19.93%
2018-01-17 12:03:00  2.11800 IOT-USD   +2.41%  284.79k   --- 34    selling  474.93528659 IOT    10.01 USD   +1.59%  +17.80%

buy stop triggered at -3.03% trade worth

2018-01-17 12:06:00  2.18420 IOT-USD   +3.12%  214.31k    -- 43    selling  459.74709461 IOT    10.03 USD   +1.42%  +14.04%

buy stop triggered at -3.04% trade worth

2018-01-17 12:09:00  2.27030 IOT-USD   +3.94%  242.35k   52 +      selling  445.04732315 IOT    10.01 USD   +2.04%  +10.38%
2018-01-17 12:12:00  2.31000 IOT-USD   +1.74%  133.43k   56 ++        sold    4.45047324 IOT  1008.30 USD   +1.85%   +8.29%

buy stop triggered at -3.01% trade worth

2018-01-17 12:15:00  2.33940 IOT-USD   +1.27%  198.93k   58 ++     selling  430.89877055 IOT    10.08 USD   +1.81%   +6.88%
2018-01-17 12:18:00  2.35570 IOT-USD   +0.69%  117.97k   59 ++        sold    4.30898771 IOT  1001.58 USD   +1.17%   +5.48%
2018-01-17 12:21:00  2.30110 IOT-USD   -2.32%    63586   53 +         sell    4.30898771 IOT  1001.58 USD   +1.14%   +7.95%
2018-01-17 12:24:00  2.30000 IOT-USD   -0.05%    61218   53 +         sell    4.30898771 IOT  1001.58 USD   +1.14%   +8.00%
2018-01-17 12:27:00  2.26110 IOT-USD   -1.70%  168.53k     - 49       sell    4.30898771 IOT  1001.58 USD   +1.13%   +9.84%
2018-01-17 12:30:00  2.25100 IOT-USD   -0.45%    31474     - 48       sell    4.30898771 IOT  1001.58 USD   +1.12%  +10.33%
2018-01-17 12:33:00  2.32000 IOT-USD   +3.06%    66726   55 ++        sell    4.30898771 IOT  1001.58 USD   +1.15%   +7.08%
2018-01-17 12:36:00  2.29030 IOT-USD   -1.29%    44294   52 +         sell    4.30898771 IOT  1001.58 USD   +1.14%   +8.46%

buy stop triggered at -3.11% trade worth

2018-01-17 12:39:00  2.33710 IOT-USD   +2.04%   174.9k   56 ++     selling  416.82474553 IOT    10.01 USD   -1.59%   +3.42%
2018-01-17 12:42:00  2.31200 IOT-USD   -1.08%    54792   53 +         sold    4.16824746 IOT   972.50 USD   -1.79%   +4.33%
zallesov commented 6 years ago

I wrote a small script to run simulations with all the strategies. I ran it on most successful pairs for the last days and also on most traded pairs. NON of the simulations showed better results than buy/hold. Most of them end up in deep minus. I used the default parameters for all the strategies.

strategies=( bollinger cci_srsi crossover_vwap dema forex_analytics macd momentum neural noop rsi sar speed srsi_macd stddev ta_ema ta_macd trend_bollinger trend_ema trendline trust_distrust wavetrend ) \n
selector=binance.GAS-BTC
days=5
zenbot backfill $selector --days $days
for s in ${!strategies[@]}
do 
    strategy="${strategies[s]}"
    zenbot sim $selector --days $days --strategy $strategy
done
jasdjensen commented 6 years ago

@rountrey
Would you please share your configs for your tests? I'm particularly interested in the settings you used for trust_distrust, and which strategy you felt was the best for gdax.LTC-USD.

I've been playing around with trust_distrust, but not having good results. Wasn't sure how to contact you outside this thread because I'm a bit of a github noob.

Thanks.

rountrey commented 6 years ago

@jasdjensen Well.... It's a lot of info, and you have to decypher how I did the spreadsheet but... https://www.dropbox.com/s/nr3jdgyue5kqdk7/zenbot%20results.ods?dl=0 (it's a LibreOffice ods, but should open in MS Excel).

Oh, and it is far from complete and I'm doing all of the sims on GDAX. If you want to just see the really good results, look at the Finals tab. After I'm done with the 90 day sims starting Sept 1, 2017, I'm going to run all the ones in the finals tab against each other with a more current 90 days. By the time I'm done with all of them, I may start them all in for Jan 2018. I was thinking of putting all these sims online, but... well, you will see how many files I've created and will come to the same conclusion.

If you really want them I have the sim.html files from completed strategies in tar.gz files, I can load them on dropbox if you really want to take a look.

Just remember, even time can change the outcome greatly. If you took any of what I have done and ran them on a current 90 days, it could go real bad or get better.

jasdjensen commented 6 years ago

Thanks.. I really appreciate this. Should be very interesting. Particularly trust_distrust, since that's the one I'm actively testing.

datafj commented 6 years ago

@rountrey Thanks for sharing the simulation results. Your result spreadsheet does not include number of trades and win %. Some of the results are not very meaningful when those two factors are not considered.

For example, the best result of stddev has 1073.05% end balance. I wonder how many trades were performed to get this result. If the number of trades are very high, transfer fees would be huge, and it will always lead to lose of money, instead of gaining. Also, limit order would be almost impossible to be filled if orders are posted very frequently.

My experience is that in simulation, you should always try taker order (with fees and slippage), because it is impossible for the simulation process to know when a maker order can be filled.

jasdjensen commented 6 years ago

I'm struggling with c.max_sell_loss_pct. I set it to -1 and it will never sell, even at a profit. "refusing to sell at $$, sell loss of +0.00".

I've tried -1.5 I've tried -0.00001, I've tried 0.00001...

Why doesn't this work properly and how do I get a value that works. I'd accept half a percent loss if it was the only option. When I put normal amounts in the buy and sell loss_pct variables, It buys high and sells low. I can't win.

And running sims is very different than running trade --paper. It seems to work better in the sim and not in trade.

@rountrey can you send me an email at jasdjensen at gmail dot com? I have some questions about what you did for your config files.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.