最简单的 tradingview 连接我的数据实时渲染带你入坑!!!

tradingview 是什么?

当你点开这片博文的的时候相信不需要我介绍你也应该知道tradingview是什么的工具了,而我也是刚接触这个工具不久,国内的资料少之又少,在掉落99根头发的情况下可以简单的运用,特此在此处记录一下,希望正在看博客的你可以少掉一些头发~


申请图表库

准备好公司的营业执照与公章,进入官网申请授权。申请需要等待7个工作日,届时会有工作人员和你邮箱联系。收集了一些资源在下方链接,你可以在申请期间阅读查看,不过这有些难度。

在这里插入图片描述


在选择框架时取决于公司的框架要求,tradingview 官方也为不同的框架提供了实例,这使得我们开发的过程更加简单了一点点,但无论选择什么框架都是大同小异的,这里我从我选择的vuejs框架进行记录学习开发过程的步骤,希望可以帮助到正在看这篇博客的你!

附件:

1.tradingview 申请地址
2.github 项目地址
3.tradingview 官方文档
4.在不同的框架上运行 tradingview
5.超级详细的中文文档


框架的选择

在选择框架时取决于公司的框架要求,tradingview 官方也为不同的框架提供了实例,这使得我们开发的过程更加简单了一点点,但无论选择什么框架都是大同小异的,这里我从我选择的vuejs框架进行记录学习开发过程的步骤,希望可以帮助到正在看这篇博客的你!

在这里插入图片描述


运行官方的实例

在下载好官方的实例后,我选择了vuejs的框架,在readme.md文件中告诉你如何启动文件。

  1. Install dependencies npm install.

  2. Copy charting_library folder from https://github.com/tradingview/charting_library/ to /public folder. The earliest supported version of the Charting Library is 1.12. If you get 404 then you need to request an access to this repository.

  3. Copy charting_library.min.js from https://github.com/tradingview/charting_library/ to /src folder.

  4. Copy datafeeds folder from https://github.com/tradingview/charting_library/ to /public.

  5. Run npm run serve. It will build the project and open a default browser with the Charting Library.

执行npm install命令下载所有依赖,如果node-sass报错可以执行npm install node-sass@latest --save-dev下载解决;第二部我们需要把charting_library文件和datafeeds文件移入到public文件夹中,再将charting_library文件夹中的charting_library.min.js文件复制到src文件夹下,执行npm run serve即可在浏览器中看见K线的组件在运行了,不过这个不是我们自己的数据,我们需要连接自己的数据!!!

在这里插入图片描述

如果你想要在自己的创建的项目中引入这个组件,你还需要在index.html中引入polyfills.js和bundle.js


链接自己的数据

这一步应该是至关重要的,也应该是大部分小伙伴最头疼的一部分,在此处推荐大家看一下附件5中的超级详细的中文文档,这可能会让你很头疼,但是后期一个项目想要完善就离不开这个文档,当然在接下的记录中我也是过呢根据文档来进行一步一步的来连接自己的数据!!!


1.绘制界面

我们讲图表的对象创建出来,绑定在#tv_chart_container的元素上面,接下来的事情就全部的交给JS Api,也就是自定义的Datafeed类。不要企图跳过这一段落,这是tradingview能够现在在页面中显示关键一步。下面的代码请仔细看哦,看着很多内容,但是其实很简单,从头到尾看一遍应该就会明白的。

<template>
  <div class="exchage" id="tv_chart_container"></div>
</template>

<script>
import { widget } from '../charting_library.min';
import http from '../util/http';
import Datafeed from '../util/datafeed';

// 定义变量读取参数
let datafeed;

export default {
  data(){
    return {
      // 定义参数接收接受图表
      tvWidget: null,
    }
  },
  mounted(){
  	// 创建datafeed实例,此时实例为自己编写的类,需要按照官网的规则编写
    datafeed = new Datafeed();
    // 实例化的widget里的参数都是图表的配置项,具体解析可以看一下文档,后续还有有很多的配置对tradingview进行美化,暂时我们将忽略这不无关紧要的配置。
    this.tvWidget = new widget({
      symbol: 'btc_usdt',
      datafeed,
      interval: '15',
      container_id: 'tv_chart_container',
      library_path: '/charting_library/',
      timezone: 'Asia/Shanghai',
      debug: false,
      autosize: true
    });
  }
}
</script>

<style scoped>
.exchage{
  height: calc(100vh - 80px);
}
</style>

2.编辑Datafeed类

DataFeed类有很多函数,其中思数据渲染出来关键的函数有四个,所以我们将用这四个函数来完成K线图的渲染工作。

class DataFeed {
  constructor() {

  }

  // 服务端配置
  onReady(cb) {

  }

