From 29b9460ce45edfc0f33c5a3df847bd1456c73f25 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 18 Mar 2019 13:26:22 -0400 Subject: [PATCH 1/3] Update README with code samples and more details --- README.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/README.md b/README.md index 20e47bb..6c56178 100644 --- a/README.md +++ b/README.md @@ -37,5 +37,123 @@ The following technical indicators are supported: - Volume-price Trend (VPT) - Williams %R (WR) +## Install + +Add the following line to Gemfile: + +```ruby +gem 'technical-analysis' +``` + +and run `bundle install` from your shell. + +To install the gem manually from your shell, run: + +```shell +gem install technical-analysis +``` + +## Usage +There are 2 ways to use this gem for technical analysis. + +First, for the sake of these code samples, we'll load some test data from `spec/ta_test_data.csv`. This is the same data used for the unit tests. The data will be an `Array` of `Hashes`. + +```ruby +input_data = SpecHelper.get_test_data(:close) +# [ +# { date_time: "2019-01-09T00:00:00.000Z", close: 153.3100 }, +# { date_time: "2019-01-08T00:00:00.000Z", close: 150.7500 }, +# ... +# { date_time: "2018-10-09T00:00:00.000Z", close: 226.8700 } +# ] +``` + +### 1) Call the `calculate` method on the specific technical indicator class +```ruby +TechnicalAnalysis::Sma.calculate(input_data, period: 30, price_key: :close) +``` + +### 2) Call the generic indicator class and pass params to the `calculate` method +The calculate method accepts: +- The indicator `symbol` as a String - `"sma"` +- The data to be used for calculations as an Array of Hashes - `input_data` +- The symbol of the calculation to be performed - `:technicals` +- The options for the indicator as a Hash - `options` +```ruby +options = { period: 30, price_key: :close } +TechnicalAnalysis::Indicator.calculate('sma', input_data, :technicals, options) +``` + +Each technical indicator has the following methods: +- `indicator_symbol` returns the symbol of the technical indicator as a String. +- `indicator_name` returns the name of the technical indicator as a String. +- `valid_options` returns an Array of keys (as Symbols) for valid options that the technical indicator accepts in its `calculate` method. +- `validate_options` returns true if the options provided are valid or raises a `ValidationError`. +- `min_data_size` returns the minimum number of observations needed (as an Integer) to calculate the technical indicator based on the options provided. +- `calculate` - Each technical indicator returns an Array of values. These values are instances of a class specific to each indicator. It's typically in the format of SymbolValue. For example, Simple Moving Average (SMA) returns an Array of `SmaValue` instances. These classes contain the appropriate data fields for each technical indicator. + +For example: +```ruby +TechnicalAnalysis::Sma.indicator_symbol +# "sma" + +TechnicalAnalysis::Sma.indicator_name +# "Simple Moving Average" + +TechnicalAnalysis::Sma.valid_options +# [:period, :price_key] + +options = { period: 30, price_key: :close } +TechnicalAnalysis::Sma.validate_options(options) +# true + +options = { period: 30, price_key: :close } +TechnicalAnalysis::Sma.min_data_size(options) +# 30 +``` + +You can also use the generic indicator class. The purpose of this class is to be a sort of master class that will find and call the correct indicator based on the params provided to it. + +Here's each example again using the generic indicator class: +```ruby +input_data = SpecHelper.get_test_data(:close) + +TechnicalAnalysis::Indicator.calculate('sma', input_data, :indicator_symbol) +# "sma" + +TechnicalAnalysis::Indicator.indicator_name('sma', input_data, :indicator_name) +# "Simple Moving Average" + +TechnicalAnalysis::Indicator.valid_options('sma', input_data, :valid_options) +# [:period, :price_key] + +options = { period: 30, price_key: :close } +TechnicalAnalysis::Indicator.validate_options('sma', input_data, :validate_options, options) +# true + +options = { period: 30, price_key: :close } +TechnicalAnalysis::Indicator.min_data_size('sma', input_data, :min_data_size, options) +# 30 +``` + +Or you can use it to find the correct technical indicator class based on symbol: +```ruby +input_data = SpecHelper.get_test_data(:close) + +indicator = TechnicalAnalysis::Indicator.find("sma") +# TechnicalAnalysis::Sma + +indicator.indicator_symbol +# "sma" + +indicator.indicator_name +# "Simple Moving Average" + +indicator.calculate(input_data, period: 30, price_key: :close) +``` + +## Further documentation +This gem is also documented using [Yard](https://yardoc.org/). You can view the [guides](https://yardoc.org/guides/index.html) to help get you started. + ## Run Tests `rspec spec` From 01a3ce03cbf5a60247d05aa3fe4edcf6e111c7aa Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 18 Mar 2019 17:17:25 -0400 Subject: [PATCH 2/3] README updates for Indicator class --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c56178..e07454a 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ TechnicalAnalysis::Sma.calculate(input_data, period: 30, price_key: :close) ``` ### 2) Call the generic indicator class and pass params to the `calculate` method -The calculate method accepts: +The `calculate` method on the `Indicator` class accepts: - The indicator `symbol` as a String - `"sma"` - The data to be used for calculations as an Array of Hashes - `input_data` - The symbol of the calculation to be performed - `:technicals` From 80edbd664be1e3ad72fb2eae524443beeb9299c3 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 19 Mar 2019 10:44:35 -0400 Subject: [PATCH 3/3] More README updates, break usage into 2 sections --- README.md | 80 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index e07454a..57abcac 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,6 @@ gem install technical-analysis ``` ## Usage -There are 2 ways to use this gem for technical analysis. - First, for the sake of these code samples, we'll load some test data from `spec/ta_test_data.csv`. This is the same data used for the unit tests. The data will be an `Array` of `Hashes`. ```ruby @@ -68,31 +66,25 @@ input_data = SpecHelper.get_test_data(:close) # ] ``` -### 1) Call the `calculate` method on the specific technical indicator class -```ruby -TechnicalAnalysis::Sma.calculate(input_data, period: 30, price_key: :close) -``` - -### 2) Call the generic indicator class and pass params to the `calculate` method -The `calculate` method on the `Indicator` class accepts: -- The indicator `symbol` as a String - `"sma"` -- The data to be used for calculations as an Array of Hashes - `input_data` -- The symbol of the calculation to be performed - `:technicals` -- The options for the indicator as a Hash - `options` -```ruby -options = { period: 30, price_key: :close } -TechnicalAnalysis::Indicator.calculate('sma', input_data, :technicals, options) -``` - Each technical indicator has the following methods: +- `calculate` - Each technical indicator returns an Array of values. These values are instances of a class specific to each indicator. It's typically in the format of SymbolValue. For example, Simple Moving Average (SMA) returns an Array of `SmaValue` instances. These classes contain the appropriate data fields for each technical indicator. - `indicator_symbol` returns the symbol of the technical indicator as a String. - `indicator_name` returns the name of the technical indicator as a String. - `valid_options` returns an Array of keys (as Symbols) for valid options that the technical indicator accepts in its `calculate` method. - `validate_options` returns true if the options provided are valid or raises a `ValidationError`. - `min_data_size` returns the minimum number of observations needed (as an Integer) to calculate the technical indicator based on the options provided. -- `calculate` - Each technical indicator returns an Array of values. These values are instances of a class specific to each indicator. It's typically in the format of SymbolValue. For example, Simple Moving Average (SMA) returns an Array of `SmaValue` instances. These classes contain the appropriate data fields for each technical indicator. -For example: +### Class-Based Usage +You can call methods on the class of the specific technical indicator that you want to calculate. To calculate a Simple Moving Average, for example, you would just call `calculate` on the Simple Moving Average class like so: + +```ruby +input_data = SpecHelper.get_test_data(:close) + +TechnicalAnalysis::Sma.calculate(input_data, period: 30, price_key: :close) +``` + +Here are examples of other methods for technical indicators: + ```ruby TechnicalAnalysis::Sma.indicator_symbol # "sma" @@ -112,44 +104,70 @@ TechnicalAnalysis::Sma.min_data_size(options) # 30 ``` +### Generic Usage You can also use the generic indicator class. The purpose of this class is to be a sort of master class that will find and call the correct indicator based on the params provided to it. +The `calculate` method on the `Indicator` class accepts: +- The indicator symbol as a String - `"sma"` +- The data to be used for calculations as an Array of Hashes - `input_data` +- The calculation to be performed as a Symbol - `:technicals` +- The options for the indicator as a Hash - `options` + +```ruby +input_data = SpecHelper.get_test_data(:close) +options = { period: 30, price_key: :close } + +TechnicalAnalysis::Indicator.calculate('sma', input_data, :technicals, options) +``` + Here's each example again using the generic indicator class: + ```ruby input_data = SpecHelper.get_test_data(:close) TechnicalAnalysis::Indicator.calculate('sma', input_data, :indicator_symbol) # "sma" -TechnicalAnalysis::Indicator.indicator_name('sma', input_data, :indicator_name) +TechnicalAnalysis::Indicator.calculate('sma', input_data, :indicator_name) # "Simple Moving Average" -TechnicalAnalysis::Indicator.valid_options('sma', input_data, :valid_options) +TechnicalAnalysis::Indicator.calculate('sma', input_data, :valid_options) # [:period, :price_key] options = { period: 30, price_key: :close } -TechnicalAnalysis::Indicator.validate_options('sma', input_data, :validate_options, options) +TechnicalAnalysis::Indicator.calculate('sma', input_data, :validate_options, options) # true options = { period: 30, price_key: :close } -TechnicalAnalysis::Indicator.min_data_size('sma', input_data, :min_data_size, options) +TechnicalAnalysis::Indicator.calculate('sma', input_data, :min_data_size, options) # 30 ``` -Or you can use it to find the correct technical indicator class based on symbol: -```ruby -input_data = SpecHelper.get_test_data(:close) +Or you can use it to find the correct technical indicator class based on indicator symbol: -indicator = TechnicalAnalysis::Indicator.find("sma") +```ruby +simple_moving_average = TechnicalAnalysis::Indicator.find("sma") # TechnicalAnalysis::Sma -indicator.indicator_symbol +input_data = SpecHelper.get_test_data(:close) +simple_moving_average.calculate(input_data, period: 30, price_key: :close) + +simple_moving_average.indicator_symbol # "sma" -indicator.indicator_name +simple_moving_average.indicator_name # "Simple Moving Average" -indicator.calculate(input_data, period: 30, price_key: :close) +simple_moving_average.valid_options +# [:period, :price_key] + +options = { period: 30, price_key: :close } +simple_moving_average.validate_options(options) +# true + +options = { period: 30, price_key: :close } +simple_moving_average.min_data_size(options) +# 30 ``` ## Further documentation