Skip to content

Commit 10a4a2f

Browse files
committed
test arbitraj
1 parent da89229 commit 10a4a2f

6 files changed

+271
-29
lines changed

poloniex/mikasa_bt_rl_q_last_4.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
from keras.models import Sequential
99
from keras.optimizers import Adam
1010

11-
from gym_mikasa.envs import MikasaLast4Env
11+
from mikasa_gym import MikasaEnv
1212

13-
EPISODES = 3000
13+
EPISODES = 10000
14+
LOOK_BACK = 4
1415

1516
random.seed(7)
1617

@@ -22,14 +23,15 @@ def __init__(self, state_size, action_size):
2223
self.memory = deque(maxlen=2000)
2324
self.gamma = 0.95 # discount rate
2425
self.epsilon = 1.0 # exploration rate
25-
self.epsilon_min = 0.0001
26+
self.epsilon_min = 0.00001
2627
self.epsilon_decay = 0.997
2728
self.learning_rate = 0.001
2829
self.model = self._build_model()
2930

3031
def _build_model(self):
3132
# Neural Net for Deep-Q learning Model
3233
model = Sequential()
34+
model.add(Dense(128, input_dim=self.state_size, activation='relu'))
3335
model.add(Dense(64, input_dim=self.state_size, activation='relu'))
3436
model.add(Dense(32, activation='relu'))
3537
model.add(Dense(self.action_size, activation='linear'))
@@ -61,28 +63,28 @@ def replay(self, batch_size):
6163

6264

6365
if __name__ == "__main__":
64-
env = MikasaLast4Env()
65-
state_size = env.observation_space.shape[0]
66+
env = MikasaEnv(source_filename='btc_etc_first100.csv', look_back=LOOK_BACK)
67+
state_size = (env.observation_space.shape[0] - 1)*LOOK_BACK + 1
6668
action_size = env.action_space.n
6769
agent = DQNAgent(state_size, action_size)
6870
done = False
69-
batch_size = 1000
71+
batch_size = 100
7072

7173
history = []
7274

