This repository has been archived by the owner on Oct 29, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 86
/
Bot_CustomStrategy.py
136 lines (110 loc) · 4.62 KB
/
Bot_CustomStrategy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import time
# Imports for the strategy
import pandas_ta as ta
# Importing these to be able to run this example
# from the main pyjuque folder
from os.path import abspath, pardir, join
import sys
curr_path = abspath(__file__)
root_path = abspath(join(curr_path, pardir, pardir))
sys.path.append(root_path)
# Import for defining the bot
from pyjuque.Bot import defineBot
def customEntryStrategy(bot_controller, symbol):
## This is the function that pyjuque will call to check for entry signal
## the first parammeter is a bot_controller, through which we have access
## to the following objects:
##
## bot_controller.bot_model (a SQLAlchemy model, containing the info that
# we store in the database for this bot plus a few methods)
## bot_controller.session (a SQLAlchemy database session)
## bot_controller.exchange (a CcxtExchanges, exposing a few wrapped methods
## written to work with pyjuque plus all the ccxt unified api methods,
## through bot_controller.exchange.ccxt)
## bot_controller.strategy (in our case it will be None)
## bot_controller.status_printer (yaspin object)
##
## and the following method:
## bot_controller.executeBot() (executes a loop of the bot - checking
## entry signals on all symbols, placing orders if any signals are
## found, then checking all the open orders and updating them)
##
## it returns a boolean (the signal) and the current price of the asset
# Get data from exchange for multiple timeframes
df_15min = bot_controller.exchange.getOHLCV(symbol, '15m', limit=100)
df_1hour = bot_controller.exchange.getOHLCV(symbol, '1h', limit=100)
df_4hour = bot_controller.exchange.getOHLCV(symbol, '4h', limit=100)
# Define and compute indicators for each timeframe
Strat = ta.Strategy(
name="EMAs",
ta=[
{"kind": "ema", "length": 20},
{"kind": "ema", "length": 50},
]
)
df_15min.ta.strategy(Strat)
df_1hour.ta.strategy(Strat)
df_4hour.ta.strategy(Strat)
# Check entry signal on each timeframe separately
entry_signal_15 = df_15min.iloc[-1]['EMA_50'] > df_15min.iloc[-1]['EMA_20']
entry_signal_1h = df_1hour.iloc[-1]['EMA_50'] > df_1hour.iloc[-1]['EMA_20']
entry_signal_4h = df_4hour.iloc[-1]['EMA_50'] > df_1hour.iloc[-1]['EMA_20'] and \
df_4hour.iloc[-2]['EMA_50'] < df_1hour.iloc[-2]['EMA_20']
# Combine them
entry_signal = entry_signal_15 and entry_signal_1h and entry_signal_4h
# Return the signal and the last price
return entry_signal, df_4hour.iloc[-1]['close']
## Defines the overall configuration of the bot
bot_config = {
# Name of the bot, as stored in the database
'name' : 'my_multi_timeframe_bot',
# exchange information (fill with your api key and secret)
'exchange' : {
'name' : 'binance',
'params' : {
'api_key': '...',
'secret' : '...'
},
},
# symbols to trade on
'symbols' : ['LINK/BTC', 'ETH/BTC', 'ADA/BTC'],
# starting balance for bot
'starting_balance' : 0.0005,
# strategy class / function (here we define the entry and exit strategies.)
# this bot places an entry order when 'customEntryStrategy' retruns true
'strategy': {
'custom': True,
'entry_function': customEntryStrategy,
},
# when the bot receives the buy signal, the order is placed according
# to the settings specified below
'entry_settings' : {
# between 0 and 100, the % of the starting_balance to put in an order
'initial_entry_allocation': 50,
# number between 0 and 100 - 1% means that when we get a buy signal,
# we place buy order 1% below current price. if 0, we place a market
# order immediately upon receiving signal
'signal_distance': 0.3
},
# This bot exits when our filled orders have reached a take_profit % above
# the buy price, or a stop_loss_value % below it
'exit_settings' : {
# take profit value between 0 and infinity, 3% means we place our sell
# orders 3% above the prices that our buy orders filled at
'take_profit' : 3,
# stop loss value in percent - 10% means stop loss at 10% below our
# buy order's filled price
'stop_loss_value': 10
} ,
}
## Runs the bot in an infinite loop, stoppable from the terminal with CTRL + C
def Main():
bot_controller = defineBot(bot_config)
while True:
try:
bot_controller.executeBot()
except KeyboardInterrupt:
return
time.sleep(60)
if __name__ == '__main__':
Main()