Closed krilson closed 6 years ago
@krilson Could you share your file with modifications ?
Thx
@dukye Sure, here it is, very simple modification: https://github.com/krilson/zenbot/commit/66fc7fae22987adb1162794f3bf97fae70d19e25#diff-c081f5fa7634cfc3a1254e982a748f9c
My conf looks like this: // Optional stop-order triggers:
// 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 // enable trailing sell stop when reaching this % profit (0 to disable) c.profit_stop_enable_pct = 0 // maintain a trailing stop this % below the high-water mark of profit c.profit_stop_pct = 1
// Order execution rules:
// avoid trading at a slippage above this pct c.max_slippage_pct = 5 // buy with this % of currency balance c.buy_pct = 50 // sell with this % of asset balance c.sell_pct = 90 // ms to adjust non-filled order after c.order_adjust_time = 30000 // avoid selling at a loss below this pct c.max_sell_loss_pct = 0.1 // ms to poll order status c.order_poll_time = 5000 // ms to wait for settlement (after an order cancel) c.wait_for_settlement = 5000 // ms to wait for settlement (after a funds on hold error) c.wait_more_for_settlement = 60000 // % to mark up or down price for orders c.markup_pct = 0
// Misc options:
// default # days for backfill and sim commands c.days = 14 // ms to poll new trades at c.poll_trades = 60000 // amount of currency to start simulations with c.currency_capital = 1000 // amount of asset to start simulations with c.asset_capital = 0 // for sim, reverse time at the end of the graph, normalizing buy/hold to 0 c.symmetrical = false // number of periods to calculate RSI at c.rsi_periods = 14 // period to record balances for stats c.balance_snapshot_period = '15m'
And I start the bot with this: ./zenbot.sh trade --period=2h --min_periods=60 --trend_ema=30 --neutral_rate=0.25 poloniex.LTC-XMR
I am experimenting now one pair with a 24h period. Experiment with the neutral rate a bit, depends how soon you want it to buy/sell.
Thank you for sharing @krilson Would you mind sharing your statistics? My bot doesn't seem to be trading with very much with these settings
@krilson when I install zenbot for the first time, are your changes already included or do I have to edit them in myself? Setting up a Raspi fresh, so asking in advance. thanks!
@krilson thanks :) @ether-btc yourself check krilson's prior post 9 days ago :) he join the diff link for trend_ema strategie.
will the fix be merged?
I was going to try this bot but then noticed this issue. Checking the code made me wonder, in the file mentioned above (extensions/strategies/trend_ema/strategy.js
), the description at the top says:
Buy when (EMA - last(EMA) > 0) and sell when (EMA - last(EMA) < 0).
_(I'm assuming s.period.trend_ema_rate
represents EMA
and s.period.trend_ema_stddev
represents last(EMA)
here. Please correct me if I'm wrong..)_
s.period.trend_ema_rate > s.period.trend_ema_stddev
does match (EMA - last(EMA) > 0)
(→ Buy)However, the code at line 59 doesn't seem to reflect this statement and it seems a logic error was made while putting it into code:
s.period.trend_ema_rate < (s.period.trend_ema_stddev * -1)
does not seem to match (EMA - last(EMA) < 0)
(→ Sell)Let's say EMA
= s.period.trend_ema_rate
= a
and last(EMA)
= s.period.trend_ema_stddev
= b
In this case, the description says we should sell when a - b < 0
, however it's clear that when we rewrite it to match the current format in code, this does not add up:
a - b < 0
(a - b) + b < 0 + b
a < b
, while in code, it currently saysa < -b
So, I'm going to change line 59 to the following and then give this bot a spin!
else if (!s.cancel_down && s.period.trend_ema_rate < s.period.trend_ema_stddev) {
Edit: Commit on hotfix branch: https://github.com/mathiasaerts/zenbot/commit/59eed42cb816effe1397d87187e208978d91e2ea#diff-c081f5fa7634cfc3a1254e982a748f9c
Edit: Commit on hotfix branch: mathiasaerts/zenbot@59eed42#diff-c081f5fa7634cfc3a1254e982a748f9c
With this change in the simulation mode, the bot shows the worst result ...
@mathiasaerts Great!. Did you already make some simulations comparing the result before and after your fix (same period, same options)? Can you do it ?
(I'm assuming s.period.trend_ema_rate represents EMA and s.period.trend_ema_stddev represents last(EMA) here. Please correct me if I'm wrong..)
Nope, you're wrong trend_ema_rate
is the trend_ema
expressed as a rate:
(EMA - last(EMA)) / last(EMA) * 100
https://github.com/carlos8f/zenbot/blob/55d877a1998e65171c3efa544d8b3476ee11e61f/extensions/strategies/trend_ema/strategy.js#L30
trend_ema_rate
is positive if EMA - last(EMA) > 0
so the signal should be buy, negative if EMA - last(EMA) < 0
so the signal should be sell
trend_ema_stddev
is a threshold value that avoid trades if -trend_ema_stddev < trend_ema_rate < trend_ema_stddev
, by default is the standard deviation of the trend_ema
on the last 10 periods, but it could be overridden by a static value passing the option neutral_rate
.
So https://github.com/carlos8f/zenbot/blob/55d877a1998e65171c3efa544d8b3476ee11e61f/extensions/strategies/trend_ema/strategy.js#L51-L64 conditions are correct, the issue is not here.
What I don't get is s.acted_on_trend
variable, looking at the code it should always be false or undefined so the ternary operator
https://github.com/carlos8f/zenbot/blob/55d877a1998e65171c3efa544d8b3476ee11e61f/extensions/strategies/trend_ema/strategy.js#L64
always resolve the first expression -> it always acts. This does not sound right to me, I'll have a look and get back.
How did that work out?
On Dec 12, 2017, 5:08 PM, at 5:08 PM, Mathias Aerts notifications@github.com wrote:
I was going to try this bot but then noticed this issue. Checking the code made me wonder, in the file mentioned above (
extensions/strategies/trend_ema/strategy.js
), the description at the top says:Buy when (EMA - last(EMA) > 0) and sell when (EMA - last(EMA) < 0).
_(I'm assuming
s.period.trend_ema_rate
representsEMA
ands.period.trend_ema_stddev
representslast(EMA)
here. Please correct me if I'm wrong..)_
- On line 51,
s.period.trend_ema_rate > s.period.trend_ema_stddev
does match(EMA - last(EMA) > 0)
(→ Buy)However, the code at line 59 doesn't seem to reflect this statement and it seems a logic error was made while putting it into code:
s.period.trend_ema_rate < (s.period.trend_ema_stddev * -1)
does not seem to match(EMA - last(EMA) < 0)
(→ Sell)Let's say
EMA
=s.period.trend_ema_rate
=a
andlast(EMA)
=s.period.trend_ema_stddev
=b
In this case, the description says we should sell whena - b < 0
, however it's clear that when we rewrite it to match the current format in code, this does not add up:
a - b < 0
(a - b) + b < 0 + b
a < b
, while in code, it currently saysa < -b
So, I'm going to change line 59 to the following and then give this bot a spin!
else if (!s.cancel_down && s.period.trend_ema_rate < s.period.trend_ema_stddev) {
-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/carlos8f/zenbot/issues/189#issuecomment-351246947
@smarzola Thanks for clearing that up. I was obviously drawing a conclusion way too fast. @kazdimenator Thanks for trying it out anyway! It seems like I need to take a better look first..
@smarzola The "acted_on_trend" part of the code does not make sense to me either. It seems like the code is trying to say "if the trend in the last period was not up, then we did not act on it", ie "act" on the first period with a buy signal. The way the code currently is, it seems like the acted_on_trend variable is a dummy variable that is not really doing anything. In live trading, the moment the buy threshold is hit (emarate > trend_ema_stddev), the console output signals a "buy"; then on the next period if emarate>trend_ema_stddev still holds, it says "buying" and attempts to make the trade until it says "bought". (similar for "sell", "selling", "sold" statuses). Not sure if this helps you in any way, just trying to spark some ideas.
@krilson it would be very interesting to see this play out so that the bot does not whipsaw as much and does not enters/exit so suddenly. i may try playing with this (ema current - ema previous = close to 0) = subsignal 1 (S1) (ema current - ema previous = positive) = subsignal 2 (S2) - ema going up (ema current - ema previous = negative) = subsignal 3 (S3) - ema going down Buy on consecutive S2 signals, or when pattern goes from S3-->S1-->S2 (reversal) Sell on consecutive S3 signals, or when the pattern goes from S2-->S1-->S3 (reversal)
Observations for neutral_rate: For using small periods like 2m or 5m, neutral_rate="auto" works well, but causes too many whipsaws. For larger periods (15m, 1h), neutral_rate="auto" does not trigger often thus some set the neutral_rate to an arbitrary .1 or .2 (i guess because this .1 or .2 is bigger than the trend_ema_stddev using a long period). I wonder if multiplying the trend_ema_stddev by a variable based on period size would work instead of setting it manually. To generalize, since neutral_rate and period are correlated, perhaps there is some variable "k" such that k*trend_ema_stddev smoothes the whipsaws, where k is larger for small periods and smaller for large periods. This would help filter out whipsaws for small-period trials and help pick up signals better for large periods trials using a variable neutral_rate.
I hope the above is helpful in some way. If i implement the new trend or new neutral_rate strategy mentioned above I will post the code snippets (despite having ever coded in node.js). Thank you for devoting the time to developing and improving Zenbot, very amazing tool.
EDIT (results): I tested multiplying the stddev by a constant - while it filters out whipsaws a bit for low periods, it makes the buy/sell trigger peaks less accurate, so there will always be that tradeoff; concluded that the default neutral_rate is great without the multiplier for low periods and ideally an arbitrary constant close to 0 for larger periods. Also briefly tested krilson's strategy - one can accomplish this using s.period.trend_ema_rate_1 = (s.lookback[0].trend_ema - s.lookback[1].trend_ema) / s.lookback[1].trend_ema 100 s.period.trend_ema_rate_2 = (s.lookback[1].trend_ema - s.lookback[2].trend_ema) / s.lookback[2].trend_ema 100 .......... (for t periods, depending on how sensitive you want the signal to be) Then for all of them do: if s.period.trend_ema_rate_t > neutral_rate, S2, if s.period.trend_ema_rate_t < -neutral_rate, S3, else S1 Store these rates in an array {rate_1, rate_2, .... , rate_t} And code the strategy: for example, if {S3 S3 S1 S2 S2} then buy, if {S2 S2 S1 S3 S3} then sell I personally got too lazy to implement all the variations for this last step; if someone has a proposition to nail these combinations, perhaps I can finish the code. I imagine this working very well at picking up momentum in low-period (1m, 2m) simulations
this might just be a layperson's observations of what's going on behind the scenes, but this is what i'm observing.
current:
the way it SHOULD be:
other thoughts: this is less of a concern for people using strategies that are <5m in period_length, but if you're over 5/10m, let's say 45m, and current period data indicates an oversold/buy/sell 10m into your current period, it's gonna wait 35m to act on that?...that don't work.
strategies are also the wrong approach. strategies should be replaced with a library of technical indicators which one should be allowed to use in order to create strategies via simple equation logic. maybe provide a handful of out of the box "strategies" to show how they are utilized, but not depend upon them for continued or base utility.
No news about this?
Hey guys! I'm working on a new bot: Bot18, which will be more flexible, better execution, not TA-dependent. Hopefully will lead to much better profitability! However, exchange support will take a while to port over and implement for the new socket-based, realtime approach. Stay tuned!
https://github.com/DeviaVir/zenbot/issues/1589
~Carlos
@shr00mie, those are my thoughts entirely, and I've implemented that approach already in Bot18. It's gonna be 🔥 !
@carlos8f so it sounds like this is going to be a lot more event driven than the on_period nature of zenbot (yay!). the approach i'm currently working around is standardization of api/websocket components to hopefully allow plug and play exchange connectivity. commands and URLs would be the variables while standardization of API/websocket/order workflow would be ubiquitous.
what would you be replacing TA with any why? not following on the desire or move away from a standardized computational lib. something hand made or custom seems like it would be considerably more error prone.
looking forward to seeing what you're doing with as well as how data is going to be stored compared to zenbot (which was pretty painful). i feel like the DB could have been considerably more utilized for things like trade history, user account storage (user app login&pass, encrypted API keys, etc).
@shr00mie yes, bot18 will need to standardize the ws API workflow. bot18 doesn't have exchange abstraction yet, so i can focus on the maximum potential of the gdax api, my primary target. abstraction will come as soon as i get the foundation laid.
I'm not replacing TA with anything, just moving TA to the background, one potential way to generate orders. The engine will be more low-level, so basically the commands are:
Then, if we're mimicking what Zenbot 4 does by default, the strategy says every 2m,
That way, the engine input is changed to 3 mix-and-match commands (you can now buy and sell at the same time with multiple orders on each side), instead of a vague "signal" which invalidates signals before it and doesn't differentiate between command 2 and 3 (you have to provide taker or maker as an arg)
And the addition of command 1, which doesn't exist in Zenbot yet, will make market-making possible, and strategies will be able to maintain trailing stops directly.
Gave this a try, exchange poloniex, default settings, live trading (not sim).
The bot consistently without exception buys at price X and sells at a lower price. It is doing the opposite of what it should be doing. ( I am not kidding, every trade was with a loss, even in this crazy bull market we have now)
Even tried disabling c.sell_stop_pct = 0 but still it persists in doing this.
Example: Buy NXT at 0.00003540 at 2017-05-24 02:13:05 Sell NXT at 0.00003449 at 2017-05-24 13:02:01
I will leave it running and keep up with the updates if the behavior changes maybe.
Edit: To also mention, I have it running on 10 pairs. Every trade that happened on any of the pairs was this way. Sold at a lower price. And it is running now for about 5 days. Maybe the long term result will be different.