基于JavaScript的Web端股票价格查看器——大道

news2024/9/23 21:21:16

🐶 基于JavaScript的Web端股票价格查看器——大道

一、项目背景

当下互联网发展迅速,互联网已经不断向传统金融领域渗透。在互联网上有大量金融领域的数据,如何利用好这些数据,对于投资者来说是十分重要的一件事情。股票价格实时变化,而大道至简(先人说的都对),我们能不能实现一种最简单的股票价格查看器,通过在网页上访问,以满足用户的股票价格查看需求。

二、国内外研究现状

笔者通过访谈、调查,了解国内外主要有以下几款Web端股票价格查看网站,功能,额…,都比我们强大一点点,不过,大道至简,功能多不一定好。我相信我们的产品能够有很多用户使用。

1、东方财富网https://www.eastmoney.com/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TZxgmZ7w-1676207921874)(null)]

2、同花顺财经http://www.10jqka.com.cn/

img

3、FINVIZ.com - Stock Screener

img

4、Stock Market - Business News, Market Data, Stock Analysis - TheStreet

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uUVEJVfR-1676207922077)(null)]

经过体验,我发现国内还没有一款功能单一、又有名的股票价格查看网站,所以我坚信我的这个股票价格查看网站大道一定能收获很多用户,在国内打败其他竞争对手,成为No.1。

三、需求分析

3.1 股票价格查看需求分析

一个朴实无华的股票价格查看和点赞功能。

大道这款产品就是至简,因为古语有云大道至简,我不是没能力,不是没技术,不是懒,不是因为什么原因,就是因为这款产品的名字叫大道,为什么叫大道,因为市面上没有一款专注于某一功能的商业产品,我们就要做第一个吃螃蟹的人。

四、系统详细设计与实现

接下来是流水账…我觉得这不是重点了。重要是你得理解什么是《大道》。

搭建express环境这里就不详述了,我们先来介绍第一个api的具体写法。

