Skip to content

Commit a8c6bf8

Browse files
Add files via upload
1 parent f2a908a commit a8c6bf8

File tree

8 files changed

+529
-1
lines changed

8 files changed

+529
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import bitfinex
2+
import datetime
3+
import time
4+
import pandas as pd
5+
6+
# Create api instance of the v2 API
7+
api_v2 = bitfinex.bitfinex_v2.api_v2()
8+
9+
# Define query parameters
10+
pair = 'BTCUSD' # Currency pair of interest
11+
TIMEFRAME = '1h'#,'4h','1h','15m','1m'
12+
13+
# Define the start date
14+
t_start = datetime.datetime(2018, 9, 1, 0, 0)
15+
t_start = time.mktime(t_start.timetuple()) * 1000
16+
17+
# Define the end date
18+
t_stop = datetime.datetime(2020, 10, 1, 0, 0)
19+
t_stop = time.mktime(t_stop.timetuple()) * 1000
20+
21+
# Download OHCL data from API
22+
result = api_v2.candles(symbol=pair, interval=TIMEFRAME, limit=1000, start=t_start, end=t_stop)
23+
24+
# Convert list of data to pandas dataframe
25+
names = ['Date', 'Open', 'Close', 'High', 'Low', 'Volume']
26+
df = pd.DataFrame(result, columns=names)
27+
df['Date'] = pd.to_datetime(df['Date'], unit='ms')
28+
29+
# we can plot our downloaded data
30+
import matplotlib.pyplot as plt
31+
plt.plot(df['Open'],'-')
32+
plt.show()