  // 解析数据
  resolveSymbol(symbolName, onSymbolResolvedCallback, onResolveErrorCallback) {

  }

  // 渲染首次视图的数据
  getBars(symbolInfo, resolution, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) {

  }

  // 新数据更新
  subscribeBars(symbolInfo, resolution, onRealtimeCallback, listenerGuid, onResetCacheNeededCallback) {

  }
}

export default DataFeed;

onReady(callback)

此方法可以设置图表库支持的图表配置。这些数据会影响到图表支持的功能,所以它被称为服务端定制。
图表库要求您使用回调函数来传递datafeed的 configurationData参数。


以上就是官方文档的原话,我们需要通过回调函数传递一个参数,这个参数如下,特别提一下supported_resolutions参数是K线的周期数组,单位为分钟,也就是分线日线等。其他的想都不要想,继续向下写就能见证奇迹!

  onReady(cb) {
    cb({
      exchanges: [],
      symbols_types: [],
      supports_time: true,
      supported_resolutions: [1, 5, 15, 30, 60, 240, 360, 480, 720, 1440, 10080, 44640],
      supports_marks: false,
      supports_timescale_marks: false
    })
  }

resolveSymbol(…arg)

在这个函数里我们可以设置表可以显示那些数据也就是上面说的分线日线等

  resolveSymbol(symbolName, onSymbolResolvedCallback, onResolveErrorCallback) {
    var data = {
      name: symbolName,
      has_intraday: true, // 分钟数据
      has_daily: true, // 日k线数据
      has_weekly_and_monthly: true, // 月,周数据
    };

    if (!this.onSymbolResolvedCallback) {
      this.onSymbolResolvedCallback = onSymbolResolvedCallback;
    }

    setTimeout(function() {
      onSymbolResolvedCallback(data);
    }, 0);
  }

getBars(…agr)

在这个函数里我们可以设置表可以显示那些数据也就是上面说的分时线等,同时最关键的异步就是这一步可以将K线数据渲染在页面!!!

  // 渲染首次视图的数据
  getBars(symbolInfo, resolution, from, to, onHistoryCallback, onErrorCallback, firstDataRequest) {
    this.firstDataRequest = firstDataRequest;
    this.onHistoryCallback = onHistoryCallback;
    this.resolution = resolution;
    // 封装函数渲染视图
    this.history(from * 1000, to * 1000, onHistoryCallback);
  }

  // 封装渲染视图的函数
  async history(from, to, cb) {

    if (to && to < 1262275200000) {
      this.bar = [];
      cb([], {
        noData: true
      });
      return;
    }
    let bar = [];
    const step = this.resolution * 60

    if (this.firstDataRequest) {
      try {
    	// 请求k线数据
        http.send().then(res => {
          if(res.status === 200) {
            const { data } = res;
            const len = data.length;
            if(len > 0) {
              data.map(item => {
                let barValue = {};
                // 时间戳
                barValue.time = Number(item[0]);
                // 开
                barValue.open = Number(item[1]);
                // 高
                barValue.high = Number(item[2]);
                // 低
                barValue.low = Number(item[3]);
                // 收
                barValue.close = Number(item[4]);
                // 量
                barValue.volume = Number(item[5]);
                bar.push(barValue);
              })
              cb(bar, {
                noData: false
              });
            } else {
              cb([], {
                noData: true
              });
            }
          } else {
            cb([], {
              noData: true
            });
          }
        })
      } catch (err) {}
    }
    this.bar = bar;
  }

当你完成此步骤时,按下 Ctrl+S 键时,页面将会展现出K线的数据,一切都是那么妙不可言呀~

subscribeBars(…agr)

