DeviaVir / zenbot

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

An option to buy and sell at specific price #736

Open billbartlett opened 6 years ago

billbartlett commented 6 years ago

Would it be possible to enable an option like --buy_price=N (c.buy_price) and --sell_price=N (c.sell_price) to enable specific buy and sell positions? When a pair is trading in a channel for extended periods, it'd be helpful to simply use specific buy and sell prices to trade that specific range.

DelScipio commented 6 years ago

Or even allow advanced limit buys and sells and stops in manual live trading. I think is very easy to implement and would improve live trading a lot! I mainly use it in manual trading and it would be amazing to have this improved.

rados10 commented 6 years ago

Hey guys, is anyone able to work on this?

ntamas commented 6 years ago

I have a home-grown strategy extension for zenbot that does this, but it's not production-quality yet. Here's a Github gist - you need to put these two files in extensions/strategies/safety and then you'll get a strategy named safety that buys and sells at fixed prices.

rados10 commented 6 years ago

Hey @ntamas. Thank you very much. I'll check it out!

ntamas commented 6 years ago

Note that the gist basically treats the "sell" price as a "stop loss" threshold - i.e. the strategy will sell if the price falls below this level. This might not be what you want, i.e. when the "buy" price is smaller than the "sell" price, the strategy should behave exactly the opposite way (buy when the price is smaller than the "buy" threshold, sell when the price is larger than the "sell" threshold). So, feel free to change the code, and of course no guarantees whatsoever.

rountrey commented 6 years ago

This is pretty nice and works well, the only issue is having to constantly watch it if you plan on doing a lot of trading. Is there a way to change it to use percentages instead of prices?

ntamas commented 6 years ago

Most likely yes - do you mean that the buy and sell thresholds should simply be derived at startup from, say, the closing price of the last candle plus-minus a given percentage? Then it would be enough to re-start the bot at regular intervals to adapt to the new price level.

rountrey commented 6 years ago

I was thinking of something that started at a given price, then work off the percentages of that price and each price thereafter, kind of toggling back and forth. I don't code but I understand it to a point. So, I'll try...

Set the initial buy.price at 100 if buy then sell at buy.price+2% //only sell at +2% if a buy came first if sell then buy at buy.price+2%-3% //only buy at -1% if sell came first

ntamas commented 6 years ago

Yes, that could work as well, but that's a different strategy and I'm afraid I don't have the time right now to work on it. However, anyone is free to fork my gist and start hacking on it.

dshetyo commented 6 years ago

The strategy looks goods. I have a question regarding code

if (!s.in_preroll) {
        if (s.period.close < s.options.sell_threshold) {
          s.signal = 'sell'
        } else if (s.period.close > s.options.buy_threshold) {
          s.signal = 'buy'
        }
      }

What is s.period.close? If it the price at which last period closed? If my understanding is correct then shouldn't the conditions be reversed?

I plan to buy when price is below X and sell when price goes above Y. So i assume i can configure X as buy_threashold and Y as sell threshold. Then the code should look like following right?

if (!s.in_preroll) {
        if (s.period.close > s.options.sell_threshold) {
          s.signal = 'sell' // when price is more then sell_threshold (Y) , sell it
        } else if (s.period.close > s.options.buy_threshold) {
          s.signal = 'buy' //  when price is below buy threshold (X) , buy it.
        }
      }
ntamas commented 6 years ago

What is s.period.close? If it the price at which last period closed?

As far as I know (I'm not that familiar with zenbot's internals), it is the close price of the current period, which is basically the most recent transaction price.

If my understanding is correct then shouldn't the conditions be reversed?

That's what I mentioned in my comment above: currently the sell threshold acts as a "stop loss" so the strategy will sell if the price falls below this level. Also, it will buy if the price crosses a threshold from below, so typically you would set the sell threshold to a strong support (so you sell if the support is broken from above, opening up the way for further losses) and the buy threshold to a strong resistance (so you buy if the resistance is broken from below, expecting that the price will go to the moon from then on).

If you want to buy when the price falls below the buy threshold, and sell (i.e. take profit) when the price rises above the sell threshold, just swap > with < in both branches. Note that in the example you have given, you have kept the second condition as is. This might also make sense, depending on what you want to do.

dshetyo commented 6 years ago

Thanks for quick reply. That makes sense.

What is the use of just using the strategy u posted earlier then? It just a stop loss strategy, which is used to minimize loss. It will never yield profit by itself?

ntamas commented 6 years ago

No, it won't. But it can be useful if you know that you'll be offline for a few days and want to sell your assets that you have bought a long time ago if the price starts to fall - in that case, it can "indirectly" yield a profit. Basically, in its original form, it's a replacement for Kraken's "stop loss" order type that was disabled a few months ago.

dshetyo commented 6 years ago

Makes sense. Thanks

rountrey commented 6 years ago

@ntamas I hate to give away an idea, but I have found this strategy to work wonderfully when trading USD/USDT. Setting to buy at $1.01 and sell at $1.02, it's a 1% gain every buy/sell cycle (with fees it's actually 0.8%). It isn't much, but it is steady gains in trading.

rados10 commented 6 years ago

@rountrey great to hear. I've modified it to use the target, stop, and buy threshold to buy on pull backs. Testing it now but it looks promising. Of course I use semi-automatic approach here and have to watch it but that's just part of my strategy.

rountrey commented 6 years ago

@rados10 Have you posted it? I'd like to take a look. Also, on the safety strategy that @ntamas wrote, I was thinking of a way to do it using the last trade percent values instead of prices. Like sell when the last trade hits 3% and sell when the last trade hits -2%. Any idea of how to work this into the safety strategy? I don't code.

rados10 commented 6 years ago

@rountrey I did not. I will post it though shortly. In the meantime, here's the code:

var z = require('zero-fill') , n = require('numbro')

module.exports = function container (get, set, clear) { return { name: 'target_stop', description: 'Safety net strategy to buy/sell if price is above/below a given pred efined level.',

getOptions: function () {
  this.option('period', 'period length', String, '30m')
  this.option('buy_threshold', 'threshold where the strategy will buy', Number, 10

0000000) this.option('sell_threshold', 'threshold where the strategy will sell', Number, 0) this.option('target', 'this is my target where I will sell', Number, 1000000) this.option('max_buy_price', 'when the price drops to desired threshold, this is the max price willing to pay to buy', Number, 100000) },

calculate: function (s) {
},

onPeriod: function (s, cb) {
  if (!s.in_preroll) {
    if (s.period.close < s.options.sell_threshold || s.period.close > s.options.ta

rget) { s.signal = 'sell' } else if (s.period.close < s.options.buy_threshold) { if (s.period.close < s.options.max_buy_price) { s.signal = 'buy' } } } cb() },

onReport: function (s) {
  var cols = []
  return cols
}

} }