RL-Bitcoin-trading-bot_6/RL-Bitcoin-trading-bot_6.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def test_agent(env, agent, visualize=True, test_episodes=10, folder="", name="Cr
432432
df = df.sort_values('Date')
433433
df = AddIndicators(df) # insert indicators to df
434434

435-
lookback_window_size = 100
435+
lookback_window_size = 50
436436
test_window = 720*3 # 3 months
437437
train_df = df[100:-test_window-lookback_window_size] # we leave 100 to have properly calculated indicators
438438
test_df = df[-test_window-lookback_window_size:]
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#================================================================
2+
#
3+
# File name : multiprocessing_env.py
4+
# Author : PyLessons
5+
# Created date: 2021-..-..
6+
# Website : https://pylessons.com/
7+
# GitHub : https://github.com/pythonlessons/RL-Bitcoin-trading-bot
8+
# Description : functions to train/test multiple custom BTC trading environments
9+
#
10+
#================================================================
11+
from collections import deque
12+
from multiprocessing import Process, Pipe
13+
import numpy as np
14+
from datetime import datetime
15+
16+
class Environment(Process):
17+
def __init__(self, env_idx, child_conn, env, training_batch_size, visualize):
18+
super(Environment, self).__init__()
19+
self.env = env
20+
self.env_idx = env_idx
21+
self.child_conn = child_conn
22+
self.training_batch_size = training_batch_size
23+
self.visualize = visualize
24+
25+
def run(self):
26+
super(Environment, self).run()
27+
state = self.env.reset(env_steps_size = self.training_batch_size)
28+
self.child_conn.send(state)
29+
while True:
30+
reset, net_worth, episode_orders = 0, 0, 0
31+
action = self.child_conn.recv()
32+
if self.env_idx == 0:
33+
self.env.render(self.visualize)
34+
state, reward, done = self.env.step(action)
35+
36+
if done or self.env.current_step == self.env.end_step:
37+
net_worth = self.env.net_worth
38+
episode_orders = self.env.episode_orders
39+
state = self.env.reset(env_steps_size = self.training_batch_size)
40+
reset = 1
41+
42+
self.child_conn.send([state, reward, done, reset, net_worth, episode_orders])
43+
44+
def train_multiprocessing(CustomEnv, agent, train_df, num_worker=4, training_batch_size=500, visualize=False, EPISODES=10000):
45+
works, parent_conns, child_conns = [], [], []
46+
episode = 0
47+
total_average = deque(maxlen=100) # save recent 100 episodes net worth
48+
best_average = 0 # used to track best average net worth
49+
50+
for idx in range(num_worker):
51+
parent_conn, child_conn = Pipe()
52+
env = CustomEnv(train_df, lookback_window_size=agent.lookback_window_size)
53+
work = Environment(idx, child_conn, env, training_batch_size, visualize)
54+
work.start()
55+
works.append(work)
56+
parent_conns.append(parent_conn)
57+
child_conns.append(child_conn)
58+
59+
agent.create_writer(env.initial_balance, env.normalize_value, EPISODES) # create TensorBoard writer
60+
61+
states = [[] for _ in range(num_worker)]
62+
next_states = [[] for _ in range(num_worker)]
63+
actions = [[] for _ in range(num_worker)]
64+
rewards = [[] for _ in range(num_worker)]
65+
dones = [[] for _ in range(num_worker)]
66+
predictions = [[] for _ in range(num_worker)]
67+
68+
state = [0 for _ in range(num_worker)]
69+
for worker_id, parent_conn in enumerate(parent_conns):
70+
state[worker_id] = parent_conn.recv()
71+
72+
while episode < EPISODES:
73+
predictions_list = agent.Actor.actor_predict(np.reshape(state, [num_worker]+[_ for _ in state[0].shape]))
74+
actions_list = [np.random.choice(agent.action_space, p=i) for i in predictions_list]
75+
76+
for worker_id, parent_conn in enumerate(parent_conns):
77+
parent_conn.send(actions_list[worker_id])
78+
action_onehot = np.zeros(agent.action_space.shape[0])
79+
action_onehot[actions_list[worker_id]] = 1
80+
actions[worker_id].append(action_onehot)
81+
predictions[worker_id].append(predictions_list[worker_id])
82+
83+
for worker_id, parent_conn in enumerate(parent_conns):
84+
next_state, reward, done, reset, net_worth, episode_orders = parent_conn.recv()
85+
states[worker_id].append(np.expand_dims(state[worker_id], axis=0))
86+
next_states[worker_id].append(np.expand_dims(next_state, axis=0))
87+
rewards[worker_id].append(reward)
88+
dones[worker_id].append(done)
89+
state[worker_id] = next_state
90+
91+
if reset:
92+
episode += 1
93+
a_loss, c_loss = agent.replay(states[worker_id], actions[worker_id], rewards[worker_id], predictions[worker_id], dones[worker_id], next_states[worker_id])
94+
total_average.append(net_worth)
95+
average = np.average(total_average)
96+
97+
agent.writer.add_scalar('Data/average net_worth', average, episode)
98+
agent.writer.add_scalar('Data/episode_orders', episode_orders, episode)
99+
100+
print("episode: {:<5} worker: {:<1} net worth: {:<7.2f} average: {:<7.2f} orders: {}".format(episode, worker_id, net_worth, average, episode_orders))
101+
if episode > len(total_average):
102+
if best_average < average:
103+
best_average = average
104+
print("Saving model")
105+
agent.save(score="{:.2f}".format(best_average), args=[episode, average, episode_orders, a_loss, c_loss])
106+
agent.save()
107+
108+
states[worker_id] = []
109+
next_states[worker_id] = []
110+
actions[worker_id] = []
111+
rewards[worker_id] = []
112+
dones[worker_id] = []
113+
predictions[worker_id] = []
114+
115+
agent.end_training_log()
116+
# terminating processes after while loop
117+
works.append(work)
118+
for work in works:
119+
work.terminate()
120+
print('TERMINATED:', work)
121+
work.join()
122+
123+
def test_multiprocessing(CustomEnv, agent, test_df, num_worker = 4, visualize=False, test_episodes=1000, folder="", name="Crypto_trader", comment="", initial_balance=1000):
124+
agent.load(folder, name)
125+
works, parent_conns, child_conns = [], [], []
126+
average_net_worth = 0
127+
average_orders = 0
128+
no_profit_episodes = 0
129+
episode = 0
130+
131+
for idx in range(num_worker):
132+
parent_conn, child_conn = Pipe()
133+
env = CustomEnv(test_df, initial_balance=initial_balance, lookback_window_size=agent.lookback_window_size)
134+
work = Environment(idx, child_conn, env, training_batch_size=0, visualize=visualize)
135+
work.start()
136+
works.append(work)
137+
parent_conns.append(parent_conn)
138+
child_conns.append(child_conn)
139+
140+
state = [0 for _ in range(num_worker)]
141+
for worker_id, parent_conn in enumerate(parent_conns):
142+
state[worker_id] = parent_conn.recv()
143+
144+
while episode < test_episodes:
145+
predictions_list = agent.Actor.actor_predict(np.reshape(state, [num_worker]+[_ for _ in state[0].shape]))
146+
actions_list = [np.random.choice(agent.action_space, p=i) for i in predictions_list]
147+
148+
for worker_id, parent_conn in enumerate(parent_conns):
149+
parent_conn.send(actions_list[worker_id])
150+
151+
for worker_id, parent_conn in enumerate(parent_conns):
152+
next_state, reward, done, reset, net_worth, episode_orders = parent_conn.recv()
153+
state[worker_id] = next_state
154+
155+
if reset:
156+
episode += 1
157+
#print(episode, net_worth, episode_orders)
158+
average_net_worth += net_worth
159+
average_orders += episode_orders
160+
if net_worth < initial_balance: no_profit_episodes += 1 # calculate episode count where we had negative profit through episode
161+
print("episode: {:<5} worker: {:<1} net worth: {:<7.2f} average_net_worth: {:<7.2f} orders: {}".format(episode, worker_id, net_worth, average_net_worth/episode, episode_orders))
162+
if episode == test_episodes: break
163+
164+
print("No profit episodes: {}".format(no_profit_episodes))
165+
# save test results to test_results.txt file
166+
with open("test_results.txt", "a+") as results:
167+
current_date = datetime.now().strftime('%Y-%m-%d %H:%M')
168+
results.write(f'{current_date}, {name}, test episodes:{test_episodes}')
169+
results.write(f', net worth:{average_net_worth/(episode+1)}, orders per episode:{average_orders/test_episodes}')
170+
results.write(f', no profit episodes:{no_profit_episodes}, comment: {comment}\n')
171+
172+
# terminating processes after while loop
173+
works.append(work)
174+
for work in works:
175+
work.terminate()
176+
print('TERMINATED:', work)
177+
work.join()
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from multiprocessing import Process, Pipe
2+
import time
3+
import random
4+
5+
class Environment(Process): # creating environment class for multiprocessing
6+
def __init__(self, env_idx, child_conn):
7+
super(Environment, self).__init__()
8+
self.env_idx = env_idx
9+
self.child_conn = child_conn
10+
11+
def run(self):
12+
super(Environment, self).run()
13+
while True:
14+
number = self.child_conn.recv()
15+
self.child_conn.send(number*2)
16+
17+
if __name__ == "__main__":
18+
works, parent_conns, child_conns = [], [], []
19+
20+
for idx in range(2):
21+
parent_conn, child_conn = Pipe() # creating a communication pipe
22+
work = Environment(idx, child_conn) # creating new process
23+
work.start() # starting process
24+
works.append(work) # saving started procsses to list
25+
parent_conns.append(parent_conn) # saving communication pipe refference to list
26+
child_conns.append(child_conn) # saving communication pipe refference to list
27+
28+
while True:
29+
for worker_id, parent_conn in enumerate(parent_conns):
30+
r = random.randint(0, 10) # creating random number between 0 and 10
31+
parent_conn.send(r) # sending message with random nuber to worker_id running process
32+
33+
time.sleep(1)
34+
35+
for worker_id, parent_conn in enumerate(parent_conns):
36+
result = parent_conn.recv() # reading received message from worker_id process
37+
print(f"From {worker_id} worker received {result}")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
numpy
2+
tensorflow==2.3.1
3+
tensorflow-gpu==2.3.1
4+
opencv-python
5+
matplotlib
6+
tensorboardx
7+
pandas
8+
mplfinance
9+
ta
10+
bitfinex-tencars
17 KB
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2021-02-01 20:19, 1984.93_Crypto_trader, test episodes:1000, net worth:1262.4095575116696, orders per episode:236.972, no profit episodes:1, comment: Dense
2+
2021-02-01 20:20, 1914.81_Crypto_trader, test episodes:1000, net worth:1155.009664210779, orders per episode:297.674, no profit episodes:31, comment: Dense
3+
2021-02-01 20:30, 2961.57_Crypto_trader, test episodes:1000, net worth:1312.6941448123623, orders per episode:452.45, no profit episodes:0, comment: CNN
4+
2021-02-01 21:18, 3142.13_Crypto_trader, test episodes:1000, net worth:1485.8628866706822, orders per episode:541.328, no profit episodes:0, comment: CNN
5+
2021-02-03 20:52, 3146.45_Crypto_trader, test episodes:1000, net worth:1332.4514580243967, orders per episode:537.654, no profit episodes:0, comment: LSTM

0 commit comments

Comments
 (0)