trading-vue-js icon indicating copy to clipboard operation
trading-vue-js copied to clipboard

Overlays set up

Open IlyaShkurenko opened this issue 3 years ago • 3 comments

I'm pretty new in using this lib so things are confusing for me. I've read all docs but still can't figure out few things. How can I add SMA,EMA,RSI etc indicators on my chart and get calculated points? I've tried to do like this

this.onchart = [ // Displayed ON the chart
                {
                  "name": "EMA, 100",
                  "type": "EMA",
                  "data": this.ohlcv,
                  "settings": {
                    lineWidth: 1,
                    color: '#d1385c'
                  } // Arbitrary settings format
                }
              ];

but can't specify the range of days. I've also saw examples like this https://github.com/tvjsx/trading-vue-js/blob/master/docs/guide/OVERLAYS.md#null-overlay but don't understand how to include it on my chart.

IlyaShkurenko avatar May 10 '21 21:05 IlyaShkurenko

You can find the how-to in docs, but it's cleary shown on tests/examples. It's simple:

import Overlays from 'tvjs-overlays'

data() {
...
    overlays: [
            Overlays['EMA'], 
            Overlays['BB'], 
            Overlays['MACD'],
            Overlays['RSI']
     ]
      <trading-vue 
      ...
      :overlays="overlays" 
this.chart = new DataCube({
            ohlcv: data,
            onchart: [
              {
                type: 'BB', name: 'BBL', data: [],             
                settings: { lineWidth: false, color: false, backColor: false, showMid: true }
              },
              {
                type: 'EMA',name: 'EMA', data: [],
                settings: {color: "#f7890c", length: 12}
              }
            ],
            offchart: [
              {
                name: "MACD", type: "MACD", data: [],
              },
              {
                type: 'RSI', name: 'RSI', data: [],
                settings: {}
              }
            ]
          })

adsonvinicius avatar May 11 '21 13:05 adsonvinicius

You can find the how-to in docs, but it's cleary shown on tests/examples. It's simple:

import Overlays from 'tvjs-overlays'

data() {
...
    overlays: [
            Overlays['EMA'], 
            Overlays['BB'], 
            Overlays['MACD'],
            Overlays['RSI']
     ]
     <trading-vue 
     ...
     :overlays="overlays" 
this.chart = new DataCube({
           ohlcv: data,
           onchart: [
             {
               type: 'BB', name: 'BBL', data: [],             
               settings: { lineWidth: false, color: false, backColor: false, showMid: true }
             },
             {
               type: 'EMA',name: 'EMA', data: [],
               settings: {color: "#f7890c", length: 12}
             }
           ],
           offchart: [
             {
               name: "MACD", type: "MACD", data: [],
             },
             {
               type: 'RSI', name: 'RSI', data: [],
               settings: {}
             }
           ]
         })

Got it, but still not clear few moments:

  1. If I will do like you suggest can I access calculated points? Seems for this I should rewrite overlay. I need analyze all calculated points of special overlay and then draw my signals so not sure which methods needs to call.
  2. Another option it's to pass already calculated data of indicator to overlay, had success for it with RSI and SMA, but not with Stoch. I've tried to to like this but it doesn't work;
  3. for what is DataCube constructor?
const stochasticData = [{
k: 22.233633946283316, d: 40.85086679593228},
{k: 8.203779000238802,d:26.116909708452596}
{k: 30.026590880312483, d: 20.154667942278195}
{k: 32.778909725975794, d: 23.669759868842352}
{k: 43.81332557140256, d: 35.53960872589693}
{k: 13.113504373016264, d: 29.9019132234648]
 {
      "name": "Stoch",
      "type": "Stoch",
      "data": stochasticData.map(i => [i.k, i.d]),
      "settings": {
        upper: 80,
        lower: 20
      }
}

Thanks for help

IlyaShkurenko avatar May 11 '21 22:05 IlyaShkurenko

"data": stochasticData.map(i => [i.k, i.d]),

I'm guessing you'll need a timestamp to map to the x-axis.

original code: https://github.com/tvjsx/tvjs-overlays/blob/master/src/overlays/Stoch/Stoch.vue#L38

I've made some customizations.

import { Overlay } from 'trading-vue-js'
export default {
  name: 'Stochastic',
  mixins: [
    Overlay
  ],
  computed: {
    lineWidth () {
      return this.settings.lineWidth || 0.75
    },
    kWidth () {
      return this.settings.kWidth || this.lineWidth
    },
    dWidth () {
      return this.settings.dWidth || this.lineWidth
    },
    kColor () {
      return this.settings.kColor || '#0915f4'
    },
    dColor () {
      return this.settings.dColor || '#f43409'
    },
    bandColor () {
      return this.settings.bandColor || '#b5b3b3'
    },
    backColor () {
      // return this.settings.backColor || '#381e9c16'
      return 'rgba(182, 178, 184, 0.1)'
    }
  },
  methods: {
    meta_info () {
      return {
        author: 'StdSquad',
        version: '1.0.1',
        desc: this.desc
      }
    },
    draw (ctx) {
      const layout = this.$props.layout
      const upper = layout.$2screen(this.settings.upper || 80)
      const lower = layout.$2screen(this.settings.lower || 20)
      // K
      ctx.lineWidth = this.kWidth
      ctx.strokeStyle = this.kColor
      ctx.beginPath()
      for (const p of this.$props.data) {
        const x = layout.t2screen(p[0])
        const y = layout.$2screen(p[1])
        ctx.lineTo(x, y)
      }
      ctx.stroke()
      // D
      ctx.lineWidth = this.dWidth
      ctx.strokeStyle = this.dColor
      ctx.beginPath()
      for (const p of this.$props.data) {
        const x = layout.t2screen(p[0])
        const y = layout.$2screen(p[2])
        ctx.lineTo(x, y)
      }
      ctx.stroke()
      ctx.strokeStyle = this.bandColor
      ctx.setLineDash([5]) // Will be removed after draw()
      ctx.beginPath()
      // Fill the area between the bands
      ctx.fillStyle = this.backColor
      ctx.fillRect(0, upper, layout.width, lower - upper)
      // Upper band
      ctx.moveTo(0, upper)
      ctx.lineTo(layout.width, upper)
      // Lower band
      ctx.moveTo(0, lower)
      ctx.lineTo(layout.width, lower)
      ctx.stroke()
    },
    use_for () {
      return ['Stochastic']
    },
    data_colors () {
      return [this.color]
    },
    y_range (hi, lo) {
      return [
        Math.max(hi, this.settings.upper || 80),
        Math.min(lo, this.settings.lower || 20)
      ]
    },
    calc () {
      return {
        props: {
          type: {
            def: 'slow'
          },
          hiddenK: {
            def: false
          },
          hiddenD: {
            def: false
          },
          k: {
            def: 5,
            text: '%K'
          },
          d: {
            def: 3,
            text: '%D'
          },
          smooth: {
            def: 3,
            text: 'Smooth'
          }
        },
        update: `
          const fast_k_array = stoch(close, high, low, k, 'stoch')
          const fast_d_array = sma(fast_k_array, d, 'sma')
          if (type === "slow") {
            const slow_k = !hiddenK ? sma(fast_k_array, smooth, fast_k_array._id)[0] : undefined
            const slow_d = !hiddenD ? sma(fast_d_array, smooth, fast_d_array._id)[0] : undefined
            return [slow_k, slow_d]
          } else {
            return [!hiddenK ? fast_k_array[0] : undefined, !hiddenD ? fast_d_array[0] : undefined]
          }
        `
      }
    }
  }
}

Seungwoo321 avatar Apr 08 '22 12:04 Seungwoo321