package com.yami.trading.huobi.hobi.internal;
|
|
import cn.hutool.core.date.DateTime;
|
import cn.hutool.http.HttpRequest;
|
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.google.common.collect.Lists;
|
import com.yami.trading.bean.data.domain.Realtime;
|
import com.yami.trading.common.http.HttpHelper;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Component;
|
|
import javax.crypto.Mac;
|
import javax.crypto.spec.SecretKeySpec;
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.Base64;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* TradingView 行情
|
* 哪吒出海
|
*/
|
@Component
|
@Slf4j
|
public class TradingViewDataServiceImpl {
|
|
|
//所有马来行情
|
private static final String ALL_QUOTES_URL = "https://scanner.tradingview.com/malaysia/scan";
|
|
//美股ETF
|
private static final String ALL_US_ETF_QUOTES_URL = "https://scanner.tradingview.com/america/scan?label-product=screener-etf";
|
|
//美股行情
|
private static final String ALL_US_STOCK_QUOTES_URL = "https://scanner.tradingview.com/america/scan?label-product=markets-screener";
|
|
/**
|
* 初始化美股所有行情 [初始化]
|
* @return
|
*/
|
public List<Realtime> realtimeUsStockSingle() {
|
log.info("正在采集美股所有行情");
|
String body = HttpRequest.post(ALL_US_STOCK_QUOTES_URL)
|
//.setHttpProxy("127.0.0.1",7890)
|
.body(getUsQuotesParams())
|
.execute()
|
.body();
|
List<Realtime> realtimeList = Lists.newArrayList();
|
//过滤数据
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject item = dataArr.getJSONObject(i);
|
//封装行情缓存
|
Realtime realtime = new Realtime();
|
String symbol = item.getString("s");
|
realtime.setSymbol(symbol);
|
JSONArray data = item.getJSONArray("d");
|
realtime.setName(data.get(1) != null ? (String) data.get(1) : "");
|
realtime.setTs(DateTime.now().getTime());
|
realtime.setOpen(data.get(6) != null ? new BigDecimal(data.get(6).toString()).doubleValue() : 0.0);
|
realtime.setClose(data.get(7) != null ? new BigDecimal(data.get(7).toString()).doubleValue() : 0.0);
|
realtime.setHigh(data.get(8) != null ? new BigDecimal(data.get(8).toString()).doubleValue() : 0.0);
|
realtime.setLow(data.get(9) != null ? new BigDecimal(data.get(9).toString()).doubleValue() : 0.0);
|
realtime.setMarketCapital(data.get(18) != null ? new BigDecimal(String.valueOf(data.get(18))).longValue() : 0L);
|
realtime.setFloatMarketCapital(data.get(18) != null ? new BigDecimal(String.valueOf(data.get(18))).longValue() : 0L);
|
realtime.setTurnoverRate(0);
|
double amount = (data.get(16) != null ? new BigDecimal(String.valueOf(data.get(16))).doubleValue() : 0.0) *
|
(data.get(7) != null ? new BigDecimal(String.valueOf(data.get(7))).doubleValue() : 0.0);
|
realtime.setAmount(amount);
|
realtime.setVolume(data.get(16) != null ? new BigDecimal(String.valueOf(data.get(16))).doubleValue() : 0.0);
|
realtime.setAsk(0.0);
|
realtime.setBid(0.0);
|
|
//无涨跌幅就为0
|
BigDecimal changeRatioVal = data.getBigDecimal(15);
|
if(changeRatioVal == null){
|
changeRatioVal = BigDecimal.ZERO;
|
}
|
|
BigDecimal netChange = new BigDecimal(realtime.getClose()).multiply(changeRatioVal).divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
|
netChange = netChange.subtract(BigDecimal.valueOf(0.10)).setScale(2, RoundingMode.HALF_UP);
|
realtime.setNetChange(netChange.doubleValue());
|
realtime.setChg(netChange.doubleValue());
|
|
BigDecimal changeRatio = changeRatioVal.setScale(2, RoundingMode.HALF_UP);
|
realtime.setChangeRatio(changeRatio.doubleValue());
|
|
realtimeList.add(realtime);
|
}
|
}
|
return realtimeList;
|
}
|
|
|
/**
|
* 采集所有美国ETF行情
|
*/
|
public static List<Realtime> realtimeUsEtfSingle(){
|
log.info(">>>>正在更新美国ETF行情<<<<");
|
String body = HttpRequest.post(ALL_US_ETF_QUOTES_URL)
|
//.setHttpProxy("127.0.0.1",7890)
|
.body(getUsEtfQuotesParams())
|
.execute()
|
.body();
|
List<Realtime> realtimeList = Lists.newArrayList();
|
//过滤数据
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject item = dataArr.getJSONObject(i);
|
//封装行情缓存
|
Realtime realtime = new Realtime();
|
String symbol = item.getString("s");
|
realtime.setSymbol(symbol);
|
JSONArray data = item.getJSONArray("d");
|
realtime.setName(data.get(1) != null ? (String) data.get(1) : "");
|
realtime.setTs(DateTime.now().getTime());
|
realtime.setOpen(data.get(6) != null ? new BigDecimal(data.get(6).toString()).doubleValue() : 0.0);
|
realtime.setClose(data.get(7) != null ? new BigDecimal(data.get(7).toString()).doubleValue() : 0.0);
|
realtime.setHigh(data.get(8) != null ? new BigDecimal(data.get(8).toString()).doubleValue() : 0.0);
|
realtime.setLow(data.get(9) != null ? new BigDecimal(data.get(9).toString()).doubleValue() : 0.0);
|
realtime.setMarketCapital(data.get(18) != null ? new BigDecimal(String.valueOf(data.get(18))).longValue() : 0L);
|
realtime.setFloatMarketCapital(data.get(18) != null ? new BigDecimal(String.valueOf(data.get(18))).longValue() : 0L);
|
realtime.setTurnoverRate(0);
|
double amount = (data.get(16) != null ? new BigDecimal(String.valueOf(data.get(16))).doubleValue() : 0.0) *
|
(data.get(7) != null ? new BigDecimal(String.valueOf(data.get(7))).doubleValue() : 0.0);
|
realtime.setAmount(amount);
|
realtime.setVolume(data.get(16) != null ? new BigDecimal(String.valueOf(data.get(16))).doubleValue() : 0.0);
|
realtime.setAsk(0.0);
|
realtime.setBid(0.0);
|
|
//无涨跌幅就为0
|
BigDecimal changeRatioVal = data.getBigDecimal(15);
|
if(changeRatioVal == null){
|
changeRatioVal = BigDecimal.ZERO;
|
}
|
|
BigDecimal netChange = new BigDecimal(realtime.getClose()).multiply(changeRatioVal).divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
|
netChange = netChange.subtract(BigDecimal.valueOf(0.10)).setScale(2, RoundingMode.HALF_UP);
|
realtime.setNetChange(netChange.doubleValue());
|
realtime.setChg(netChange.doubleValue());
|
|
BigDecimal changeRatio = changeRatioVal.setScale(2, RoundingMode.HALF_UP);
|
realtime.setChangeRatio(changeRatio.doubleValue());
|
|
|
|
realtimeList.add(realtime);
|
}
|
}
|
return realtimeList;
|
}
|
|
/**
|
* 所有马来股票行情
|
*/
|
public static List<Realtime> realtimeMySingle(){
|
log.info("正在采集马来西亚股票所有行情");
|
String body = HttpRequest.post(ALL_QUOTES_URL)
|
//.setHttpProxy("127.0.0.1",7890)
|
.body(getAllQuotesParams())
|
.execute()
|
.body();
|
List<Realtime> realtimeList = Lists.newArrayList();
|
//过滤数据
|
JSONObject bodyJson = JSON.parseObject(body);
|
JSONArray dataArr = bodyJson.getJSONArray("data");
|
if (dataArr != null) {
|
for (int i = 0; i < dataArr.size(); i++) {
|
JSONObject item = dataArr.getJSONObject(i);
|
//封装行情缓存
|
Realtime realtime = new Realtime();
|
String symbol = item.getString("s");
|
realtime.setSymbol(symbol);
|
JSONArray data = item.getJSONArray("d");
|
realtime.setName(data.get(1) != null ? (String) data.get(1) : "");
|
realtime.setTs(DateTime.now().getTime());
|
realtime.setOpen(data.get(6) != null ? new BigDecimal(data.get(6).toString()).doubleValue() : 0.0);
|
realtime.setClose(data.get(7) != null ? new BigDecimal(data.get(7).toString()).doubleValue() : 0.0);
|
realtime.setHigh(data.get(8) != null ? new BigDecimal(data.get(8).toString()).doubleValue() : 0.0);
|
realtime.setLow(data.get(9) != null ? new BigDecimal(data.get(9).toString()).doubleValue() : 0.0);
|
realtime.setMarketCapital(data.get(18) != null ? new BigDecimal(String.valueOf(data.get(18))).longValue() : 0L);
|
realtime.setFloatMarketCapital(data.get(18) != null ? new BigDecimal(String.valueOf(data.get(18))).longValue() : 0L);
|
realtime.setTurnoverRate(0);
|
double amount = (data.get(16) != null ? new BigDecimal(String.valueOf(data.get(16))).doubleValue() : 0.0) *
|
(data.get(7) != null ? new BigDecimal(String.valueOf(data.get(7))).doubleValue() : 0.0);
|
realtime.setAmount(amount);
|
realtime.setVolume(data.get(16) != null ? new BigDecimal(String.valueOf(data.get(16))).doubleValue() : 0.0);
|
realtime.setAsk(0.0);
|
realtime.setBid(0.0);
|
realtimeList.add(realtime);
|
}
|
}
|
return realtimeList;
|
}
|
|
public static void main(String[] args) {
|
//realtimeMySingle();
|
|
String url = "https://www.futunn.com/quote-api/quote-v2/get-stock-list?marketType=27&plateType=1&rankType=1&page=0&pageSize=50";
|
Map<String, String> headers = HttpHelper.getRequestHeaders(url);
|
System.out.println(headers);
|
|
}
|
|
private static String getAllQuotesParams(){
|
// 创建并填充 JSON 对象
|
JSONObject jsonObject = new JSONObject();
|
jsonObject.put("columns", new JSONArray()
|
.fluentAdd("name")
|
.fluentAdd("description")
|
.fluentAdd("logoid")
|
.fluentAdd("update_mode")
|
.fluentAdd("type")
|
.fluentAdd("typespecs")
|
.fluentAdd("open")
|
.fluentAdd("close")
|
.fluentAdd("high")
|
.fluentAdd("low")
|
.fluentAdd("pricescale")
|
.fluentAdd("minmov")
|
.fluentAdd("fractional")
|
.fluentAdd("minmove2")
|
.fluentAdd("currency")
|
.fluentAdd("change")
|
.fluentAdd("volume")
|
.fluentAdd("relative_volume_10d_calc")
|
.fluentAdd("market_cap_basic")
|
.fluentAdd("fundamental_currency_code")
|
.fluentAdd("price_earnings_ttm")
|
.fluentAdd("earnings_per_share_diluted_ttm")
|
.fluentAdd("earnings_per_share_diluted_yoy_growth_ttm")
|
.fluentAdd("dividends_yield_current")
|
.fluentAdd("sector.tr")
|
.fluentAdd("market")
|
.fluentAdd("sector")
|
.fluentAdd("recommendation_mark"));
|
|
jsonObject.put("preset", "all_stocks");
|
jsonObject.put("ignore_unknown_fields", false);
|
jsonObject.put("options", new JSONObject().fluentPut("lang", "zh"));
|
jsonObject.put("range", new JSONArray().fluentAdd(0).fluentAdd(20000));
|
jsonObject.put("sort", new JSONObject()
|
.fluentPut("sortBy", "name")
|
.fluentPut("sortOrder", "asc")
|
.fluentPut("nullsFirst", false));
|
return jsonObject.toJSONString();
|
}
|
|
private static String getUsEtfQuotesParams() {
|
// 创建并填充 JSON 对象
|
com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
|
|
jsonObject.put("columns", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd("name")
|
.fluentAdd("description")
|
.fluentAdd("logoid")
|
.fluentAdd("update_mode")
|
.fluentAdd("type")
|
.fluentAdd("typespecs")
|
.fluentAdd("open")
|
.fluentAdd("close")
|
.fluentAdd("high")
|
.fluentAdd("low")
|
.fluentAdd("pricescale")
|
.fluentAdd("minmov")
|
.fluentAdd("fractional")
|
.fluentAdd("minmove2")
|
.fluentAdd("currency")
|
.fluentAdd("change")
|
.fluentAdd("volume")
|
.fluentAdd("relative_volume_10d_calc")
|
.fluentAdd("market_cap_basic")
|
.fluentAdd("fundamental_currency_code")
|
.fluentAdd("price_earnings_ttm")
|
.fluentAdd("earnings_per_share_diluted_ttm")
|
.fluentAdd("earnings_per_share_diluted_yoy_growth_ttm")
|
.fluentAdd("dividends_yield_current")
|
.fluentAdd("sector.tr")
|
.fluentAdd("market")
|
.fluentAdd("sector")
|
.fluentAdd("recommendation_mark"));
|
|
jsonObject.put("ignore_unknown_fields", false);
|
|
jsonObject.put("options", new com.alibaba.fastjson2.JSONObject().fluentPut("lang", "zh"));
|
|
jsonObject.put("range", new com.alibaba.fastjson2.JSONArray().fluentAdd(0).fluentAdd(400));
|
|
jsonObject.put("sort", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("sortBy", "aum")
|
.fluentPut("sortOrder", "desc"));
|
|
jsonObject.put("symbols", new com.alibaba.fastjson2.JSONObject());
|
|
jsonObject.put("markets", new com.alibaba.fastjson2.JSONArray().fluentAdd("america"));
|
|
jsonObject.put("filter", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("left", "aum")
|
.fluentPut("operation", "egreater")
|
.fluentPut("right", 10000000000L)
|
));
|
|
jsonObject.put("filter2", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "and")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operation", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "or")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operation", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "and")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("expression", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("left", "typespecs")
|
.fluentPut("operation", "has")
|
.fluentPut("right", new com.alibaba.fastjson2.JSONArray().fluentAdd("etf"))
|
)
|
)
|
)
|
)
|
)
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operation", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("operator", "and")
|
.fluentPut("operands", new com.alibaba.fastjson2.JSONArray()
|
.fluentAdd(new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("expression", new com.alibaba.fastjson2.JSONObject()
|
.fluentPut("left", "type")
|
.fluentPut("operation", "equal")
|
.fluentPut("right", "structured")
|
)
|
)
|
)
|
)
|
)
|
)
|
)
|
)
|
)
|
);
|
|
return jsonObject.toJSONString();
|
}
|
|
private static String getUsQuotesParams() {
|
return "{\"columns\":[\"name\",\"description\",\"logoid\",\"update_mode\",\"type\",\"typespecs\",\"open\",\"close\",\"high\",\"low\",\"pricescale\",\"minmov\",\"fractional\",\"minmove2\",\"currency\",\"change\",\"volume\",\"relative_volume_10d_calc\",\"market_cap_basic\",\"fundamental_currency_code\",\"price_earnings_ttm\",\"earnings_per_share_diluted_ttm\",\"earnings_per_share_diluted_yoy_growth_ttm\",\"dividends_yield_current\",\"sector.tr\",\"market\",\"sector\",\"recommendation_mark\",\"exchange\"],\"filter\":[{\"left\":\"is_primary\",\"operation\":\"equal\",\"right\":true}],\"ignore_unknown_fields\":false,\"options\":{\"lang\":\"zh\"},\"range\":[0,8200],\"sort\":{\"sortBy\":\"market_cap_basic\",\"sortOrder\":\"desc\"},\"symbols\":{},\"markets\":[\"america\"],\"filter2\":{\"operator\":\"and\",\"operands\":[{\"operation\":{\"operator\":\"or\",\"operands\":[{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"stock\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has\",\"right\":[\"common\"]}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"stock\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has\",\"right\":[\"preferred\"]}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"dr\"}}]}},{\"operation\":{\"operator\":\"and\",\"operands\":[{\"expression\":{\"left\":\"type\",\"operation\":\"equal\",\"right\":\"fund\"}},{\"expression\":{\"left\":\"typespecs\",\"operation\":\"has_none_of\",\"right\":[\"etf\"]}}]}}]}}]}}";
|
}
|
|
}
|