Merge branch 'feature/kline-alternate-source' into 'develop'
Add alternate source See merge request india/india_market_java!43
This commit is contained in:
@@ -60,6 +60,10 @@ public class MoneyStockPO {
|
||||
* NSE India的id */
|
||||
String nseIndiaId;
|
||||
|
||||
/**
|
||||
* NSE India Chart的id */
|
||||
String nseIndiaChartId;
|
||||
|
||||
/**
|
||||
* 自有self_url */
|
||||
String selfUrl;
|
||||
|
||||
@@ -2,18 +2,21 @@ package cn.stock.market.utils;
|
||||
|
||||
import cn.stock.market.dto.StockHistoryRequest;
|
||||
import cn.stock.market.dto.StockHistoryResponse;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import okhttp3.*;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class NseIndiaRequest {
|
||||
private static final String NSE_INDIA_URL = "https://www.nseindia.com";
|
||||
private static final String NSE_INDIA_CHART_URL = "https://charting.nseindia.com";
|
||||
private static final OkHttpClient client;
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
static {
|
||||
client = new OkHttpClient.Builder()
|
||||
@@ -47,8 +50,8 @@ public class NseIndiaRequest {
|
||||
return request;
|
||||
}
|
||||
|
||||
private static void initCookie() {
|
||||
Request request = createRequest(NSE_INDIA_URL);
|
||||
private static void initCookie(String url) {
|
||||
Request request = createRequest(url);
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Failed to fetch initial cookies");
|
||||
@@ -58,8 +61,35 @@ public class NseIndiaRequest {
|
||||
}
|
||||
}
|
||||
|
||||
private static Integer getCode(String symbol) {
|
||||
Request request = createRequest(NSE_INDIA_CHART_URL + "//Charts/GetEQMasters").newBuilder()
|
||||
.addHeader("referer", NSE_INDIA_CHART_URL)
|
||||
.addHeader("origin", NSE_INDIA_CHART_URL)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Failed to get EQ code");
|
||||
}
|
||||
|
||||
String result = response.body().string();
|
||||
|
||||
String regex = "(\\d+)\\|" + symbol + "\\|.*";
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(result);
|
||||
|
||||
if (matcher.find()) {
|
||||
return Integer.valueOf(matcher.group(1));
|
||||
}
|
||||
throw new IOException("No data found");
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to get EQ code", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static JSONObject stockByJYSFromHttp(String stockType, String symbol, String nseIndiaId) {
|
||||
initCookie();
|
||||
initCookie(NSE_INDIA_URL);
|
||||
|
||||
String url = NSE_INDIA_URL + "/api/quote-equity?symbol=" + nseIndiaId;
|
||||
Request request = createRequest(url).newBuilder()
|
||||
@@ -96,18 +126,44 @@ public class NseIndiaRequest {
|
||||
}
|
||||
}
|
||||
|
||||
public static StockHistoryResponse stockKLineFromHttp(StockHistoryRequest stockHistoryRequest) {
|
||||
initCookie();
|
||||
public static StockHistoryResponse stockKLineFromHttp(StockHistoryRequest stockHistoryRequest, String resolution) {
|
||||
initCookie(NSE_INDIA_CHART_URL);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
|
||||
String fromDate = sdf.format(new Date(stockHistoryRequest.getFrom() * 1000));
|
||||
String toDate = sdf.format(new Date(stockHistoryRequest.getTo() * 1000));
|
||||
Integer code = getCode(stockHistoryRequest.getSymbol());
|
||||
|
||||
String url = String.format("%s/api/historical/cm/equity?symbol=%s&from=%s&to=%s", NSE_INDIA_URL, stockHistoryRequest.getSymbol(), fromDate, toDate);
|
||||
int interval = 1;
|
||||
if (StringUtils.equals("H", resolution)) {
|
||||
resolution = "I";
|
||||
interval = 60;
|
||||
}
|
||||
|
||||
Request request = createRequest(url).newBuilder()
|
||||
.addHeader("referer", NSE_INDIA_URL)
|
||||
.addHeader("origin", NSE_INDIA_URL)
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("chartPeriod", resolution);
|
||||
body.put("chartStart", 0);
|
||||
body.put("exch", "N");
|
||||
body.put("fromDate", 0);
|
||||
body.put("instrType", "C");
|
||||
body.put("scripCode", code);
|
||||
body.put("timeInterval", interval);
|
||||
body.put("toDate", stockHistoryRequest.getTo() + 18000);
|
||||
body.put("ulToken", code);
|
||||
|
||||
String payload;
|
||||
try {
|
||||
payload = objectMapper.writeValueAsString(body);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to serialize body", e);
|
||||
}
|
||||
|
||||
RequestBody requestBody = RequestBody.create(
|
||||
MediaType.get("application/json; charset=utf-8"),
|
||||
payload
|
||||
);
|
||||
|
||||
Request request = createRequest(NSE_INDIA_CHART_URL + "//Charts/symbolhistoricaldata/").newBuilder()
|
||||
.addHeader("referer", NSE_INDIA_CHART_URL)
|
||||
.addHeader("origin", NSE_INDIA_CHART_URL)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
@@ -115,52 +171,7 @@ public class NseIndiaRequest {
|
||||
throw new IOException("Request failed with code: " + response.code());
|
||||
}
|
||||
|
||||
JSONObject jsonData = JSONObject.parseObject(response.body().string());
|
||||
JSONArray data =jsonData.getJSONArray("data");
|
||||
|
||||
StockHistoryResponse result = new StockHistoryResponse();
|
||||
List<Long> tList = new ArrayList<>();
|
||||
List<Double> oList = new ArrayList<>();
|
||||
List<Double> hList = new ArrayList<>();
|
||||
List<Double> lList = new ArrayList<>();
|
||||
List<Double> cList = new ArrayList<>();
|
||||
List<Long> vList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Long t, v;
|
||||
Double o, h, l, c;
|
||||
|
||||
try {
|
||||
JSONObject jsonObject = data.getJSONObject(i);
|
||||
|
||||
String timestampStr = jsonObject.getString("TIMESTAMP");
|
||||
Instant instant = Instant.parse(timestampStr);
|
||||
t = instant.toEpochMilli() / 1000;
|
||||
|
||||
o = jsonObject.getDouble("CH_OPENING_PRICE");
|
||||
c = jsonObject.getDouble("CH_CLOSING_PRICE");
|
||||
h = jsonObject.getDouble("CH_TRADE_HIGH_PRICE");
|
||||
l = jsonObject.getDouble("CH_TRADE_LOW_PRICE");
|
||||
v = jsonObject.getLong("CH_TOT_TRADED_VAL");
|
||||
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tList.add(t);
|
||||
oList.add(o);
|
||||
hList.add(h);
|
||||
lList.add(l);
|
||||
cList.add(c);
|
||||
vList.add(v);
|
||||
}
|
||||
|
||||
result.setT(tList);
|
||||
result.setO(oList);
|
||||
result.setH(hList);
|
||||
result.setL(lList);
|
||||
result.setC(cList);
|
||||
result.setV(vList);
|
||||
StockHistoryResponse result = objectMapper.readValue(response.body().string(), StockHistoryResponse.class);
|
||||
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -745,22 +745,20 @@ public class MoneyApiController {
|
||||
// API request successful, return the response
|
||||
return ResponseEntity.ok(response);
|
||||
} else {
|
||||
if (!StringUtils.equals("H", resolution)) {
|
||||
try {
|
||||
MoneyStock moneyStock = moneyStockRepository.findOne((QMoneyStockPO.moneyStockPO.moneyScId.eq(symbol))
|
||||
.and(QMoneyStockPO.moneyStockPO.isLock.eq(0))
|
||||
.and(QMoneyStockPO.moneyStockPO.isShow.eq(0)))
|
||||
.orElse(null);
|
||||
try {
|
||||
MoneyStock moneyStock = moneyStockRepository.findOne((QMoneyStockPO.moneyStockPO.moneyScId.eq(symbol))
|
||||
.and(QMoneyStockPO.moneyStockPO.isLock.eq(0))
|
||||
.and(QMoneyStockPO.moneyStockPO.isShow.eq(0)))
|
||||
.orElse(null);
|
||||
|
||||
if (moneyStock != null && moneyStock.getNseIndiaId() != null && !moneyStock.getNseIndiaId().isEmpty()) {
|
||||
request.setSymbol(moneyStock.getNseIndiaId());
|
||||
response = NseIndiaRequest.stockKLineFromHttp(request);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to get data from nseindia.", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
||||
if (moneyStock != null && moneyStock.getNseIndiaChartId() != null && !moneyStock.getNseIndiaChartId().isEmpty()) {
|
||||
request.setSymbol(moneyStock.getNseIndiaChartId());
|
||||
response = NseIndiaRequest.stockKLineFromHttp(request, resolution);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to get data from nseindia.", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
// All retries failed, return an error response
|
||||
|
||||
Reference in New Issue
Block a user