module.exports = function (app) {

  app.route('/api/stock-prices')
    .get(async function (req, res){
      const{ stock , like } = req.query;
         console.log(req.query);
         res.json({
            "success": "true"
    });    
  
};

先测试路由是不是写对了,经测试没有问题。不给你们看了。

然后我们需要调用一个股票接口,接口返回数据示例如下:

{
    "avgTotalVolume":31209460,
    "calculationPrice":"close",
    "change":-2.857,
    "changePercent":-0.02534,
    "close":null,
    "closeSource":"official",
    "closeTime":null,
    "companyName":"Alphabet Inc - Class C",
    "currency":"USD",
    "delayedPrice":null,
    "delayedPriceTime":null,
    "extendedChange":null,
    "extendedChangePercent":null,
    "extendedPrice":null,
    "extendedPriceTime":null,
    "high":null,
    "highSource":null,
    "highTime":null,
    "iexAskPrice":0,
    "iexAskSize":0,
    "iexBidPrice":0,
    "iexBidSize":0,
    "iexClose":109.96,
    "iexCloseTime":1658174399531,
    "iexLastUpdated":0,
    "iexMarketPercent":null,
    "iexOpen":null,
    "iexOpenTime":null,
    "iexRealtimePrice":0,
    "iexRealtimeSize":0,
    "iexVolume":0,
    "lastTradeTime":1658174399901,
    "latestPrice":109.91,
    "latestSource":"Close",
    "latestTime":"July 18, 2022",
    "latestUpdate":1658174401108,
    "latestVolume":null,
    "low":null,
    "lowSource":null,
    "lowTime":null,
    "marketCap":74208045489,
    "oddLotDelayedPrice":null,
    "oddLotDelayedPriceTime":null,
    "open":null,
    "openTime":null,
    "openSource":"official",
    "peRatio":null,
    "previousClose":112.767,
    "previousVolume":34330759.99999999,
    "primaryExchange":"NASDAQ",
    "symbol":"GOOG",
    "volume":null,
    "week52High":152.1,
    "week52Low":102.21,
    "ytdChange":-0.2656608471137929,
    "isUSMarketOpen":false
}

接口很强大吧,我们需要下载一个node-fetch包来调用该接口,获取接口内的数据。

const fetchRes = await fetch(`https://*******/v1/stock/${stock}/quote`)

直接fetch即可。

'use strict';

var fetch = require("node-fetch");

const stocksDB = {};

async function getStock(stock) {
  const fetchRes = await fetch(`https://*******/v1/stock/${stock}/quote`)
  const {symbol ,latestPrice} = await fetchRes.json()
  // return fetchResData;
  return {
    symbol,
    price: `${latestPrice}`
  }
}

async function addToStockDB(stock,like) {
  	const returnedStock = await getStock(stock);
    const {symbol,price} = returnedStock
    
    if(stocksDB.hasOwnProperty(symbol)){
      stocksDB[symbol] = {
        price,
        like: like ? stocksDB[symbol].like + 1 : stocksDB[symbol].like
      }
    }else{
      stocksDB[symbol] = {
        price,
        like: like ? 1 : 0
    }
  }
}

module.exports = function (app) {
  app.route('/api/stock-prices')
    .get(async function (req, res){
      const{ stock , like } = req.query;
      if(stock){
        if(typeof stock === 'string'){
          await addToStockDB(stock,like)
        }else{
          for(let i=0;i<stock.length;i++){
          await addToStockDB(stock[i],like)
          }
        }
      }

      
      // const googStock = await getStock('GOOG');
      res.json(stocksDB);
    });
};

然后我们取fetch到的json文件中的两个字段symbol ,latestPrice。

const {symbol ,latestPrice} = await fetchRes.json()

addToStockDB(stock,like)将price、like、symbol放入stocksDB对象。

下面再接受参数,将参数传到addToStockDB。

请求以下url。

https://boilerplate-project-stockchecker.reganyue.repl.co/api/stock-prices/?stock=aapl&stock=goog&stock=msft&like=true

得到:

{"GOOG":{"price":"113.04","like":2},"AAPL":{"price":"149.64","like":3},"MSFT":{"price":"257.84","like":1}}

好了,基本的功能实现了。

接下来看下面这段代码

module.exports = function (app) {
  app.route('/api/stock-prices')
    .get(async function (req, res){
      const{ stock , like } = req.query;

      const stockKeys = [];
      if(stock){
        if(typeof stock === 'string'){
          await addToStockDB(stock,like)
          stockKeys.push(stock.toUpperCase())
        }else{
          for(let i=0;i<stock.length;i++){
          await addToStockDB(stock[i],like)
            stockKeys.push(stock[i].toUpperCase())
          }
        }
      }

      const result = Object.keys(stocksDB)
        .filter(key => stockKeys.includes(key))
        .map(key => ({
          stock:key,
          ...stocksDB[key]
        }));
      
      res.json({
        stockData : result
      });
    });
};

我们新建一个stockKeys数组,将stocksDB对象里面所有key,然后用filter来过滤stockKeys,只保留stocksDB的keys中在stockKeys中存在的key,然后再用map,求stocksDB对象中所有key的值。

请求url:https://boilerplate-project-stockchecker.reganyue.repl.co/api/stock-prices/?stock=aapl&stock=goog&stock=msft&like=true

得到:

{"stockData":[{"stock":"AAPL","price":"151","like":1},{"stock":"GOOG","price":"114.62","like":1},{"stock":"MSFT","price":"259.53","like":1}]}

五、结语

万物之始,大道至简,衍化至繁。

致虚极,守静笃,万物并作,吾以观复。夫物芸芸,各复归其根,归根曰静,静曰复命。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/341039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaSE学习day4_01 循环for,while,do...while

1. 循环高级 1.1 无限循环 for、while、do...while都有无限循环的写法。 最为常用的是while格式的。 因为无限循环是不知道循环次数的&#xff0c;所以用while格式的 代码示例&#xff1a; while(true){} 1.2 跳转控制语句&#xff08;掌握&#xff09; 跳转控制语句&…

MySQL 插入数据

数据库与表创建成功以后&#xff0c;需要向数据库的表中插入数据。在 MySQL 中可以使用 INSERT 语句向数据库已有的表中插入一行或者多行元组数据。 你可以通过 mysql> 命令提示窗口中向数据表中插入数据&#xff0c;或者通过PHP脚本来插入数据。 语法 以下为向MySQL数据表…

51单片机——步进电机实验,小白讲解,相互学习

步进电机简介&#xff1a; 步进电机是将电脉冲信号转变为角位移或多线位移的开源控制元件。在非超载的情况下&#xff0c;电机的转速&#xff0c;停止的位置只取决于脉冲信号的频率和脉冲数&#xff0c;而不受负载变化的影响&#xff0c;即给电机加一个脉冲信号&#xff0c;电机…

Android - 自动系统签名

一、系统签名 以下是两类应用开发场景&#xff1a; 普通应用开发&#xff1a;使用公司自定义 keystore 进行签名&#xff0c;如&#xff1a;微信、支付宝系统应用开发&#xff1a;使用 AOSP 系统签名或厂商自定义 keystore 进行签名&#xff0c;如&#xff1a;设置、录音 系…

数学建模拓展内容:卡方检验和Fisher精确性检验(附有SPSS使用步骤)

卡方检验和Fisher精确性检验卡方拟合度检验卡方独立性检验卡方检验的前提假设Fisher精确性检验卡方拟合度检验 卡方拟合度检验概要&#xff1a;卡方拟合度检验也被称为单因素卡方检验&#xff0c;用于检验一个分类变量的预期频率和观察到的频率之间是否存在显著差异。 卡方拟…

第一部分:简单句——第二章:简单句的补充

简单句的核心构成&#xff1a;一主一谓 主语/宾语/表语 可以变成名词/代词/doing/to do 谓语动词有四种核心变化&#xff1a;三态 一否 时态语态情态否定 简单句的核心&#xff1a;将简单句给写对 简单句的补充&#xff1a;将简单句给写的更好、更充分 简单句的补充 1、限定…

计算机网络之HTTP04ECDHE握手解析

DH算法 离散读对数问题是DH算法的数学基础 &#xff08;1&#xff09;计算公钥 &#xff08;2&#xff09;交换公钥&#xff0c;并计算 对方公钥^我的私钥 mod p 离散对数的交换幂运算交换律使二者算出来的值一样&#xff0c;都为K k就是对称加密的秘钥 2. DHE算法 E&#…

DNS 原理入门指南(一)

DNS 是互联网核心协议之一。不管是上网浏览&#xff0c;还是编程开发&#xff0c;都需要了解一点它的知识。 本文详细介绍DNS的原理&#xff0c;以及如何运用工具软件观察它的运作。我的目标是&#xff0c;读完此文后&#xff0c;你就能完全理解DNS。 一、DNS 是什么&#xff1…

记录每日LeetCode 1138.字母板上的路径 Java实现

题目描述&#xff1a; 我们从一块字母板上的位置 (0, 0) 出发&#xff0c;该坐标对应的字符为 board[0][0]。 在本题里&#xff0c;字母板为board ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]&#x…

Linux重定向符、管道符讲解

目录 重定向 将命令与文件进行互动 输出重定向 输入重定向 管道符 将命令与命令互动起来 重定向 将命令与文件进行互动 重定向分类 一般情况下&#xff0c;Linux命令运行时都会打开一下三个文件 标准输入文件&#xff1a;stdin文件&#xff0c;文件描述符为0&#xff0c;Li…

自定义ESLint规则开发与使用

自定义eslint及使用 项目结构 |-eslint-plugin-demo //自定义eslint插件项目 | |-demo-app // 使用自定义eslint的测试应用 |-README.md 项目效果&#xff1a; github项目地址 自定义ESLint环境准备 安装脚手架 执行下列命令来安装开发eslint的脚手架。 yo(y…

中小学信息学相关编程比赛清单及报名网站汇总(C++类)

1、NOI系列比赛(CSP-J CSP-S NOIP NOI APIO CTSC IOI ISIJ等) NOI官网 NOI全国青少年信息学奥林匹克竞赛https://www.noi.cn/ 2、蓝桥杯青少年创意编程大赛 https://www.lanqiaoqingshao.cn/home 3、中国电子协会考评中心

数据结构 - Set 与 Map 接口介绍(TreeMap,HashMap,TreeSet,HashSet类)

文章目录前言1. Set / Map接口2. TreeSet类3. TreeMap 类4. HashSet 与 HashMap4.1 HashSet / HashMap 底层哈希表4.2 解决哈希冲突总结✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来&#xff01; 编程真是一件很奇妙的东西。你只是浅尝辄止&#xff0c;那么只会觉得…

神经网络基础知识

神经网络基础知识 文章目录神经网络基础知识一、人工神经网络1.激活函数sigmod函数Tanh函数Leaky Relu函数分析2.过拟合和欠拟合二、学习与感知机1.损失函数与代价函数2. 线性回归和逻辑回归3. 监督学习与无监督学习三、优化1.梯度下降法2.随机梯度下降法(SGD)3. 批量梯度下降法…

JavaScript系列之new运算符

文章の目录一、什么是new&#xff1f;二、new经历了什么过程&#xff1f;三、new的过程分析四、其他作用参考写在最后一、什么是new&#xff1f; 众所周知&#xff0c;在JS中&#xff0c;new的作用是通过构造函数来创建一个实例对象。 像下面这样&#xff1a;&#xff08;和普…

Centos篇-Centos Minimal安装

安装Centos Minimal 下载镜像 由于使用Centos主要是安装K8s以及使用K8s或者docker安装各种服务&#xff0c;可以理解为就是单纯的服务器使用&#xff0c;所以不需要GUI&#xff0c;直接使用Centos的Server版本。 所以选择centos的minimal版本进行下载&#xff1a; 地址&#…

FreeRTOS队列集、事件标志组 | FreeRTOS十一

目录 说明&#xff1a; 一、队列集 1.1、队列集简介 1.2、队列集作用 二、队列集相关API函数 2.1、创建队列集函数 2.2、往队列集添加队列函数 2.3、队列集移除队列函数 2.4、获取队列集中有有效队列 三、事件标志组 3.1、什么是事件标志组 3.2、事件标志组的特点 …

Matlab傅里叶谱方法求解二维波动方程

傅里叶谱方法求解基本偏微分方程—二维波动方程 二维波动方程 将一维波动方程中的一维无界弦自由振动方程推广到二维空间上, 就得到了描述无界 (−∞<x,y<∞)(-\infty<x, y<\infty)(−∞<x,y<∞) 弹性薄膜的波动方程: ∂2u∂t2a2(∂2∂x2∂2∂y2)u(1)\frac…

HTML img和video object-fit 属性

简介 Css中object-fit主要是应用到img标签和Video标签的&#xff0c;来控制显示缩放效果的。 首先我们存在一张图片&#xff0c;原始图片的尺寸是 1080px x 600px, 展示效果如下&#xff1a; 如果我们的css样式中的img大小设定并不能满足图片的原始大小&#xff0c;比如我们的…

Syzkaller学习笔记---更新syz-extract/syz-sysgen(一)

Syzkaller学习笔记Syzkaller 安装文件系统内核Android common kernel参考文献syzkaller 源码阅读笔记-1前言syz-extractmainarchListcreateArchesworkerprocessArchprocessFileextractcheckUnsupportedCallsarchList小结syz-sysgenmainprocessJob()generateExecutorSyscalls()w…