1 package org.oxerr.okcoin.rest.dto.valuereader;
2
3 import java.math.BigDecimal;
4 import java.text.ParseException;
5 import java.text.SimpleDateFormat;
6 import java.time.Instant;
7 import java.util.TimeZone;
8
9 import org.oxerr.okcoin.rest.dto.IcebergOrder;
10 import org.oxerr.okcoin.rest.dto.IcebergOrderHistory;
11 import org.oxerr.okcoin.rest.dto.Status;
12 import org.oxerr.okcoin.rest.dto.Type;
13 import org.oxerr.okcoin.rest.service.web.LoginRequiredException;
14 import org.w3c.dom.Node;
15 import org.w3c.dom.NodeList;
16 import org.w3c.dom.Text;
17 import org.w3c.dom.html.HTMLAnchorElement;
18 import org.w3c.dom.html.HTMLCollection;
19 import org.w3c.dom.html.HTMLDivElement;
20 import org.w3c.dom.html.HTMLDocument;
21 import org.w3c.dom.html.HTMLTableCellElement;
22 import org.w3c.dom.html.HTMLTableElement;
23 import org.w3c.dom.html.HTMLTableRowElement;
24
25 public class IcebergOrdersReader extends HtmlPageReader<IcebergOrderHistory> {
26
27 private static final IcebergOrdersReader INSTANCE = new IcebergOrdersReader();
28
29 public static IcebergOrdersReader getInstance() {
30 return INSTANCE;
31 }
32
33 private final SimpleDateFormat dateFormat;
34
35 public IcebergOrdersReader() {
36 dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
37 dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
38 }
39
40
41
42
43 @Override
44 public IcebergOrderHistory read(HTMLDocument doc) {
45 NodeList tableNodeList = doc.getElementsByTagName("table");
46 if (tableNodeList.getLength() == 0) {
47 throw new LoginRequiredException("No HTML table found.");
48 }
49
50 Node tableNode = tableNodeList.item(0);
51 HTMLTableElement table = (HTMLTableElement) tableNode;
52 HTMLCollection rows = table.getRows();
53 IcebergOrder[] orders = new IcebergOrder[rows.getLength() - 1];
54 for (int i = 1; i < rows.getLength(); i++) {
55 HTMLTableRowElement row = (HTMLTableRowElement) rows.item(i);
56 HTMLCollection cells = row.getCells();
57
58 if (cells.getLength() == 1) {
59
60 orders = new IcebergOrder[0];
61 break;
62 }
63
64 HTMLTableCellElement dateCell = (HTMLTableCellElement) cells.item(0);
65 HTMLTableCellElement sideCell = (HTMLTableCellElement) cells.item(1);
66 HTMLTableCellElement tradeValueCell = (HTMLTableCellElement) cells.item(2);
67 HTMLTableCellElement singleAvgCell = (HTMLTableCellElement) cells.item(3);
68 HTMLTableCellElement depthRangeCell = (HTMLTableCellElement) cells.item(4);
69 HTMLTableCellElement protectedPriceCell = (HTMLTableCellElement) cells.item(5);
70 HTMLTableCellElement filledCell = (HTMLTableCellElement) cells.item(6);
71 HTMLTableCellElement statusCell = (HTMLTableCellElement) cells.item(7);
72
73 String dateContent = dateCell.getTextContent();
74 String sideContent = sideCell.getTextContent();
75 String tradeValueContent = tradeValueCell.getTextContent();
76 String singleAvgContent = singleAvgCell.getTextContent();
77 String depthRangeContent = depthRangeCell.getTextContent();
78 String protetedPriceContent = protectedPriceCell.getTextContent();
79 String filledContent = filledCell.getTextContent();
80 String idContent = statusCell.getId();
81
82 Instant date;
83 synchronized (dateFormat) {
84 try {
85 date = dateFormat.parse(dateContent).toInstant();
86 } catch (ParseException e) {
87 throw new IllegalArgumentException(e);
88 }
89 }
90
91 Type side = sideContent.equals("Bid") ? Type.BUY : Type.SELL;
92 BigDecimal tradeValue = new BigDecimal(tradeValueContent.substring(1));
93 BigDecimal singleAvg = new BigDecimal(singleAvgContent.substring(1));
94 BigDecimal depthRange = new BigDecimal(depthRangeContent.substring(0, depthRangeContent.length() - 1));
95 BigDecimal protectedPrice = new BigDecimal(protetedPriceContent.substring(1).replace(",", ""));
96 BigDecimal filled = new BigDecimal(filledContent.substring(1));
97 long id = Long.valueOf(idContent.substring("continuous_".length()));
98
99 NodeList statusChildNodes = statusCell.getChildNodes();
100 Node statusFirstChild = statusChildNodes.item(0);
101 Status status = Status.UNFILLED;
102 if (statusFirstChild instanceof HTMLAnchorElement) {
103
104 status = filled.compareTo(BigDecimal.ZERO) == 0 ? Status.UNFILLED : Status.PARTIALLY_FILLED;
105 } else if (statusFirstChild instanceof Text){
106 String statusText = statusFirstChild.getTextContent();
107 switch (statusText) {
108 case "Cancelled":
109 status = Status.CANCELLED;
110 break;
111 default:
112 status = Status.UNFILLED;
113 break;
114 }
115 }
116
117 orders[i - 1] = new IcebergOrder(id, date, side, tradeValue, singleAvg, depthRange, protectedPrice, filled, status);
118 }
119
120
121 int currentPage = 1;
122 boolean hasNextPage = false;
123 NodeList divNodeList = doc.getElementsByTagName("div");
124 if (divNodeList.getLength() > 0) {
125 HTMLDivElement div = (HTMLDivElement) divNodeList.item(0);
126 NodeList anchorNodeList = div.getElementsByTagName("a");
127 for (int i = 0; i < anchorNodeList.getLength(); i++) {
128 HTMLAnchorElement anchor = (HTMLAnchorElement) anchorNodeList.item(i);
129 if ("current_ss".equals(anchor.getClassName())) {
130 currentPage = Integer.parseInt(anchor.getTextContent());
131 }
132 if (">".equals(anchor.getTextContent())) {
133 hasNextPage = true;
134 }
135 }
136 }
137
138 return new IcebergOrderHistory(currentPage, hasNextPage, orders);
139 }
140
141 }