Compare commits

...

18 Commits

Author SHA1 Message Date
quangnguyen202
ba29ab98c7 Add api for optional stock 2024-10-01 14:06:24 +07:00
Gavin g
94ec73874b Merge branch 'feature/kline-alternate-source' into 'develop'
Add alternate source

See merge request india/india_market_java!43
2024-09-26 09:57:06 +00:00
quangnguyen202
549345719a Add alternate source 2024-09-26 16:51:41 +07:00
gavin
3870400411 修改切换备用数据源的判断条件 2024-09-19 15:59:12 +08:00
Gavin g
94d2936ffb Merge branch 'feature/stock-kline-nseindia' into 'develop'
Add alternal source

See merge request india/india_market_java!42
2024-09-19 07:37:45 +00:00
quangnguyen202
59e4aa9e1a Add alternal source 2024-09-19 14:33:22 +07:00
gavin
bae645e3c6 修复官方查询时名称写死的问题 2024-09-12 14:15:31 +08:00
gavin
94d9aea2c8 指定股票更换详情测试代码 2024-09-10 13:11:01 +08:00
gavin
5ae9762d45 指定股票更换详情测试代码 2024-09-09 14:59:38 +08:00
quangnguyen202
ece52491dd Merge branch 'refactor/optimization' into 'develop'
Optimize

See merge request india/india_market_java!38
2024-09-09 06:54:16 +00:00
quangnguyen202
6235d41711 Optimize 2024-09-06 11:17:41 +07:00
vpckiet
c865eccaf4 Merge branch 'refactor/optimization' into 'develop'
Optimize code

See merge request india/india_market_java!37
2024-09-06 01:53:33 +00:00
quangnguyen202
136020a497 Update 2024-09-05 16:30:46 +07:00
quangnguyen202
d7da59aca1 Optimize code 2024-09-05 15:59:13 +07:00
gavin
8427bed427 指定股票更换详情测试代码 2024-09-04 12:52:17 +08:00
gavin
269f02b79d 指定股票更换详情测试代码 2024-09-04 11:56:04 +08:00
gavin
7cc456bcd8 同步手动更新代码 2024-09-02 15:32:50 +08:00
vpckiet
be05d403af Merge branch 'bug/craw_img_news' into 'develop'
update crawl img news

See merge request india/india_market_java!33
2024-09-02 06:47:52 +00:00
11 changed files with 569 additions and 140 deletions

View File

@@ -0,0 +1,41 @@
package cn.stock.market.infrastructure.db.po;
import static com.querydsl.core.types.PathMetadataFactory.*;
import com.querydsl.core.types.dsl.*;
import com.querydsl.core.types.PathMetadata;
import javax.annotation.Generated;
import com.querydsl.core.types.Path;
/**
* QOptionalStockPO is a Querydsl query type for OptionalStockPO
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QOptionalStockPO extends EntityPathBase<OptionalStockPO> {
private static final long serialVersionUID = 1161631810L;
public static final QOptionalStockPO optionalStockPO = new QOptionalStockPO("optionalStockPO");
public final StringPath company = createString("company");
public final NumberPath<Integer> id = createNumber("id", Integer.class);
public final StringPath symbol = createString("symbol");
public QOptionalStockPO(String variable) {
super(OptionalStockPO.class, forVariable(variable));
}
public QOptionalStockPO(Path<? extends OptionalStockPO> path) {
super(path.getType(), path.getMetadata());
}
public QOptionalStockPO(PathMetadata metadata) {
super(OptionalStockPO.class, metadata);
}
}

View File

@@ -0,0 +1,16 @@
package cn.stock.market.domain.basic.convert;
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
import cn.qutaojing.common.utils.SpringUtils;
import cn.stock.market.domain.basic.entity.OptionalStock;
import cn.stock.market.infrastructure.db.po.OptionalStockPO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Component
@Lazy
public class OptionalStockConvert extends SimpleEntityPOConvert<OptionalStock, OptionalStockPO> {
public static OptionalStockConvert of() {
return SpringUtils.getBean(OptionalStockConvert.class);
}
}

View File

@@ -0,0 +1,16 @@
package cn.stock.market.domain.basic.entity;
import cn.stock.market.infrastructure.db.po.OptionalStockPO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@Data
@NoArgsConstructor
@SuperBuilder
@EqualsAndHashCode(
callSuper = false
)
public class OptionalStock extends OptionalStockPO {
}

View File

@@ -0,0 +1,32 @@
package cn.stock.market.domain.basic.repository;
import cn.qutaojing.common.domain.convert.IEntityPOConvert;
import cn.qutaojing.common.domain.respostory.SimplePoConvertEntityRepository;
import cn.stock.market.domain.basic.convert.OptionalStockConvert;
import cn.stock.market.domain.basic.entity.OptionalStock;
import cn.stock.market.infrastructure.db.po.OptionalStockPO;
import cn.stock.market.infrastructure.db.repo.OptionalStockRepo;
import com.rp.spring.jpa.GenericJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor(
onConstructor = @__(@Autowired)
)
public class OptionalStockRepository extends SimplePoConvertEntityRepository<OptionalStock, OptionalStockPO, Integer> {
final OptionalStockRepo repo;
final OptionalStockConvert convert;
@Override
public GenericJpaRepository<OptionalStockPO, Integer> repo() {
return repo;
}
@Override
public IEntityPOConvert<OptionalStock, OptionalStockPO> convert() {
return convert;
}
}

View File

@@ -0,0 +1,18 @@
package cn.stock.market.dto;
import lombok.Data;
@Data
public class OptionalStockResponse {
private String message;
private Integer code;
private DataResponse data = new DataResponse();
@Data
public static class DataResponse {
private String symbol;
private String company;
private Double pricecurrent;
private Float pricepercentchange;
}
}

View File

@@ -56,6 +56,14 @@ public class MoneyStockPO {
* 展示表示 */
String selfDispId;
/**
* NSE India的id */
String nseIndiaId;
/**
* NSE India Chart的id */
String nseIndiaChartId;
/**
* 自有self_url */
String selfUrl;

