Open MaxCCC opened 6 years ago
Would be interesting to see some more signals. Adding the trigger should be easy once the MACD has been implemented. Feel free to look into adding the signal yourself - have a look at the calculate_RSI
method inside the trader.py
file (line 343 currently). If you add a calculate_MACD
method there, I can help you add it to the buy strategy.
@MaxCCC @JPStrydom It seems it should not be too difficult when I look here. Using stockstats and/or panda it should be relatively easy to calculate macd. Maybe the difficulty could be getting the right data? I'm not in the codebase (yet) + have to look which data the bittrex API can provide.
To implement this we'll probably need APIv2 instead of 1.1 of Bittrex: https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=BTC-WAVES&tickInterval=thirtyMin&_=1499127220008 I don't know if it's an option for you @JPStrydom (not sure if it's official)
I'm already using some of the V2 endpoints in the bot. I use one for the RSI. Have a look at the code I mentioned, and you'll see how to use it.
@JPStrydom I looked a bit in the code. First of all, I'm not a python dev as you probably will see. I checked the historical_data
which I need to calculate the macd. So I used this part int the code (inget_closing_prices in trader.py
)
historical_data = self.Bittrex.get_historical_data(coin_pair, period, unit)
I replaced it with (This is not a real implementation but it looked the best way to me to test it):
historical_data = self.Bittrex.get_historical_data(coin_pair, period, unit)
self.calculate_MACD(historical_data)
exit()
_PS. I'm not sur why this seems not to work:
historical_data = self.Bittrex.get_historical_data('BTC-LTC', 'day', 100)
Or even not the same values as the defauls:
un_historical_data = self.Bittrex.get_historical_data('BTC-LTC', 'fiveMin', 42)
_
But okay I just get the historical data and trigger calculate_MACD.
Historical data looks like this:
[{'O': 0.016291, 'H': 0.016291, 'L': 0.01625555, 'C': 0.01627328, 'V': 148.4653244, 'T': '2018-05-02T14:45:00', 'BV': 2.41433593}, ...
Where O is open, H is high, L is low, C is close, V is volume, T is datetime, BV is Base volume. I found the stockstats. It seems to expect: open, high, low, close, volume (like here).
import pandas as pd
from stockstats import StockDataFrame
def calculate_MACD(self, historical_data):
df = pd.io.json.json_normalize(historical_data)
# Get logical order and ignore unnecessary BV
df = df[['T', 'L', 'H', 'O', 'C']]
df.columns = ['datetime', 'low', 'high', 'open', 'close']
df = StockDataFrame.retype(df)
df['macd'] = df.get('macd')
print(df)
Is this something you could use? I did not verify the data yet. Maybe I can create a drawing to check if it's the same as bittrex is providing.
OUTPUT:
datetime low high open close close_12_ema \
0 2018-05-02T14:50:00 0.016260 0.016291 0.016260 0.016291 0.016291
1 2018-05-02T14:55:00 0.016290 0.016291 0.016291 0.016291 0.016291
2 2018-05-02T15:00:00 0.016274 0.016291 0.016291 0.016274 0.016284
3 2018-05-02T15:05:00 0.016270 0.016291 0.016274 0.016274 0.016281
4 2018-05-02T15:10:00 0.016271 0.016291 0.016291 0.016271 0.016278
5 2018-05-02T15:15:00 0.016260 0.016271 0.016270 0.016271 0.016276
6 2018-05-02T15:20:00 0.016270 0.016271 0.016271 0.016271 0.016275
7 2018-05-02T15:25:00 0.016256 0.016271 0.016271 0.016271 0.016274
8 2018-05-02T15:30:00 0.016257 0.016291 0.016271 0.016291 0.016278
9 2018-05-02T15:35:00 0.016291 0.016314 0.016291 0.016291 0.016280
10 2018-05-02T15:40:00 0.016291 0.016314 0.016314 0.016300 0.016284
11 2018-05-02T15:45:00 0.016300 0.016320 0.016313 0.016316 0.016290
12 2018-05-02T15:50:00 0.016300 0.016322 0.016320 0.016322 0.016295
13 2018-05-02T15:55:00 0.016300 0.016322 0.016300 0.016319 0.016299
14 2018-05-02T16:00:00 0.016300 0.016322 0.016319 0.016322 0.016303
15 2018-05-02T16:05:00 0.016270 0.016322 0.016322 0.016300 0.016303
16 2018-05-02T16:10:00 0.016270 0.016322 0.016300 0.016270 0.016297
17 2018-05-02T16:15:00 0.016270 0.016290 0.016290 0.016270 0.016293
18 2018-05-02T16:20:00 0.016270 0.016322 0.016270 0.016300 0.016294
19 2018-05-02T16:25:00 0.016280 0.016322 0.016280 0.016322 0.016298
20 2018-05-02T16:30:00 0.016290 0.016351 0.016322 0.016290 0.016297
21 2018-05-02T16:35:00 0.016270 0.016350 0.016290 0.016350 0.016305
22 2018-05-02T16:40:00 0.016270 0.016350 0.016322 0.016316 0.016307
23 2018-05-02T16:45:00 0.016267 0.016350 0.016316 0.016283 0.016303
24 2018-05-02T16:50:00 0.016256 0.016350 0.016299 0.016260 0.016297
25 2018-05-02T16:55:00 0.016256 0.016350 0.016280 0.016295 0.016296
26 2018-05-02T17:00:00 0.016255 0.016365 0.016350 0.016256 0.016290
27 2018-05-02T17:05:00 0.016255 0.016357 0.016260 0.016257 0.016285
28 2018-05-02T17:10:00 0.016138 0.016356 0.016257 0.016327 0.016291
29 2018-05-02T17:15:00 0.016250 0.016325 0.016300 0.016270 0.016288
30 2018-05-02T17:20:00 0.016270 0.016325 0.016270 0.016294 0.016289
31 2018-05-02T17:25:00 0.016240 0.016294 0.016280 0.016275 0.016287
32 2018-05-02T17:30:00 0.016250 0.016310 0.016275 0.016310 0.016290
33 2018-05-02T17:35:00 0.016294 0.016325 0.016310 0.016325 0.016296
34 2018-05-02T17:40:00 0.016295 0.016325 0.016325 0.016325 0.016300
35 2018-05-02T17:45:00 0.016320 0.016358 0.016325 0.016358 0.016309
36 2018-05-02T17:50:00 0.016328 0.016358 0.016328 0.016342 0.016314
37 2018-05-02T17:55:00 0.016320 0.016358 0.016358 0.016350 0.016320
38 2018-05-02T18:00:00 0.016304 0.016358 0.016350 0.016342 0.016323
39 2018-05-02T18:05:00 0.016295 0.016358 0.016342 0.016325 0.016323
40 2018-05-02T18:10:00 0.016320 0.016325 0.016325 0.016320 0.016323
41 2018-05-02T18:15:00 0.016320 0.016350 0.016320 0.016325 0.016323
close_26_ema macd macds macdh
0 0.016291 0.000000e+00 0.000000e+00 0.000000e+00
1 0.016291 0.000000e+00 0.000000e+00 0.000000e+00
2 0.016285 -5.364720e-07 -2.198656e-07 -6.332128e-07
3 0.016282 -7.673224e-07 -4.053184e-07 -7.240079e-07
4 0.016279 -9.840482e-07 -5.774774e-07 -8.131415e-07
5 0.016278 -1.095833e-06 -7.179806e-07 -7.557047e-07
6 0.016276 -1.148646e-06 -8.269706e-07 -6.433513e-07
7 0.016276 -1.175578e-06 -9.107475e-07 -5.296611e-07
8 0.016278 -1.736492e-07 -7.404742e-07 1.133650e-06
9 0.016280 5.396186e-07 -4.536591e-07 1.986555e-06
10 0.016282 1.526417e-06 -2.042976e-08 3.093693e-06
11 0.016286 3.128891e-06 6.559122e-07 4.945957e-06
12 0.016291 4.593851e-06 1.489317e-06 6.209068e-06
13 0.016294 5.477145e-06 2.323573e-06 6.307143e-06
14 0.016297 6.230060e-06 3.133363e-06 6.193394e-06
15 0.016297 5.388769e-06 3.597508e-06 3.582521e-06
16 0.016294 2.824995e-06 3.439446e-06 -1.228904e-06
17 0.016292 8.256166e-07 2.907090e-06 -4.162947e-06
18 0.016293 1.203498e-06 2.561390e-06 -2.715784e-06
19 0.016296 2.907763e-06 2.631472e-06 5.525815e-07
20 0.016295 2.079193e-06 2.519988e-06 -8.815903e-07
21 0.016300 5.436837e-06 3.107695e-06 4.658285e-06
22 0.016301 5.687564e-06 3.626732e-06 4.121664e-06
23 0.016300 3.550644e-06 3.611442e-06 -1.215975e-07
24 0.016296 2.234972e-07 2.931284e-06 -5.415573e-06
25 0.016296 9.827136e-08 2.362964e-06 -4.529385e-06
26 0.016293 -2.806667e-06 1.326532e-06 -8.266398e-06
27 0.016290 -4.934626e-06 7.187325e-08 -1.001300e-05
28 0.016293 -1.516713e-06 -2.463365e-07 -2.540754e-06
29 0.016291 -2.946092e-06 -7.869569e-07 -4.318271e-06
30 0.016291 -2.243066e-06 -1.078467e-06 -2.329197e-06
31 0.016290 -3.088491e-06 -1.480791e-06 -3.215400e-06
32 0.016292 -1.129961e-06 -1.410580e-06 5.612388e-07
33 0.016294 1.523832e-06 -8.234002e-07 4.694464e-06
34 0.016297 3.581661e-06 5.796961e-08 7.047384e-06
35 0.016302 7.647501e-06 1.576369e-06 1.214226e-05
36 0.016305 9.523706e-06 3.166249e-06 1.271491e-05
37 0.016308 1.148908e-05 4.831160e-06 1.331583e-05
38 0.016311 1.228623e-05 6.322422e-06 1.192762e-05
39 0.016312 1.146973e-05 7.352020e-06 8.235417e-06
40 0.016313 1.032424e-05 7.946527e-06 4.755419e-06
41 0.016314 9.684967e-06 8.294244e-06 2.781445e-06
Process finished with exit code 0
Looking good dude 👍 I'm not entirely sure how to use the MACD for triggers, but if the function gives it in a easy to read format, it can easily be added as a buy/sell trigger.
How would one interpret the MACD output?
@JPStrydom Well I have to admit I need to investigate it more (also know someone who knows it well). I'm more familiar with the charts and comparing the macd and signal line instead of looking to the real data. But what I found here:
(I'm still checking every 5minutes while I think it needs to be a day, but that's stuff I need to explore more)
def calculate_MACD(self, historical_data):
df = pd.io.json.json_normalize(historical_data)
df = df[['T', 'L', 'H', 'O', 'C']]
#ignore BV
df.columns = ['datetime', 'low', 'high', 'open', 'close']
df = StockDataFrame.retype(df)
df['macd'] = df.get('macd')
#print(df)
signal = df['macds']
macd = df['macd']
listLongShort = ["No data"]
for i in range(1, len(signal)):
# # If the MACD crosses the signal line upward
if macd[i] > signal[i] and macd[i - 1] <= signal[i - 1]:
listLongShort.append("BUY")
# # The other way around
elif macd[i] < signal[i] and macd[i - 1] >= signal[i - 1]:
listLongShort.append("SELL")
# # Do nothing if not crossed
else:
listLongShort.append("HOLD")
df['Advice'] = listLongShort
# The advice column means "Buy/Sell/Hold" at the end of this day or
# at the beginning of the next day, since the market will be closed
print(df['Advice'])
Output:
Tracking 192 Bittrex Markets
0 No data
1 BUY
2 SELL
3 HOLD
4 HOLD
5 HOLD
6 BUY
7 HOLD
8 HOLD
9 HOLD
10 HOLD
11 SELL
12 HOLD
13 HOLD
14 HOLD
15 HOLD
16 HOLD
17 HOLD
18 HOLD
19 BUY
20 HOLD
21 HOLD
22 HOLD
23 HOLD
24 HOLD
25 HOLD
26 HOLD
27 HOLD
28 HOLD
29 HOLD
30 HOLD
31 HOLD
32 HOLD
33 SELL
34 HOLD
35 HOLD
36 HOLD
37 BUY
38 SELL
39 HOLD
40 BUY
41 HOLD
I went a bit more in depth and macd and RSI are often combined. The unit (5 minutes in the example) can be used for macd too. It's just a choice like with RSI. It can also be one day.
"You can combine them by first validating the MACD (like above: Buy/Hold/Sell..). When it's a BUY you can start checking the RSI and if it's low enough -> Buy. I read to avoid executing trades when RSI is between 45-55 or to be more conservative between 40-60. This means it's less strict but it's using 2 indicators."
2) "Enter the market whenever the RSI gives an overbought or oversold signal which is supported by a MACD signal line crossing. (70/30) which is supported by a MACD signal line crossing. (Buy in the list above)" Buy signal.
I think it needs some further research. A blind implementation won't be useful. I don't know if I have the time/knowledge to try to implement some "test" scenario without buying/selling in reality. I'm convinced they can be useful when they are combined but it's a "search" to find out good values for RSI (30/70, 25/75, 20/80) + 14 period (or 7, 9 or, 10) which are also used in 'short term' trading) etc...
I'm adding some test scenario with what I've posted above. I'm using a thickinterval of 30 mins but as I've mentioned it can be everything. I'm not sure about the period (to get the historical data). Now I chose for 100 because I saw it as max period in crypto-signal .. It can be as much as I want. I'm using the value of RSI for my 30 mins and I use the last value of my df list.
df
printed (last line):
99 2018-05-04T19:00:00 0.016947 0.016947 0.016947 0.016947 0.016853
So it's 7PM at (bittrex API time, I checked it). When I translate it to my time it corresponds with the latest ThickInterval.
Get the list:
0 No data
1 SELL
2 HOLD
3 BUY
4 HOLD
5 HOLD
6 HOLD
7 HOLD
8 HOLD
9 HOLD
10 HOLD
11 HOLD
12 HOLD
13 HOLD
14 HOLD
15 HOLD
16 HOLD
17 SELL
18 BUY
19 HOLD
20 HOLD
21 HOLD
22 HOLD
23 HOLD
24 SELL
25 HOLD
26 HOLD
27 HOLD
28 HOLD
29 HOLD
...
70 HOLD
71 HOLD
72 HOLD
73 BUY
74 HOLD
75 HOLD
76 HOLD
77 HOLD
78 HOLD
79 HOLD
80 HOLD
81 HOLD
82 HOLD
83 HOLD
84 HOLD
85 HOLD
86 HOLD
87 HOLD
88 HOLD
89 HOLD
90 HOLD
91 SELL
92 HOLD
93 HOLD
94 HOLD
95 BUY
96 HOLD
97 HOLD
98 HOLD
99 HOLD
and I pick the last value which is HOLD
in this case (most cases). Now it would be cool to adapt the other functions to use RSI and macd. If you're still interested we could maybe implement this in a side branch and use it as test before implementing it? My knowledge does not extend far enough now to adjust everything (changing parameter stuff, buy / sell function etc).
Otherwise I'll stop spamming you and maybe try some stuff on my own :)
I like the idea of only applying the RSI check to MACD buy signals. It'll make the trades more secure.
Once I have some time I'll make a new branch and add this functionality to it.
I'll add it to buy first and then later to sell.
I'll use your functionality for the MACD and I'll let you know when it's up.
Thanks for all the work! 👍
Has the MACD check been integrated into the rest of the source code? I can't find any recent commits
Is there a chance we can trigger our auto-buys/auto-sells with a MACD (Moving Average Convergence Divergence) indicator in the feature?