Skip to content

Commit c4a69b1

Browse files
committed
stocks
1 parent 655b351 commit c4a69b1

File tree

17 files changed

+629
-64
lines changed

17 files changed

+629
-64
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# dependencies
66
/node_modules
77
conf/db.conf.ts
8+
conf/api.conf.ts
89

910
# misc
1011
.DS_Store

src/@types/global.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,5 @@
22
export {}
33

44
declare global {
5-
export interface IAnyObject {
6-
[key: string]: any
7-
}
5+
type AnyObject<T = any> = Record<string, T>
86
}

src/controllers/StockController.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { Equal, Like, Between, FindManyOptions} from "typeorm";
2+
import { Context } from '@core/koa'
3+
import { Stock } from '../entities/mysql/shares/stock'
4+
import { Guid } from "../utils/tools";
5+
import { getSharesManager, getSharesRepository } from '../database/dbUtils';
6+
import $http from '../utils/http'
7+
import StockService from '../services/StockService'
8+
import { Stock_Name_Origin, Stock_Name_API_Host, Stock_Name_API_Url, UA } from '../../conf/api.conf'
9+
10+
interface IStockKLineResponse {
11+
code: string
12+
name: string
13+
klines: string[]
14+
}
15+
16+
enum EBLock {
17+
主板 = 1,
18+
创业板,
19+
科创板
20+
}
21+
22+
const requestApi = async(code: string) => {
23+
const params = {
24+
secid: code,
25+
klt: 101,
26+
fqt: 1,
27+
lmt: 1,
28+
end: 20500000,
29+
iscca: 1,
30+
fields1: 'f1,f2,f3,f4,f5,f6,f7,f8',
31+
fields2: 'f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f62,f63,f64',
32+
ut: 'f057cbcbce2a86e2866ab8877db1d059',
33+
forcect: 1,
34+
}
35+
const url = `https://${Stock_Name_API_Host}${Stock_Name_API_Url}`
36+
const result = await $http.get(url, {
37+
params,
38+
headers: {
39+
'Host': `${Stock_Name_API_Host}`,
40+
'Origin': `https://${Stock_Name_Origin}`,
41+
'Referer': `https://${Stock_Name_Origin}`,
42+
'User-Agent': UA
43+
}
44+
});
45+
const _data: IStockKLineResponse = result.data || {}
46+
return {
47+
code: _data.code,
48+
name: _data.name
49+
}
50+
}
51+
52+
53+
54+
class StockController {
55+
56+
async getByCode(code: string) {
57+
const stock = await getSharesRepository(Stock).findOne({code})
58+
return stock
59+
}
60+
61+
async pages1(ctx: Context) {
62+
const { page = 1, pageSize = 10, code, name, market, block } = ctx.query
63+
const [list, total] = await StockService.pages(page, pageSize, code, name, market, block)
64+
ctx.Pages({ list, total })
65+
}
66+
67+
async pages(delta = 0, size = 10) {
68+
const options: FindManyOptions<Stock> = {
69+
skip: delta * size,
70+
take: size,
71+
order: { id: 'ASC'},
72+
where: {}
73+
}
74+
const pages = await getSharesRepository(Stock).findAndCount(options)
75+
return pages
76+
}
77+
78+
async getList(delta = 0, size = 100) {
79+
const options: FindManyOptions<Stock> = {
80+
skip: delta * size,
81+
take: size,
82+
order: { id: 'ASC'},
83+
where: {}
84+
}
85+
const stocks = await getSharesRepository(Stock).find(options)
86+
return stocks
87+
}
88+
89+
async batchInsert(ctx: Context) {
90+
const delta = 900
91+
92+
const arr = Array(100).fill(0).map((v, i) => {
93+
return `1.688${(i + delta).toString().padStart(3, '0')}`
94+
})
95+
96+
const pro = arr.map(requestApi)
97+
98+
const dcRes = await Promise.all(pro)
99+
const result = dcRes.filter(d => d.code)
100+
console.log('result:', result.length)
101+
// ctx.Json({data: result})
102+
103+
const insertDatas = result.map(StockController.add)
104+
const _insertRes = await Promise.all(insertDatas)
105+
ctx.Json({data: _insertRes})
106+
}
107+
108+
async insert(ctx: Context) {
109+
const { code, name } = ctx.query
110+
let model = new Stock()
111+
model.uuid = Guid()
112+
model.code = code
113+
model.name = name
114+
model.market = 2
115+
model.block = 2
116+
model.amount = 100
117+
const result = await getSharesManager().save(model)
118+
ctx.Json({data: result})
119+
}
120+
121+
static async add(data: {code: string, name: string}) {
122+
const { code, name } = data
123+
let model = new Stock()
124+
model.uuid = Guid()
125+
model.code = code
126+
model.name = name
127+
model.market = 1
128+
model.block = 3
129+
model.amount = 200
130+
const result = await getSharesManager().save(model)
131+
return result
132+
}
133+
134+
}
135+
136+
export default new StockController
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import { Equal, Like, Between, FindManyOptions} from "typeorm";
2+
import { Context } from '@core/koa'
3+
import { StockHistory, History, KeyofHistory } from '../entities/mysql/shares/stockHistory'
4+
import { Guid } from "../utils/tools";
5+
import { getSharesManager, getSharesRepository } from '../database/dbUtils';
6+
import $http from '../utils/http'
7+
import StockCtrl from './StockController'
8+
import StockService from '../services/StockService'
9+
import StockHistoryService from "../services/StockHistoryService";
10+
import { Stock_His_API_Origin, Stock_His_API_Host, Stock_His_API_Url, Stock_His_API_Cookie, UA } from '../../conf/api.conf'
11+
12+
interface IStockKLineResponse {
13+
code: string
14+
name: string
15+
klines: string[]
16+
}
17+
18+
const cols = ["timestamp","volume","open","high","low","close","chg","percent","turnoverrate","amount","volume_post","amount_post","pe","pb","ps","pcf","market_capital","balance","hold_volume_cn","hold_ratio_cn","net_volume_cn","hold_volume_hk","hold_ratio_hk","net_volume_hk"]
19+
20+
const requestXueqiu = async (code: string) => {
21+
const params = {
22+
symbol: code,
23+
begin: 1628567129263,
24+
period: 'day',
25+
type: 'before',
26+
count: -10000,
27+
indicator: 'kline,pe,pb,ps,pcf,market_capital,agt,ggt,balance',
28+
}
29+
const url = `https://${Stock_His_API_Host}${Stock_His_API_Url}`
30+
31+
return await $http.get(url, {
32+
params,
33+
headers: {
34+
'Cookie': Stock_His_API_Cookie,
35+
'Origin': `https://${Stock_His_API_Origin}`,
36+
'Referer': `https://${Stock_His_API_Origin}`,
37+
'User-Agent': UA
38+
}
39+
})
40+
}
41+
42+
43+
class SharesController {
44+
45+
async batchInsert(ctx: Context) {
46+
const { page = 0 } = ctx.query
47+
try {
48+
// 数据库查数据
49+
console.time('a')
50+
const _stocks = await StockCtrl.getList(page, 10)
51+
const stocks = _stocks.map(s => {
52+
delete s.uuid
53+
s.code = `${s.market === 1 ? 'SH' : 'SZ'}${s.code}`
54+
return s
55+
});
56+
console.log('stock------', stocks)
57+
console.timeEnd('a')
58+
59+
// 拉雪球的数据,并且写入库
60+
const proList = stocks.map(async stock => {
61+
const res1 = await requestXueqiu(stock.code) // {data: {item: [1,2,3,4]}}
62+
const list1: number[][] = (res1.data.item || [])
63+
console.log('list1------', stock.name, stock.code, list1.length)
64+
const res2 = await SharesController.addListArr(list1, stock.id)
65+
return res2
66+
})
67+
console.log('入库..., ', page)
68+
const res = await Promise.all(proList)
69+
70+
// const single = stocks[0]
71+
// console.time('b')
72+
// const result = await requestXueqiu(single.code) // {data: {item: [1,2,3,4]}}
73+
// const dayLines: number[][] = (result.data.item || [])
74+
// console.log(dayLines.length, 'length.....', single)
75+
// console.timeEnd('b')
76+
// console.time('c')
77+
// const res = await SharesController.addListArr(dayLines, single.id)
78+
// console.timeEnd('c')
79+
80+
ctx.Json({
81+
msg: 'success',
82+
data: res
83+
})
84+
85+
// ctx.Json({
86+
// msg: 'success',
87+
// data: dayLines.length
88+
// })
89+
90+
} catch(e) {
91+
throw e
92+
}
93+
}
94+
95+
static async insert(args: Partial<StockHistory>) {
96+
let model = new StockHistory()
97+
model.uuid = Guid()
98+
model.tradeAt = args.tradeAt
99+
model.open = args.open
100+
model.close = args.close
101+
model.high = args.high
102+
model.low = args.low
103+
model.total = args.total
104+
model.totalAmt = args.totalAmt
105+
model.amplitude = args.amplitude
106+
model.rasingRatio = args.rasingRatio
107+
model.rasingPrice = args.rasingPrice
108+
model.exchangeRatio = args.exchangeRatio
109+
const result = await getSharesManager().save(model)
110+
console.log(result.id)
111+
return result.id
112+
}
113+
114+
static async add(data: History) {
115+
let model = new History()
116+
model.stockId = data.stockId
117+
model.timestamp = data.timestamp
118+
model.volume = data.volume
119+
model.open = data.open
120+
model.high = data.high
121+
model.low = data.low
122+
model.close = data.close
123+
model.chg = data.chg
124+
model.percent = data.percent
125+
model.turnoverrate = data.turnoverrate
126+
model.amount = data.amount
127+
model.volume_post = data.volume_post
128+
model.amount_post = data.amount_post
129+
model.pe = data.pe
130+
model.pb = data.pb
131+
model.ps = data.ps
132+
model.pcf = data.pcf
133+
model.market_capital = data.market_capital
134+
model.balance = data.balance
135+
model.hold_volume_cn = data.hold_volume_cn
136+
model.hold_ratio_cn = data.hold_ratio_cn
137+
model.net_volume_cn = data.net_volume_cn
138+
model.hold_volume_hk = data.hold_volume_hk
139+
model.hold_ratio_hk = data.hold_ratio_hk
140+
model.net_volume_hk = data.net_volume_hk
141+
const result = await getSharesManager().save(model)
142+
return result.id
143+
}
144+
145+
static async addList(list: number[], stockId: number) {
146+
let model = new History()
147+
model.stockId = stockId
148+
cols.forEach((c: KeyofHistory, i) => {
149+
return model[c] = list[i]
150+
})
151+
const result = await getSharesManager().save(model)
152+
return result.id
153+
}
154+
155+
static async addListArr(list: number[][], stockId: number) {
156+
const _list: History[] = []
157+
list.forEach(kline => {
158+
let model = new History()
159+
model.stockId = stockId
160+
cols.forEach((c: KeyofHistory, i) => {
161+
return model[c] = kline[i]
162+
})
163+
_list.push(model)
164+
})
165+
const result = await getSharesManager().save(_list)
166+
return result.map(r => r.id)
167+
}
168+
169+
async pages(ctx: Context) {
170+
const { code, page = 1, pageSize = 10 } = ctx.query
171+
if(!code) {
172+
ctx.Json({msg: 'code参数缺失', status: 400})
173+
}
174+
const [list, total] = await StockService.pages(page, pageSize, code)
175+
ctx.Pages({list, total})
176+
}
177+
178+
async updateHistory(ctx: Context) {
179+
const { code } = ctx.fields
180+
const stock = await StockService.getByCode(code)
181+
const [list, total] = await StockHistoryService.pages(1, 10, stock.id)
182+
let lastestDate = 0
183+
if(total > 0) {
184+
lastestDate = list[total - 1].timestamp
185+
const today = new Date
186+
// const
187+
} else {
188+
//
189+
}
190+
return stock
191+
}
192+
}
193+
194+
export default new SharesController

src/core/koa.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11

2-
import { IResponseData, IReturnPage } from '@src/models/ResponseData';
2+
import { ResponseData, ReturnPage } from '@src/models/ResponseData';
33
import {Context as KoaContext} from 'koa'
44

55
export interface Context extends KoaContext {
66
// post fields
7-
fields?: IAnyObject
7+
fields?: AnyObject
88

99
// session
1010
session?: object
@@ -16,8 +16,8 @@ export interface Context extends KoaContext {
1616
}
1717

1818
// response
19-
Json?: <T = any>(res: T | IResponseData<T> | (() => T)) => IResponseData<T>
20-
Pages?: <T = any>(res: IReturnPage<T>) => IResponseData<T>
19+
Json?: <T = any>(res: T | ResponseData<T> | (() => T)) => ResponseData<T>
20+
Pages?: <T = any>(res: ReturnPage<T>) => ResponseData<T[]>
2121
}
2222

2323

0 commit comments

Comments
 (0)