View File

@@ -0,0 +1,35 @@
package cn.stock.market.infrastructure.db.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@SuperBuilder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@DynamicInsert
@DynamicUpdate
@Table(
name = "optional_stock"
)
public class OptionalStockPO {
@Id
@GeneratedValue(
strategy = javax.persistence.GenerationType.IDENTITY
)
Integer id;
String symbol;
String company;
}

View File

@@ -0,0 +1,7 @@
package cn.stock.market.infrastructure.db.repo;
import cn.stock.market.infrastructure.db.po.OptionalStockPO;
import com.rp.spring.jpa.GenericJpaRepository;
public interface OptionalStockRepo extends GenericJpaRepository<OptionalStockPO, Integer> {
}

View File

@@ -0,0 +1,181 @@
package cn.stock.market.utils;
import cn.stock.market.dto.StockHistoryRequest;
import cn.stock.market.dto.StockHistoryResponse;
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.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()
.cookieJar(new CookieJar() {
private final Map<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
}
private static Request createRequest(String url) {
Request request = new Request.Builder()
.url(url)
.header("accept", "application/json, text/plain, */*")
.header("accept-language", "en-US,en;q=0.9")
.header("cache-control", "no-cache")
.header("pragma", "no-cache")
.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36")
.build();
return request;
}
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");
}
} catch (IOException e) {
throw new RuntimeException("Failed to initialize cookies", e);
}
}
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(NSE_INDIA_URL);
String url = NSE_INDIA_URL + "/api/quote-equity?symbol=" + nseIndiaId;
Request request = createRequest(url).newBuilder()
.addHeader("referer", NSE_INDIA_URL)
.addHeader("origin", NSE_INDIA_URL)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Request failed with code: " + response.code());
}
JSONObject jsonData = JSONObject.parseObject(response.body().string());
JSONObject data =jsonData.getJSONObject("priceInfo");
JSONObject json = new JSONObject();
json.put("pricepercentchange",data.getString("pChange"));
json.put("stockType",stockType);
json.put("pricechange",data.getString("change"));
json.put("pricecurrent",data.getString("lastPrice"));
json.put("priceprevclose",data.getString("previousClose"));
json.put("PREVDATE","");
json.put("VOL",jsonData.getJSONObject("preOpenMarket").getString("totalTradedVolume"));
json.put("dataSourceType","3");
json.put("symbol",symbol);
json.put("BSEID",symbol);
json.put("NSEID",symbol);
json.put("LTH",data.getString("upperCP"));
json.put("LTL",data.getString("lowerCP"));
json.put("OPN",data.getString("open"));
return json;
} catch (IOException e) {
throw new RuntimeException("Failed to fetch data", e);
}
}
public static StockHistoryResponse stockKLineFromHttp(StockHistoryRequest stockHistoryRequest, String resolution) {
initCookie(NSE_INDIA_CHART_URL);
Integer code = getCode(stockHistoryRequest.getSymbol());
int interval = 1;
if (StringUtils.equals("H", resolution)) {
resolution = "I";
interval = 60;
}
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()) {
if (!response.isSuccessful()) {
throw new IOException("Request failed with code: " + response.code());
}
StockHistoryResponse result = objectMapper.readValue(response.body().string(), StockHistoryResponse.class);
return result;
} catch (IOException e) {
throw new RuntimeException("Failed to fetch data", e);
}
}
}

View File

