mirror of
https://github.com/zhangxiangliang/stock-api.git
synced 2025-01-23 14:20:23 +08:00
feat: 初始化 v3 版本
This commit is contained in:
parent
6b760659ad
commit
77b7d04c85
@ -1,12 +0,0 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
14
.eslintrc
14
.eslintrc
@ -1,14 +0,0 @@
|
||||
{
|
||||
"extends": ["taro"],
|
||||
"rules": {
|
||||
"semi": ["error", "always"]
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"useJSXTextNode": true,
|
||||
"project": "./tsconfig.json"
|
||||
}
|
||||
}
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
dist/
|
||||
.DS_Store
|
||||
node_modules/
|
||||
coverage/
|
@ -1,7 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 12
|
||||
before_install:
|
||||
- yarn install
|
||||
after_script:
|
||||
- yarn run coverage
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 20222 ZHANGXIANGLIANG
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
150
README.md
150
README.md
@ -1,151 +1,37 @@
|
||||
<h1 align="center">股票数据小助手</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://codecov.io/github/jiucaixiaozhu/stock-api?branch=master"><img src="https://img.shields.io/codecov/c/github/jiucaixiaozhu/stock-api/master.svg?sanitize=true" alt="Coverage Status"></a>
|
||||
<a href="https://npmcharts.com/compare/stock-api?minimal=true"><img src="https://img.shields.io/npm/dm/stock-api.svg?sanitize=true" alt="Downloads"></a>
|
||||
<a href="https://www.npmjs.com/package/stock-api"><img src="https://img.shields.io/npm/v/stock-api.svg?sanitize=true" alt="Version"></a>
|
||||
<a href="https://www.npmjs.com/package/stock-api"><img src="https://img.shields.io/npm/l/stock-api.svg?sanitize=true" alt="License"></a>
|
||||
<a href="https://www.npmjs.com/package/stock-api"><img src="https://img.shields.io/badge/language-typescript-blue" alt="License"></a>
|
||||
</p>
|
||||
|
||||
|
||||
# 股票数据小助手
|
||||
|
||||
## 简介
|
||||
|
||||
一款聚焦在 `股票实时数据` 和 `周边相关服务` 的接口小助手。
|
||||
一款聚焦在 `股票实时数据` 和 `周边相关服务` 的代码库。
|
||||
|
||||
## 股票数据
|
||||
|
||||
| 名称 | 接口名 | 搜索股票代码 | 获取股票实时数据 | 获取股票组实时数据 | 官网 |
|
||||
| :---: | :---: | :---: | :---: | :---: | :---: |
|
||||
| 网易财经 | netease | [已实现](#搜索股票代码) | [已实现](#获取股票实时数据) | [已实现](#获取股票组实时数据) | [传送门](https://money.163.com/) |
|
||||
| 雪球 | xueqiu | [已实现](#搜索股票代码) | [已实现](#获取股票实时数据) | [已实现](#获取股票组实时数据) | [传送门](https://xueqiu.com/) |
|
||||
| 新浪股票 | sina | [已实现](#搜索股票代码) | [已实现](#获取股票实时数据) | [已实现](#获取股票组实时数据) | [传送门](https://finance.sina.com.cn/) |
|
||||
| 腾讯股票 | tencent | [已实现](#搜索股票代码) | [已实现](#获取股票实时数据) | [已实现](#获取股票组实时数据) | [传送门](http://gu.qq.com/) |
|
||||
### [网易财经](https://money.163.com)
|
||||
|
||||
## 安装
|
||||
- [] 搜索股票代码
|
||||
- [] 获取股票实时数据
|
||||
- [] 获取股票组实时数据
|
||||
|
||||
```shell
|
||||
npm install stock-api
|
||||
yarn add stock-api
|
||||
```
|
||||
### [雪球](https://xueqiu.com)
|
||||
|
||||
## 使用
|
||||
- [] 搜索股票代码
|
||||
- [] 获取股票实时数据
|
||||
- [] 获取股票组实时数据
|
||||
|
||||
### 接口概览
|
||||
### [新浪股票](https://finance.sina.com.cn)
|
||||
|
||||
* [选择数据源](#选择数据源)
|
||||
* [搜索股票代码](#搜索股票代码)
|
||||
* [获取股票实时数据](#获取股票实时数据)
|
||||
* [获取股票组实时数据](#获取股票组实时数据)
|
||||
|
||||
### 股票代码
|
||||
|
||||
由于每个交易所数据规则不一样,为了能统一规范对代码定义了规则 `交易所+股票代码`。
|
||||
|
||||
| 交易所 | 代号 | 实例 |
|
||||
| --- | --- | --- |
|
||||
| 上海交易所 | SH | SH000001 |
|
||||
| 深圳交易所 | SZ | SZ399001 |
|
||||
| 香港交易所 | HK | HKHSI |
|
||||
| 美国交易所 | US | USDJI |
|
||||
|
||||
|
||||
### 选择数据源
|
||||
|
||||
##### 可选导入
|
||||
|
||||
```typescript
|
||||
import { stocks } from "stock-api";
|
||||
|
||||
// 数据源
|
||||
const sina = stocks.sina;
|
||||
const xueqiu = stocks.xueqiu;
|
||||
const netease = stocks.netease;
|
||||
const tencent = stocks.tencent;
|
||||
```
|
||||
|
||||
### 搜索股票代码
|
||||
|
||||
##### 示例
|
||||
|
||||
```typescript
|
||||
import { stocks } from "stock-api";
|
||||
|
||||
// 获取股票组实时数据
|
||||
stocks.sina.searchStocks(["510500"]).then(console.log);
|
||||
```
|
||||
|
||||
##### 输出
|
||||
|
||||
```typescript
|
||||
[{
|
||||
code: 'SH510500',
|
||||
name: '500ETF',
|
||||
percent: 0.028383,
|
||||
now: 7.174,
|
||||
low: 6.93,
|
||||
high: 7.184,
|
||||
yesterday: 6.976
|
||||
}]
|
||||
```
|
||||
|
||||
### 获取股票实时数据
|
||||
|
||||
##### 示例
|
||||
|
||||
```typescript
|
||||
import { stocks } from "stock-api";
|
||||
|
||||
// 获取股票实时数据
|
||||
stocks.sina.getStock("SH510500").then(console.log);
|
||||
```
|
||||
|
||||
##### 输出
|
||||
|
||||
```typescript
|
||||
{
|
||||
code: 'SH510500',
|
||||
name: '500ETF',
|
||||
percent: 0.028383,
|
||||
now: 7.174,
|
||||
low: 6.93,
|
||||
high: 7.184,
|
||||
yesterday: 6.976
|
||||
}
|
||||
```
|
||||
|
||||
### 获取股票组实时数据
|
||||
|
||||
##### 示例
|
||||
|
||||
```typescript
|
||||
import { stocks } from "stock-api";
|
||||
|
||||
// 获取股票组实时数据
|
||||
stocks.sina.getStocks(["SH510500"]).then(console.log);
|
||||
```
|
||||
|
||||
##### 输出
|
||||
|
||||
```typescript
|
||||
[{
|
||||
code: 'SH510500',
|
||||
name: '500ETF',
|
||||
percent: 0.028383,
|
||||
now: 7.174,
|
||||
low: 6.93,
|
||||
high: 7.184,
|
||||
yesterday: 6.976
|
||||
}]
|
||||
```
|
||||
- [] 搜索股票代码
|
||||
- [] 获取股票实时数据
|
||||
- [] 获取股票组实时数据
|
||||
|
||||
### [腾讯股票](http://gu.qq.com)
|
||||
|
||||
- [] 搜索股票代码
|
||||
- [] 获取股票实时数据
|
||||
- [] 获取股票组实时数据
|
||||
|
||||
## 一起成长
|
||||
|
||||
> 韭菜小猪也有暴富梦~
|
||||
|
||||
- 在困惑的城市里总少不了并肩同行的 伙伴 让我们一起成长。
|
||||
- 如果您想让更多人看到文章可以点个 点赞。
|
||||
- 如果您想激励小二可以到 Github 给个 小星星。
|
||||
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"verbose": true,
|
||||
"testTimeout": 15000,
|
||||
"transform": {
|
||||
"^.+\\.(t|j)sx?$": "ts-jest"
|
||||
},
|
||||
"testRegex": "(/test/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
"js",
|
||||
"jsx",
|
||||
"json",
|
||||
"node"
|
||||
],
|
||||
"moduleDirectories": ["node_modules", "src"],
|
||||
"moduleNameMapper": {
|
||||
"^@stocks/(.*)$": "<rootDir>/src/stocks/$1",
|
||||
"^@utils/(.*)$": "<rootDir>/src/utils/$1",
|
||||
"^types/(.*)$": "<rootDir>/types/$1"
|
||||
}
|
||||
}
|
41
package.json
41
package.json
@ -1,47 +1,16 @@
|
||||
{
|
||||
"name": "stock-api",
|
||||
"version": "2.0.5",
|
||||
"description": "【韭菜小猪】免费股票数据分析相关接口",
|
||||
"version": "3.0.0",
|
||||
"description": "免费股票数据分析相关接口",
|
||||
"keywords": [
|
||||
"股票",
|
||||
"数据分析",
|
||||
"接口"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"repository": "https://github.com/jiucaixiaozhu/stock-api",
|
||||
"repository": "https://github.com/zhangxiangliang/stock-api",
|
||||
"author": "zhangxiangliang",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"types/**/*"
|
||||
],
|
||||
"scripts": {
|
||||
"prepublishOnly": "yarn run test",
|
||||
"prepare": "rm -rf ./dist && yarn run build",
|
||||
"preversion": "npm test",
|
||||
"version": "git add -A ./",
|
||||
"postversion": "git push && git push --tags",
|
||||
"build": "ttsc",
|
||||
"watch": "ttsc --watch",
|
||||
"test": "jest --config jestconfig.json --coverage",
|
||||
"coverage": "yarn run test && codecov"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.5",
|
||||
"@typescript-eslint/parser": "^3.7.0",
|
||||
"codecov": "^3.7.2",
|
||||
"jest": "^26.1.0",
|
||||
"nyc": "^15.1.0",
|
||||
"ts-jest": "^26.1.3",
|
||||
"ttypescript": "^1.5.10",
|
||||
"typescript": "^3.9.7",
|
||||
"typescript-transform-paths": "^1.1.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.159",
|
||||
"iconv-lite": "^0.6.2",
|
||||
"lodash": "^4.17.20",
|
||||
"superagent": "^5.3.1"
|
||||
}
|
||||
"dist"
|
||||
]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
// Stocks
|
||||
import stocks from './stocks/index';
|
||||
|
||||
export { stocks };
|
||||
export default { stocks };
|
@ -1,37 +0,0 @@
|
||||
// Utils
|
||||
import { ERROR_UNDEFINED_GET_STOCK, ERROR_UNDEFINED_GET_STOCKS, ERROR_UNDEFINED_SEARCH_STOCK } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import StockApi from "types/stocks/index";
|
||||
|
||||
/**
|
||||
* 基础股票代码接口
|
||||
*/
|
||||
const Base: StockApi = {
|
||||
/**
|
||||
* 获取股票数据
|
||||
* @param code 股票代码
|
||||
*/
|
||||
async getStock(code: string): Promise<Stock> {
|
||||
throw new Error(ERROR_UNDEFINED_GET_STOCK);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取股票数据组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
async getStocks(codes: string[]): Promise<Stock[]> {
|
||||
throw new Error(ERROR_UNDEFINED_GET_STOCKS);
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜索股票代码
|
||||
* @param key 关键字
|
||||
*/
|
||||
async searchStocks(key: string): Promise<Stock[]> {
|
||||
throw new Error(ERROR_UNDEFINED_SEARCH_STOCK);
|
||||
}
|
||||
};
|
||||
|
||||
export default Base;
|
@ -1,77 +0,0 @@
|
||||
// Utils
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { ERROR_UNDEFINED_API_CODE, ERROR_UNDEFINED_SZ_API_CODE, ERROR_UNDEFINED_SH_API_CODE, ERROR_UNDEFINED_HK_API_CODE, ERROR_UNDEFINED_US_API_CODE, ERROR_API_CODE } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import ApiCodeTransform from "types/stocks/transforms/api-code";
|
||||
|
||||
/**
|
||||
* 【基础】股票代码转换统一代码
|
||||
*/
|
||||
class BaseApiCodeTransform implements ApiCodeTransform {
|
||||
/**
|
||||
* 股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
if (code.indexOf(COMMON_SH) === 0) {
|
||||
return this.SHTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(COMMON_SZ) === 0) {
|
||||
return this.SZTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(COMMON_HK) === 0) {
|
||||
return this.HKTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(COMMON_US) === 0) {
|
||||
return this.USTransform(code);
|
||||
}
|
||||
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 股票代码组转换统一代码组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return codes.map((code) => this.transform(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_SZ_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_SH_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_HK_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_US_API_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseApiCodeTransform;
|
@ -1,77 +0,0 @@
|
||||
// Utils
|
||||
import { ERROR_COMMON_CODE, ERROR_UNDEFINED_SZ_COMMON_CODE, ERROR_UNDEFINED_SH_COMMON_CODE, ERROR_UNDEFINED_HK_COMMON_CODE, ERROR_UNDEFINED_US_COMMON_CODE } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import CommonCodeTransform from "types/stocks/transforms/common-code";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "../utils/constant";
|
||||
|
||||
/**
|
||||
* 【基础】统一代码转换股票代码
|
||||
*/
|
||||
class BaseCommonCodeTransform implements CommonCodeTransform {
|
||||
/**
|
||||
* 交易所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
if (code.indexOf(COMMON_SH) === 0) {
|
||||
return this.SHTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(COMMON_SZ) === 0) {
|
||||
return this.SZTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(COMMON_HK) === 0) {
|
||||
return this.HKTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(COMMON_US) === 0) {
|
||||
return this.USTransform(code);
|
||||
}
|
||||
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所统一代码组转股票代码组
|
||||
* @param codes 统一代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return codes.map((code) => this.transform(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_SZ_COMMON_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_SH_COMMON_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_HK_COMMON_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
throw new Error(ERROR_UNDEFINED_US_COMMON_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseCommonCodeTransform;
|
@ -1,68 +0,0 @@
|
||||
// Utils
|
||||
import { ERROR_UNDEFINED_GET_CODE, ERROR_UNDEFINED_GET_NAME, ERROR_UNDEFINED_GET_NOW, ERROR_UNDEFINED_GET_LOW, ERROR_UNDEFINED_GET_HIGH, ERROR_UNDEFINED_GET_YESTERDAY, ERROR_UNDEFINED_GET_PERCENT, ERROR_UNDEFINED_GET_STOCK } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
|
||||
/**
|
||||
* 基础股票数据解析
|
||||
*/
|
||||
class BaseStockTransform {
|
||||
/**
|
||||
* 获取代码
|
||||
*/
|
||||
getCode(): string {
|
||||
throw new Error(ERROR_UNDEFINED_GET_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
*/
|
||||
getName(): string {
|
||||
throw new Error(ERROR_UNDEFINED_GET_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取现价
|
||||
*/
|
||||
getNow(): number {
|
||||
throw new Error(ERROR_UNDEFINED_GET_NOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最低价
|
||||
*/
|
||||
getLow(): number {
|
||||
throw new Error(ERROR_UNDEFINED_GET_LOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最高价
|
||||
*/
|
||||
getHigh(): number {
|
||||
throw new Error(ERROR_UNDEFINED_GET_HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨日收盘价
|
||||
*/
|
||||
getYesterday(): number {
|
||||
throw new Error(ERROR_UNDEFINED_GET_YESTERDAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取涨跌
|
||||
*/
|
||||
getPercent(): number {
|
||||
throw new Error(ERROR_UNDEFINED_GET_PERCENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
*/
|
||||
getStock(): Stock {
|
||||
throw new Error(ERROR_UNDEFINED_GET_STOCK);
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseStockTransform;
|
@ -1,6 +0,0 @@
|
||||
// 默认交易所常量
|
||||
export const COMMON_SZ = "SZ"; // 深交所相关常量
|
||||
export const COMMON_SH = "SH"; // 上交所相关常量
|
||||
export const COMMON_HK = "HK"; // 港交所相关常量
|
||||
export const COMMON_US = "US"; // 美交所相关常量
|
||||
|
@ -1,22 +0,0 @@
|
||||
// Stocks
|
||||
import base from "./base";
|
||||
import sina from "./sina";
|
||||
import xueqiu from "./xueqiu";
|
||||
import netease from "./netease";
|
||||
import tencent from "./tencent";
|
||||
|
||||
export {
|
||||
base,
|
||||
sina,
|
||||
xueqiu,
|
||||
netease,
|
||||
tencent,
|
||||
};
|
||||
|
||||
export default {
|
||||
base,
|
||||
sina,
|
||||
xueqiu,
|
||||
netease,
|
||||
tencent,
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
|
||||
// NPM
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
// Stocks
|
||||
import NeteaseStockTransform from "@stocks/netease/transforms/stock";
|
||||
import NeteaseCommonCodeTransform from "@stocks/netease/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import fetch from "@utils/fetch";
|
||||
import { DEFAULT_STOCK } from "@utils/constant";
|
||||
import { COMMON_SZ, COMMON_SH } from "@stocks/base/utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import StockApi from "types/stocks/index";
|
||||
import Dictionary from "types/utils/dictionary";
|
||||
|
||||
/**
|
||||
* 网易股票代码接口
|
||||
*/
|
||||
const Netease: StockApi = {
|
||||
/**
|
||||
* 获取股票数据
|
||||
* @param code 股票代码
|
||||
*/
|
||||
async getStock(code: string): Promise<Stock> {
|
||||
const transform = (new NeteaseCommonCodeTransform).transform(code);
|
||||
|
||||
const url = `https://api.money.126.net/data/feed/${transform},money.api?callback=topstock`;
|
||||
const res = await fetch.get(url);
|
||||
|
||||
const items = JSON.parse(res.body.toString().replace(/\(|\)|;|(topstock)|\s/g, '').replace('{{', '{').replace('}}}', "}}"));
|
||||
const params = items[transform];
|
||||
|
||||
if (!params) {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
const data = (new NeteaseStockTransform(code, params));
|
||||
return data.getStock();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取股票数据组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
async getStocks(codes: string[]): Promise<Stock[]> {
|
||||
codes = uniq(codes.filter(i => i !== ''));
|
||||
|
||||
// 无股票时返回空数组
|
||||
if (codes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const transforms = (new NeteaseCommonCodeTransform).transforms(codes);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://api.money.126.net/data/feed/${transforms.join(',')},money.api?callback=topstock`;
|
||||
const res = await fetch.get(url);
|
||||
|
||||
// 解析数据
|
||||
const items = JSON.parse(res.body.toString().replace(/\(|\)|;|(topstock)|\s/g, '').replace('{{', '{').replace('}}}', "}}"));
|
||||
return codes.map(code => {
|
||||
const transform = (new NeteaseCommonCodeTransform).transform(code);
|
||||
const params = items[transform];
|
||||
|
||||
if (!params) {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
const data = (new NeteaseStockTransform(code, params));
|
||||
|
||||
return data.getStock();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜索股票代码
|
||||
* @param key 关键字
|
||||
*/
|
||||
async searchStocks(key: string): Promise<Stock[]> {
|
||||
// 数据获取
|
||||
const url = `https://quotes.money.163.com/stocksearch/json.do?type=&count=5&word=${encodeURIComponent(key)}&callback=topstock`;
|
||||
const res = await fetch.get(url);
|
||||
|
||||
// 解析数据
|
||||
const row = res.body.toString().replace(/\(|\)|;|(topstock)|\s/g, '').replace('{{', '{').replace('}}}', "}}");
|
||||
const items: Dictionary<string>[] = JSON.parse(row);
|
||||
|
||||
const codes: string[] = items.map(i => {
|
||||
if (i.tag.includes(COMMON_SZ) || i.type.includes(COMMON_SZ)) {
|
||||
return COMMON_SZ + i.symbol;
|
||||
}
|
||||
|
||||
if (i.tag.includes(COMMON_SH) || i.type.includes(COMMON_SH)) {
|
||||
return COMMON_SH + i.symbol;
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
|
||||
return await Netease.getStocks(uniq(codes.filter(i => i !== '')));
|
||||
}
|
||||
}
|
||||
|
||||
export default Netease;
|
@ -1,94 +0,0 @@
|
||||
// Stocks
|
||||
import BaseApiCodeTransform from "@stocks/base/transforms/api-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_API_CODE } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { NETEASE_SZ, NETEASE_SH, NETEASE_HK, NETEASE_US } from "@stocks/netease/utils/constant";
|
||||
|
||||
/**
|
||||
* 网易股票代码转统一代码
|
||||
*/
|
||||
class NeteaseApiCodeTransform extends BaseApiCodeTransform {
|
||||
/**
|
||||
* 股票代码转统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
if (code.indexOf(NETEASE_SZ) === 0) {
|
||||
return this.SZTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(NETEASE_SH) === 0) {
|
||||
return this.SHTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(NETEASE_HK) === 0) {
|
||||
return this.HKTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(NETEASE_US) === 0) {
|
||||
return this.USTransform(code);
|
||||
}
|
||||
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 股票代码组转统一代码组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return codes.map((code) => this.transform(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所股票代码转统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (code.indexOf(NETEASE_SZ) !== 0) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SZ + code.replace(NETEASE_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所股票代码转统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (!code.includes(NETEASE_SH)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SH + code.replace(NETEASE_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所股票代码转统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (!code.includes(NETEASE_HK)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_HK + code.replace(NETEASE_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所股票代码转统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (!code.includes(NETEASE_US)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_US + code.replace(NETEASE_US, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default NeteaseApiCodeTransform;
|
@ -1,78 +0,0 @@
|
||||
// Stocks
|
||||
import BaseCommonCodeTransform from "@stocks/base/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_COMMON_CODE } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { NETEASE_SZ, NETEASE_SH, NETEASE_HK, NETEASE_US } from "@stocks/netease/utils/constant";
|
||||
|
||||
/**
|
||||
* 【网易】统一代码转股票代码
|
||||
*/
|
||||
class NeteaseCommonCodeTransform extends BaseCommonCodeTransform {
|
||||
/**
|
||||
* 统一代码转股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
return super.transform(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一代码组转换股票代码组
|
||||
* @param codes 统一代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所统一代码转股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (!code.includes(COMMON_SZ)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return NETEASE_SZ + code.replace(COMMON_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所统一代码转股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (!code.includes(COMMON_SH)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return NETEASE_SH + code.replace(COMMON_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所统一代码转股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (!code.includes(COMMON_HK)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return NETEASE_HK + code.replace(COMMON_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所统一代码转股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (!code.includes(COMMON_US)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return NETEASE_US + code.replace(COMMON_US, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default NeteaseCommonCodeTransform;
|
@ -1,88 +0,0 @@
|
||||
// Stocks
|
||||
import BaseStockTransform from "@stocks/base/transforms/stock";
|
||||
|
||||
// Utils
|
||||
import { DEFAULT_STRING, DEFAULT_NUMBER } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import Dictionary from "types/utils/dictionary";
|
||||
|
||||
/**
|
||||
* 网易股票数据解析
|
||||
*/
|
||||
class NeteaseStockTransform extends BaseStockTransform {
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
constructor(public code: string, public params: Dictionary<number | string>) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代码
|
||||
*/
|
||||
getCode(): string {
|
||||
return String(this.code).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
*/
|
||||
getName(): string {
|
||||
return String(this.params.name || DEFAULT_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取现价
|
||||
*/
|
||||
getNow(): number {
|
||||
return Number(this.params.price || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最低价
|
||||
*/
|
||||
getLow(): number {
|
||||
return Number(this.params.low || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最高价
|
||||
*/
|
||||
getHigh(): number {
|
||||
return Number(this.params.high || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨日收盘价
|
||||
*/
|
||||
getYesterday(): number {
|
||||
return Number(this.params.yestclose || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取涨跌
|
||||
*/
|
||||
getPercent(): number {
|
||||
return this.getNow() ? this.getNow() / this.getYesterday() - 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
*/
|
||||
getStock(): Stock {
|
||||
return {
|
||||
code: this.getCode(),
|
||||
name: this.getName(),
|
||||
percent: this.getPercent(),
|
||||
|
||||
now: this.getNow(),
|
||||
low: this.getLow(),
|
||||
high: this.getHigh(),
|
||||
yesterday: this.getYesterday(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default NeteaseStockTransform;
|
@ -1,5 +0,0 @@
|
||||
// 默认交易所常量
|
||||
export const NETEASE_SZ = "1"; // 深交所相关常量
|
||||
export const NETEASE_SH = "0"; // 上交所相关常量
|
||||
export const NETEASE_HK = "hk"; // 港交所相关常量
|
||||
export const NETEASE_US = "US_"; // 美交所相关常量
|
@ -1,132 +0,0 @@
|
||||
// NPM
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
// Stocks
|
||||
import SinaStockTransform from "@stocks/sina/transforms/stock";
|
||||
import SinaCommonCodeTransform from "@stocks/sina/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import fetch from "@utils/fetch";
|
||||
import iconv from "@utils/iconv";
|
||||
import { DEFAULT_STOCK } from "@utils/constant";
|
||||
import { COMMON_SZ, COMMON_SH, COMMON_US, COMMON_HK } from "@stocks/base/utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import StockApi from "types/stocks/index";
|
||||
|
||||
/**
|
||||
* 新浪股票代码接口
|
||||
*/
|
||||
const Sina: StockApi = {
|
||||
/**
|
||||
* 获取股票数据
|
||||
* @param code 股票代码
|
||||
*/
|
||||
async getStock(code: string): Promise<Stock> {
|
||||
const transform = (new SinaCommonCodeTransform).transform(code);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://hq.sinajs.cn/list=${transform}`;
|
||||
const res = await fetch.get(url);
|
||||
|
||||
const body = iconv.decode(res.body, "gb18030");
|
||||
const rows = body.split(";\n");
|
||||
const row = rows[0];
|
||||
|
||||
// 数据深解析
|
||||
const [_, paramsUnformat] = row.split('=');
|
||||
|
||||
if (paramsUnformat === '""') {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
const params = paramsUnformat.replace('"', '').split(",");
|
||||
const data = (new SinaStockTransform(code, params));
|
||||
|
||||
return data.getStock();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取股票数据组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
async getStocks(codes: string[]): Promise<Stock[]> {
|
||||
codes = uniq(codes.filter(i => i !== ''));
|
||||
|
||||
// 无股票时返回空数组
|
||||
if (codes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const transforms = (new SinaCommonCodeTransform).transforms(codes);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://hq.sinajs.cn/list=${transforms.join(',')}`;
|
||||
const res = await fetch.get(url);
|
||||
|
||||
const body = iconv.decode(res.body, "gb18030");
|
||||
const rows = body.split(";\n");
|
||||
|
||||
return codes.map((code, index) => {
|
||||
// 数据深解析
|
||||
const [_, paramsUnformat] = rows[index].split('=');
|
||||
|
||||
if (paramsUnformat === '""') {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
const params = paramsUnformat.replace('"', '').split(",");
|
||||
const data = (new SinaStockTransform(code, params));
|
||||
|
||||
return data.getStock();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜索股票代码
|
||||
* @param key 关键字
|
||||
*/
|
||||
async searchStocks(key: string): Promise<Stock[]> {
|
||||
// 数据获取
|
||||
const url = `http://suggest3.sinajs.cn/suggest/type=2&key=${encodeURIComponent(key)}`;
|
||||
const res = await fetch.get(url);
|
||||
|
||||
const body = iconv.decode(res.body, "gb18030");
|
||||
const rows: string[] = body.replace('var suggestvalue="', '').replace('";', '').split(';');
|
||||
|
||||
let codes: string[] = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let code: string = rows[i].split(',')[0];
|
||||
|
||||
if (code.indexOf('us') === 0) {
|
||||
code = code.replace('us', '');
|
||||
codes = [...codes, COMMON_US + code];
|
||||
}
|
||||
|
||||
if (code.indexOf('sz') === 0) {
|
||||
code = code.replace('sz', '');
|
||||
codes = [...codes, COMMON_SZ + code];
|
||||
}
|
||||
|
||||
if (code.indexOf('sh') === 0) {
|
||||
code = code.replace('sh', '');
|
||||
codes = [...codes, COMMON_SH + code];
|
||||
}
|
||||
|
||||
if (code.indexOf('hk') === 0) {
|
||||
code = code.replace('hk', '');
|
||||
codes = [...codes, COMMON_HK + code];
|
||||
}
|
||||
|
||||
if (code.indexOf('of') === 0) {
|
||||
code = code.replace('of', '');
|
||||
codes = [...codes, COMMON_SZ + code, COMMON_SH + code];
|
||||
}
|
||||
}
|
||||
|
||||
return await Sina.getStocks(uniq(codes.filter(i => i !== '')));
|
||||
}
|
||||
}
|
||||
|
||||
export default Sina;
|
@ -1,94 +0,0 @@
|
||||
// Stocks
|
||||
import BaseCommonCodeTransform from "@stocks/base/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_API_CODE } from "@utils/constant";
|
||||
import { SINA_SZ, SINA_SH, SINA_HK, SINA_US } from "@stocks/sina/utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
|
||||
/**
|
||||
* 【新浪】股票代码转换统一代码
|
||||
*/
|
||||
class SinaCommonCodeTransform extends BaseCommonCodeTransform {
|
||||
/**
|
||||
* 交易所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
if (code.indexOf(SINA_SZ) === 0) {
|
||||
return this.SZTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(SINA_SH) === 0) {
|
||||
return this.SHTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(SINA_HK) === 0) {
|
||||
return this.HKTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(SINA_US) === 0) {
|
||||
return this.USTransform(code);
|
||||
}
|
||||
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所股票代码组转换统一代码组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (code.indexOf(SINA_SZ) !== 0) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SZ + code.replace(SINA_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (code.indexOf(SINA_SH) !== 0) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SH + code.replace(SINA_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (code.indexOf(SINA_HK) !== 0) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_HK + code.replace(SINA_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (code.indexOf(SINA_US) !== 0) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_US + code.replace(SINA_US, "").toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
export default SinaCommonCodeTransform;
|
@ -1,78 +0,0 @@
|
||||
// Stocks
|
||||
import BaseCommonCodeTransform from "@stocks/base/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_COMMON_CODE } from "@utils/constant";
|
||||
import { SINA_SZ, SINA_SH, SINA_HK, SINA_US } from "@stocks/sina/utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
|
||||
/**
|
||||
* 【新浪】统一代码转换股票代码
|
||||
*/
|
||||
class SinaCommonCodeTransform extends BaseCommonCodeTransform {
|
||||
/**
|
||||
* 交易所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
return super.transform(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所统一代码组转换股票代码组
|
||||
* @param codes 统一代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (code.indexOf(COMMON_SZ) !== 0) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return SINA_SZ + code.replace(COMMON_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (code.indexOf(COMMON_SH) !== 0) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return SINA_SH + code.replace(COMMON_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (code.indexOf(COMMON_HK) !== 0) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return SINA_HK + code.replace(COMMON_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (code.indexOf(COMMON_US) !== 0) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return SINA_US + code.replace(COMMON_US, "").toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
export default SinaCommonCodeTransform;
|
@ -1,143 +0,0 @@
|
||||
// Stocks
|
||||
import BaseStockTransform from "@stocks/base/transforms/stock";
|
||||
|
||||
// Utils
|
||||
import { DEFAULT_STRING, DEFAULT_NUMBER } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
|
||||
/**
|
||||
* 新浪股票数据解析
|
||||
*/
|
||||
class SinaStockTransform extends BaseStockTransform {
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
constructor(public code: string, public params: string[]) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代码
|
||||
*/
|
||||
getCode(): string {
|
||||
return String(this.code).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
*/
|
||||
getName(): string {
|
||||
switch (this.code.slice(0, 2)) {
|
||||
case COMMON_SH:
|
||||
return String(this.params[0] || DEFAULT_STRING);
|
||||
case COMMON_SZ:
|
||||
return String(this.params[0] || DEFAULT_STRING);
|
||||
case COMMON_HK:
|
||||
return String(this.params[1] || DEFAULT_STRING);
|
||||
case COMMON_US:
|
||||
return String(this.params[0] || DEFAULT_STRING);
|
||||
default:
|
||||
return DEFAULT_STRING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取现价
|
||||
*/
|
||||
getNow(): number {
|
||||
switch (this.code.slice(0, 2)) {
|
||||
case COMMON_SH:
|
||||
return Number(this.params[3] || DEFAULT_NUMBER);
|
||||
case COMMON_SZ:
|
||||
return Number(this.params[3] || DEFAULT_NUMBER);
|
||||
case COMMON_HK:
|
||||
return Number(this.params[6] || DEFAULT_NUMBER);
|
||||
case COMMON_US:
|
||||
return Number(this.params[1] || DEFAULT_NUMBER);
|
||||
default:
|
||||
return DEFAULT_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最低价
|
||||
*/
|
||||
getLow(): number {
|
||||
switch (this.code.slice(0, 2)) {
|
||||
case COMMON_SH:
|
||||
return Number(this.params[5] || DEFAULT_NUMBER);
|
||||
case COMMON_SZ:
|
||||
return Number(this.params[5] || DEFAULT_NUMBER);
|
||||
case COMMON_HK:
|
||||
return Number(this.params[5] || DEFAULT_NUMBER);
|
||||
case COMMON_US:
|
||||
return Number(this.params[7] || DEFAULT_NUMBER);
|
||||
default:
|
||||
return DEFAULT_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最高价
|
||||
*/
|
||||
getHigh(): number {
|
||||
switch (this.code.slice(0, 2)) {
|
||||
case COMMON_SH:
|
||||
return Number(this.params[4] || DEFAULT_NUMBER);
|
||||
case COMMON_SZ:
|
||||
return Number(this.params[4] || DEFAULT_NUMBER);
|
||||
case COMMON_HK:
|
||||
return Number(this.params[4] || DEFAULT_NUMBER);
|
||||
case COMMON_US:
|
||||
return Number(this.params[6] || DEFAULT_NUMBER);
|
||||
default:
|
||||
return DEFAULT_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨日收盘价
|
||||
*/
|
||||
getYesterday(): number {
|
||||
switch (this.code.slice(0, 2)) {
|
||||
case COMMON_SH:
|
||||
return Number(this.params[2] || DEFAULT_NUMBER);
|
||||
case COMMON_SZ:
|
||||
return Number(this.params[2] || DEFAULT_NUMBER);
|
||||
case COMMON_HK:
|
||||
return Number(this.params[3] || DEFAULT_NUMBER);
|
||||
case COMMON_US:
|
||||
return Number(this.params[26] || DEFAULT_NUMBER);
|
||||
default:
|
||||
return DEFAULT_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取涨跌
|
||||
*/
|
||||
getPercent(): number {
|
||||
return this.getNow() ? this.getNow() / this.getYesterday() - 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
*/
|
||||
getStock(): Stock {
|
||||
return {
|
||||
code: this.getCode(),
|
||||
name: this.getName(),
|
||||
percent: this.getPercent(),
|
||||
|
||||
now: this.getNow(),
|
||||
low: this.getLow(),
|
||||
high: this.getHigh(),
|
||||
yesterday: this.getYesterday(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default SinaStockTransform;
|
@ -1,5 +0,0 @@
|
||||
// 默认交易所常量
|
||||
export const SINA_SZ = "sz"; // 深交所相关常量
|
||||
export const SINA_SH = "sh"; // 上交所相关常量
|
||||
export const SINA_HK = "hk"; // 港交所相关常量
|
||||
export const SINA_US = "gb_"; // 美交所相关常量
|
@ -1,117 +0,0 @@
|
||||
// NPM
|
||||
import { uniq } from "lodash";
|
||||
|
||||
// Stocks
|
||||
import TencentStockTransform from "@stocks/tencent/transforms/stock";
|
||||
import TencentCommonCodeTransform from "@stocks/tencent/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import fetch from "@utils/fetch";
|
||||
import iconv from "@utils/iconv";
|
||||
import { DEFAULT_STOCK } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_US, COMMON_HK } from "@stocks/base/utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import StockApi from "types/stocks/index";
|
||||
|
||||
/**
|
||||
* 腾讯股票代码接口
|
||||
*/
|
||||
const Tencent: StockApi = {
|
||||
/**
|
||||
* 获取股票数据
|
||||
* @param code 股票代码
|
||||
*/
|
||||
async getStock(code: string): Promise<Stock> {
|
||||
const transform = (new TencentCommonCodeTransform).transform(code);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://qt.gtimg.cn/q=${transform}`;
|
||||
const res = await fetch.get(url).responseType('blob');
|
||||
|
||||
const body = iconv.decode(res.body, "gbk");
|
||||
const rows = body.split(";\n");
|
||||
const row = rows[0];
|
||||
|
||||
if (!row.includes(transform)) {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
// 数据深解析
|
||||
const [_, paramsUnformat] = row.split('=');
|
||||
const params = paramsUnformat.replace('"', '').split("~");
|
||||
const data = (new TencentStockTransform(code, params));
|
||||
|
||||
return data.getStock();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取股票数据组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
async getStocks(codes: string[]): Promise<Stock[]> {
|
||||
codes = uniq(codes.filter(i => i !== ''));
|
||||
|
||||
// 无股票时返回空数组
|
||||
if (codes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const transforms = (new TencentCommonCodeTransform).transforms(codes);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://qt.gtimg.cn/q=${transforms.join(',')}`;
|
||||
const res = await fetch.get(url).responseType('blob');
|
||||
|
||||
const body = iconv.decode(res.body, "gbk");
|
||||
const rows: string[] = body.split(";\n");
|
||||
|
||||
return codes.map((code, index) => {
|
||||
const transform = (new TencentCommonCodeTransform).transform(code);
|
||||
if (!rows.find(row => row.includes(transform))) {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
// 数据深解析
|
||||
const [_, paramsUnformat] = rows[index].split('=');
|
||||
const params = paramsUnformat.replace('"', '').split("~");
|
||||
const data = (new TencentStockTransform(code, params));
|
||||
|
||||
return data.getStock();
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜索股票代码
|
||||
* @param key 关键字
|
||||
*/
|
||||
async searchStocks(key: string): Promise<Stock[]> {
|
||||
const url = `https://smartbox.gtimg.cn/s3/?v=2&t=all&c=1&q=${encodeURIComponent(key)}`;
|
||||
const res = await fetch.get(url).responseType('blob');
|
||||
|
||||
const body = iconv.decode(res.body, "gbk");
|
||||
const rows: string[] = body.replace('v_hint="', '').replace('"', "").split('^');
|
||||
|
||||
const codes: string[] = rows.map(row => {
|
||||
const [type, code] = row.split('~');
|
||||
|
||||
switch (type) {
|
||||
case 'sz':
|
||||
return COMMON_SZ + code;
|
||||
case 'sh':
|
||||
return COMMON_SH + code;
|
||||
case 'hk':
|
||||
return COMMON_HK + code;
|
||||
case 'us':
|
||||
return COMMON_US + code.split('.')[0].toUpperCase();
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
return await Tencent.getStocks(uniq(codes.filter(i => i !== '')));
|
||||
}
|
||||
}
|
||||
|
||||
export default Tencent;
|
@ -1,94 +0,0 @@
|
||||
// Stocks
|
||||
import BaseApiCodeTransform from "@stocks/base/transforms/api-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_API_CODE } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { TENCENT_SZ, TENCENT_SH, TENCENT_HK, TENCENT_US } from "@stocks/tencent/utils/constant";
|
||||
|
||||
/**
|
||||
* 【腾讯】股票代码转换统一代码
|
||||
*/
|
||||
class TencentApiCodeTransform extends BaseApiCodeTransform {
|
||||
/**
|
||||
* 交易所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
if (code.indexOf(TENCENT_SZ) === 0) {
|
||||
return this.SZTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(TENCENT_SH) === 0) {
|
||||
return this.SHTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(TENCENT_HK) === 0) {
|
||||
return this.HKTransform(code);
|
||||
}
|
||||
|
||||
if (code.indexOf(TENCENT_US) === 0) {
|
||||
return this.USTransform(code);
|
||||
}
|
||||
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所股票代码组转换统一代码组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (!code.includes(TENCENT_SZ)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SZ + code.replace(TENCENT_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (!code.includes(TENCENT_SH)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SH + code.replace(TENCENT_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (!code.includes(TENCENT_HK)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_HK + code.replace(TENCENT_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (!code.includes(TENCENT_US)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_US + code.replace(TENCENT_US, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default TencentApiCodeTransform;
|
@ -1,85 +0,0 @@
|
||||
// Stocks
|
||||
import BaseCommonCodeTransform from "@stocks/base/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_COMMON_CODE } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { TENCENT_SZ, TENCENT_SH, TENCENT_HK, TENCENT_US } from "@stocks/tencent/utils/constant";
|
||||
|
||||
/**
|
||||
* 【腾讯】统一代码转换股票代码
|
||||
*/
|
||||
class TencentCommonCodeTransform extends BaseCommonCodeTransform {
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
return super.transform(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所统一代码组转换股票代码组
|
||||
* @param codes 统一代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (!code.includes(COMMON_SZ)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return TENCENT_SZ + code.replace(COMMON_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (!code.includes(COMMON_SH)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return TENCENT_SH + code.replace(COMMON_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (!code.includes(COMMON_HK)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return TENCENT_HK + code.replace(COMMON_HK, "").toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (!code.includes(COMMON_US)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return TENCENT_US + code.replace(COMMON_US, "").toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
export default TencentCommonCodeTransform;
|
@ -1,87 +0,0 @@
|
||||
// Stocks
|
||||
import BaseStockTransform from "@stocks/base/transforms/stock";
|
||||
|
||||
// Utils
|
||||
import { DEFAULT_STRING, DEFAULT_NUMBER } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
|
||||
/**
|
||||
* 腾讯股票数据解析
|
||||
*/
|
||||
class TencentStockTransform extends BaseStockTransform {
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
constructor(public code: string, public params: string[]) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代码
|
||||
*/
|
||||
getCode(): string {
|
||||
return String(this.code).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
*/
|
||||
getName(): string {
|
||||
return String(this.params[1] || DEFAULT_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取现价
|
||||
*/
|
||||
getNow(): number {
|
||||
return Number(this.params[3] || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最低价
|
||||
*/
|
||||
getLow(): number {
|
||||
return Number(this.params[34] || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最高价
|
||||
*/
|
||||
getHigh(): number {
|
||||
return Number(this.params[33] || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨日收盘价
|
||||
*/
|
||||
getYesterday(): number {
|
||||
return Number(this.params[4] || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取涨跌
|
||||
*/
|
||||
getPercent(): number {
|
||||
return this.getNow() ? this.getNow() / this.getYesterday() - 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
*/
|
||||
getStock(): Stock {
|
||||
return {
|
||||
code: this.getCode(),
|
||||
name: this.getName(),
|
||||
percent: this.getPercent(),
|
||||
|
||||
now: this.getNow(),
|
||||
low: this.getLow(),
|
||||
high: this.getHigh(),
|
||||
yesterday: this.getYesterday(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default TencentStockTransform;
|
@ -1,5 +0,0 @@
|
||||
// 默认交易所常量
|
||||
export const TENCENT_SZ = "sz"; // 深交所相关常量
|
||||
export const TENCENT_SH = "sh"; // 上交所相关常量
|
||||
export const TENCENT_HK = "hk"; // 港交所相关常量
|
||||
export const TENCENT_US = "us"; // 美交所相关常量
|
@ -1,151 +0,0 @@
|
||||
// NPM
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
// Stocks
|
||||
import XueqiuStockTransform from "@stocks/xueqiu/transforms/stock";
|
||||
import XueqiuCommonCodeTransform from "@stocks/xueqiu/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import fetch from "@utils/fetch";
|
||||
import { DEFAULT_STOCK } from "@utils/constant";
|
||||
import { COMMON_SZ, COMMON_SH, COMMON_HK, COMMON_US } from '@stocks/base/utils/constant';
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import StockApi from "types/stocks/index";
|
||||
import Dictionary from "types/utils/dictionary";
|
||||
|
||||
let token: string = '';
|
||||
|
||||
/**
|
||||
* 雪球股票代码接口
|
||||
*/
|
||||
const Xueqiu: StockApi & { getToken(): Promise<string> } = {
|
||||
/**
|
||||
* 获取 Token
|
||||
*/
|
||||
async getToken(): Promise<string> {
|
||||
if (token !== '') return token;
|
||||
|
||||
const res = await fetch.get('https://xueqiu.com/');
|
||||
const cookies: string[] = res.headers['set-cookie'];
|
||||
|
||||
const param: string = cookies.filter(key => key.includes('xq_a_token'))[0] || '';
|
||||
token = param.split(';')[0] || '';
|
||||
|
||||
return token;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
* @param code 股票代码
|
||||
*/
|
||||
async getStock(code: string): Promise<Stock> {
|
||||
const token = await this.getToken();
|
||||
const transform = (new XueqiuCommonCodeTransform).transform(code);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://stock.xueqiu.com/v5/stock/quote.json?symbol=${transform}`;
|
||||
const res = await fetch.get(url).set('Cookie', token);
|
||||
|
||||
const body = JSON.parse(res.text);
|
||||
const row: Dictionary<number | string> = body.data.quote;
|
||||
|
||||
// 数据深解析
|
||||
const params = row;
|
||||
const data = (new XueqiuStockTransform(code, params));
|
||||
|
||||
return params ? data.getStock() : { ...DEFAULT_STOCK, code };
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取股票数据组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
async getStocks(codes: string[]): Promise<Stock[]> {
|
||||
codes = uniq(codes.filter(i => i !== ''));
|
||||
|
||||
// 无股票时返回空数组
|
||||
if (codes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const token = await this.getToken();
|
||||
const transforms = (new XueqiuCommonCodeTransform).transforms(codes);
|
||||
|
||||
// 数据获取
|
||||
const url = `https://stock.xueqiu.com/v5/stock/batch/quote.json?symbol=${transforms.join(',')}`;
|
||||
const res = await fetch.get(url).set('Cookie', token);
|
||||
|
||||
const body = JSON.parse(res.text);
|
||||
const rows: Dictionary<Dictionary<number | string>>[] = body.data.items;
|
||||
|
||||
return codes.map(code => {
|
||||
// 数据深解析
|
||||
const transform = (new XueqiuCommonCodeTransform).transform(code);
|
||||
|
||||
const params = rows.find(i => {
|
||||
if (!i.quote) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i.market.region === 'US') {
|
||||
return i.quote.code === transform;
|
||||
}
|
||||
|
||||
if (i.market.region === 'CN') {
|
||||
return i.quote.symbol === transform;
|
||||
}
|
||||
|
||||
if (i.market.region === 'HK') {
|
||||
return i.market.region + i.quote.code === transform;
|
||||
}
|
||||
}) || null;
|
||||
|
||||
if (!params) {
|
||||
return { ...DEFAULT_STOCK, code };
|
||||
}
|
||||
|
||||
const data = (new XueqiuStockTransform(code, params.quote));
|
||||
return data.getStock();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜索股票代码
|
||||
* @param key 关键字
|
||||
*/
|
||||
async searchStocks(key: string): Promise<Stock[]> {
|
||||
const token = await this.getToken();
|
||||
|
||||
// 数据获取
|
||||
const url = `https://xueqiu.com/stock/search.json?code=${encodeURIComponent(key)}`;
|
||||
const res = await fetch.get(url).set('Cookie', token);
|
||||
|
||||
const body = JSON.parse(res.text);
|
||||
const rows: Dictionary<string>[] = body.stocks;
|
||||
|
||||
let codes: string[] = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let code: string = rows[i].code;
|
||||
|
||||
if (code.indexOf('SZ') === 0) {
|
||||
code = code.replace('SZ', '');
|
||||
codes = [...codes, COMMON_SZ + code];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code.indexOf('SH') === 0) {
|
||||
code = code.replace('SH', '');
|
||||
codes = [...codes, COMMON_SH + code];
|
||||
continue;
|
||||
}
|
||||
|
||||
codes = [...codes, COMMON_HK + code, COMMON_US + code];
|
||||
}
|
||||
|
||||
return await Xueqiu.getStocks(uniq(codes.filter(i => i !== '')));
|
||||
}
|
||||
}
|
||||
|
||||
export default Xueqiu;
|
@ -1,90 +0,0 @@
|
||||
// Stocks
|
||||
import BaseApiCodeTransform from "@stocks/base/transforms/api-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_API_CODE } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { XUEQIU_SZ, XUEQIU_SH, XUEQIU_HK, XUEQIU_US } from "@stocks/xueqiu/utils/constant";
|
||||
|
||||
/**
|
||||
* 【雪球】股票代码转换统一代码
|
||||
*/
|
||||
class XueqiuApiCodeTransform extends BaseApiCodeTransform {
|
||||
/**
|
||||
* 交易所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
if (code.includes(XUEQIU_SZ)) {
|
||||
return this.SZTransform(code);
|
||||
}
|
||||
|
||||
if (code.includes(XUEQIU_SH)) {
|
||||
return this.SHTransform(code);
|
||||
}
|
||||
|
||||
if (code.includes(XUEQIU_HK)) {
|
||||
return this.HKTransform(code);
|
||||
}
|
||||
|
||||
return this.USTransform(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所股票组代码组转换统一代码组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (!code.includes(XUEQIU_SZ)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SZ + code.replace(XUEQIU_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (!code.includes(XUEQIU_SH)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_SH + code.replace(XUEQIU_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (!code.includes(XUEQIU_HK)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_HK + code.replace(XUEQIU_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所股票代码转换统一代码
|
||||
* @param code 股票代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (code.includes(XUEQIU_SZ) || code.includes(XUEQIU_SH) || code.includes(XUEQIU_HK)) {
|
||||
throw new Error(ERROR_API_CODE);
|
||||
}
|
||||
|
||||
return COMMON_US + code.replace(XUEQIU_US, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default XueqiuApiCodeTransform;
|
@ -1,78 +0,0 @@
|
||||
// Stocks
|
||||
import BaseCommonCodeTransform from "@stocks/base/transforms/common-code";
|
||||
|
||||
// Utils
|
||||
import { ERROR_COMMON_CODE } from "@utils/constant";
|
||||
import { COMMON_SH, COMMON_SZ, COMMON_HK, COMMON_US } from "@stocks/base/utils/constant";
|
||||
import { XUEQIU_SZ, XUEQIU_SH, XUEQIU_HK, XUEQIU_US } from "@stocks/xueqiu/utils/constant";
|
||||
|
||||
/**
|
||||
* 【雪球】统一代码转换股票代码
|
||||
*/
|
||||
class XueqiuCommonCodeTransform extends BaseCommonCodeTransform {
|
||||
/**
|
||||
* 交易所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public transform(code: string): string {
|
||||
return super.transform(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 交易所股 统一代码 转换 票组代码
|
||||
* @param codes 统一代码组
|
||||
*/
|
||||
public transforms(codes: string[]): string[] {
|
||||
return super.transforms(codes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SZTransform(code: string): string {
|
||||
if (!code.includes(COMMON_SZ)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return XUEQIU_SZ + code.replace(COMMON_SZ, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public SHTransform(code: string): string {
|
||||
if (!code.includes(COMMON_SH)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return XUEQIU_SH + code.replace(COMMON_SH, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 港交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public HKTransform(code: string): string {
|
||||
if (!code.includes(COMMON_HK)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return XUEQIU_HK + code.replace(COMMON_HK, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 美交所统一代码转换股票代码
|
||||
* @param code 统一代码
|
||||
*/
|
||||
public USTransform(code: string): string {
|
||||
if (!code.includes(COMMON_US)) {
|
||||
throw new Error(ERROR_COMMON_CODE);
|
||||
}
|
||||
|
||||
return XUEQIU_US + code.replace(COMMON_US, "");
|
||||
}
|
||||
}
|
||||
|
||||
export default XueqiuCommonCodeTransform;
|
@ -1,88 +0,0 @@
|
||||
// Stocks
|
||||
import BaseStockTransform from "@stocks/base/transforms/stock";
|
||||
|
||||
// Utils
|
||||
import { DEFAULT_STRING, DEFAULT_NUMBER } from "@utils/constant";
|
||||
|
||||
// Types
|
||||
import Stock from "types/utils/stock";
|
||||
import Dictionary from "types/utils/dictionary";
|
||||
|
||||
/**
|
||||
* 雪球股票数据解析
|
||||
*/
|
||||
class XueqiuStockTransform extends BaseStockTransform {
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
constructor(public code: string, public params: Dictionary<number | string>) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代码
|
||||
*/
|
||||
getCode(): string {
|
||||
return String(this.code).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取名称
|
||||
*/
|
||||
getName(): string {
|
||||
return String(this.params.name || DEFAULT_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取现价
|
||||
*/
|
||||
getNow(): number {
|
||||
return Number(this.params.current || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最低价
|
||||
*/
|
||||
getLow(): number {
|
||||
return Number(this.params.low || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最高价
|
||||
*/
|
||||
getHigh(): number {
|
||||
return Number(this.params.high || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨日收盘价
|
||||
*/
|
||||
getYesterday(): number {
|
||||
return Number(this.params.last_close || DEFAULT_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取涨跌
|
||||
*/
|
||||
getPercent(): number {
|
||||
return this.getNow() ? this.getNow() / this.getYesterday() - 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
*/
|
||||
getStock(): Stock {
|
||||
return {
|
||||
code: this.getCode(),
|
||||
name: this.getName(),
|
||||
percent: this.getPercent(),
|
||||
|
||||
now: this.getNow(),
|
||||
low: this.getLow(),
|
||||
high: this.getHigh(),
|
||||
yesterday: this.getYesterday(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default XueqiuStockTransform;
|
@ -1,5 +0,0 @@
|
||||
// 默认交易所常量
|
||||
export const XUEQIU_SZ = "SZ"; // 深交所相关常量
|
||||
export const XUEQIU_SH = "SH"; // 上交所相关常量
|
||||
export const XUEQIU_HK = "HK"; // 港交所相关常量
|
||||
export const XUEQIU_US = ""; // 美交所相关常量
|
@ -1,44 +0,0 @@
|
||||
// 默认股票名称常量
|
||||
export const DEFAULT_NUMBER = 0;
|
||||
export const DEFAULT_STRING = "---";
|
||||
|
||||
// 默认错误提示常量
|
||||
export const ERROR_API_CODE = "请检查股票代码是否正确";
|
||||
export const ERROR_COMMON_CODE = "请检查统一代码是否正确";
|
||||
|
||||
export const ERROR_UNDEFINED_GET_STOCK = "未实现获取股票数据";
|
||||
export const ERROR_UNDEFINED_GET_STOCKS = "未实现获取股票数据组";
|
||||
export const ERROR_UNDEFINED_SEARCH_STOCK = "未实现搜索股票代码";
|
||||
|
||||
export const ERROR_UNDEFINED_COMMON_CODE = "未实现统一代码转换股票代码";
|
||||
export const ERROR_UNDEFINED_SZ_COMMON_CODE = "未实现深交所统一代码转换股票代码";
|
||||
export const ERROR_UNDEFINED_SH_COMMON_CODE = "未实现上交所统一代码转换股票代码";
|
||||
export const ERROR_UNDEFINED_HK_COMMON_CODE = "未实现港交所统一代码转换股票代码";
|
||||
export const ERROR_UNDEFINED_US_COMMON_CODE = "未实现美交所统一代码转换股票代码";
|
||||
|
||||
export const ERROR_UNDEFINED_API_CODE = "未实现股票代码转换统一代码";
|
||||
export const ERROR_UNDEFINED_API_CODES = "未实现股票代码组转换统一代码组";
|
||||
export const ERROR_UNDEFINED_SZ_API_CODE = "未实现深交所股票代码转换统一代码";
|
||||
export const ERROR_UNDEFINED_SH_API_CODE = "未实现上交所股票代码转换统一代码";
|
||||
export const ERROR_UNDEFINED_HK_API_CODE = "未实现港交所股票代码转换统一代码";
|
||||
export const ERROR_UNDEFINED_US_API_CODE = "未实现美交所股票代码转换统一代码";
|
||||
|
||||
export const ERROR_UNDEFINED_GET_CODE = '未实现获取代码';
|
||||
export const ERROR_UNDEFINED_GET_NAME = '未实现获取名称';
|
||||
export const ERROR_UNDEFINED_GET_NOW = '未实现获取现价';
|
||||
export const ERROR_UNDEFINED_GET_LOW = '未实现获取最低价';
|
||||
export const ERROR_UNDEFINED_GET_HIGH = '未实现获取最高价';
|
||||
export const ERROR_UNDEFINED_GET_PERCENT = '未实现获取涨跌';
|
||||
export const ERROR_UNDEFINED_GET_YESTERDAY = '未实现获取昨日收盘价';
|
||||
|
||||
// 默认股票数据常量
|
||||
export const DEFAULT_STOCK = {
|
||||
code: DEFAULT_STRING,
|
||||
name: DEFAULT_STRING,
|
||||
percent: DEFAULT_NUMBER,
|
||||
|
||||
now: DEFAULT_NUMBER,
|
||||
low: DEFAULT_NUMBER,
|
||||
high: DEFAULT_NUMBER,
|
||||
yesterday: DEFAULT_NUMBER,
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
const superagent = require('superagent');
|
||||
|
||||
export default superagent;
|
@ -1,3 +0,0 @@
|
||||
const iconv = require("iconv-lite");
|
||||
|
||||
export default iconv;
|
@ -1,28 +0,0 @@
|
||||
// Stock
|
||||
const Base = require("stocks/base").default;
|
||||
|
||||
describe("【基础】股票代码接口", () => {
|
||||
const {
|
||||
ERROR_UNDEFINED_GET_STOCK,
|
||||
ERROR_UNDEFINED_GET_STOCKS,
|
||||
ERROR_UNDEFINED_SEARCH_STOCK,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("需要获取的股票代码", async () => {
|
||||
await expect(Base.getStock("SZ000000"))
|
||||
.rejects
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_STOCK));
|
||||
});
|
||||
|
||||
it("需要获取的股票代码组", async () => {
|
||||
await expect(Base.getStocks(["SZ000000"]))
|
||||
.rejects
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_STOCKS));
|
||||
});
|
||||
|
||||
it("搜索股票代码", async () => {
|
||||
await expect(Base.searchStocks("510500"))
|
||||
.rejects
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SEARCH_STOCK));
|
||||
});
|
||||
});
|
@ -1,66 +0,0 @@
|
||||
// Stock
|
||||
const BaseApiCodeTransform = require("stocks/base/transforms/api-code").default;
|
||||
|
||||
describe("【基础】股票代码转换统一代码", () => {
|
||||
const {
|
||||
ERROR_API_CODE,
|
||||
ERROR_UNDEFINED_SZ_API_CODE,
|
||||
ERROR_UNDEFINED_SH_API_CODE,
|
||||
ERROR_UNDEFINED_HK_API_CODE,
|
||||
ERROR_UNDEFINED_US_API_CODE
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new BaseApiCodeTransform()).SZTransform("SZ000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SZ_API_CODE));
|
||||
});
|
||||
|
||||
it("上交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new BaseApiCodeTransform()).SHTransform("SH000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SH_API_CODE));
|
||||
});
|
||||
|
||||
it("港交所股票代码转换统一代码", async () => {
|
||||
expect(() => new BaseApiCodeTransform().HKTransform("HK000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_HK_API_CODE));
|
||||
});
|
||||
|
||||
it("美交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new BaseApiCodeTransform()).USTransform("US000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_US_API_CODE));
|
||||
});
|
||||
|
||||
it("交易所股票代码转换统一代码", async () => {
|
||||
expect(() => (new BaseApiCodeTransform()).transform("000000"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transform("SZ000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SZ_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transform("SH000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SH_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transform("HK000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_HK_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transform("US000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_US_API_CODE));
|
||||
});
|
||||
|
||||
it("交易所股票代码组转换统一代码组", async () => {
|
||||
expect(() => (new BaseApiCodeTransform()).transforms(["000000"]))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transforms(["SZ000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SZ_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transforms(["SH000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SH_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transforms(["HK000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_HK_API_CODE));
|
||||
|
||||
expect(() => (new BaseApiCodeTransform()).transforms(["US000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_US_API_CODE));
|
||||
});
|
||||
});
|
@ -1,66 +0,0 @@
|
||||
// Stock
|
||||
const BaseCommonCodeTransform = require("stocks/base/transforms/common-code").default;
|
||||
|
||||
describe("【基础】统一代码转换股票代码", () => {
|
||||
const {
|
||||
ERROR_COMMON_CODE,
|
||||
ERROR_UNDEFINED_SZ_COMMON_CODE,
|
||||
ERROR_UNDEFINED_SH_COMMON_CODE,
|
||||
ERROR_UNDEFINED_HK_COMMON_CODE,
|
||||
ERROR_UNDEFINED_US_COMMON_CODE
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new BaseCommonCodeTransform()).SZTransform("SZ000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SZ_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("上交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new BaseCommonCodeTransform()).SHTransform("SH000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SH_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("港交所统一代码转换股票代码", async () => {
|
||||
expect(() => new BaseCommonCodeTransform().HKTransform("HK000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_HK_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("美交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new BaseCommonCodeTransform()).USTransform("US000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_US_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("交易所统一代码转换股票代码", async () => {
|
||||
expect(() => (new BaseCommonCodeTransform()).transform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transform("SZ000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SZ_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transform("SH000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SH_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transform("HK000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_HK_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transform("US000000"))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_US_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("交易所统一代码组转换股票代码组", async () => {
|
||||
expect(() => (new BaseCommonCodeTransform()).transforms(["000000"]))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transforms(["SZ000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_SZ_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transforms(["SH000000"]))
|
||||
.toThrow(new Error("未实现上交所统一代码转换股票代码"));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transforms(["HK000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_HK_COMMON_CODE));
|
||||
|
||||
expect(() => (new BaseCommonCodeTransform()).transforms(["US000000"]))
|
||||
.toThrow(new Error(ERROR_UNDEFINED_US_COMMON_CODE));
|
||||
});
|
||||
});
|
@ -1,55 +0,0 @@
|
||||
// Stock
|
||||
const BaseStockTransform = require("stocks/base/transforms/stock").default;
|
||||
|
||||
describe("【基础】股票数据转换测试", () => {
|
||||
const {
|
||||
ERROR_UNDEFINED_GET_CODE,
|
||||
ERROR_UNDEFINED_GET_NAME,
|
||||
ERROR_UNDEFINED_GET_NOW,
|
||||
ERROR_UNDEFINED_GET_LOW,
|
||||
ERROR_UNDEFINED_GET_HIGH,
|
||||
ERROR_UNDEFINED_GET_STOCK,
|
||||
ERROR_UNDEFINED_GET_PERCENT,
|
||||
ERROR_UNDEFINED_GET_YESTERDAY,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("获取股票代码", async () => {
|
||||
expect(() => (new BaseStockTransform()).getCode())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_CODE));
|
||||
});
|
||||
|
||||
it("获取股票名称", async () => {
|
||||
expect(() => (new BaseStockTransform()).getName())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_NAME));
|
||||
});
|
||||
|
||||
it("获取股票现价", async () => {
|
||||
expect(() => (new BaseStockTransform()).getNow())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_NOW));
|
||||
});
|
||||
|
||||
it("获取股票最低价", async () => {
|
||||
expect(() => (new BaseStockTransform()).getLow())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_LOW));
|
||||
});
|
||||
|
||||
it("获取股票最高价", async () => {
|
||||
expect(() => (new BaseStockTransform()).getHigh())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_HIGH));
|
||||
});
|
||||
|
||||
it("获取股票昨日收盘价", async () => {
|
||||
expect(() => (new BaseStockTransform()).getYesterday())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_YESTERDAY));
|
||||
});
|
||||
|
||||
it("获取股票涨跌", async () => {
|
||||
expect(() => (new BaseStockTransform()).getPercent())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_PERCENT));
|
||||
});
|
||||
|
||||
it("获取股票数据", async () => {
|
||||
expect(() => (new BaseStockTransform()).getStock())
|
||||
.toThrow(new Error(ERROR_UNDEFINED_GET_STOCK));
|
||||
});
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
// Stock
|
||||
const Netease = require("stocks/netease").default;
|
||||
|
||||
describe("【网易】股票代码接口", () => {
|
||||
it("需要获取的股票代码", async () => {
|
||||
await expect(Netease.getStock("SH510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SH510500", name: "500ETF" });
|
||||
|
||||
await expect(Netease.getStock("SZ510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SZ510500", name: "---" });
|
||||
});
|
||||
|
||||
it("需要获取的股票代码组", async () => {
|
||||
await expect(Netease.getStocks(["SH510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH510500", name: "500ETF" })]));
|
||||
|
||||
await expect(Netease.getStocks(["SZ510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ510500", name: "---" })]));
|
||||
|
||||
await expect(Netease.getStocks([]))
|
||||
.resolves
|
||||
.toEqual([]);
|
||||
});
|
||||
|
||||
it("搜索股票代码", async () => {
|
||||
await expect(Netease.searchStocks("格力电器"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ000651", name: "格力电器" })]));
|
||||
|
||||
await expect(Netease.searchStocks("贵州茅台"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH600519", name: "贵州茅台" })]));
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const NeteaseApiCodeTransform = require("stocks/netease/transforms/api-code").default;
|
||||
|
||||
describe("【网易】股票代码转换统一代码", () => {
|
||||
const {
|
||||
ERROR_API_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new NeteaseApiCodeTransform()).SZTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).SZTransform("1000000"))
|
||||
.toBe("SZ000000");
|
||||
});
|
||||
|
||||
it("上交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new NeteaseApiCodeTransform()).SHTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).SHTransform("0000000"))
|
||||
.toBe("SH000000");
|
||||
});
|
||||
|
||||
it("港交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new NeteaseApiCodeTransform()).HKTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).HKTransform("hk000000"))
|
||||
.toBe("HK000000");
|
||||
});
|
||||
|
||||
it("美交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new NeteaseApiCodeTransform()).USTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).USTransform("US_000000"))
|
||||
.toBe("US000000");
|
||||
});
|
||||
|
||||
it("交易所股票代码转换统一代码", async () => {
|
||||
expect((new NeteaseApiCodeTransform()).transform("1000000"))
|
||||
.toBe("SZ000000");
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).transform("0000000"))
|
||||
.toBe("SH000000");
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).transform("hk000000"))
|
||||
.toBe("HK000000");
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).transform("US_000000"))
|
||||
.toBe("US000000");
|
||||
|
||||
expect(() => (new NeteaseApiCodeTransform()).transform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
});
|
||||
|
||||
it("交易所股票代码组转换统一代码组", async () => {
|
||||
expect((new NeteaseApiCodeTransform()).transforms(["1000000"]))
|
||||
.toStrictEqual(["SZ000000"]);
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).transforms(["0000000"]))
|
||||
.toStrictEqual(["SH000000"]);
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).transforms(["hk000000"]))
|
||||
.toStrictEqual(["HK000000"]);
|
||||
|
||||
expect((new NeteaseApiCodeTransform()).transforms(["US_000000"]))
|
||||
.toStrictEqual(["US000000"]);
|
||||
|
||||
expect(() => (new NeteaseApiCodeTransform()).transforms(["STOCKAPI"]))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const NeteaseCommonCodeTransform = require("stocks/netease/transforms/common-code").default;
|
||||
|
||||
describe("【网易】统一代码转换股票代码", () => {
|
||||
const {
|
||||
ERROR_COMMON_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new NeteaseCommonCodeTransform()).SZTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).SZTransform("SZ000000"))
|
||||
.toBe("1000000");
|
||||
});
|
||||
|
||||
it("上交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new NeteaseCommonCodeTransform()).SHTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).SHTransform("SH000000"))
|
||||
.toBe("0000000");
|
||||
});
|
||||
|
||||
it("港交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new NeteaseCommonCodeTransform()).HKTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).HKTransform("HK000000"))
|
||||
.toBe("hk000000");
|
||||
});
|
||||
|
||||
it("美交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new NeteaseCommonCodeTransform()).USTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).USTransform("US000000"))
|
||||
.toBe("US_000000");
|
||||
});
|
||||
|
||||
it("交易所统一代码转换股票代码", async () => {
|
||||
expect((new NeteaseCommonCodeTransform()).transform("SZ000000"))
|
||||
.toBe("1000000");
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).transform("SH000000"))
|
||||
.toBe("0000000");
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).transform("HK000000"))
|
||||
.toBe("hk000000");
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).transform("US000000"))
|
||||
.toBe("US_000000");
|
||||
|
||||
expect(() => (new NeteaseCommonCodeTransform()).transform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("交易所统一代码组转换股票代码组", async () => {
|
||||
expect((new NeteaseCommonCodeTransform()).transforms(["SZ000000"]))
|
||||
.toStrictEqual(["1000000"]);
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).transforms(["SH000000"]))
|
||||
.toStrictEqual(["0000000"]);
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).transforms(["HK000000"]))
|
||||
.toStrictEqual(["hk000000"]);
|
||||
|
||||
expect((new NeteaseCommonCodeTransform()).transforms(["US000000"]))
|
||||
.toStrictEqual(["US_000000"]);
|
||||
|
||||
expect(() => (new NeteaseCommonCodeTransform()).transforms(["STOCKAPI"]))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
});
|
@ -1,50 +0,0 @@
|
||||
// Stock
|
||||
const NeteaseStockTransform = require("stocks/netease/transforms/stock").default;
|
||||
|
||||
describe("【网易】股票数据转换测试", () => {
|
||||
const code = 'SH510500';
|
||||
const body = `topstock({"0510500":{"code": "0510500", "precloseiopv": 7.152, "percent": 0.010491, "high": 7.28, "askvol3": 32300, "askvol2": 88400, "askvol5": 19000, "askvol4": 572800, "iopv": 7.226, "price": 7.224, "open": 7.147, "bid5": 7.22, "bid4": 7.221, "bid3": 7.222, "bid2": 7.223, "bid1": 7.224, "low": 7.085, "updown": 0.075, "type": "SH", "symbol": "510500", "status": 0, "ask4": 7.228, "bidvol3": 37000, "bidvol2": 32900, "bidvol1": 6300, "update": "2020/07/31 15:59:59", "bidvol5": 14300, "bidvol4": 28600, "yestclose": 7.149, "askvol1": 389300, "ask5": 7.229, "volume": 272478144, "ask1": 7.225, "name": "500ETF", "ask3": 7.227, "ask2": 7.226, "arrow": "\u2191", "time": "2020/07/31 15:59:58", "turnover": 1964297124} });`;
|
||||
const items = JSON.parse(body.replace(/\(|\)|;|(topstock)/g, ''));
|
||||
const params = items['0510500'];
|
||||
|
||||
it("获取股票代码", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getCode())
|
||||
.toBe('SH510500');
|
||||
});
|
||||
|
||||
it("获取股票名称", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getName())
|
||||
.toBe('500ETF');
|
||||
});
|
||||
|
||||
it("获取股票现价", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getNow())
|
||||
.toBe(7.224);
|
||||
});
|
||||
|
||||
it("获取股票最低价", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getLow())
|
||||
.toBe(7.085);
|
||||
});
|
||||
|
||||
it("获取股票最高价", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getHigh())
|
||||
.toBe(7.28);
|
||||
});
|
||||
|
||||
it("获取股票昨日收盘价", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getYesterday())
|
||||
.toBe(7.149);
|
||||
});
|
||||
|
||||
it("获取股票涨跌", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getPercent())
|
||||
.toBe(7.224 / 7.149 - 1);
|
||||
});
|
||||
|
||||
it("获取股票数据", async () => {
|
||||
expect(new NeteaseStockTransform(code, params).getStock())
|
||||
.toStrictEqual({ "code": "SH510500", "high": 7.28, "low": 7.085, "name": "500ETF", "now": 7.224, "percent": 7.224 / 7.149 - 1, "yesterday": 7.149 });
|
||||
});
|
||||
});
|
||||
|
@ -1,44 +0,0 @@
|
||||
// Stock
|
||||
const Sina = require("stocks/sina").default;
|
||||
|
||||
describe("【新浪】股票代码接口", () => {
|
||||
it("需要获取的股票代码", async () => {
|
||||
await expect(Sina.getStock("SH510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SH510500", name: "500ETF" });
|
||||
await expect(Sina.getStock("SZ510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SZ510500", name: "---" });
|
||||
});
|
||||
|
||||
it("需要获取的股票代码组", async () => {
|
||||
await expect(Sina.getStocks(["SH510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH510500", name: "500ETF" })]));
|
||||
|
||||
await expect(Sina.getStocks(["SZ510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ510500", name: "---" })]));
|
||||
|
||||
await expect(Sina.getStocks([]))
|
||||
.resolves
|
||||
.toEqual([]);
|
||||
});
|
||||
|
||||
it("搜索股票代码", async () => {
|
||||
await expect(Sina.searchStocks("格力电器"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ000651", name: "格力电器" })]));
|
||||
|
||||
await expect(Sina.searchStocks("贵州茅台"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH600519", name: "贵州茅台" })]));
|
||||
|
||||
await expect(Sina.searchStocks("安踏体育"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ code: "HK02020", name: "安踏体育" }),
|
||||
expect.objectContaining({ code: "USANPDF", name: "安踏" }),
|
||||
]));
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const SinaApiCodeTransform = require("stocks/sina/transforms/api-code").default;
|
||||
|
||||
describe("【新浪】股票代码转换统一代码", () => {
|
||||
const {
|
||||
ERROR_API_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new SinaApiCodeTransform()).SZTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new SinaApiCodeTransform()).SZTransform("sz000000"))
|
||||
.toBe("SZ000000");
|
||||
});
|
||||
|
||||
it("上交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new SinaApiCodeTransform()).SHTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new SinaApiCodeTransform()).SHTransform("sh000000"))
|
||||
.toBe("SH000000");
|
||||
});
|
||||
|
||||
it("港交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new SinaApiCodeTransform()).HKTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new SinaApiCodeTransform()).HKTransform("hk000000"))
|
||||
.toBe("HK000000");
|
||||
});
|
||||
|
||||
it("美交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new SinaApiCodeTransform()).USTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new SinaApiCodeTransform()).USTransform("gb_000000"))
|
||||
.toBe("US000000");
|
||||
});
|
||||
|
||||
it("交易所股票代码转换统一代码", async () => {
|
||||
expect((new SinaApiCodeTransform()).transform("sz000000"))
|
||||
.toBe("SZ000000");
|
||||
|
||||
expect((new SinaApiCodeTransform()).transform("sh000000"))
|
||||
.toBe("SH000000");
|
||||
|
||||
expect((new SinaApiCodeTransform()).transform("hk000000"))
|
||||
.toBe("HK000000");
|
||||
|
||||
expect((new SinaApiCodeTransform()).transform("gb_000000"))
|
||||
.toBe("US000000");
|
||||
|
||||
expect(() => (new SinaApiCodeTransform()).transform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
});
|
||||
|
||||
it("交易所股票代码转换统一代码", async () => {
|
||||
expect((new SinaApiCodeTransform()).transforms(["sz000000"]))
|
||||
.toStrictEqual(["SZ000000"]);
|
||||
|
||||
expect((new SinaApiCodeTransform()).transforms(["sh000000"]))
|
||||
.toStrictEqual(["SH000000"]);
|
||||
|
||||
expect((new SinaApiCodeTransform()).transforms(["hk000000"]))
|
||||
.toStrictEqual(["HK000000"]);
|
||||
|
||||
expect((new SinaApiCodeTransform()).transforms(["gb_000000"]))
|
||||
.toStrictEqual(["US000000"]);
|
||||
|
||||
expect(() => (new SinaApiCodeTransform()).transforms(["STOCKAPI"]))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const SinaCommonCodeTransform = require("stocks/sina/transforms/common-code").default;
|
||||
|
||||
describe("【新浪】统一代码转换股票代码", () => {
|
||||
const {
|
||||
ERROR_COMMON_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new SinaCommonCodeTransform()).SZTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new SinaCommonCodeTransform()).SZTransform("SZ000000"))
|
||||
.toBe("sz000000");
|
||||
});
|
||||
|
||||
it("上交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new SinaCommonCodeTransform()).SHTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new SinaCommonCodeTransform()).SHTransform("SH000000"))
|
||||
.toBe("sh000000");
|
||||
});
|
||||
|
||||
it("港交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new SinaCommonCodeTransform()).HKTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new SinaCommonCodeTransform()).HKTransform("HK000000"))
|
||||
.toBe("hk000000");
|
||||
});
|
||||
|
||||
it("美交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new SinaCommonCodeTransform()).USTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new SinaCommonCodeTransform()).USTransform("US000000"))
|
||||
.toBe("gb_000000");
|
||||
});
|
||||
|
||||
it("交易所统一代码转换股票代码", async () => {
|
||||
expect((new SinaCommonCodeTransform()).transform("SZ000000"))
|
||||
.toBe("sz000000");
|
||||
|
||||
expect((new SinaCommonCodeTransform()).transform("SH000000"))
|
||||
.toBe("sh000000");
|
||||
|
||||
expect((new SinaCommonCodeTransform()).transform("HK000000"))
|
||||
.toBe("hk000000");
|
||||
|
||||
expect((new SinaCommonCodeTransform()).transform("US000000"))
|
||||
.toBe("gb_000000");
|
||||
|
||||
expect(() => (new SinaCommonCodeTransform()).transform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("交易所统一代码组转换股票代码组", async () => {
|
||||
expect((new SinaCommonCodeTransform()).transforms(["SZ000000"]))
|
||||
.toStrictEqual(["sz000000"]);
|
||||
|
||||
expect((new SinaCommonCodeTransform()).transforms(["SH000000"]))
|
||||
.toStrictEqual(["sh000000"]);
|
||||
|
||||
expect((new SinaCommonCodeTransform()).transforms(["HK000000"]))
|
||||
.toStrictEqual(["hk000000"]);
|
||||
|
||||
expect((new SinaCommonCodeTransform()).transforms(["US000000"]))
|
||||
.toStrictEqual(["gb_000000"]);
|
||||
|
||||
expect(() => (new SinaCommonCodeTransform()).transforms(["000000"]))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
});
|
@ -1,86 +0,0 @@
|
||||
// Stock
|
||||
const SinaStockTransform = require("stocks/sina/transforms/stock").default;
|
||||
|
||||
describe("【新浪】股票数据转换测试", () => {
|
||||
// 上交所相关代码
|
||||
const SHCode = 'SH510500';
|
||||
const SHBody = `var hq_str_sh510500="500ETF,7.147,7.149,7.224,7.280,7.085,7.224,7.225,272478144,1964297124.000,6300,7.224,32900,7.223,37000,7.222,28600,7.221,14300,7.220,389300,7.225,88400,7.226,32300,7.227,572800,7.228,19000,7.229,2020-07-31,15:00:00,00,";`
|
||||
const SHRow = SHBody.split(";\n")[0];
|
||||
const SHParams = SHRow.split('=').reverse()[0].replace('"', '').split(",");
|
||||
|
||||
// 深交所
|
||||
const SZCode = 'SZ399001';
|
||||
const SZBody = `var hq_str_sz399001="深证成指,13464.207,13466.854,13637.883,13748.034,13399.859,0.000,0.000,48559923962,650202505377.656,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,2020-07-31,15:00:03,00";`;
|
||||
const SZRow = SZBody.split(";\n")[0];
|
||||
const SZParams = SZRow.split('=').reverse()[0].replace('"', '').split(",");
|
||||
|
||||
// 港交所
|
||||
const HKCode = 'HKHSI';
|
||||
const HKBody = `var hq_str_hkHSI="Hang Seng Index,恒生指数,24747.29,24710.59,24938.85,24534.79,24595.35,-115.24,-0.47,0.000,0.000,119153830,0,0.000,0.00,29174.92,21139.26,2020/07/31,16:08";`;
|
||||
const HKRow = HKBody.split(";\n")[0];
|
||||
const HKParams = HKRow.split('=').reverse()[0].replace('"', '').split(",");
|
||||
|
||||
// 美交所
|
||||
const USCode = 'USDJI';
|
||||
const USBody = `var hq_str_gb_dji="道琼斯,26428.3203,0.44,2020-08-01 05:07:40,114.6700,26409.3301,26440.0195,26013.5898,29568.5703,18213.6504,491372564,397524206,0,0.00,--,0.00,0.00,0.00,0.00,0,0,0.0000,0.00,0.0000,,Jul 31 05:07PM EDT,26313.6504,0,1,2020";`;
|
||||
const USRow = USBody.split(";\n")[0];
|
||||
const USParams = USRow.split('=').reverse()[0].replace('"', '').split(",");
|
||||
|
||||
it("获取股票代码", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getCode()).toBe("SH510500");
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getCode()).toBe("SZ399001");
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getCode()).toBe("HKHSI");
|
||||
expect(new SinaStockTransform(USCode, USParams).getCode()).toBe("USDJI");
|
||||
expect(new SinaStockTransform("000000", []).getCode()).toBe("000000");
|
||||
});
|
||||
|
||||
it("获取股票名称", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getName()).toBe('500ETF');
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getName()).toBe('深证成指');
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getName()).toBe('恒生指数');
|
||||
expect(new SinaStockTransform(USCode, USParams).getName()).toBe("道琼斯");
|
||||
});
|
||||
|
||||
it("获取股票现价", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getNow()).toBe(7.224);
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getNow()).toBe(13637.883);
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getNow()).toBe(24595.35);
|
||||
expect(new SinaStockTransform(USCode, USParams).getNow()).toBe(26428.3203);
|
||||
});
|
||||
|
||||
it("获取股票最低价", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getLow()).toBe(7.085);
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getLow()).toBe(13399.859);
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getLow()).toBe(24534.79);
|
||||
expect(new SinaStockTransform(USCode, USParams).getLow()).toBe(26013.5898);
|
||||
});
|
||||
|
||||
it("获取股票最高价", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getHigh()).toBe(7.28);
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getHigh()).toBe(13748.034);
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getHigh()).toBe(24938.85);
|
||||
expect(new SinaStockTransform(USCode, USParams).getHigh()).toBe(26440.0195);
|
||||
});
|
||||
|
||||
it("获取股票昨日收盘价", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getYesterday()).toBe(7.149);
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getYesterday()).toBe(13466.854);
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getYesterday()).toBe(24710.59);
|
||||
expect(new SinaStockTransform(USCode, USParams).getYesterday()).toBe(26313.6504);
|
||||
});
|
||||
|
||||
it("获取股票涨跌", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getPercent()).toBe(7.224 / 7.149 - 1);
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getPercent()).toBe(13637.883 / 13466.854 - 1);
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getPercent()).toBe(24595.35 / 24710.59 - 1);
|
||||
expect(new SinaStockTransform(USCode, USParams).getPercent()).toBe(26428.3203 / 26313.6504 - 1);
|
||||
});
|
||||
|
||||
it("获取股票数据", async () => {
|
||||
expect(new SinaStockTransform(SHCode, SHParams).getStock()).toStrictEqual({ code: "SH510500", name: "500ETF", percent: 7.224 / 7.149 - 1, now: 7.224, low: 7.085, high: 7.28, yesterday: 7.149 });
|
||||
expect(new SinaStockTransform(SZCode, SZParams).getStock()).toStrictEqual({ code: 'SZ399001', name: '深证成指', percent: 13637.883 / 13466.854 - 1, now: 13637.883, low: 13399.859, high: 13748.034, yesterday: 13466.854 });
|
||||
expect(new SinaStockTransform(HKCode, HKParams).getStock()).toStrictEqual({ code: 'HKHSI', name: '恒生指数', percent: 24595.35 / 24710.59 - 1, now: 24595.35, low: 24534.79, high: 24938.85, yesterday: 24710.59 });
|
||||
expect(new SinaStockTransform(USCode, USParams).getStock()).toStrictEqual({ code: 'USDJI', name: '道琼斯', percent: 26428.3203 / 26313.6504 - 1, now: 26428.3203, low: 26013.5898, high: 26440.0195, yesterday: 26313.6504 });
|
||||
});
|
||||
});
|
||||
|
@ -1,49 +0,0 @@
|
||||
// Stock
|
||||
const Tencent = require("stocks/tencent").default;
|
||||
|
||||
describe("【腾讯】股票代码接口", () => {
|
||||
const {
|
||||
ERROR_UNDEFINED_SEARCH_STOCK,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("需要获取的股票代码", async () => {
|
||||
await expect(Tencent.getStock("SH510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SH510500", name: "500ETF" });
|
||||
|
||||
await expect(Tencent.getStock("SZ510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SZ510500", name: "---" });
|
||||
});
|
||||
|
||||
it("需要获取的股票代码组", async () => {
|
||||
await expect(Tencent.getStocks(["SH510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH510500", name: "500ETF" })]));
|
||||
|
||||
await expect(Tencent.getStocks(["SZ510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ510500", name: "---" })]));
|
||||
|
||||
await expect(Tencent.getStocks([]))
|
||||
.resolves
|
||||
.toEqual([]);
|
||||
});
|
||||
|
||||
it("搜索股票代码", async () => {
|
||||
await expect(Tencent.searchStocks("格力电器"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ000651", name: "格力电器" })]));
|
||||
|
||||
await expect(Tencent.searchStocks("贵州茅台"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH600519", name: "贵州茅台" })]));
|
||||
|
||||
await expect(Tencent.searchStocks("安踏体育"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ code: "HK02020", name: "安踏体育" }),
|
||||
expect.objectContaining({ code: "USANPDY", name: "安踏体育" }),
|
||||
]));
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const TencentApiCodeTransform = require("stocks/tencent/transforms/api-code").default;
|
||||
|
||||
describe("【腾讯】股票代码转换统一代码", () => {
|
||||
const {
|
||||
ERROR_API_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new TencentApiCodeTransform()).SZTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new TencentApiCodeTransform()).SZTransform("sz000000"))
|
||||
.toBe("SZ000000");
|
||||
});
|
||||
|
||||
it("上交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new TencentApiCodeTransform()).SHTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new TencentApiCodeTransform()).SHTransform("sh000000"))
|
||||
.toBe("SH000000");
|
||||
});
|
||||
|
||||
it("港交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new TencentApiCodeTransform()).HKTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new TencentApiCodeTransform()).HKTransform("hk000000"))
|
||||
.toBe("HK000000");
|
||||
});
|
||||
|
||||
it("美交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new TencentApiCodeTransform()).USTransform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new TencentApiCodeTransform()).USTransform("us000000"))
|
||||
.toBe("US000000");
|
||||
});
|
||||
|
||||
it("交易所股票代码转换统一代码", async () => {
|
||||
expect((new TencentApiCodeTransform()).transform("sz000000"))
|
||||
.toBe("SZ000000");
|
||||
|
||||
expect((new TencentApiCodeTransform()).transform("sh000000"))
|
||||
.toBe("SH000000");
|
||||
|
||||
expect((new TencentApiCodeTransform()).transform("hk000000"))
|
||||
.toBe("HK000000");
|
||||
|
||||
expect((new TencentApiCodeTransform()).transform("us000000"))
|
||||
.toBe("US000000");
|
||||
|
||||
expect(() => (new TencentApiCodeTransform()).transform("STOCKAPI"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
});
|
||||
|
||||
it("交易所股票代码组转换统一代码组", async () => {
|
||||
expect((new TencentApiCodeTransform()).transforms(["sz000000"]))
|
||||
.toStrictEqual(["SZ000000"]);
|
||||
|
||||
expect((new TencentApiCodeTransform()).transforms(["sh000000"]))
|
||||
.toStrictEqual(["SH000000"]);
|
||||
|
||||
expect((new TencentApiCodeTransform()).transforms(["hk000000"]))
|
||||
.toStrictEqual(["HK000000"]);
|
||||
|
||||
expect((new TencentApiCodeTransform()).transforms(["us000000"]))
|
||||
.toStrictEqual(["US000000"]);
|
||||
|
||||
expect(() => (new TencentApiCodeTransform()).transforms(["STOCKAPI"]))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const TencentCommonCodeTransform = require("stocks/tencent/transforms/common-code").default;
|
||||
|
||||
describe("【腾讯】统一代码转换股票代码", () => {
|
||||
const {
|
||||
ERROR_COMMON_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new TencentCommonCodeTransform()).SZTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new TencentCommonCodeTransform()).SZTransform("SZ000000"))
|
||||
.toBe("sz000000");
|
||||
});
|
||||
|
||||
it("上交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new TencentCommonCodeTransform()).SHTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new TencentCommonCodeTransform()).SHTransform("SH000000"))
|
||||
.toBe("sh000000");
|
||||
});
|
||||
|
||||
it("港交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new TencentCommonCodeTransform()).HKTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new TencentCommonCodeTransform()).HKTransform("HK000000"))
|
||||
.toBe("hk000000");
|
||||
});
|
||||
|
||||
it("美交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new TencentCommonCodeTransform()).USTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new TencentCommonCodeTransform()).USTransform("US000000"))
|
||||
.toBe("us000000");
|
||||
});
|
||||
|
||||
it("交易所统一代码转换股票代码", async () => {
|
||||
expect((new TencentCommonCodeTransform()).transform("SZ000000"))
|
||||
.toBe("sz000000");
|
||||
|
||||
expect((new TencentCommonCodeTransform()).transform("SH000000"))
|
||||
.toBe("sh000000");
|
||||
|
||||
expect((new TencentCommonCodeTransform()).transform("HK000000"))
|
||||
.toBe("hk000000");
|
||||
|
||||
expect((new TencentCommonCodeTransform()).transform("US000000"))
|
||||
.toBe("us000000");
|
||||
|
||||
expect(() => (new TencentCommonCodeTransform()).transform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("交易所统一代码组转换股票代码组", async () => {
|
||||
expect((new TencentCommonCodeTransform()).transforms(["SZ000000"]))
|
||||
.toStrictEqual(["sz000000"]);
|
||||
|
||||
expect((new TencentCommonCodeTransform()).transforms(["SH000000"]))
|
||||
.toStrictEqual(["sh000000"]);
|
||||
|
||||
expect((new TencentCommonCodeTransform()).transforms(["HK000000"]))
|
||||
.toStrictEqual(["hk000000"]);
|
||||
|
||||
expect((new TencentCommonCodeTransform()).transforms(["US000000"]))
|
||||
.toStrictEqual(["us000000"]);
|
||||
|
||||
expect(() => (new TencentCommonCodeTransform()).transforms(["000000"]))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
});
|
@ -1,54 +0,0 @@
|
||||
// Stock
|
||||
const TencentStockTransform = require("stocks/tencent/transforms/stock").default;
|
||||
|
||||
describe("【腾讯】股票数据转换测试", () => {
|
||||
const code = 'SH510500';
|
||||
const body = `v_sh510500="1~500ETF~510500~7.224~7.149~7.147~2724781~1351032~1373749~7.224~63~7.223~329~7.222~370~7.221~286~7.220~143~7.225~3893~7.226~884~7.227~323~7.228~5728~7.229~190~~20200731154041~0.075~1.05~7.280~7.085~7.224/2724781/1964297124~2724781~196430~~~~7.280~7.085~2.73~~~0.00~7.864~6.434~1.20~-9827~7.209~~~~~~196429.7124~0.0000~0~ ~ETF~26.51~~~~";`
|
||||
|
||||
const rows = body.split(";\n");
|
||||
const row = rows[0];
|
||||
|
||||
const [_, paramsUnformat] = row.split('=');
|
||||
const params = paramsUnformat.replace('"', '').split("~");
|
||||
|
||||
it("获取股票代码", async () => {
|
||||
expect(new TencentStockTransform(code, params).getCode())
|
||||
.toBe('SH510500');
|
||||
});
|
||||
|
||||
it("获取股票名称", async () => {
|
||||
expect(new TencentStockTransform(code, params).getName())
|
||||
.toBe('500ETF');
|
||||
});
|
||||
|
||||
it("获取股票现价", async () => {
|
||||
expect(new TencentStockTransform(code, params).getNow())
|
||||
.toBe(7.224);
|
||||
});
|
||||
|
||||
it("获取股票最低价", async () => {
|
||||
expect(new TencentStockTransform(code, params).getLow())
|
||||
.toBe(7.085);
|
||||
});
|
||||
|
||||
it("获取股票最高价", async () => {
|
||||
expect(new TencentStockTransform(code, params).getHigh())
|
||||
.toBe(7.28);
|
||||
});
|
||||
|
||||
it("获取股票昨日收盘价", async () => {
|
||||
expect(new TencentStockTransform(code, params).getYesterday())
|
||||
.toBe(7.149);
|
||||
});
|
||||
|
||||
it("获取股票涨跌", async () => {
|
||||
expect(new TencentStockTransform(code, params).getPercent())
|
||||
.toBe(7.224 / 7.149 - 1);
|
||||
});
|
||||
|
||||
it("获取股票数据", async () => {
|
||||
expect(new TencentStockTransform(code, params).getStock())
|
||||
.toStrictEqual({ "code": "SH510500", "high": 7.28, "low": 7.085, "name": "500ETF", "now": 7.224, "percent": 7.224 / 7.149 - 1, "yesterday": 7.149 });
|
||||
});
|
||||
});
|
||||
|
@ -1,51 +0,0 @@
|
||||
// Stock
|
||||
const Xueqiu = require("stocks/xueqiu").default;
|
||||
|
||||
describe("【雪球】股票代码接口", () => {
|
||||
it("获取 Token", async () => {
|
||||
await expect(Xueqiu.getToken())
|
||||
.resolves
|
||||
.toContain('xq_a_token');
|
||||
});
|
||||
|
||||
it("需要获取的股票代码", async () => {
|
||||
await expect(Xueqiu.getStock("SH510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SH510500", name: "中证500ETF" });
|
||||
|
||||
await expect(Xueqiu.getStock("SZ510500"))
|
||||
.resolves
|
||||
.toMatchObject({ code: "SZ510500", name: "---" });
|
||||
});
|
||||
|
||||
it("需要获取的股票代码组", async () => {
|
||||
await expect(Xueqiu.getStocks(["SH510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH510500", name: "中证500ETF" })]));
|
||||
|
||||
await expect(Xueqiu.getStocks(["SZ510500"]))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ510500", name: "---" })]));
|
||||
|
||||
await expect(Xueqiu.getStocks([]))
|
||||
.resolves
|
||||
.toEqual([]);
|
||||
});
|
||||
|
||||
it("搜索股票代码", async () => {
|
||||
await expect(Xueqiu.searchStocks("格力电器"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SZ000651", name: "格力电器" })]));
|
||||
|
||||
await expect(Xueqiu.searchStocks("贵州茅台"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([expect.objectContaining({ code: "SH600519", name: "贵州茅台" })]));
|
||||
|
||||
await expect(Xueqiu.searchStocks("安踏体育"))
|
||||
.resolves
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ code: "HK02020", name: "安踏体育" }),
|
||||
expect.objectContaining({ code: "USANPDY", name: "安踏体育ADR" }),
|
||||
]));
|
||||
});
|
||||
});
|
@ -1,68 +0,0 @@
|
||||
// Stock
|
||||
const XueqiuApiCodeTransform = require("stocks/xueqiu/transforms/api-code").default;
|
||||
|
||||
describe("【雪球】股票代码转换统一代码", () => {
|
||||
const {
|
||||
ERROR_API_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new XueqiuApiCodeTransform()).SZTransform("000000"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).SZTransform("SZ000000"))
|
||||
.toBe("SZ000000");
|
||||
});
|
||||
|
||||
it("上交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new XueqiuApiCodeTransform()).SHTransform("000000"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).SHTransform("SH000000"))
|
||||
.toBe("SH000000");
|
||||
});
|
||||
|
||||
it("港交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new XueqiuApiCodeTransform()).HKTransform("000000"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).HKTransform("HK000000"))
|
||||
.toBe("HK000000");
|
||||
});
|
||||
|
||||
it("美交所股票代码转换统一代码", async () => {
|
||||
expect(() => (new XueqiuApiCodeTransform()).USTransform("SZ000000"))
|
||||
.toThrow(new Error(ERROR_API_CODE));
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).USTransform("000000"))
|
||||
.toBe("US000000");
|
||||
});
|
||||
|
||||
it("交易所股票代码转换统一代码", async () => {
|
||||
expect((new XueqiuApiCodeTransform()).transform("SZ000000"))
|
||||
.toBe("SZ000000");
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).transform("SH000000"))
|
||||
.toBe("SH000000");
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).transform("HK000000"))
|
||||
.toBe("HK000000");
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).transform("000000"))
|
||||
.toBe("US000000");
|
||||
});
|
||||
|
||||
it("交易所股票代码组转换统一代码组", async () => {
|
||||
expect((new XueqiuApiCodeTransform()).transforms(["SZ000000"]))
|
||||
.toStrictEqual(["SZ000000"]);
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).transforms(["SH000000"]))
|
||||
.toStrictEqual(["SH000000"]);
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).transforms(["HK000000"]))
|
||||
.toStrictEqual(["HK000000"]);
|
||||
|
||||
expect((new XueqiuApiCodeTransform()).transforms(["000000"]))
|
||||
.toStrictEqual(["US000000"]);
|
||||
});
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
// Stock
|
||||
const XueqiuCommonCodeTransform = require("stocks/xueqiu/transforms/common-code").default;
|
||||
|
||||
describe("【雪球】统一代码转换股票代码", () => {
|
||||
const {
|
||||
ERROR_COMMON_CODE,
|
||||
} = require("utils/constant");
|
||||
|
||||
it("深交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new XueqiuCommonCodeTransform()).SZTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).SZTransform("SZ000000"))
|
||||
.toBe("SZ000000");
|
||||
});
|
||||
|
||||
it("上交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new XueqiuCommonCodeTransform()).SHTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).SHTransform("SH000000"))
|
||||
.toBe("SH000000");
|
||||
});
|
||||
|
||||
it("港交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new XueqiuCommonCodeTransform()).HKTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).HKTransform("HK000000"))
|
||||
.toBe("HK000000");
|
||||
});
|
||||
|
||||
it("美交所统一代码转换股票代码", async () => {
|
||||
expect(() => (new XueqiuCommonCodeTransform()).USTransform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).USTransform("US000000"))
|
||||
.toBe("000000");
|
||||
});
|
||||
|
||||
it("交易所统一代码转换股票代码", async () => {
|
||||
expect((new XueqiuCommonCodeTransform()).transform("SZ000000"))
|
||||
.toBe("SZ000000");
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).transform("SH000000"))
|
||||
.toBe("SH000000");
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).transform("HK000000"))
|
||||
.toBe("HK000000");
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).transform("US000000"))
|
||||
.toBe("000000");
|
||||
|
||||
expect(() => (new XueqiuCommonCodeTransform()).transform("000000"))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
|
||||
it("交易所统一代码组转换股票代码组", async () => {
|
||||
expect((new XueqiuCommonCodeTransform()).transforms(["SZ000000"]))
|
||||
.toStrictEqual(["SZ000000"]);
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).transforms(["SH000000"]))
|
||||
.toStrictEqual(["SH000000"]);
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).transforms(["HK000000"]))
|
||||
.toStrictEqual(["HK000000"]);
|
||||
|
||||
expect((new XueqiuCommonCodeTransform()).transforms(["US000000"]))
|
||||
.toStrictEqual(["000000"]);
|
||||
|
||||
expect(() => (new XueqiuCommonCodeTransform()).transforms(["000000"]))
|
||||
.toThrow(new Error(ERROR_COMMON_CODE));
|
||||
});
|
||||
});
|
@ -1,50 +0,0 @@
|
||||
// Stock
|
||||
const XueqiuStockTransform = require("stocks/xueqiu/transforms/stock").default;
|
||||
|
||||
describe("【雪球】股票数据转换测试", () => {
|
||||
const code = 'SH510500';
|
||||
const body = `{"data":{"market":{"status_id":8,"region":"CN","status":"休市","time_zone":"Asia/Shanghai","time_zone_desc":null},"quote":{"symbol":"SH510500","code":"510500","avg_price":6.982,"delayed":0,"type":13,"percent":0.5,"tick_size":0.001,"float_shares":null,"amplitude":null,"current":7.224,"high":7.28,"current_year_percent":22.38,"float_market_capital":null,"issue_date":1363276800000,"low": 7.085,"sub_type":"EBS","market_capital":4.25501735904E10,"currency":"CNY","lot_size":100,"lock_set":null,"timestamp":1595207715950,"amount":null,"chg":0.035,"last_close":7.149,"volume":null,"turnover_rate":null,"name":"中证500ETF","exchange":"SH","time":1595207715000,"total_shares":6094267200,"open":null,"status":1},"others":{"pankou_ratio":null,"cyb_switch":false},"tags":[{"description":"融","value":6},{"description":"空","value":7}]},"error_code":0,"error_description":""}`
|
||||
|
||||
const params = JSON.parse(body).data.quote;
|
||||
|
||||
it("获取股票代码", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getCode())
|
||||
.toBe('SH510500');
|
||||
});
|
||||
|
||||
it("获取股票名称", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getName())
|
||||
.toBe('中证500ETF');
|
||||
});
|
||||
|
||||
it("获取股票现价", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getNow())
|
||||
.toBe(7.224);
|
||||
});
|
||||
|
||||
it("获取股票最低价", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getLow())
|
||||
.toBe(7.085);
|
||||
});
|
||||
|
||||
it("获取股票最高价", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getHigh())
|
||||
.toBe(7.28);
|
||||
});
|
||||
|
||||
it("获取股票昨日收盘价", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getYesterday())
|
||||
.toBe(7.149);
|
||||
});
|
||||
|
||||
it("获取股票涨跌", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getPercent())
|
||||
.toBe(7.224 / 7.149 - 1);
|
||||
});
|
||||
|
||||
it("获取股票数据", async () => {
|
||||
expect(new XueqiuStockTransform(code, params).getStock())
|
||||
.toStrictEqual({ "code": "SH510500", "high": 7.28, "low": 7.085, "name": "中证500ETF", "now": 7.224, "percent": 7.224 / 7.149 - 1, "yesterday": 7.149 });
|
||||
});
|
||||
});
|
||||
|
@ -1,39 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"rootDir": "src",
|
||||
"target": "es5",
|
||||
"outDir": "dist",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"paths": {
|
||||
"types/*": [
|
||||
"../types/*"
|
||||
],
|
||||
"@stocks/*": [
|
||||
"stocks/*"
|
||||
],
|
||||
"@utils/*": [
|
||||
"utils/*"
|
||||
],
|
||||
"@interfaces/*": [
|
||||
"interfaces/*"
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"transform": "typescript-transform-paths"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules/**",
|
||||
"dist/**"
|
||||
]
|
||||
}
|
21
types/index.d.ts
vendored
21
types/index.d.ts
vendored
@ -1,21 +0,0 @@
|
||||
import StockApi from './stocks/index';
|
||||
|
||||
export declare const stocks: {
|
||||
base: StockApi,
|
||||
netease: StockApi,
|
||||
sina: StockApi,
|
||||
tencent: StockApi,
|
||||
xueqiu: StockApi,
|
||||
};
|
||||
|
||||
export declare const root: {
|
||||
stocks: {
|
||||
base: StockApi,
|
||||
netease: StockApi,
|
||||
sina: StockApi,
|
||||
tencent: StockApi,
|
||||
xueqiu: StockApi,
|
||||
},
|
||||
};
|
||||
|
||||
export default root;
|
23
types/stocks/index.d.ts
vendored
23
types/stocks/index.d.ts
vendored
@ -1,23 +0,0 @@
|
||||
import Stock from '../utils/stock';
|
||||
|
||||
export interface StockApi {
|
||||
/**
|
||||
* 获取股票数据
|
||||
* @param code 股票代码
|
||||
*/
|
||||
getStock(code: string): Promise<Stock>;
|
||||
|
||||
/**
|
||||
* 获取股票数据组
|
||||
* @param codes 股票代码组
|
||||
*/
|
||||
getStocks(codes: string[]): Promise<Stock[]>;
|
||||
|
||||
/**
|
||||
* 搜索股票代码
|
||||
* @param key 关键字
|
||||
*/
|
||||
searchStocks(key: string): Promise<Stock[]>;
|
||||
}
|
||||
|
||||
export default StockApi;
|
10
types/stocks/transforms/api-code.d.ts
vendored
10
types/stocks/transforms/api-code.d.ts
vendored
@ -1,10 +0,0 @@
|
||||
export interface ApiCodeTransform {
|
||||
transform(code: string): string;
|
||||
transforms(codes: string[]): string[];
|
||||
SZTransform(code: string): string;
|
||||
SHTransform(code: string): string;
|
||||
HKTransform(code: string): string;
|
||||
USTransform(code: string): string;
|
||||
}
|
||||
|
||||
export default ApiCodeTransform;
|
10
types/stocks/transforms/common-code.d.ts
vendored
10
types/stocks/transforms/common-code.d.ts
vendored
@ -1,10 +0,0 @@
|
||||
export interface CommonCodeTransform {
|
||||
transform(code: string): string;
|
||||
transforms(codes: string[]): string[];
|
||||
SZTransform(code: string): string;
|
||||
SHTransform(code: string): string;
|
||||
HKTransform(code: string): string;
|
||||
USTransform(code: string): string;
|
||||
}
|
||||
|
||||
export default CommonCodeTransform;
|
48
types/stocks/transforms/stock.d.ts
vendored
48
types/stocks/transforms/stock.d.ts
vendored
@ -1,48 +0,0 @@
|
||||
// Types
|
||||
import Stock from "../../utils/stock";
|
||||
|
||||
/**
|
||||
* 基础股票数据解析
|
||||
*/
|
||||
export interface StockTransform {
|
||||
/**
|
||||
* 获取代码
|
||||
*/
|
||||
getCode(): string;
|
||||
/**
|
||||
* 获取名称
|
||||
*/
|
||||
getName(): string;
|
||||
|
||||
/**
|
||||
* 获取现价
|
||||
*/
|
||||
getNow(): number;
|
||||
|
||||
/**
|
||||
* 获取最低价
|
||||
*/
|
||||
getLow(): number;
|
||||
|
||||
/**
|
||||
* 获取最高价
|
||||
*/
|
||||
getHigh(): number;
|
||||
|
||||
/**
|
||||
* 获取昨日收盘价
|
||||
*/
|
||||
getYesterday(): number;
|
||||
|
||||
/**
|
||||
* 获取涨跌
|
||||
*/
|
||||
getPercent(): number;
|
||||
|
||||
/**
|
||||
* 获取股票数据
|
||||
*/
|
||||
getStock(): Stock;
|
||||
}
|
||||
|
||||
export default StockTransform;
|
3
types/utils/dictionary.d.ts
vendored
3
types/utils/dictionary.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
export type Dictionary<T, K extends string | number = string> = { [key in K]: T };
|
||||
|
||||
export default Dictionary;
|
12
types/utils/stock.d.ts
vendored
12
types/utils/stock.d.ts
vendored
@ -1,12 +0,0 @@
|
||||
export interface Stock {
|
||||
name: string;
|
||||
code: string;
|
||||
|
||||
now: number;
|
||||
low: number;
|
||||
high: number;
|
||||
percent: number;
|
||||
yesterday: number;
|
||||
}
|
||||
|
||||
export default Stock;
|
Loading…
Reference in New Issue
Block a user