diff --git a/app/demo/src/demo/algo/moon.clj b/app/demo/src/demo/algo/moon.clj index 061603a8..5bf2e1ee 100644 --- a/app/demo/src/demo/algo/moon.clj +++ b/app/demo/src/demo/algo/moon.clj @@ -76,7 +76,7 @@ {:signal-text {:type "chars" :char "!" :textColor (color :steelblue) - ;:title "moon-phase-fullmoon" ; title is not working + :title "moon-phase-fullmoon" ; title should show up in pane settings }} {:volume {:type "line" :plottype (plot-type :columns)}}] :shapes moon-phase-shapes ; fixed-shapes diff --git a/app/demo/src/demo/goldly/page/backtest.cljs b/app/demo/src/demo/goldly/page/backtest.cljs index 5e3b90a9..764a0c5f 100644 --- a/app/demo/src/demo/goldly/page/backtest.cljs +++ b/app/demo/src/demo/goldly/page/backtest.cljs @@ -6,8 +6,8 @@ [ui.highcharts :refer [highstock]] [input] [ta.tradingview.goldly.tradingview :refer [ tradingview-chart]] - [ta.tradingview.goldly.interact :refer [tv-widget-atom wrap-chart-ready add-shape]] - [ta.tradingview.goldly.interact2 :refer [set-symbol chart-active]] + [ta.tradingview.goldly.interact :refer [tv-widget-atom ]] + [ta.tradingview.goldly.interact2 :refer [set-symbol chart-active wrap-chart-ready add-shape]] [demo.goldly.lib.ui :refer [link-href]] [demo.goldly.view.backtest :refer [navs-chart navs-view roundtrips-view metrics-view]] [demo.goldly.view.aggrid :refer [study-table]] @@ -64,7 +64,7 @@ (defn add-marks-to-tv [tradingview-server] (when-let [marks (:marks tradingview-server)] ;(println "adding " (count marks) "marks to tv") - (doall (map #(add-shape (:points %) (assoc (:override %) :disableUndo true)) marks))) + (doall (map #(add-shape @tv-widget-atom (:points %) (assoc (:override %) :disableUndo true)) marks))) ) (defn clear-marks-tv [] @@ -77,7 +77,7 @@ (when (not (= [algo opts] tradingview-state)) ;(info (str "changing tv data for running algo for: " algo "opts: " opts)) (swap! algo-state assoc :tradingview-state [algo opts]) - (wrap-chart-ready + (wrap-chart-ready @tv-widget-atom (fn [] (clear-marks-tv) (set-symbol @tv-widget-atom (:symbol opts) "1D") @@ -86,7 +86,7 @@ (defn tv-data [tradingview-server] (when tradingview-server - (wrap-chart-ready + (wrap-chart-ready @tv-widget-atom (fn [] (add-marks-to-tv tradingview-server))) nil)) diff --git a/app/demo/src/demo/goldly/page/tvalgo.cljs b/app/demo/src/demo/goldly/page/tvalgo.cljs index 80819a66..651b6f26 100644 --- a/app/demo/src/demo/goldly/page/tvalgo.cljs +++ b/app/demo/src/demo/goldly/page/tvalgo.cljs @@ -1,7 +1,6 @@ (ns demo.goldly.page.tvalgo (:require [reagent.core :as r] - [re-frame.core :as rf] [goldly.service.core :refer [run-a]] [goldly.page :as page] [input] diff --git a/app/demo/src/demo/goldly/repl/tradingview/admin.clj b/app/demo/src/demo/goldly/repl/tradingview/admin.clj index 7ba17f22..2d46ff5d 100644 --- a/app/demo/src/demo/goldly/repl/tradingview/admin.clj +++ b/app/demo/src/demo/goldly/repl/tradingview/admin.clj @@ -133,4 +133,8 @@ ;widget.activeChart () .getAllShapes () .forEach (({name}) => console.log (name)); ;widget.activeChart().setPriceToBarRatio(0.7567, { disableUndo: true }); ;widget.activeChart () .getPanes () [1] .moveTo (0); -;widget.activeChart () .getTimeScaleLogicalRange () \ No newline at end of file +;widget.activeChart () .getTimeScaleLogicalRange () + + +(eval-code! + (ta.tradingview.goldly.interact2/set-layout "2h")) \ No newline at end of file diff --git a/lib/tradingview/src/ta/tradingview/chart/plot.clj b/lib/tradingview/src/ta/tradingview/chart/plot.clj index 5bc06161..ff8b8d16 100644 --- a/lib/tradingview/src/ta/tradingview/chart/plot.clj +++ b/lib/tradingview/src/ta/tradingview/chart/plot.clj @@ -80,15 +80,16 @@ (defn shape [shape-kw] (or (get shape-types shape-kw) (:cross shape-types))) - + + ;; TEXT-SIZE (def text-sizes {:auto "auto" :tiny "tiny" :small "small" :normal "normal" + :large "large" :huge "huge"}) - (defn text-size [size-kw] (or (get text-sizes size-kw) diff --git a/lib/tradingview/src/ta/tradingview/goldly/algo/indicator.cljs b/lib/tradingview/src/ta/tradingview/goldly/algo/indicator.cljs index cb46a8c0..757a4d02 100644 --- a/lib/tradingview/src/ta/tradingview/goldly/algo/indicator.cljs +++ b/lib/tradingview/src/ta/tradingview/goldly/algo/indicator.cljs @@ -30,41 +30,35 @@ (:type spec))) (def default-plot-styles - {"line" {:linestyle 0 - :visible true + {"line" {:visible true + :transparency 0 + :linestyle 0 + :trackPrice false ; Show price line (horizontal line with last price) :linewidth 2 ; Make the line thinner :plottype 2 ; Plot type is Line - :trackPrice true ; Show price line (horizontal line with last price) :color "#880000" ; Set the plotted line color to dark red - :transparency 0 } "chars" {:visible true + :transparency 0 + :trackPrice false ; Show price line (horizontal line with last price) :char "*" :location "AboveBar" ; AboveBar BelowBar Top Bottom Right Left Absolute AbsoluteUp AbsoluteDown - :trackPrice false ; Show price line (horizontal line with last price) :textColor "#ffff00" ; Set the plotted line color to dark red + :size "small"} + "shape" {:visible true :transparency 0 - :size "small" - } - "cols" {:linestyle 0 - :visible true - :linewidth 1 ; Make the line thinner - :plottype 5 ; Plot type is Column - :trackPrice false ; Show price line (horizontal line with last price) - :color "#880000" ; Set the plotted line color to dark red - :transparency 0 - } + :trackPrice false ; Show price line (horizontal line with last price) + :style "xcross" + :location "AboveBar" ; AboveBar BelowBar Top Bottom Right Left Absolute AbsoluteUp AbsoluteDown + + :color "#880000" ; Set the plotted line color to dark red + :textColor "#ffff00"} "arrows" {:visible true - :colorup "#880000" - :colordown "#00ff00" :transparency 0 - } - - ;"chars" {:visible true - ; :char "X" - ; :location "AboveBar" - ; :color "#880000" - ; } + :trackPrice false + :location "AboveBar" ; AboveBar BelowBar Top Bottom Right Left Absolute AbsoluteUp AbsoluteDown + :colorup "#880000" + :colordown "#00ff00"} }) diff --git a/lib/tradingview/src/ta/tradingview/goldly/algo/indicator_config.cljs b/lib/tradingview/src/ta/tradingview/goldly/algo/indicator_config.cljs index cfd1c8be..b7b2e840 100644 --- a/lib/tradingview/src/ta/tradingview/goldly/algo/indicator_config.cljs +++ b/lib/tradingview/src/ta/tradingview/goldly/algo/indicator_config.cljs @@ -3,23 +3,15 @@ [promesa.core :as p] [goldly.service.core :refer [clj]] [ta.tradingview.goldly.indicator.bar-colorer :refer [study-bar-colorer]] - [ta.tradingview.goldly.indicator.clj :refer [study-clj]] - [ta.tradingview.goldly.indicator.clj-main :refer [study-clj-main]] - [ta.tradingview.goldly.indicator.clj-col :refer [study-clj-col]] - [ta.tradingview.goldly.indicator.clj-char :refer [study-clj-char]] [ta.tradingview.goldly.algo.indicator :refer [study-chart-studies all-algo->studies]] - [ta.tradingview.goldly.algo.context :as c] - )) + [ta.tradingview.goldly.algo.context :as c])) (defn custom-indicator-promise [PineJS] (println "custom-indicator-promise getter running...") (let [s (clj->js [study-bar-colorer ;(js/equitystudy PineJS) - (study-clj PineJS) - (study-clj-main PineJS) - (study-clj-col PineJS) - (study-clj-char PineJS)])] + ])] (set! (.-pine js/window) PineJS) (.log js/console s) (.resolve js/Promise s))) diff --git a/lib/tradingview/src/ta/tradingview/goldly/feed/algo.cljs b/lib/tradingview/src/ta/tradingview/goldly/feed/algo.cljs deleted file mode 100644 index 8144ebb4..00000000 --- a/lib/tradingview/src/ta/tradingview/goldly/feed/algo.cljs +++ /dev/null @@ -1,188 +0,0 @@ -(ns ta.tradingview.goldly.feed.algo - (:require - [goldly.service.core :refer [run-cb]] - [ta.tradingview.goldly.interact :as interact] - [ta.tradingview.goldly.helper :refer [extract-period]] - )) - -(defn study-col? [symbol] - (.includes symbol "#")) - -(defn study-col [symbol] - (let [a (.split symbol "#") - symbol (aget a 0) - col (aget a 1)] - {:symbol symbol - :col col})) - -(defn convert-bar [b] - {:time (* 1000 (:epoch b)) - :open (:open b) - :high (:high b) - :low (:low b) - :close (:close b) - :volume (:volume b) - :isBarClosed true - :isLastBar false}) - -(defn convert-bars [bars] - (->> (map convert-bar bars) - (into []) - (clj->js))) - -(defn convert-col-bar [col b] - {:time (* 1000 (:epoch b)) - :open (col b) - :high (col b) - :low (col b) - :close (col b) - :volume (col b) - :isBarClosed true - :isLastBar false}) - -(defn convert-col-bars [col bars] - (let [col (keyword col)] - ;(println "convert-col-bars " col) - (->> (map #(convert-col-bar col %) bars) - (into []) - (clj->js)))) - - - - -(defn request-shapes [algo symbol frequency options epoch-start epoch-end] - (let [cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - batch-add (fn [] - (doall - (map #(interact/add-shape (:points %) (:override %)) result)))] - ;(println "SHAPES RCVD: " result) - ;[{:points [{:time 1649791880}], :override {:shape vertical_line}} - (js/setTimeout batch-add 1300)))] - - ;(println "GETTING SHAPES" algo epoch-start epoch-end) - (run-cb {:fun 'ta.algo.manager/algo-shapes - :args [algo symbol frequency options epoch-start epoch-end] - :cb cb}))) - - - -(defn tradingview-algo-feed [get-algo-and-options] - ;(println "tradingview-algo-feed setup ..") - (clj->js - {:onReady (fn [onConfigCallback] - (let [cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - result-js (clj->js result)] - ;(println "TV CONFIG: " result) - (onConfigCallback result-js)))] - ;(println "TV/CONFIG..") - (run-cb {:fun 'ta.tradingview.handler-datasource/get-server-config - :args {} - :cb cb}))) - :searchSymbols (fn [userInput exchange symbolType onResultReadyCallback] - ;(println "TV/SEARCH " userInput exchange symbolType) - (let [query userInput - type symbolType - limit 10 - cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - result-js (clj->js result)] - ;(println "TV SYMBOL SEARCH: " result) - (onResultReadyCallback result-js)))] - (run-cb {:fun 'ta.tradingview.handler-datasource/symbol-search - :args [query type exchange limit] - :cb cb}))) - :resolveSymbol (fn [symbolName onSymbolResolvedCallback _onResolveErrorCallback] - ;(println "TV/resolve symbol" symbolName) - (let [cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - result-js (clj->js result)] - ;(println "TV SYMBOL INFO: " result) - (onSymbolResolvedCallback result-js)))] - (run-cb {:fun 'ta.tradingview.handler-datasource/symbol-info - :args [symbolName] ; {:symbol symbolName} - :cb cb}))) - :getBars (fn [symbolInfo resolution period onHistoryCallback _onErrorCallback] - (let [period-clj (extract-period period) - epoch-start (:from period-clj) - epoch-end (:to period-clj) - - frequency (if (= resolution "1D") - "D" - resolution) - symbol-info-clj (js->clj symbolInfo :keywordize-keys true) - symbol (:ticker symbol-info-clj) - ;algo (or (get-algo) "buy-hold") - ;options {} - {:keys [algo options]} (get-algo-and-options) - study? (study-col? symbol) - col (when study? (:col (study-col symbol))) - symbol (if study? (:symbol (study-col symbol)) symbol)] - (if study? - (println "study col: " col) - (request-shapes algo symbol frequency options epoch-start epoch-end)) - ;(println "GET-BARS" symbol-info-clj resolution period-clj "study: " study?) - (let [cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - ;result-js (clj->js result) - ] - ;(println "TV BARS: " result) - (let [bars-tv (if study? - (convert-col-bars col result) - (convert-bars result))] - ;(println "TV BARS CONVERTED: " bars-tv) - (onHistoryCallback bars-tv))))] - (run-cb {:fun 'ta.algo.manager/run-window-browser - :args [algo symbol frequency options epoch-start epoch-end] - :cb cb})))) - :subscribeBars (fn [symbolInfo resolution _onRealtimeCallback subscribeUID _onResetCacheNeededCallback] - ;(println "subscribe: " symbolInfo resolution subscribeUID) - ) - :unsubscribeBars (fn [subscriberUID] - ;(println "unsubscribe: " subscriberUID) - ) - :getServerTime (fn [onTimeCallback] - (let [cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - result-js (clj->js result)] - ;(println "TV TIME: " result) - (onTimeCallback result-js)))] - ;(println "TV/TIME") - (run-cb {:fun :tv/time - :args [] - :cb cb}))) - :calculateHistoryDepth (fn [resolution resolutionBack intervalBack] - (println "calculate history depth:" resolution resolutionBack intervalBack)) - - :getMarks (fn [symbolInfo startDate endDate onDataCallback resolution] - (let [;period-clj (extract-period period) - epoch-start startDate ; (:from period-clj) - epoch-end endDate ; (:to period-clj) - frequency (if (= resolution "1D") - "D" - resolution) - symbol-info-clj (js->clj symbolInfo :keywordize-keys true) - symbol (:ticker symbol-info-clj) - {:keys [algo options]} (get-algo-and-options) - ;algo (or (get-algo) "buy-hold") - ;options {} - cb (fn [[_ data]] ; _ = event-type - (let [{:keys [result _error]} data - result-js (clj->js result)] - ;(println "TV MARKS: " result) - (onDataCallback result-js)))] - ;(println "TV MARKS: algo" algo symbol startDate endDate frequency) - (run-cb {:fun 'ta.algo.manager/algo-marks - :args [algo symbol frequency options epoch-start epoch-end] - :cb cb}))) - :getTimeScaleMarks (fn [symbolInfo startDate endDate _onDataCallback resolution] - ;(println "get-timescale-marks" symbolInfo startDate endDate resolution) - ) - :about "algo-feed"})) - - -(defn get-tradingview-options-algo-feed [get-algo-and-options] - (fn [] - {:datafeed (tradingview-algo-feed get-algo-and-options) - :charts_storage_url "/api/tv/storage"})) diff --git a/lib/tradingview/src/ta/tradingview/goldly/feed/algo2.cljs b/lib/tradingview/src/ta/tradingview/goldly/feed/algo2.cljs index bf9982a7..0b68b478 100644 --- a/lib/tradingview/src/ta/tradingview/goldly/feed/algo2.cljs +++ b/lib/tradingview/src/ta/tradingview/goldly/feed/algo2.cljs @@ -2,7 +2,8 @@ (:require [promesa.core :as p] [goldly.service.core :refer [run-cb clj]] - [ta.tradingview.goldly.interact :as interact] + [ta.tradingview.goldly.interact2 :refer [add-shape]] + [ta.tradingview.goldly.interact :refer [tv-widget-atom]] [ta.tradingview.goldly.helper :refer [extract-period]] [ta.tradingview.goldly.algo.context :as c])) @@ -100,7 +101,7 @@ (let [{:keys [result _error]} data batch-add (fn [] (doall - (map #(interact/add-shape (:points %) (:override %)) result)))] + (map #(add-shape @tv-widget-atom (:points %) (:override %)) result)))] ;(println "SHAPES RCVD: " result) ;[{:points [{:time 1649791880}], :override {:shape vertical_line}} (js/setTimeout batch-add 1300)))] diff --git a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj.cljs b/lib/tradingview/src/ta/tradingview/goldly/indicator/clj.cljs deleted file mode 100644 index 0da11232..00000000 --- a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj.cljs +++ /dev/null @@ -1,78 +0,0 @@ -(ns ta.tradingview.goldly.indicator.clj) - - -(def clj-meta - {:_metainfoVersion 51 - :id "clj@tv-basicstudies-1" - :name "CLJ" - :description "CLJ" ; this is used in the api - :shortDescription "CLJ DESC" - "isCustomIndicator" true - "is_price_study" false ; plot in main chart-pane - "isTVScript" false - "isTVScriptStub" false - "format" {"type" "price" - "precision" 4} - "plots" [{"id" "plot_0" - "type" "line"}] - "defaults" {"styles" {"plot_0" {"linestyle" 0 - "visible" true - "linewidth" 1 ; Make the line thinner - "plottype" 2 ; Plot type is Line - "trackPrice" true ; Show price line (horizontal line with last price) - "color" "#880000" ; Set the plotted line color to dark red - }}} - - "inputs" [{"id" "col" - "name" "col" - "type" "text" ; "integer" - "defval" "#close"}] - - "styles" {"plot_0" {"title" "algo column value" ; Output name will be displayed in the Style window - "histogramBase" 0}}}) - - -(defn clj-study-runner [PineJS] - (fn [] - (clj->js - {:init (fn [context inputCallback] - (let [main-symbol (-> PineJS .-Std (.ticker context)) - col (or (inputCallback 0) "close") - symbol (str main-symbol "#" col) - p (-> PineJS .-Std (.period context)) ;PineJS.Std.period (this._context) - ] - ;(println "CLJ INIT! PERIOD: " p "SYMBOL: " main-symbol "COL: " col) ; called 1x - ;(.log js/console inputCallback) - ;(.log js/console context) - - ;this._context = context; - ;this._input = inputCallback; - (.new_sym context symbol "D") - nil)) - :main (fn [context _inputCallback] - ;(println "CLJ MAIN!") ; called for EACH BAR. - (.select_sym context 1) ;this._context.select_sym (1); - (let [v (-> PineJS .-Std (.close context)) ;var v = PineJS.Std.close (this._context); - ;t (-> PineJS .-Std (.updatetime context)) ;var v = PineJS.Std.updatetime (this._context); - ;(this._context['symbol']['time'] !=NaN){ - ;X (aget context "symbol") - ;t (aget X "time") - ;year (-> PineJS .-Std (.year context)) - ;month (-> PineJS .-Std (.month context)) - ;day (-> PineJS .-Std (.dayofmonth context)) - ; updatetime - ;main-symbol (-> PineJS .-Std (.ticker context)) - ] - ;(println "VALUE: " v "SYMBOL: " main-symbol "TIME:" t ) ;year "-" month "-" day - ;this._context = context; - ;this._input = inputCallback; - #js [v]))}))) - - - - -(defn study-clj [PineJS] - (clj->js - {:name "CLJ" - :metainfo clj-meta - :constructor (clj-study-runner PineJS)})) diff --git a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_char.cljs b/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_char.cljs deleted file mode 100644 index c4567f59..00000000 --- a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_char.cljs +++ /dev/null @@ -1,32 +0,0 @@ -(ns ta.tradingview.goldly.indicator.clj-char - (:require - [ta.tradingview.goldly.indicator.clj :refer [clj-meta clj-study-runner ]]) - ) - -(def clj-meta-char - (merge - clj-meta - {:id "cljchar@tv-basicstudies-1" - :name "CLJCHAR" - :description "CLJCHAR" ; this is used in the api - :shortDescription "CLJCHAR DESC" - "is_price_study" true - "plots" [{"id" "plot_0" - "type" "chars"}] - "defaults" {"styles" {"plot_0" {"linestyle" 0 - "visible" true - "char" "*" - "title" "bongo" - "location" "AboveBar" ; AboveBar BelowBar Top Bottom Right Left Absolute AbsoluteUp AbsoluteDown - "linewidth" 1 ; Make the line thinner - "plottype" 2 ; Plot type is Line - "trackPrice" false ; Show price line (horizontal line with last price) - "color" "#880000" ; Set the plotted line color to dark red - }}}})) - - -(defn study-clj-char [PineJS] - (clj->js - {:name "CLJCHAR" - :metainfo clj-meta-char - :constructor (clj-study-runner PineJS)})) \ No newline at end of file diff --git a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_col.cljs b/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_col.cljs deleted file mode 100644 index 9cc62681..00000000 --- a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_col.cljs +++ /dev/null @@ -1,19 +0,0 @@ -(ns ta.tradingview.goldly.indicator.clj-col - (:require - [ta.tradingview.goldly.indicator.clj :refer [clj-meta clj-study-runner]])) - -(def clj-meta-col - (merge - (assoc-in clj-meta - ["defaults" "styles" "plot_0" "plottype"] 5) ; 5- columns - {:id "cljcol@tv-basicstudies-1" - :name "CLJCOL" - :description "CLJCOL" ; this is used in the api - :shortDescription "CLJCOL DESC" - "is_price_study" false})) - -(defn study-clj-col [PineJS] - (clj->js - {:name "CLJCOL" - :metainfo clj-meta-col - :constructor (clj-study-runner PineJS)})) diff --git a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_main.cljs b/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_main.cljs deleted file mode 100644 index 0ab47530..00000000 --- a/lib/tradingview/src/ta/tradingview/goldly/indicator/clj_main.cljs +++ /dev/null @@ -1,19 +0,0 @@ -(ns ta.tradingview.goldly.indicator.clj-main - (:require - [ta.tradingview.goldly.indicator.clj :refer [clj-meta clj-study-runner]])) - - -(def clj-meta-main - (merge clj-meta - {:id "cljmain@tv-basicstudies-1" - :name "CLJMAIN" - :description "CLJMAIN" ; this is used in the api - :shortDescription "CLJMAIN DESC" - "is_price_study" true})) - - -(defn study-clj-main [PineJS] - (clj->js - {:name "CLJMAIN" - :metainfo clj-meta-main - :constructor (clj-study-runner PineJS)})) \ No newline at end of file diff --git a/lib/tradingview/src/ta/tradingview/goldly/interact.cljs b/lib/tradingview/src/ta/tradingview/goldly/interact.cljs index 626a7be1..20d891f9 100644 --- a/lib/tradingview/src/ta/tradingview/goldly/interact.cljs +++ b/lib/tradingview/src/ta/tradingview/goldly/interact.cljs @@ -1,215 +1,21 @@ (ns ta.tradingview.goldly.interact (:require - [reagent.core :as r]) - ) + [reagent.core :as r] + [ta.tradingview.goldly.interact2 :as i])) -(defn extract-range [r] - (let [from (.-from r) - to (.-to r)] - {:from from :to to})) - (defonce state (r/atom {})) (def tv-widget-atom (r/atom nil)) -(defn chart-active [] - (.activeChart @tv-widget-atom)) - - - -; window.tvWidget.activeChart().dataReady(() => { - -(defn wrap-chart-ready [f] - ; It's now safe to call any other methods of the widget - (.onChartReady @tv-widget-atom f)) - -; (wrap-chart-ready (fn [] (println "chart ready!"))) - -(defn wrap-header-ready [f] - (.headerReady @tv-widget-atom f)) - -; (wrap-header-ready (fn [] (println "header ready!"))) - -(defn add-header-button [text tooltip on-click-fn] - (let [options (clj->js nil) - button (.createButton @tv-widget-atom options)] - ;(println "button: " button) - (set! (.-textContent button) text) - (set! (.-title button) tooltip) - (.addEventListener button "click" on-click-fn))) - - -(defn get-symbol [] - (let [i (.symbolInterval @tv-widget-atom) - symbol (.-symbol i) - interval (.-interval i)] - ;(println "symbol: " symbol "interval: " interval) - {:symbol symbol :interval interval})) - -; .symbolExt () - -(defn on-crosshair-moved [f] - (let [chart (chart-active) - cross-hair (.crossHairMoved chart)] - (.subscribe cross-hair nil f))) - -(defn print-position [r] - (let [price (.-price r) - time (.-time r) - position {:price price :time time}] - ;(set! (.-bongo js/globalThis) r) - ;(println "tv pos: " position) - (swap! state assoc :position position))) - -(defn demo-crosshair [] - (on-crosshair-moved print-position)) - - - - - -(defn get-range [] - ; getVisibleRange () - ; Returns the object {from, to} . from and to are Unix timestamps in the timezone of the chart. - (let [chart (chart-active)] - (-> (.getVisibleRange chart) - (extract-range)))) - -; getVisiblePriceRange () -; Returns the object {from, to} . from and to are boundaries of the price scale visible range in main series area. -; Date.UTC (2018, 0, 1) / 1000 - -(defn set-range [{:keys [_from _to] :as range} opts] ; Date.UTC (2012, 2, 3) / 1000, - (let [chart (chart-active) - range-js (clj->js range) - opts (or opts {}) - opts-js (clj->js opts)] - (-> (.setVisibleRange chart range-js opts-js)))) - - +; in scratchpad: +; (show-tradingview-widget "scratchpadtest" {:feed :ta}) +;@tv-widget-atom -(defn on-range-change [f] - (let [chart (chart-active) - visible-range (.onVisibleRangeChanged chart) - on-change (fn [r] - (f (extract-range r)))] - (.subscribe visible-range nil on-change))) (defn track-range [] (let [f (fn [{:keys [_from _to] :as vis-range}] ;(.log js/console "visible range changed from: " from "to: " to) (swap! state assoc :range vis-range))] - (swap! state assoc :range (get-range)) - (on-range-change f))) - -(defn show-features [] - (let [features (.getAllFeatures @tv-widget-atom)] - (.keys js/Object features))) - - - -(defn refresh-marks [_f] - (let [chart (chart-active)] - ;(println "refreshing marks..") - (.refreshMarks chart) - nil)) - -;; - -(defn add-shape [points shape] - (let [chart (chart-active) - points-js (clj->js points) - shape-js (clj->js shape)] - ;(println "ADDING SHAPE: " points shape) - (let [id (.createMultipointShape chart points-js shape-js)] - ;(println "SHAPE ADDED: " id) - (.log js/console shape-js) - (.log js/console points-js) - id))) - -(defn get-shape-properties [id] - ; widget.activeChart () .getShapeById ('YGC4tE') .getProperties () - (let [chart (chart-active) - shape (.getShapeById chart id) - props (.getProperties shape)] - (.log js/console "SHAPE PROPS: " props) - ;props - nil)) - - - - - - -(defonce tv-data (r/atom nil)) - -(defn on-save [data] - ;(println "chart saved to: window.data") - (.log js/console data) - (reset! tv-data data) - (set! (.-data js/globalThis) data)) - -(defn save-chart [] - ;(println "saving chart..") - (.save @tv-widget-atom on-save) - ;nil - "started saving chart..") - -(defn get-chart [] - ;data.pa [0] .charts - (let [d @tv-data - ;pa (.-pa d) - ;d-clj (js->clj d) - ;d-clj (jsx->clj d) - ;charts (:charts d-clj) - ;charts-clj (jsx->clj charts) - ] - ;(println "get-chart: ") - (.log js/console d) - ;(println d-clj) - ;(println charts-clj) - ;d-clj - (.stringify js/JSON d))) - -(defn add-context-menu [menu] - (let [;chart (chart-active) - menu-js (clj->js menu) - add-context-menu (fn [unixtime _price] - ;(println "adding menu: " menu) - ;(println "args: " unixtime) - menu-js)] - ;(println "adding menu: phase1: " menu) - ;(println "menu-js: " menu-js) - (.onContextMenu @tv-widget-atom add-context-menu))) - - -(defn add-series [location [k v]] ; "CLJ" [:trade "column"] - ;(println "adding col:" k "to: " location "value: " v) - ;(if (= v "column") - ;(add-study (str location "COL") [k]) ; v = plot type. this is ignored. - ;(add-study location [k]) ; v = plot type. this is ignored. -; ) -) - -(defn add-plot [location plot] - ;(println "adding plot " plot " to: " location) - ;[{:trade "flags"}] - (doall - (map #(add-series location %) plot))) - -(defn add-algo-studies [plots] - ;(println "add-algo-studies: " plots) - ;(remove-all-studies) - (let [plot-main (first plots) - plots (rest plots)] - (when plot-main - (add-plot "CLJMAIN" plot-main)) - (doall - (map #(add-plot "CLJ" %) plots)))) - - - -; in scratchpad: -; (show-tradingview-widget "scratchpadtest" {:feed :ta}) -;@tv-widget-atom + (swap! state assoc :range (i/get-range @tv-widget-atom)) + (i/on-range-change @tv-widget-atom f))) diff --git a/lib/tradingview/src/ta/tradingview/goldly/interact2.cljs b/lib/tradingview/src/ta/tradingview/goldly/interact2.cljs index 45513fbd..59137953 100644 --- a/lib/tradingview/src/ta/tradingview/goldly/interact2.cljs +++ b/lib/tradingview/src/ta/tradingview/goldly/interact2.cljs @@ -55,4 +55,171 @@ ;(println "remove-all-studies") (let [chart (chart-active tv)] (.removeAllStudies chart) - nil)) \ No newline at end of file + nil)) + +; crosshair-moved + +(defn- get-position [r] + (let [price (.-price r) + time (.-time r)] + {:price price :time time})) + + +(defn on-crosshair-moved [tv f] + (let [chart (chart-active tv) + cross-hair (.crossHairMoved chart) + wrapped-f (fn [r] + (let [r-clj (get-position r)] + (f r-clj))) + ] + (.subscribe cross-hair nil wrapped-f))) + +; RANGE + +(defn- extract-range [r] + (let [from (.-from r) + to (.-to r)] + {:from from :to to})) + +(defn get-range [tv] + ; getVisibleRange () + ; Returns the object {from, to} . from and to are Unix timestamps in the timezone of the chart. + (let [chart (chart-active tv)] + (-> (.getVisibleRange chart) + (extract-range)))) + + +; getVisiblePriceRange () +; Returns the object {from, to} . from and to are boundaries of the price scale visible range in main series area. +; Date.UTC (2018, 0, 1) / 1000 + +(defn set-range [tv {:keys [_from _to] :as range} opts] ; Date.UTC (2012, 2, 3) / 1000, + (let [chart (chart-active tv) + range-js (clj->js range) + opts (or opts {}) + opts-js (clj->js opts)] + (-> (.setVisibleRange chart range-js opts-js)))) + + + +(defn on-range-change [tv f] + (let [chart (chart-active tv) + visible-range (.onVisibleRangeChanged chart) + wrapped-f (fn [r] + (f (extract-range r)))] + (.subscribe visible-range nil wrapped-f))) + +;; features + +(defn show-features [tv] + (let [features (.getAllFeatures tv)] + (.keys js/Object features))) + +;; EVENTS + +; window.tvWidget.activeChart().dataReady(() => { + +(defn wrap-chart-ready [tv f] + ; It's now safe to call any other methods of the widget + (.onChartReady tv f)) + +; (wrap-chart-ready (fn [] (println "chart ready!"))) + +(defn wrap-header-ready [tv f] + ; A promise that resolves if and when the header is ready to be used. + ; headerReady() => Promise + (.headerReady tv f)) + + +;; SHAPE + +(defn add-shape [tv points shape] + (println "ADDING SHAPE: " points shape) + (let [chart (chart-active tv) + points-js (clj->js points) + shape-js (clj->js shape) + id (.createMultipointShape chart points-js shape-js)] + (.log js/console shape-js) + (.log js/console points-js) + id)) + +(defn get-shape-properties [tv id] + ; widget.activeChart () .getShapeById ('YGC4tE') .getProperties () + (let [chart (chart-active tv) + shape (.getShapeById chart id) + props (.getProperties shape)] + (.log js/console "SHAPE PROPS: " props) + ;props + nil)) + +;; MARKS + +(defn refresh-marks [tv _f] + (let [chart (chart-active tv)] + ;(println "refreshing marks..") + (.refreshMarks chart) + nil)) + +;; SYMBOL + +(defn get-symbol-and-interval [tv] + (let [i (.symbolInterval tv) + symbol (.-symbol i) + interval (.-interval i)] + ;(println "symbol: " symbol "interval: " interval) + {:symbol symbol :interval interval})) + +; .symbolExt () + +;; CHART + +(defn save-chart [tv f] + ;(println "saving chart..") + (let [wrapped-f (fn [d] + (.stringify js/JSON d) + )] + (.save tv wrapped-f) + )) + +;; MENU + +(defn add-header-button [tv text tooltip on-click-fn] + (let [options (clj->js nil) + ;var button = widget.createButton (); + button (.createButton tv options)] ; + ;(println "button: " button) + ; button.textContent = 'My custom button caption'; + (set! (.-textContent button) text) + ; button.setAttribute('title', 'My custom button tooltip'); + (set! (.-title button) tooltip) + ; button.addEventListener('click', function() { alert("My custom button pressed!"); }); + (.addEventListener button "click" on-click-fn))) + +(defn add-context-menu [tv menu] + (let [;chart (chart-active) + menu-js (clj->js menu) + add-context-menu (fn [unixtime _price] + ;(println "adding menu: " menu) + ;(println "args: " unixtime) + menu-js)] + ;(println "adding menu: phase1: " menu) + ;(println "menu-js: " menu-js) + (.onContextMenu tv add-context-menu))) + +;; DEBUG + +(defn set-debug-mode [tv enabled?] + (println "set-debug-mode: " enabled?) + (.setDebugMode tv enabled?)) + + +;; LAYOUT + +;; Widget does not support Layout. +;; TradingTerminal does support it. + +#_(defn set-layout [tv layout] + (println "set-layout: " layout) + ; layout A string representation of the new layout type. E.g. '2h' for two charts split vertically. + ; ​"2h" | "2v" | "2-1" | "3s" | "3h" | "3v" | "4" | "6" | "8" | "1-2" | "3r" | "4h" | "4v" | "4s" | "5h" | "6h" | "7h" | "8h" | "1-3" | "2-2" | "2-3" | "1-4" | "5s" | "6c" | "8c" | "10c5" | "12c6" | "12c4" | "14c7" | "16c8" | "16c4" + (.setLayout tv layout)) diff --git a/lib/tradingview/tradingview.md b/lib/tradingview/tradingview.md index c7b8d06e..c3dda90f 100644 --- a/lib/tradingview/tradingview.md +++ b/lib/tradingview/tradingview.md @@ -1,6 +1,10 @@ +https://github.com/bitblockart/tradingview-charting-library + +https://www.tradingview.com/pine-script-docs +https://www.tradingview.com/pine-script-reference +https://www.tradingview.com/charting-library-docs/latest https://www.tradingcode.net/ -https://github.com/bitblockart/tradingview-charting-library \ No newline at end of file