-
Notifications
You must be signed in to change notification settings - Fork 0
/
TradingService.java
129 lines (113 loc) · 4.71 KB
/
TradingService.java
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
package service.trades;
import service.model.trades.Trade;
import service.model.trades.TradeResult;
import service.trades._tools.holders.CurrentTradesHolder;
import service.trades._tools.rest_client.TradesRestApiClient;
import service.trades._tools.simulator.TradingSimulator;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import static java.util.Collections.reverse;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
* Get trades from the client api and loads them in CurrentTradesHolder.
* It also updates them every certain time (5 seconds).
*/
public class TradingService {
private static TradingService tradingService;
private CurrentTradesHolder currentTradesHolder;
private TradesRestApiClient tradesRestApiClient;
private ScheduledFuture<?> scheduledFuture;
private final Runnable updateTradesRunnable = this::updateTrades;
private ScheduledExecutorService executor;
private TradingService(
TradesRestApiClient tradesRestApiClient,
ScheduledExecutorService executor,
TradingSimulator tradingSimulator) {
this.tradesRestApiClient = tradesRestApiClient;
currentTradesHolder = new CurrentTradesHolder(getTradesFromApi(tradesRestApiClient), tradingSimulator);
this.executor = executor;
}
/**
* Returns an instance of the service by specifying the simulator that will be used to add simulated trades.
* @param tradingSimulator The simulator that will be used to add simulated trades.
* @return a new or existing instance of this class.
*/
public static TradingService getInstance(TradingSimulator tradingSimulator) {
if (tradingService == null) {
tradingService = new TradingService(new TradesRestApiClient(), getScheduledExecutor(), tradingSimulator);
}
return tradingService;
}
/**
* Returns an instance of the service by specifying the api client and trades simulator.
* @param tradesRestApiClient The object that interacts with Bitso(c) REST Api.
* @param tradingSimulator The simulator that will be used to add simulated trades.
* @return a new or existing instance of this class.
*/
public static TradingService getInstance(
TradesRestApiClient tradesRestApiClient,
TradingSimulator tradingSimulator) {
if (tradingService == null) {
tradingService = new TradingService(tradesRestApiClient, getScheduledExecutor(), tradingSimulator);
}
return tradingService;
}
/**
* Starts the process for trades updating.
*/
public void start() {
scheduledFuture = executor.scheduleWithFixedDelay(updateTradesRunnable, 5, 5, SECONDS);
}
/**
* Calls the trades holder to get the current trades.
* @param limit Maximum number of trades to be returned.
* @return A list of trades according to the limit.
*/
public List<Trade> getLastTrades(int limit) {
List<Trade> trades = currentTradesHolder.getTrades();
return trades.subList(0, limit > trades.size() ? trades.size() : limit);
}
/**
* Stops the trades updating process.
*/
public void stop() {
scheduledFuture.cancel(true);
executor.shutdown();
}
private static ScheduledThreadPoolExecutor getScheduledExecutor() {
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
return scheduledThreadPoolExecutor;
}
static TradingService getInstance(
TradesRestApiClient tradesRestApiClient,
ScheduledExecutorService executor,
TradingSimulator tradingSimulator,
CurrentTradesHolder currentTradesHolder) {
if (tradingService == null) {
tradingService = new TradingService(tradesRestApiClient, executor, tradingSimulator);
tradingService.currentTradesHolder = currentTradesHolder;
}
return tradingService;
}
private List<Trade> getTradesFromApi(TradesRestApiClient tradesRestApiClient) {
List<Trade> tradeList = tradesRestApiClient.getTrades(100).getTradeList();
reverse(tradeList);
return tradeList;
}
void updateTrades() {
TradeResult tradesSince = tradesRestApiClient.getTradesSince(currentTradesHolder.getLastTradeId());
currentTradesHolder.addTrades(tradesSince.getTradeList());
}
Runnable getUpdateTradesRunnable() {
return updateTradesRunnable;
}
/**
* It should only used for testing.
*/
public static void clearInstance() {
tradingService = null;
}
}