想要实现数据实时更新,你看可以使用websocket或者http轮询的方式,这里看个人选择;在subscribeBars中当您调用onRealtimeCallback且K线时间等于最新K线时间时,那么这条最新K线将被您传入的K线所替换,这样就可以实现数据实时更新,关键的问题就是怎么去调用onRealtimeCallback函数,由于本人也不知道如何去调用这个onRealtimeCallback函数,于是我便把这个函数给了一个公共的参数,把websocket推送过来的数据写在公众的数据里面,写一个轮询去执行这个函数实现数据更新。

  subscribeBars(symbolInfo, resolution, onRealtimeCallback, listenerGuid, onResetCacheNeededCallback) {
    this.onResetCacheNeededCallback = onResetCacheNeededCallback
    if (this._subscribers.hasOwnProperty(listenerGuid)) {
      return;
    }
    this._subscribers[listenerGuid] = {
      lastBarTime: null,
      listener: onRealtimeCallback,
      resolution: resolution,
      symbolInfo: symbolInfo
    };
  }
  
  // 更新
  update(listenerGuid, lastBar) {
    // 已取消监听取消追加
    if (!this._subscribers.hasOwnProperty(listenerGuid)) {
      return;
    }
    let subscriptionRecord = this._subscribers[listenerGuid];
    if (
      subscriptionRecord.lastBarTime !== null &&
      lastBar.time < subscriptionRecord.lastBarTime
    ) {
      return;
    }
    const isNewBar =
      subscriptionRecord.lastBarTime !== null &&
      lastBar.time > subscriptionRecord.lastBarTime;
    if (isNewBar) {
      subscriptionRecord.lastBarTime = lastBar.time;
    }
    subscriptionRecord.listener(lastBar);
  }

  // 循环读取实时数据
  async readTicker() {
    // ws 将数据存放在 windown.g_k_ticker 中
    if(window.g_k_ticker && window.g_k_ticker.length) {
        for (let listenerGuid in this._subscribers) {
          let item = window.g_k_ticker;
          if (item[0]) {
            let d = {
              time : parseInt(item[0]),
              open : Number(item[1]),
              high : Number(item[2]),
              low : Number(item[3]),
              close : Number(item[4]),
              volume : Number(item[5])
            };
            // 更新 tradingView 视图
            this.update(listenerGuid, d);
          }
        }
    }
    // 更新完成后清空上次的数据
    window.g_k_ticker = [];
    // 轮询延时
    await new Promise(resolve => {
      setTimeout(resolve, 300);
    });
    // 轮询
    this.readTicker();
  }

总结

一个简单的tradingview图表就这样实现了,在以上的代码中可能你会看的有点懵懂的状态,不过没关系,一步一步的写下去,一步一步的输出打印,但最后就一定会可以实现K线的功能,而接下来的就是一下UI界面的调整来适配,这些都是次要的,仔细看文档的配置就可以慢慢调整UI样式,当然如果以上的写法中有什么不足或者错误的地方欢迎在评论区浏览,看到后一定第一时间与大家互动交流~

### LlamaIndex 多模态 RAG 实现 LlamaIndex 支持多种数据类型的接入与处理,这使得它成为构建多模态检索增强生成(RAG)系统的理想选择[^1]。为了实现这一目标,LlamaIndex 结合了不同种类的数据连接器、索引机制以及强大的查询引擎。 #### 数据连接器支持多样化输入源 对于多模态数据的支持始于数据收集阶段。LlamaIndex 的数据连接器可以从多个异构资源中提取信息,包括但不限于APIs、PDF文档、SQL数据库等。这意味着无论是文本还是多媒体文件中的内容都可以被纳入到后续的分析流程之中。 #### 统一化的中间表示形式 一旦获取到了原始资料之后,下一步就是创建统一而高效的内部表达方式——即所谓的“中间表示”。这种转换不仅简化了下游任务的操作难度,同时也提高了整个系统的性能表现。尤其当面对复杂场景下的混合型数据集时,良好的设计尤为关键。 #### 查询引擎助力跨媒体理解能力 借助于内置的强大搜索引擎组件,用户可以通过自然语言提问的形式轻松获得所需答案;而对于更复杂的交互需求,则提供了专门定制版聊天机器人服务作为补充选项之一。更重要的是,在这里实现了真正的语义级关联匹配逻辑,从而让计算机具备了一定程度上的‘认知’功能去理解和回应人类意图背后所蕴含的意义所在。 #### 应用实例展示 考虑到实际应用场景的需求多样性,下面给出一段Python代码示例来说明如何利用LlamaIndex搭建一个多模态RAG系统: ```python from llama_index import GPTSimpleVectorIndex, SimpleDirectoryReader, LLMPredictor, PromptHelper, ServiceContext from langchain.llms.base import BaseLLM import os def create_multi_modal_rag_system(): documents = SimpleDirectoryReader(input_dir='./data').load_data() llm_predictor = LLMPredictor(llm=BaseLLM()) # 假设已经定义好了具体的大型预训练模型 service_context = ServiceContext.from_defaults( chunk_size_limit=None, prompt_helper=PromptHelper(max_input_size=-1), llm_predictor=llm_predictor ) index = GPTSimpleVectorIndex(documents, service_context=service_context) query_engine = index.as_query_engine(similarity_top_k=2) response = query_engine.query("请描述一下图片里的人物表情特征") print(response) ``` 此段脚本展示了从加载本地目录下各类格式文件开始直到最终完成一次基于相似度排序后的top-k条目返回全过程。值得注意的是,“query”方法接收字符串参数代表使用者想要询问的内容,而在后台则会自动调用相应的解析模块并结合先前准备好的知识库来进行推理计算得出结论。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值