@@ -3,14 +3,19 @@ package cn.stock.market.web;
import cn.hutool.core.date.DateUtil;
import cn.stock.market.MoneyStockSuggestDTO;
import cn.stock.market.domain.basic.entity.MoneyStock;
import cn.stock.market.domain.basic.entity.OptionalStock;
import cn.stock.market.domain.basic.repository.MoneyStockRepository;
import cn.stock.market.domain.basic.repository.OptionalStockRepository;
import cn.stock.market.dto.OptionalStockResponse;
import cn.stock.market.dto.StockHistoryRequest;
import cn.stock.market.dto.StockHistoryResponse;
import cn.stock.market.infrastructure.db.po.QMoneyStockPO;
import cn.stock.market.utils.RequestCacheUtils;
import cn.stock.market.utils.HttpRequest;
import cn.stock.market.utils.NseIndiaRequest;
import cn.stock.market.utils.ServerResponse;
import cn.stock.market.web.annotations.EncryptFilter;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
@@ -36,13 +41,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -61,15 +67,20 @@ public class MoneyApiController {
@Autowired
private MoneyStockRepository moneyStockRepository;
@Autowired
private OptionalStockRepository optionalStockRepository;
@Autowired
private ObjectMapper objectMapper;
private static final String EXTERNAL_API_URL = "https://priceapi.moneycontrol.com/techCharts/indianMarket/stock/history";
private static final String OPTIONAL_STOCK_MONEYCONTROL_URL = "https://priceapi.moneycontrol.com/pricefeed/notapplicable/inidicesindia/";
@ApiOperation(value = "股票详情信息",httpMethod = "GET")
@ApiOperation(value = "股票详情信息", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name="stockType",value = "BSE或者NSE"),
@ApiImplicitParam(name="symbol",value = "scId值"),
@ApiImplicitParam(name="id",value = "id值"),
@ApiImplicitParam(name = "stockType", value = "BSE或者NSE"),
@ApiImplicitParam(name = "symbol", value = "scId值"),
@ApiImplicitParam(name = "id", value = "id值"),
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "" +
@@ -168,53 +179,67 @@ public class MoneyApiController {
"priceprevclose: 前一交易日的收盘价\n" +
"30DayAvg: 过去30天的平均", response = JSONObject.class),
})
@GetMapping({"/market/api/market/money/getStockDetail","/api/market/money/getStockDetail"})
@GetMapping({"/market/api/market/money/getStockDetail", "/api/market/money/getStockDetail"})
@ResponseBody
@EncryptFilter(decryptRequest = false)
public ServerResponse getStockDetail(@RequestParam String stockType, @RequestParam String symbol ) {
String url = String.format("https://priceapi.moneycontrol.com/pricefeed/%s/equitycash/%s",stockType,symbol);
public ServerResponse getStockDetail(@RequestParam String stockType, @RequestParam String symbol) {
MoneyStock moneyStock = moneyStockRepository.findOne(QMoneyStockPO.moneyStockPO.stockType.eq(stockType)
.and(QMoneyStockPO.moneyStockPO.moneyScId.eq(symbol))
.and(QMoneyStockPO.moneyStockPO.isLock.eq(0))
.and(QMoneyStockPO.moneyStockPO.isShow.eq(0)))
.and(QMoneyStockPO.moneyStockPO.moneyScId.eq(symbol))
.and(QMoneyStockPO.moneyStockPO.isLock.eq(0))
.and(QMoneyStockPO.moneyStockPO.isShow.eq(0)))
.orElse(null);
/* if(moneyStock==null){
return ServerResponse.createByErrorMsg("没有找到该股票");
}*/
// 设置重试次数
if ("ANI".equals(symbol)) {
JSONObject json1 = new JSONObject();
json1.put("company", "Archit Nuwood Industries Ltd");
json1.put("pricepercentchange", "Archit Nuwood Industries Ltd");
json1.put("stockType", stockType);
json1.put("pricecurrent", "386");
json1.put("dataSourceType", "3");
json1.put("symbol", "ANI");
json1.put("BSEID", "ANI");
json1.put("NSEID", "ANI");
return ServerResponse.createBySuccess(json1);
}
String url = String.format("https://priceapi.moneycontrol.com/pricefeed/%s/equitycash/%s", stockType, symbol);
int maxRetries = 3;
for (int retry = 1; retry <= maxRetries; retry++) {
try {
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
JSONObject json1 = new JSONObject();
if (responseEntity.getStatusCode().value() == 200 && responseEntity.getBody() != null ) {
if (responseEntity.getStatusCode().value() == 200 && responseEntity.getBody() != null) {
JSONObject data = JSONObject.parseObject(responseEntity.getBody()).getJSONObject("data");
if(data!=null){
json1.put("company",data.getString("SC_FULLNM"));
json1.put("pricepercentchange",data.getString("pricepercentchange"));
json1.put("stockType",stockType);
json1.put("pricechange",data.getString("pricechange"));
json1.put("pricecurrent",data.getString("pricecurrent"));
json1.put("priceprevclose",data.getString("priceprevclose"));
json1.put("PREVDATE",data.getString("PREVDATE"));
json1.put("VOL",data.getString("VOL"));
json1.put("dataSourceType","3");
json1.put("symbol",data.getString("symbol"));
json1.put("BSEID",data.getString("BSEID"));
json1.put("NSEID",data.getString("NSEID"));
json1.put("LTH",data.getString("HP"));
json1.put("LTL",data.getString("LP"));
json1.put("OPN",data.getString("OPN"));
if(null!=moneyStock){
json1.put("id",moneyStock.getId());
if (data != null) {
json1.put("company", data.getString("SC_FULLNM"));
json1.put("pricepercentchange", data.getString("pricepercentchange"));
json1.put("stockType", stockType);
json1.put("pricechange", data.getString("pricechange"));
json1.put("pricecurrent", data.getString("pricecurrent"));
json1.put("priceprevclose", data.getString("priceprevclose"));
json1.put("PREVDATE", data.getString("PREVDATE"));
json1.put("VOL", data.getString("VOL"));
json1.put("dataSourceType", "3");
json1.put("symbol", data.getString("symbol"));
json1.put("BSEID", data.getString("BSEID"));
json1.put("NSEID", data.getString("NSEID"));
json1.put("LTH", data.getString("HP"));
json1.put("LTL", data.getString("LP"));
json1.put("OPN", data.getString("OPN"));
if (null != moneyStock) {
json1.put("id", moneyStock.getId());
}
if(StringUtils.equals(data.getString("pricecurrent"),"0.00")
&& (!StringUtils.equals(data.getString("priceprevclose"),"0.00"))){
json1.put("pricecurrent",data.getString("priceprevclose"));
if (StringUtils.equals(data.getString("pricecurrent"), "0.00")
&& (!StringUtils.equals(data.getString("priceprevclose"), "0.00"))) {
json1.put("pricecurrent", data.getString("priceprevclose"));
}
}
return ServerResponse.createBySuccess(json1);
if (json1.size() > 0)
return ServerResponse.createBySuccess(json1);
}
} catch (Exception e) {
}
@@ -228,20 +253,31 @@ public class MoneyApiController {
}
}
}
if (moneyStock != null && moneyStock.getNseIndiaId() != null && !moneyStock.getNseIndiaId().isEmpty()) {
try {
// Get data from nseindia
JSONObject json = NseIndiaRequest.stockByJYSFromHttp(stockType, symbol, moneyStock.getNseIndiaId());
json.put("id", moneyStock.getId());
json.put("company",moneyStock.getStockName());
return ServerResponse.createBySuccess(json);
} catch (Exception e) {
return null;
}
}
return null;
}
private static List<MoneyStockSuggestDTO> nseActives() {
private static List<MoneyStockSuggestDTO> nseActives() {
List<MoneyStockSuggestDTO> list = new ArrayList<>();
String url = "https://www.moneycontrol.com/stocks/marketstats/nse-mostactive-stocks/nifty-50-9/";
try {
Document doc = Jsoup.connect(url).get();
int size = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr").size();
for (int i =1;i<=size;i++){
for (int i = 1; i <= size; i++) {
MoneyStockSuggestDTO dto = new MoneyStockSuggestDTO();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child("+i+") > td.PR > span > a").first();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td.PR > span > a").first();
if (company_a != null) {
String stockUrl = company_a.attr("href");
String stockName = company_a.text();
@@ -249,7 +285,7 @@ public class MoneyApiController {
dto.setStockUrl(stockUrl);
}
String highPrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child("+i+") > td:nth-child(2)").first());
String highPrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(2)").first());
dto.setHighPrice(highPrice);
String lowPrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(3)").first());
@@ -274,7 +310,7 @@ public class MoneyApiController {
return list;
}
private static List<MoneyStockSuggestDTO> bseActives() {
private static List<MoneyStockSuggestDTO> bseActives() {
List<MoneyStockSuggestDTO> list = new ArrayList<>();
String url = "https://www.moneycontrol.com/stocks/marketstats/bsemact1/index.php";
@@ -282,9 +318,9 @@ public class MoneyApiController {
Document doc = Jsoup.connect(url).get();
int size = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr").size();
System.err.println(size);
for (int i =1;i<=size;i++){
for (int i = 1; i <= size; i++) {
MoneyStockSuggestDTO dto = new MoneyStockSuggestDTO();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child("+i+") > td.PR > span > a").first();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td.PR > span > a").first();
if (company_a != null) {
String stockUrl = company_a.attr("href");
String stockName = company_a.text();
@@ -313,19 +349,19 @@ public class MoneyApiController {
}
} catch (IOException e) {
log.error("occur Exception",e);
log.error("occur Exception", e);
}
return list;
}
private static List<MoneyStockSuggestDTO> bseGainer() {
private static List<MoneyStockSuggestDTO> bseGainer() {
String url = "https://www.moneycontrol.com/stocks/marketstats/bse-gainer/sensex_4/";
List<MoneyStockSuggestDTO> list = Lists.newArrayList();
try {
Document doc = Jsoup.connect(url).get();
int size = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr").size();
for (int i =1;i<=size;i++){
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child("+i+") > td.PR > span > a").first();
for (int i = 1; i <= size; i++) {
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td.PR > span > a").first();
MoneyStockSuggestDTO dto = new MoneyStockSuggestDTO();
if (company_a != null) {
String stockUrl = company_a.attr("href");
@@ -369,9 +405,9 @@ public class MoneyApiController {
try {
Document doc = Jsoup.connect(url).get();
int size = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr").size();
for (int i =1;i<=size;i++){
for (int i = 1; i <= size; i++) {
MoneyStockSuggestDTO dto = new MoneyStockSuggestDTO();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child("+i+") > td.PR > span > h3 > a").first();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td.PR > span > h3 > a").first();
if (company_a != null) {
String stockUrl = company_a.attr("href");
String stockName = company_a.text();
@@ -406,20 +442,20 @@ public class MoneyApiController {
return list;
}
private static List<MoneyStockSuggestDTO> nseTopLoser() {
private static List<MoneyStockSuggestDTO> nseTopLoser() {
String url = "https://www.moneycontrol.com/stocks/marketstats/nseloser/index.php";
List<MoneyStockSuggestDTO> list = Lists.newArrayList();
try {
Document doc = Jsoup.connect(url).get();
int size = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr").size();
for (int i =1;i<=size;i++){
for (int i = 1; i <= size; i++) {
MoneyStockSuggestDTO dto = new MoneyStockSuggestDTO();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child("+i+") > td.PR > span > h3 > a").first();
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td.PR > span > h3 > a").first();
if (company_a != null) {
String stockUrl = company_a.attr("href");
String stockName = company_a.text();
dto.setStockUrl(stockUrl);
dto.setStockUrl(stockUrl);
dto.setStockName(stockName);
}
@@ -446,7 +482,7 @@ public class MoneyApiController {
} catch (IOException e) {
e.printStackTrace();
}
return list;
return list;
}
private static List<MoneyStockSuggestDTO> bseTopLoser() {
@@ -456,7 +492,7 @@ public class MoneyApiController {
try {
Document doc = Jsoup.connect(url).get();
int size = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr").size();
for (int i =1;i<=size;i++){
for (int i = 1; i <= size; i++) {
Element company_a = doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td.PR > span > a").first();
MoneyStockSuggestDTO dto = new MoneyStockSuggestDTO();
if (company_a != null) {
@@ -501,17 +537,15 @@ public class MoneyApiController {
}
@ApiOperation(value = "股票推荐TopGainer",httpMethod = "GET")
@ApiOperation(value = "股票推荐TopGainer", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name="stockType",value = "BSE或者NSE"),
@ApiImplicitParam(name = "stockType", value = "BSE或者NSE"),
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "" +
"股票推荐相关: top gainer", response = JSONObject.class),
})
@GetMapping({"/market/api/market/money/getTopGainer","/api/market/money/getTopGainer"})
@GetMapping({"/market/api/market/money/getTopGainer", "/api/market/money/getTopGainer"})
@ResponseBody
@EncryptFilter(decryptRequest = false)
@@ -529,15 +563,15 @@ public class MoneyApiController {
}
Map<Object, Boolean> map = new HashMap<>();
moneyStockSuggestDTOS = moneyStockSuggestDTOS.stream()
.filter(f->StringUtils.isNotBlank(f.getStockName()))
.filter(f -> StringUtils.isNotBlank(f.getStockName()))
.filter(i -> map.putIfAbsent(i.getStockName(), Boolean.TRUE) == null).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){
if (CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)) {
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(selfUlrList)){
if (CollectionUtils.isNotEmpty(selfUlrList)) {
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList));
if(CollectionUtils.isNotEmpty(all)){
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
if (CollectionUtils.isNotEmpty(all)) {
moneyStockSuggestDTOS.stream().filter(f -> all.stream().anyMatch(s -> s.getStockName().equals(f.getStockName())))
.forEach(f -> f.setScId(all.stream().filter(s -> s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
}
}
gainerStockSuggestCache.put(stockType, moneyStockSuggestDTOS);
@@ -548,47 +582,47 @@ public class MoneyApiController {
}
@ApiOperation(value = "股票推荐TopLoser",httpMethod = "GET")
@ApiOperation(value = "股票推荐TopLoser", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name="stockType",value = "BSE或者NSE"),
@ApiImplicitParam(name = "stockType", value = "BSE或者NSE"),
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "" +
"股票推荐相关: TopLoser", response = JSONObject.class),
})
@GetMapping({"/market/api/market/money/getTopLoser","/api/market/money/getTopLoser"})
@GetMapping({"/market/api/market/money/getTopLoser", "/api/market/money/getTopLoser"})
@ResponseBody
@EncryptFilter(decryptRequest = false)
public List<MoneyStockSuggestDTO> getTopLoser(@RequestParam String stockType) {
List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null;
moneyStockSuggestDTOS = loserStockSuggestCache.getIfPresent(stockType);
if(null==moneyStockSuggestDTOS){
if(StringUtils.equals(stockType,"nse")){
if (null == moneyStockSuggestDTOS) {
if (StringUtils.equals(stockType, "nse")) {
moneyStockSuggestDTOS = nseTopLoser();
}else if(StringUtils.equals(stockType,"bse")){
} else if (StringUtils.equals(stockType, "bse")) {
moneyStockSuggestDTOS = bseTopLoser();
}
Map<Object, Boolean> map = new HashMap<>();
moneyStockSuggestDTOS = moneyStockSuggestDTOS.stream()
.filter(f->StringUtils.isNotBlank(f.getStockName()))
.filter(f -> StringUtils.isNotBlank(f.getStockName()))
.filter(i -> map.putIfAbsent(i.getStockName(), Boolean.TRUE) == null).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){
moneyStockSuggestDTOS.stream().forEach(f->f.setDispId(extractLastSegment(f.getStockUrl())));
if (CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)) {
moneyStockSuggestDTOS.stream().forEach(f -> f.setDispId(extractLastSegment(f.getStockUrl())));
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(selfUlrList)){
if (CollectionUtils.isNotEmpty(selfUlrList)) {
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList));
if(CollectionUtils.isNotEmpty(all)){
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
if (CollectionUtils.isNotEmpty(all)) {
moneyStockSuggestDTOS.stream().filter(f -> all.stream().anyMatch(s -> s.getStockName().equals(f.getStockName())))
.forEach(f -> f.setScId(all.stream().filter(s -> s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
}
List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isBlank(f.getScId())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(noScIdList)){
List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f -> StringUtils.isBlank(f.getScId())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(noScIdList)) {
List<String> dispIdList = noScIdList.stream().map(MoneyStockSuggestDTO::getDispId).collect(Collectors.toList());
List<MoneyStock> all1 = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.selfDispId.in(dispIdList));
if(CollectionUtils.isNotEmpty(all1)){
moneyStockSuggestDTOS.stream().filter(f->all1.stream().anyMatch(s->s.getSelfDispId().equals(f.getDispId())))
.forEach(f->f.setScId(all.stream().filter(s->s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId()));
if (CollectionUtils.isNotEmpty(all1)) {
moneyStockSuggestDTOS.stream().filter(f -> all1.stream().anyMatch(s -> s.getSelfDispId().equals(f.getDispId())))
.forEach(f -> f.setScId(all.stream().filter(s -> s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId()));
}
}
}
@@ -599,49 +633,47 @@ public class MoneyApiController {
}
@ApiOperation(value = "股票推荐TopActive",httpMethod = "GET")
@ApiOperation(value = "股票推荐TopActive", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name="stockType",value = "BSE或者NSE"),
@ApiImplicitParam(name = "stockType", value = "BSE或者NSE"),
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "" +
"股票推荐相关: top active", response = JSONObject.class),
})
@GetMapping({"/market/api/market/money/getTopActives","/api/market/money/getTopActives"})
@GetMapping({"/market/api/market/money/getTopActives", "/api/market/money/getTopActives"})
@ResponseBody
@EncryptFilter(decryptRequest = false)
public List<MoneyStockSuggestDTO> getTopActive(@RequestParam String stockType) {
List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null;
moneyStockSuggestDTOS = activesStockSuggestCache.getIfPresent(stockType);
if(moneyStockSuggestDTOS ==null){
if(StringUtils.equals(stockType,"nse")){
if (moneyStockSuggestDTOS == null) {
if (StringUtils.equals(stockType, "nse")) {
moneyStockSuggestDTOS = nseActives();
}else if(StringUtils.equals(stockType,"bse")){
} else if (StringUtils.equals(stockType, "bse")) {
moneyStockSuggestDTOS = bseActives();
}
Map<Object, Boolean> map = new HashMap<>();
moneyStockSuggestDTOS = moneyStockSuggestDTOS.stream()
.filter(f->StringUtils.isNotBlank(f.getStockName()))
.filter(f -> StringUtils.isNotBlank(f.getStockName()))
.filter(i -> map.putIfAbsent(i.getStockName(), Boolean.TRUE) == null).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){
moneyStockSuggestDTOS.stream().forEach(f->f.setDispId(extractLastSegment(f.getStockUrl())));
if (CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)) {
moneyStockSuggestDTOS.stream().forEach(f -> f.setDispId(extractLastSegment(f.getStockUrl())));
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(selfUlrList)){
if (CollectionUtils.isNotEmpty(selfUlrList)) {
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList));
if(CollectionUtils.isNotEmpty(all)){
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
if (CollectionUtils.isNotEmpty(all)) {
moneyStockSuggestDTOS.stream().filter(f -> all.stream().anyMatch(s -> s.getStockName().equals(f.getStockName())))
.forEach(f -> f.setScId(all.stream().filter(s -> s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
}
List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isBlank(f.getScId())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(noScIdList)){
List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f -> StringUtils.isBlank(f.getScId())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(noScIdList)) {
List<String> dispIdList = noScIdList.stream().map(MoneyStockSuggestDTO::getDispId).collect(Collectors.toList());
List<MoneyStock> all1 = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.selfDispId.in(dispIdList));
if(CollectionUtils.isNotEmpty(all1)){
moneyStockSuggestDTOS.stream().filter(f->all1.stream().anyMatch(s->s.getSelfDispId().equals(f.getDispId())))
.forEach(f->f.setScId(all.stream().filter(s->s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId()));
if (CollectionUtils.isNotEmpty(all1)) {
moneyStockSuggestDTOS.stream().filter(f -> all1.stream().anyMatch(s -> s.getSelfDispId().equals(f.getDispId())))
.forEach(f -> f.setScId(all.stream().filter(s -> s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId()));
}
}
}
@@ -653,9 +685,8 @@ public class MoneyApiController {
}
@GetMapping({"/market/api/market/money/history/kLine","/api/market/money/history/kLine"})
@ApiOperation(value = "获取kline的money数据源", notes = "获取kline的money数据源",response = StockHistoryResponse.class)
@GetMapping({"/market/api/market/money/history/kLine", "/api/market/money/history/kLine"})
@ApiOperation(value = "获取kline的money数据源", notes = "获取kline的money数据源", response = StockHistoryResponse.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "symbol", value = "Stock symbol 对应的是NSEID 或者是BSEID", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "resolution", value = "单位:60 1D 1W 1D 对应H,D,W,Y", required = true, dataType = "String", paramType = "query"),
@@ -665,34 +696,34 @@ public class MoneyApiController {
@ApiImplicitParam(name = "currencyCode", value = "INR 不变", required = true, dataType = "String", paramType = "query")
})
@ResponseBody
@EncryptFilter(decryptRequest = false)
public ResponseEntity<StockHistoryResponse> getStockHistory( @RequestParam String symbol,
@RequestParam String resolution
) {
@EncryptFilter(decryptRequest = false)
public ResponseEntity<StockHistoryResponse> getStockHistory(@RequestParam String symbol,
@RequestParam String resolution
) {
// 向外部API发起请求并获取响应
StockHistoryRequest request = new StockHistoryRequest();
request.setSymbol(symbol);
Long to = null;
Long from = null;
int countback = 5;
if(StringUtils.equals("H",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - ( 60 * 60 );
if (StringUtils.equals("H", resolution)) {
to = (long) (System.currentTimeMillis() / 1000);
from = to - (60 * 60);
countback = 60;
request.setResolution("1");
}else if(StringUtils.equals("D",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (24 * 60 * 60 );
} else if (StringUtils.equals("D", resolution)) {
to = (long) (System.currentTimeMillis() / 1000);
from = to - (24 * 60 * 60);
countback = 390;
request.setResolution("1");
}else if(StringUtils.equals("W",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (7 * 24 * 60 * 60 );
} else if (StringUtils.equals("W", resolution)) {
to = (long) (System.currentTimeMillis() / 1000);
from = to - (7 * 24 * 60 * 60);
countback = 471;
request.setResolution("5");
}else if(StringUtils.equals("M",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (35 * 24 * 60 * 60 );
} else if (StringUtils.equals("M", resolution)) {
to = (long) (System.currentTimeMillis() / 1000);
from = to - (35 * 24 * 60 * 60);
countback = 328;
request.setResolution("30");
}
@@ -702,7 +733,7 @@ public class MoneyApiController {
request.setCountback(countback);
request.setCurrencyCode("INR");
String apiUrl = buildApiUrl(request);
log.info("request url:"+apiUrl);
log.info("request url:" + apiUrl);
StockHistoryResponse response = null;
int maxRetries = 3;
int retryCount = 0;
@@ -725,11 +756,27 @@ public class MoneyApiController {
}
}
if (response != null) {
setResponse(response,resolution);
if (response != null && !response.getS().equals("error")) {
setResponse(response, resolution);
// API request successful, return the response
return ResponseEntity.ok(response);
} else {
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.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
log.error("Failed to get a successful response after {} retries.", maxRetries);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
@@ -737,14 +784,41 @@ public class MoneyApiController {
// 返回响应
}
private void setResponse(StockHistoryResponse response,String resolution){
if(!"ok".equals(response.getS())){
@GetMapping({"/market/api/market/stock/optional", "/api/market/stock/optional"})
@ResponseBody
@EncryptFilter(decryptRequest = false)
public ResponseEntity<List<Object>> getOptionalStock() {
List<OptionalStock> optionalStocks = optionalStockRepository.findAll();
List<Object> data = optionalStocks.stream().map(stock -> {
try {
String responseStr = HttpRequest.doGrabGet(OPTIONAL_STOCK_MONEYCONTROL_URL + URLEncoder.encode(stock.getSymbol(), "UTF-8"));
OptionalStockResponse response = objectMapper.readValue(responseStr, OptionalStockResponse.class);
if (response != null && response.getCode().equals(200)) {
return response.getData();
}
}
catch (Exception e) {
log.error("Failed to get optional stock from moneycontrol for " + stock.getSymbol(), e);
}
OptionalStockResponse response = new OptionalStockResponse();
response.getData().setSymbol(stock.getSymbol());
response.getData().setSymbol(stock.getCompany());
return response.getData();
}).collect(Collectors.toList());
return ResponseEntity.ok(data);
}
private void setResponse(StockHistoryResponse response, String resolution) {
if (!"ok".equals(response.getS())) {
return;
}
if(Objects.isNull(response.getT())){
if (Objects.isNull(response.getT())) {
return;
}
if(StringUtils.equals("H",resolution) || StringUtils.equals("D",resolution)) {
if (StringUtils.equals("H", resolution) || StringUtils.equals("D", resolution)) {
List<Long> t = new ArrayList<>();
List<Double> o = new ArrayList<>();
List<Double> h = new ArrayList<>();
@@ -756,7 +830,7 @@ public class MoneyApiController {
Date currentTime = new Date();
//判断最后一条是不是当天的数据,如果不是,把最后一条的时间作为当天的时间
long getTime = response.getT().get(response.getT().size() - 1) * 1000L;
if(!DateUtil.isSameDay(currentTime, new Date(getTime))){
if (!DateUtil.isSameDay(currentTime, new Date(getTime))) {
currentTime = new Date(getTime);
}
int i = 0;
@@ -782,14 +856,14 @@ public class MoneyApiController {
}
private String buildApiUrl(StockHistoryRequest request) {
// 构建外部API的URL
return String.format("%s?symbol=%s&resolution=%s&from=%d&to=%d&countback=%d&currencyCode=%s",
EXTERNAL_API_URL, request.getSymbol(), request.getResolution(), request.getFrom(),
request.getTo(), request.getCountback(), request.getCurrencyCode());
};
}
;
private static String extractLastSegment(String url) {
@@ -814,7 +888,7 @@ public class MoneyApiController {
//// bseTopLoser();
System.out.println(new Date());
System.out.println(new Date(1713949200000L));
System.out.println(DateUtil.isSameDay(new Date(),new Date(1713949200000L)));
System.out.println(DateUtil.isSameDay(new Date(), new Date(1713949200000L)));
}
private Cache<String, List<MoneyStockSuggestDTO>> gainerStockSuggestCache = CacheBuilder.newBuilder()

View File

@@ -14,6 +14,7 @@ import cn.qutaojing.common.jpa.ConditionBuilder;
import cn.stock.market.domain.basic.entity.SiteNews;
import cn.stock.market.domain.basic.repository.SiteNewsRepository;
import cn.stock.market.infrastructure.db.po.QSiteNewsPO;
import cn.stock.market.infrastructure.job.InvestingTask;
import cn.stock.market.web.annotations.EncryptFilter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -178,7 +179,7 @@ public class StockApiController {
newsList.forEach( n -> {
String contentUrl = n.substring(1, n.indexOf("class=\"img-smllnews\"") - 2);
String id = contentUrl.substring(contentUrl.lastIndexOf("-") + 1, contentUrl.lastIndexOf("_"));
String imgUrl = n.substring(n.indexOf("img loading=\"lazy\" src=") + 24, n.indexOf("?"));
String imgUrl = InvestingTask.extractImgSrc(n);
// String time = n.substring(n.indexOf("Last Updated") + 23, n.indexOf("IST") - 9);
// Extract the date and time using regex
Pattern pattern = Pattern.compile("Updated On :<!-- --> <!-- -->(.*?)<!-- -->");