From 1a330b73ee4f83a4190e4883bf0fed79c0fab7cd Mon Sep 17 00:00:00 2001 From: awb99 Date: Wed, 27 Mar 2024 17:21:07 -0500 Subject: [PATCH] indicator: MAD --- lib/indicator/src/ta/indicator/rolling.clj | 41 ++++++++++++- lib/indicator/src/ta/indicator/ta4j/ta4j.clj | 1 - lib/indicator/test/ta/indicator/atr_test.clj | 21 +++---- .../test/ta/indicator/bollinger_test_bad.clj | 5 +- .../test/ta/indicator/stats_test.clj | 57 +++++++++++++++++++ .../test/ta/indicator/stats_test_bad.clj | 48 ---------------- lib/math/src/ta/math/stats.clj | 53 +++++++++++++++++ 7 files changed, 163 insertions(+), 63 deletions(-) create mode 100644 lib/indicator/test/ta/indicator/stats_test.clj delete mode 100644 lib/indicator/test/ta/indicator/stats_test_bad.clj diff --git a/lib/indicator/src/ta/indicator/rolling.clj b/lib/indicator/src/ta/indicator/rolling.clj index d5b3ae65..78139f42 100644 --- a/lib/indicator/src/ta/indicator/rolling.clj +++ b/lib/indicator/src/ta/indicator/rolling.clj @@ -3,7 +3,9 @@ [tech.v3.dataset.rolling :as r] [tech.v3.datatype.functional :as dfn] [tablecloth.api :as tc] - [ta.indicator.returns :as ret])) + [ta.indicator.returns :as ret] + [ta.math.stats :as stats] + )) (defn rolling-window-reduce [rf n vec] (let [ds (tc/dataset {:in vec})] @@ -25,6 +27,36 @@ [n v] (rolling-window-reduce r/min n v)) + +(defn trailing-variance + "returns the trailing-variance over n bars of column v. + the current row is included in the window." + [n v] + (rolling-window-reduce r/variance n v)) + + +(defn trailing-variance-population + "returns the trailing mean-deviaton over n bars of column v. + the current row is included in the window." + [n v] + (rolling-window-reduce (fn [col-name] + {:column-name col-name + :reducer stats/variance-population + :datatype :float64}) + n v)) + + + +(defn trailing-mad + "returns the trailing mean-deviaton over n bars of column v. + the current row is included in the window." + [n v] + (rolling-window-reduce (fn [col-name] + {:column-name col-name + :reducer stats/mad + :datatype :float64}) + n v)) + (defn trailing-return-stddev "returns the trailing-stddev over n bars of column v. the current row is included in the window." @@ -87,6 +119,13 @@ (trailing-return-stddev 3 ds) + (trailing-mad 2 (:close ds)) + ; tmd-1: 1.1 + 2.2 = 3.3 / 2 = 1.65 - 2.2 = -0.55 + + (rolling-window-reduce + r/min + 2 + (:close ds)) ; ) diff --git a/lib/indicator/src/ta/indicator/ta4j/ta4j.clj b/lib/indicator/src/ta/indicator/ta4j/ta4j.clj index 259a8e46..9ee148d1 100644 --- a/lib/indicator/src/ta/indicator/ta4j/ta4j.clj +++ b/lib/indicator/src/ta/indicator/ta4j/ta4j.clj @@ -34,7 +34,6 @@ (defn ind-helper [sub-ns class-key & args] (let [namespace (str "org.ta4j.core.indicators." sub-ns ".") - _ (println "namespace: " namespace) ctor (constructor namespace "Indicator")] (ctor class-key args))) diff --git a/lib/indicator/test/ta/indicator/atr_test.clj b/lib/indicator/test/ta/indicator/atr_test.clj index 76249d9b..e70f2ae4 100644 --- a/lib/indicator/test/ta/indicator/atr_test.clj +++ b/lib/indicator/test/ta/indicator/atr_test.clj @@ -12,25 +12,22 @@ (deftest test-atr (is (all-fuzzy= 0.1 - (ta4j/bar ds :ATR 4) - (->> (ind/atr-mma {:n 4} ds) (into [])) - ))) + (ta4j/bar ds :ATR 4) + (->> (ind/atr-mma {:n 4} ds) (into []))))) - -(comment +(comment (ind/tr ds) (->> (ind/atr {:n 4} ds) - (into [])) + (into [])) (ind/sma {:n 4} [30.0 30.0 40.0 40.0]) - + (->> (ind/atr-mma {:n 4} ds) - (into []) - ) - - (ta4j/bar ds :ATR 4) - + (into [])) + + (ta4j/bar ds :ATR 4) + ; ) diff --git a/lib/indicator/test/ta/indicator/bollinger_test_bad.clj b/lib/indicator/test/ta/indicator/bollinger_test_bad.clj index 4b4a525a..38c6be94 100644 --- a/lib/indicator/test/ta/indicator/bollinger_test_bad.clj +++ b/lib/indicator/test/ta/indicator/bollinger_test_bad.clj @@ -3,7 +3,10 @@ [ta.indicator.util.fuzzy :refer [all-fuzzy=]] [ta.indicator.util.ta4j :as ta4j] [ta.indicator.util.data :refer [ds]] - [ta.indicator.band :as band])) + [ta.indicator.band :as band]) + (:import [org.ta4j.core BaseStrategy #_BaseTimeSeries$SeriesBuilder + ;TimeSeriesManager + ])s) ; ta4j calculates bollinger via facade; diff --git a/lib/indicator/test/ta/indicator/stats_test.clj b/lib/indicator/test/ta/indicator/stats_test.clj new file mode 100644 index 00000000..2427ef91 --- /dev/null +++ b/lib/indicator/test/ta/indicator/stats_test.clj @@ -0,0 +1,57 @@ +(ns ta.indicator.stats-test + (:require [clojure.test :refer :all] + [ta.indicator.util.fuzzy :refer [all-fuzzy=]] + [ta.indicator.util.ta4j :as ta4j] + [ta.indicator.util.data :refer [ds]] + [ta.indicator.rolling :as roll] + [tech.v3.datatype.functional :as dfn])) + +(deftest test-mad-2 + (is (all-fuzzy= + (ta4j/close ds :statistics/MeanDeviation 2) + (roll/trailing-mad 2 (:close ds))))) + +(deftest test-mad-3 + (is (all-fuzzy= + (-> (ta4j/close ds :statistics/MeanDeviation 3) rest rest) + (-> (roll/trailing-mad 3 (:close ds)) rest rest)))) + +(deftest test-mad-4 + (is (all-fuzzy= + (-> (ta4j/close ds :statistics/MeanDeviation 4) rest rest rest) + (-> (roll/trailing-mad 4 (:close ds)) rest rest rest)))) + + + +#_(deftest test-stddev + (is (all-fuzzy= 0.1 + (ta4j/close ds :statistics/StandardDeviation 4) + (->> (roll/trailing-stddev 4 ds) (into [])) + ;(-> (ind/atr-mma {:n 4} ds) (round)) + ))) +(comment + (ta4j/close ds :statistics/MeanDeviation 2) + (roll/trailing-mad 2 (:close ds)) + + (ta4j/close ds :statistics/Variance 2) + ;; => (0.0 0.25 193.55555555555554 259.25 216.5 54.1875 85.6875 116.0 230.75 200.75 17.1875 17.1875 54.6875 92.1875 50.0) + + (roll/trailing-variance 2 (:close ds)) + + (roll/trailing-variance-population 4 (:close ds)) + + + + (ta4j/close ds :statistics/StandardDeviation 4) + + + + + (ta4j/close ds :statistics/StandardDeviation 4) + (roll/trailing-stddev 4 ds) + + +; + ) + + diff --git a/lib/indicator/test/ta/indicator/stats_test_bad.clj b/lib/indicator/test/ta/indicator/stats_test_bad.clj deleted file mode 100644 index 437bb0fc..00000000 --- a/lib/indicator/test/ta/indicator/stats_test_bad.clj +++ /dev/null @@ -1,48 +0,0 @@ -(ns ta.indicator.stats-test-bad - (:require [clojure.test :refer :all] - [ta.indicator.util.fuzzy :refer [all-fuzzy=]] - [ta.indicator.util.ta4j :as ta4j] - [ta.indicator.util.data :refer [ds]] - [ta.indicator.rolling :as roll] - )) - - - - -(deftest test-stddev - (is (all-fuzzy= 0.1 - (ta4j/close ds :statistics/StandardDeviation 4) - (->> (roll/trailing-stddev 4 ds) (into [])) - ;(-> (ind/atr-mma {:n 4} ds) (round)) - ))) - - -(comment - (roll/trailing-stddev 4 ds) - ;; => #tech.v3.dataset.column[15] - ;; :out - ;; [0.000, 0.5000, 14.84, 18.59, 16.99, 8.500, 10.69, 12.44, - ;; 17.54, 16.36, 4.787, 4.787, 8.539, 11.09, 8.165] - - (ta4j/close ds :statistics/StandardDeviation 4) - ;; => (0.0 - ;; 0.5 - ;; 13.912424503139471 - ;; 16.101242188104617 - ;; 14.713938969562161 - ;; 7.361215932167728 - ;; 9.256754290786809 - ;; 10.770329614269007 - ;; 15.190457530963313 - ;; 14.168627315304754 - ;; 4.14578098794425 - ;; 4.14578098794425 - ;; 7.39509972887452 - ;; 9.60143218483576 - ;; 7.0710678118654755) - - -; - ) - - diff --git a/lib/math/src/ta/math/stats.clj b/lib/math/src/ta/math/stats.clj index a2baa92e..de2d43f2 100644 --- a/lib/math/src/ta/math/stats.clj +++ b/lib/math/src/ta/math/stats.clj @@ -6,6 +6,20 @@ (defn mean [coll] (/ (reduce + coll) (count coll))) + +(defn variance-sample [coll] + (let [avg (mean coll) + squares (map #(Math/pow (- % avg) 2) coll)] + (-> (reduce + squares) + (/ (dec (count coll)))))) + +(defn variance-population [coll] + (let [avg (mean coll) + squares (map #(Math/pow (- % avg) 2) coll)] + (-> (reduce + squares) + (/ (count coll)) + Math/sqrt))) + ;;for sample (not population) (defn standard-deviation [coll] (let [avg (mean coll) @@ -14,6 +28,15 @@ (/ (dec (count coll))) Math/sqrt))) +(defn standard-deviation-population [coll] + (let [avg (mean coll) + squares (map #(Math/pow (- % avg) 2) coll)] + (-> (reduce + squares) + (/ (count coll)) + Math/sqrt))) + + + (defn standardize [xs] (-> xs (dfn/- (dfn/mean xs)) @@ -22,3 +45,33 @@ (defn rand-numbers [n] (dtype/clone (dtype/make-reader :float32 n (rand)))) + + +(defn mad + "mad = mean absolute deviation. + the mean of the absolute deviation of the mean. + more applicable to reality than the standard deviation" + [vec] + (let [m (dfn/mean vec) + ad (-> (dfn/- vec m) (dfn/abs))] + (dfn/mean ad))) + +(comment + (mad [1 2 3]) + ; mean = 2. + ; diffs: 1 0 1 + ; mad (2/3) + + (dfn/variance [1 2 3 4 5]) + (variance-sample [1 2 3 4 5]) + (variance-population [1 2 3 4 5]) + + + (dfn/standard-deviation [1 2 3 4 5]) + (standard-deviation [1 2 3 4 5]) + (standard-deviation-population [1 2 3 4 5]) + + +; + ) + \ No newline at end of file