7375
for e in range(EPISODES):
7476
state = env.reset()
7577
state = np.reshape(state, [1, state_size])
7678
reward_sum = 0.0
77-
for time in range(1010):
79+
for time in range(110):
7880
action = agent.act(state)
7981
next_state, reward, done, _ = env.step(action)
8082
reward_sum += reward
8183
next_state = np.reshape(next_state, [1, state_size])
8284
agent.remember(state, action, reward, next_state, done)
8385
state = next_state
8486
if done:
85-
print("episode: {}/{}, score: {:+.2f}, e: {:.3f}"
87+
print("episode: {}/{}, score: {:+.2f}, e: {:.6f}"
8688
.format(e, EPISODES, reward_sum, agent.epsilon))
8789
history.append(reward_sum)
8890
break

poloniex/mikasa_bt_rl_test_mikasa_gym_package.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
from keras.optimizers import Adam
55
from rl.agents.dqn import DQNAgent
66
from rl.memory import SequentialMemory
7-
from rl.policy import EpsGreedyQPolicy, GreedyQPolicy
7+
from rl.policy import EpsGreedyQPolicy
88

99
from mikasa_gym import MikasaEnv
1010

11+
from matplotlib import pyplot as plt
12+
1113
# create Mikasa gym env
1214
env = MikasaEnv(source_filename='btc_etc_first100.csv')
1315
np.random.seed(123)
@@ -25,11 +27,13 @@
2527
model.add(Activation('linear'))
2628

2729
# configure agent
28-
policy = GreedyQPolicy()
30+
policy = EpsGreedyQPolicy()
2931
memory = SequentialMemory(limit=50000, window_length=1)
3032
dqn = DQNAgent(model=model, nb_actions=nb_actions, memory=memory, nb_steps_warmup=100,
3133
target_model_update=1e-2, policy=policy)
3234
dqn.compile(Adam(lr=1e-3), metrics=['mse'])
3335

3436
# run agent
35-
dqn.fit(env, nb_steps=50000, visualize=False, verbose=1)
37+
history = dqn.fit(env, nb_steps=50000, visualize=False, verbose=1)
38+
plt.plot(history.history['episode_reward'])
39+
plt.show()

poloniex/test_poloniex_api.py

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import hashlib
2+
import hmac
3+
import config
4+
import time
5+
import requests
6+
7+
from poloniex import Poloniex
8+
from urllib.parse import urlencode
9+
10+
MIN_SPREAD = 5e-4
11+
TRADE_VOLUME = 1e-6
12+
13+
polo = Poloniex()
14+
15+
16+
class YobitAPI:
17+
TRADE_API = 'https://yobit.net/tapi'
18+
19+
def __init__(self, api_key, secret):
20+
self.api_key = api_key
21+
self.secret = secret
22+
23+
def api_call(self, method, params=None):
24+
if params is None:
25+
params = {}
26+
params['method'] = method
27+
params['nonce'] = str(int(time.time()))
28+
post_data = urlencode(params).encode()
29+
signature = hmac.new(
30+
self.secret.encode(),
31+
post_data,
32+
hashlib.sha512).hexdigest()
33+
headers = {
34+
'Sign': signature,
35+
'Key': self.api_key,
36+
'User-Agent': "Mozilla/5.0"
37+
}
38+
response = requests.post(YobitAPI.TRADE_API, data=params, headers=headers)
39+
response.raise_for_status()
40+
return response.json()
41+
42+
def get_active_orders(self, pair):
43+
return self.api_call('ActiveOrders', {'pair': pair})
44+
45+
def get_info(self):
46+
return self.api_call('getInfo')
47+
48+
def trade(self, pair, type, price, volume):
49+
if type not in ['buy', 'sell']:
50+
raise Exception('type should be in ["buy", "sell"]')
51+
return self.api_call('Trade', {
52+
'pair': pair,
53+
'type': type,
54+
'rate': price,
55+
'amount': volume
56+
})
57+
58+
def withdraw(self, coin, volume, address):
59+
return self.api_call('WithdrawCoinsToAddress', {
60+
'coinName': coin,
61+
'amount': volume,
62+
'address': address
63+
})
64+
65+
66+
def get_min_order(orders):
67+
result_vol = 0
68+
result_price = 1e6
69+
for o in orders:
70+
o = list(map(float, o))
71+
if o[0] < result_price:
72+
result_price = o[0]
73+
result_vol = o[1]
74+
return result_price, result_vol
75+
76+
77+
def get_max_order(orders):
78+
result_vol = 0
79+
result_price = 0
80+
for o in orders:
81+
o = list(map(float, o))
82+
if o[0] > result_price:
83+
result_price = o[0]
84+
result_vol = o[1]
85+
return result_price, result_vol
86+
87+
88+
def get_ticker(pair):
89+
return polo.returnTicker()[pair]
90+
91+
92+
def get_orders(pair):
93+
return polo.returnOrderBook()[pair]
94+
95+
96+
def arbitrage(pair):
97+
orders = get_orders(pair)
98+
highest_bid, bid_vol = get_max_order(orders['bids'])
99+
sell_price = float(highest_bid)
100+
101+
_pair = map(str.lower, pair.split('_')[::-1])
102+
_target_coin, _base_coin = _pair
103+
_pair = '_'.join(_pair)
104+
r = requests.get('https://yobit.net/api/3/depth/{}'.format(_pair))
105+
r.raise_for_status()
106+
data = r.json()
107+
108+
orders = data[_pair]
109+
lowest_ask, ask_vol = get_min_order(orders['asks'])
110+
buy_price = float(lowest_ask)
111+
112+
print('Spread:\t{:.6f}\tVolume:\t{:.6f}'.format(sell_price - buy_price, min(ask_vol, bid_vol)))
113+
yoapi = YobitAPI(config.API_KEY, config.API_SECRET)
114+
yoapi.trade(_pair, 'buy', buy_price, TRADE_VOLUME)
115+
print('Buy ({}): {} for {}'.format(_pair, TRADE_VOLUME, buy_price))
116+
yoapi.withdraw(_target_coin, TRADE_VOLUME, config.TARGET_LTC_ADDRESS)
117+
print('Transfer {} {} to {}'.format(TRADE_VOLUME, _target_coin, config.TARGET_LTC_ADDRESS))
118+
119+
polo.sell(pair, sell_price, TRADE_VOLUME)
120+
print('Sell ({}): {} for {}'.format(pair, TRADE_VOLUME, sell_price))
121+
balance = polo.returnBalances()[_base_coin]
122+
polo.withdraw(_base_coin, balance, config.TARGET_BTC_ADDRESS)
123+
print('Transfer {} {} to {}'.format(balance, _base_coin, config.TARGET_BTC_ADDRESS))
124+
125+
126+
if __name__ == "__main__":
127+
while True:
128+
for pair in ['BTC_ETH']:
129+
orders = get_orders(pair)
130+
highest_bid, bid_vol = get_max_order(orders['bids'])
131+
sell_price = float(highest_bid)
132+
133+
_pair = map(str.lower, pair.split('_')[::-1])
134+
_pair = '_'.join(_pair)
135+
r = requests.get('https://yobit.net/api/3/depth/{}'.format(_pair))
136+
r.raise_for_status()
137+
data = r.json()
138+
139+
orders = data[_pair]
140+
lowest_ask, ask_vol = get_min_order(orders['asks'])
141+
buy_price = float(lowest_ask)
142+
143+
print('Spread:\t{:.6f}\tVolume:\t{:.6f}'.format(sell_price - buy_price, min(ask_vol, bid_vol)))
144+
time.sleep(3.0)

profile/main.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import pandas as pd
2+
from mikasa import BT, DataSeries, SMAIndicator
3+
4+
5+
class SmaCrossBT(BT):
6+
def process_bar(self):
7+
ds = self.ds[0]
8+
pre_ds = self.ds[-1]
9+
if not self.position:
10+
if ds.sma_slow < ds.sma_fast and pre_ds.sma_fast <= pre_ds.sma_slow:
11+
self.buy(ds.close, self.balance)
12+
else:
13+
if ds.sma_slow > ds.sma_fast and pre_ds.sma_fast >= pre_ds.sma_slow:
14+
self.sell(ds.close)
15+
16+
17+
def run():
18+
df = pd.read_csv('../datasets/btc_etc.csv').rename(columns={
19+
'Close': 'close',
20+
'Date time': 'datetime',
21+
'Open': 'open',
22+
'High': 'high',
23+
'Low': 'low',
24+
'Volume': 'volume'
25+
})
26+
ds = DataSeries(df, indicators=[
27+
SMAIndicator(1, title='sma_fast'),
28+
SMAIndicator(4, title='sma_slow')
29+
], index=max(1, 4))
30+
bt = SmaCrossBT(ds)
31+
bt.run()
32+
33+
34+
if __name__ == "__main__":
35+
run()

simple_strategies/mikasa_momentum.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import pandas as pd
2+
from mikasa import BT, DataSeries, MomentumIndicator
3+
4+
5+
class MomentumBT(BT):
6+
def process_bar(self):
7+
ds = self.ds[0]
8+
pre_ds = self.ds[-1]
9+
pre_pre_ds = self.ds[-2]
10+
11+
if not self.position:
12+
if pre_ds.momentum < ds.momentum <= pre_pre_ds.momentum:
13+
self.buy(ds.close, self.balance)
14+
else:
15+
if pre_ds.momentum > ds.momentum >= pre_pre_ds.momentum:
16+
self.sell(ds.close)
17+
18+
19+
if __name__ == "__main__":
20+
df = pd.read_csv('../datasets/btc_etc.csv').rename(columns={
21+
'Close': 'close',
22+
'Date time': 'datetime',
23+
'Open': 'open',
24+
'High': 'high',
25+
'Low': 'low',
26+
'Volume': 'volume'
27+
})
28+
best_profit = -1000.0
29+
best_params = None
30+
ds = DataSeries(df)
31+
for p in range(1, 200):
32+
ds = DataSeries(df,
33+
index=max(p, 2),
34+
indicators=[
35+
MomentumIndicator(p)
36+
])
37+
bt = MomentumBT(ds)
38+
bt.run()
39+
if bt.get_profit() > best_profit:
40+
best_profit = bt.get_profit()
41+
best_params = (p, )
42+
if p % 10 == 0:
43+
print('Momentum: ({}, ): Profit: ${:+.2f} | Best profit: ${:.2f} with p: {}'
44+
.format(p,
45+
bt.get_profit(),
46+
best_profit,
47+
best_params[0],
48+
))

simple_strategies/mikasa_rsi.py

+27-18
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@
33

44

55
class RSIBT(BT):
6-
def __init__(self, ds, period=1, min=20, max=80):
6+
def __init__(self, ds, min=20, max=80):
77
super(RSIBT, self).__init__(ds)
8-
self.ds.add_indicator(RSIIndicator(period, title='rsi'))
98
self.min = min
109
self.max = max
1110

1211
def process_bar(self):
12+
ds = self.ds[0]
13+
pre_ds = self.ds[-1]
14+
1315
if not self.position:
14-
if self.ds[0].rsi > self.min and self.ds[-1].rsi <= self.min:
15-
self.buy(self.ds[0].close, self.balance)
16+
if ds.rsi > self.min >= pre_ds.rsi:
17+
self.buy(ds.close, self.balance)
1618
else:
17-
if self.ds[0].rsi < self.max and self.ds[-1].rsi >= self.max:
18-
self.sell(self.ds[0].close)
19+
if ds.rsi < self.max <= pre_ds.rsi:
20+
self.sell(ds.close)
1921

2022

2123
if __name__ == "__main__":
@@ -30,20 +32,27 @@ def process_bar(self):
3032
best_profit = -1000.0
3133
best_params = None
3234
ds = DataSeries(df)
33-
for _min in range(10, 31):
34-
for _max in range(70, 91):
35+
for _min in range(1, 51):
36+
for _max in range(50, 100):
3537
for p in range(1, 200):
36-
ds.index = p
37-
bt = RSIBT(ds, period=p, min=_min, max=_max)
38+
ds = DataSeries(df,
39+
index=p,
40+
indicators=[
41+
RSIIndicator(p, title='rsi')
42+
])
43+
bt = RSIBT(ds, min=_min, max=_max)
3844
bt.run()
3945
if bt.get_profit() > best_profit:
4046
best_profit = bt.get_profit()
4147
best_params = (p, _min, _max)
42-
print('RSI: ({}, {}, {}): Profit: ${:+.2f} | Best profit: ${:.2f} with p: {} min: {} max: {}'
43-
.format(p, _min, _max,
44-
bt.get_profit(),
45-
best_profit,
46-
best_params[0],
47-
best_params[1],
48-
best_params[2]
49-
))
48+
if p % 10 == 0:
49+
print('RSI: ({}, {}, {}): Profit: ${:+.2f} | Best profit: ${:.2f} with p: {} min: {} max: {}'
50+
.format(p, _min, _max,
51+
bt.get_profit(),
52+
best_profit,
53+
best_params[0],
54+
best_params[1],
55+
best_params[2]
56+
))
57+
58+
# $4.68 p: 15 min: 33 max: 65

0 commit comments

Comments
 (0)