sqa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.envrc +4 -0
  3. data/CHANGELOG.md +5 -0
  4. data/LICENSE +21 -0
  5. data/README.md +29 -0
  6. data/Rakefile +4 -0
  7. data/bin/sqa +6 -0
  8. data/checksums/sqa-0.0.1.gem.sha512 +1 -0
  9. data/docs/requirements.md +40 -0
  10. data/lib/sqa/activity.rb +10 -0
  11. data/lib/sqa/cli.rb +310 -0
  12. data/lib/sqa/datastore/active_record.rb +89 -0
  13. data/lib/sqa/datastore/csv/yahoo_finance.rb +51 -0
  14. data/lib/sqa/datastore/csv.rb +93 -0
  15. data/lib/sqa/datastore/sqlite.rb +7 -0
  16. data/lib/sqa/datastore.rb +6 -0
  17. data/lib/sqa/errors.rb +5 -0
  18. data/lib/sqa/indicator/README.md +33 -0
  19. data/lib/sqa/indicator/average_true_range.md +9 -0
  20. data/lib/sqa/indicator/average_true_range.rb +30 -0
  21. data/lib/sqa/indicator/bollinger_bands.md +15 -0
  22. data/lib/sqa/indicator/bollinger_bands.rb +28 -0
  23. data/lib/sqa/indicator/candlestick_pattern_recognizer.md +4 -0
  24. data/lib/sqa/indicator/candlestick_pattern_recognizer.rb +60 -0
  25. data/lib/sqa/indicator/classify_market_profile.md +4 -0
  26. data/lib/sqa/indicator/classify_market_profile.rb +33 -0
  27. data/lib/sqa/indicator/donchian_channel.md +5 -0
  28. data/lib/sqa/indicator/donchian_channel.rb +29 -0
  29. data/lib/sqa/indicator/double_top_bottom_pattern.md +3 -0
  30. data/lib/sqa/indicator/double_top_bottom_pattern.rb +34 -0
  31. data/lib/sqa/indicator/ema_analysis.md +19 -0
  32. data/lib/sqa/indicator/ema_analysis.rb +70 -0
  33. data/lib/sqa/indicator/fibonacci_retracement.md +3 -0
  34. data/lib/sqa/indicator/fibonacci_retracement.rb +25 -0
  35. data/lib/sqa/indicator/head_and_shoulders_pattern.md +3 -0
  36. data/lib/sqa/indicator/head_and_shoulders_pattern.rb +26 -0
  37. data/lib/sqa/indicator/identify_wave_condition.md +6 -0
  38. data/lib/sqa/indicator/identify_wave_condition.rb +40 -0
  39. data/lib/sqa/indicator/mean_reversion.md +8 -0
  40. data/lib/sqa/indicator/mean_reversion.rb +37 -0
  41. data/lib/sqa/indicator/momentum.md +19 -0
  42. data/lib/sqa/indicator/momentum.rb +26 -0
  43. data/lib/sqa/indicator/moving_average_convergence_divergence.md +23 -0
  44. data/lib/sqa/indicator/moving_average_convergence_divergence.rb +25 -0
  45. data/lib/sqa/indicator/relative_strength_index.md +6 -0
  46. data/lib/sqa/indicator/relative_strength_index.md.rb +47 -0
  47. data/lib/sqa/indicator/simple_moving_average.md +8 -0
  48. data/lib/sqa/indicator/simple_moving_average.rb +21 -0
  49. data/lib/sqa/indicator/simple_moving_average_trend.rb +31 -0
  50. data/lib/sqa/indicator/stochastic_oscillator.md +5 -0
  51. data/lib/sqa/indicator/stochastic_oscillator.rb +39 -0
  52. data/lib/sqa/indicator/true_range.md +12 -0
  53. data/lib/sqa/indicator/true_range.rb +37 -0
  54. data/lib/sqa/indicator.rb +11 -0
  55. data/lib/sqa/protfolio.rb +8 -0
  56. data/lib/sqa/stock.rb +29 -0
  57. data/lib/sqa/version.rb +5 -0
  58. data/lib/sqa.rb +12 -0
  59. metadata +105 -0
@@ -0,0 +1,6 @@
1
+ # lib/sqa/datastore.rb
2
+
3
+ require_relative 'datastore/csv'
4
+ require_relative 'datastore/active_record'
5
+
6
+ # require_relative 'datastore/sqlite'
data/lib/sqa/errors.rb ADDED
@@ -0,0 +1,5 @@
1
+ # lib/sqa/errors.rb
2
+
3
+ module SQA
4
+ class BadParameterError < ArgumentError; end
5
+ end
@@ -0,0 +1,33 @@
1
+ # Indicators
2
+
3
+ An indicator is a formula/metric on a stock's historical activity. It is presumed to be a forecast as to what the stock activity might be in the future. A single indicator is not necessarily an accurate predictor of future events not is any specific group of indicators.
4
+
5
+ In other words the future is uncertain. Is it a coin flip? Heads the stock's price goes up. Tails, the stock's price goes down. Its one or the other right? What if the price never changes. Then its not a coin flip. Also what is the time frame involved in the forecast? Is it tomorrow, next week, next month, next year, next decade? What is the delta change in price that can be expected?
6
+
7
+ So indicators are like TV weather forecastors. Sometimes they are right. Sometimes they are wrong.
8
+
9
+ We are dealing with uncertainity. In uncertainity there is chaos. If it is possible to be right more times that you are wrong you can make money. If you are always wrong then always do the opposite and you will make money. When you are wrong more times than you are right.... you loose.
10
+
11
+ Its a game. Game theory tells us that there are winners and losers. Bookies at the track make money every day by taking a cut of the losers loses before giving them to the winners. Bookies always win so long as they keep their books balanced. Accounts are important.
12
+
13
+ Back to indicators. Here is a list of the current indicators:
14
+
15
+
16
+
17
+ * [Average True Range](average true range.md)
18
+ * [Bollinger Bands](bollinger bands.md)
19
+ * [Vandlestick Pattern Recognizer](candlestick pattern recognizer.md)
20
+ * [Vlassify Market Profile](classify market profile.md)
21
+ * [Donchian Channel](donchian channel.md)
22
+ * [Double Top Bottom Pattern](double top bottom pattern.md)
23
+ * [EMA Analysis](ema analysis.md)
24
+ * [Fibonacci Retracement](fibonacci retracement.md)
25
+ * [Head and Shoulders Pattern](head and shoulders pattern.md)
26
+ * [Identify Wave Condition](identify wave condition.md)
27
+ * [MACD](macd.md)
28
+ * [Mean Reversion](mean reversion.md)
29
+ * [Momentum](momentum.md)
30
+ * [RSI](rsi.md)
31
+ * [Simple Moving Average](simple moving average.md)
32
+ * [Stochastic Oscillator](stochastic oscillator.md)
33
+ * [True Range](true range.md)
@@ -0,0 +1,9 @@
1
+ # Average True Range
2
+
3
+ Calculates the Average True Range (ATR) for a given set of price data.
4
+
5
+ The Average True Range is an indicator that calculates the average of the True Range values over a specified period. It provides a measure of the average volatility of a security over that period.
6
+
7
+ The ATR is commonly used to assess the volatility of a security, identify potential trend reversals, and determine appropriate stop-loss levels. Higher ATR values indicate higher volatility, while lower ATR values indicate lower volatility.
8
+
9
+ For example, a 14-day Average True Range would calculate the average of the True Range values over the past 14 trading days. Traders and analysts may use this indicator to set stop-loss levels based on the average volatility of the security.
@@ -0,0 +1,30 @@
1
+ # lib/sqa/indicator/average_true_range.rb
2
+
3
+ # See Also: true_range
4
+
5
+ module SQA::Indicator; class << self
6
+
7
+ def average_true_range(
8
+ high_prices, # Array of the day's high price
9
+ low_prices, # Array of the day's low price
10
+ close_prices, # Array of the day's closing price
11
+ period # Integer the number of days to consider
12
+ )
13
+ true_ranges = true_range(high_prices, low_prices, close_prices)
14
+ atr_values = []
15
+
16
+ true_ranges.each_with_index do |true_range, index|
17
+ if index < period - 1
18
+ atr_values << nil
19
+ elsif index == period - 1
20
+ atr_values << true_ranges[0..index].sum / period.to_f
21
+ else
22
+ atr_values << (atr_values[index - 1] * (period - 1) + true_range) / period.to_f
23
+ end
24
+ end
25
+
26
+ atr_values # Array
27
+ end
28
+ alias_method :atr, :average_true_range
29
+
30
+ end; end
@@ -0,0 +1,15 @@
1
+
2
+
3
+ # Bollinger Bands
4
+
5
+ This method takes in an array of historical prices for a stock, a period (the number of days to calculate the moving average and standard deviation over), and the number of standard deviations to use for the upper and lower Bollinger Bands. It uses the `moving_averages` method to calculate the moving average for the given period, and then calculates the standard deviation of the closing prices for each window of the given period. Finally, it calculates the upper and lower Bollinger Bands based on the moving average and standard deviation, and returns an array containing the upper and lower bands.
6
+
7
+ The `num_std_dev` parameter in the Bollinger Bands method specifies the number of standard deviations to use for the upper and lower bands. The default value for this parameter can depend on the specific security being analyzed and the time period being used.
8
+
9
+ A common default value for `num_std_dev` is 2, which corresponds to the standard deviation of the price data over the given time period. Using a value of 2 for `num_std_dev` will result in the upper and lower bands being placed at a distance of two standard deviations from the moving average.
10
+
11
+ However, the optimal value for `num_std_dev` can vary depending on the volatility of the security being analyzed. For highly volatile securities, a larger value for `num_std_dev` may be more appropriate, while for less volatile securities, a smaller value may be more appropriate.
12
+
13
+ Ultimately, the best default value for `num_std_dev` will depend on the specific use case and should be chosen based on the characteristics of the security being analyzed and the preferences of the analyst.
14
+
15
+ The difference between the upper and lower bands can be an indicator of how volatile the stock is.
@@ -0,0 +1,28 @@
1
+ # lib/sqa/indicator/bollinger_bands.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def bollinger_bands(
6
+ prices, # Array of prices
7
+ period, # Integer number of entries to consider
8
+ num_std_devs=2 # Integer number of standard deviations
9
+ )
10
+ moving_averages = simple_moving_average(prices, period)
11
+ standard_deviations = []
12
+
13
+ prices.each_cons(period) do |window|
14
+ standard_deviation = Math.sqrt(window.map { |price| (price - moving_averages.last) ** 2 }.sum / period)
15
+ standard_deviations << standard_deviation
16
+ end
17
+
18
+ upper_band = moving_averages.last + (num_std_devs * standard_deviations.last)
19
+ lower_band = moving_averages.last - (num_std_devs * standard_deviations.last)
20
+
21
+ {
22
+ upper_band: upper_band, # Array
23
+ ;pwer_band: lower_band # Array
24
+ }
25
+ end
26
+ alias_method :bb, :bollinger_bands
27
+
28
+ end; end
@@ -0,0 +1,4 @@
1
+ # Candlestick Chart Pattern
2
+
3
+ Recognizes common candlestick chart patterns in the given price data.
4
+
@@ -0,0 +1,60 @@
1
+ # lib/sqa/indicator/candlestick_pattern_recognizer.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def candlestick_pattern_recognizer(
6
+ open_prices, # Array day's ppen price
7
+ high_prices, # Array day's high price
8
+ low_prices, # Array day's low price
9
+ close_prices # Array day's closing price
10
+ )
11
+ patterns = []
12
+
13
+ close_prices.each_with_index do |close, index|
14
+ if index >= 2
15
+ previous_close = close_prices[index - 1]
16
+ previous_open = open_prices[index - 1]
17
+ previous_high = high_prices[index - 1]
18
+ previous_low = low_prices[index - 1]
19
+
20
+ second_previous_close = close_prices[index - 2]
21
+ second_previous_open = open_prices[index - 2]
22
+ second_previous_high = high_prices[index - 2]
23
+ second_previous_low = low_prices[index - 2]
24
+
25
+ if close > previous_close &&
26
+ previous_close < previous_open &&
27
+ close < previous_open &&
28
+ close > previous_low &&
29
+ close > second_previous_close
30
+ patterns << :bullish_engulfing
31
+
32
+ elsif close < previous_close &&
33
+ previous_close > previous_open &&
34
+ close > previous_open &&
35
+ close < previous_high &&
36
+ close < second_previous_close
37
+ patterns << :bearish_engulfing
38
+
39
+ elsif close > previous_close &&
40
+ previous_close < previous_open &&
41
+ close < previous_open &&
42
+ close < previous_low &&
43
+ close < second_previous_close
44
+ patterns << :bearish_harami
45
+
46
+ elsif close < previous_close &&
47
+ previous_close > previous_open &&
48
+ close > previous_open &&
49
+ close > previous_high &&
50
+ close > second_previous_close
51
+ patterns << :bullish_harami
52
+ end
53
+ end
54
+ end
55
+
56
+ patterns
57
+ end
58
+
59
+ end; end
60
+
@@ -0,0 +1,4 @@
1
+ # Market Profile Analysis
2
+
3
+ Market profile analysis involves studying the distribution of trading volume and price levels over time. It helps identify areas of support and resistance and provides insights into market sentiment.
4
+
@@ -0,0 +1,33 @@
1
+ # lib/sqa/indicator/classify_market_profile.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def classify_market_profile(
6
+ volumes, # Array of volumes
7
+ prices, # Array of prices
8
+ support_threshold, # Float stock's support price estimate
9
+ resistance_threshold # Float stock's resistance price estimate
10
+ )
11
+ return :unknown if volumes.empty? || prices.empty?
12
+
13
+ total_volume = volumes.sum
14
+ average_volume = total_volume / volume.length.to_f
15
+ max_volume = volume.max
16
+
17
+ support_levels = prices.select { |price| price <= support_threshold }
18
+ resistance_levels = prices.select { |price| price >= resistance_threshold }
19
+
20
+ if support_levels.empty? &&
21
+ resistance_levels.empty?
22
+ :neutral
23
+ elsif support_levels.empty?
24
+ :resistance
25
+ elsif resistance_levels.empty?
26
+ :support
27
+ else
28
+ :mixed
29
+ end
30
+ end
31
+
32
+ end; end
33
+
@@ -0,0 +1,5 @@
1
+ # Donchian Channel
2
+
3
+ In the domain of computer programming, a Donchian Channel is a technical analysis indicator used to identify potential breakouts and trend reversals in financial markets. It consists of three lines: the upper channel line, the lower channel line, and the middle line.
4
+
5
+ The upper channel line is calculated by finding the highest high over a specified period of time, while the lower channel line is calculated by finding the lowest low over the same period. The middle line is simply the average of the upper and lower channel lines.
@@ -0,0 +1,29 @@
1
+ # lib/sqa/indicator/donchian_channel.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def donchian_channel(
6
+ prices, # Array of prices
7
+ period # Integer number of entries to consider
8
+ )
9
+ max = -999999999
10
+ min = 999999999
11
+ donchian_channel = []
12
+
13
+ prices.each_with_index do |value, index|
14
+ value = value.to_f
15
+ max = value if value > max
16
+ min = value if value < min
17
+
18
+ if index >= period - 1
19
+ donchian_channel << [max, min, (max + min) / 2]
20
+ max = -999999999
21
+ min = 999999999
22
+ end
23
+ end
24
+
25
+ donchian_channel
26
+ end
27
+
28
+ end; end
29
+
@@ -0,0 +1,3 @@
1
+ # Double Top Double Bottom Pattern
2
+
3
+ Checks if a "double top" or "double bottom" pattern is present in the given price data.
@@ -0,0 +1,34 @@
1
+ # lib/sqa/indicator/double_top_bottom_pattern.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def double_top_bottom_pattern(
6
+ prices # Array of prices
7
+ )
8
+ return :no_pattern if prices.length < 5
9
+
10
+ data = prices.last(5)
11
+
12
+ first_peak = data[0]
13
+ valley = data[1]
14
+ second_peak = data[2]
15
+ neckline = data[3]
16
+ confirmation_price = data[4]
17
+
18
+ if first_peak < second_peak &&
19
+ valley > first_peak &&
20
+ valley > second_peak &&
21
+ confirmation_price < neckline
22
+ :double_top
23
+ elsif first_peak > second_peak &&
24
+ valley < first_peak &&
25
+ valley < second_peak &&
26
+ confirmation_price > neckline
27
+ :double_bottom
28
+ else
29
+ :no_pattern
30
+ end
31
+ end
32
+
33
+ end; end
34
+
@@ -0,0 +1,19 @@
1
+ # Exponential Moving Average (EMA)
2
+
3
+ In financial analysis, the Exponential Moving Average (EMA) is a commonly used technical indicator that helps identify trends and smooth out price data. It is a type of moving average that gives more weight to recent prices, making it more responsive to recent price changes compared to other moving averages.
4
+
5
+ The EMA is calculated by applying a smoothing factor (often represented as a percentage) to the previous EMA value and adding a weighted average of the current price. The smoothing factor determines the weight given to the most recent price data, with higher values giving more weight to recent prices.
6
+
7
+ The EMA is used for various purposes in financial analysis, including:
8
+
9
+ 1. Trend Identification: The EMA is often used to identify the direction and strength of a trend. When the current price is above the EMA, it suggests an uptrend, while a price below the EMA suggests a downtrend. Traders and investors may use the EMA crossover (when the price crosses above or below the EMA) as a signal to enter or exit positions.
10
+
11
+ 2. Support and Resistance Levels: The EMA can act as dynamic support or resistance levels. In an uptrend, the EMA may provide support, and in a downtrend, it may act as resistance. Traders may use the EMA as a reference point for setting stop-loss orders or profit targets.
12
+
13
+ 3. Price Reversals: The EMA can help identify potential price reversals. When the price deviates significantly from the EMA, it may indicate an overbought or oversold condition, suggesting a potential reversal in the near future. Traders may use this information to anticipate price reversals and adjust their trading strategies accordingly.
14
+
15
+ 4. Volatility Assessment: The EMA can be used to assess market volatility. When the EMA is relatively flat, it suggests low volatility, while a steeply sloping EMA indicates higher volatility. Traders may adjust their trading strategies based on the level of volatility indicated by the EMA.
16
+
17
+ It's important to note that the EMA is just one of many technical indicators used in financial analysis. It is often used in combination with other indicators, such as the Simple Moving Average (SMA), to gain a more comprehensive understanding of market trends and price movements.
18
+
19
+ Traders and investors should consider their own trading strategies, risk tolerance, and timeframes when using the EMA or any other technical indicator for financial analysis. It's also recommended to backtest and validate any trading strategies before applying them in real-time trading.
@@ -0,0 +1,70 @@
1
+ # lib/sqa/indicator/ema_analysis.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def ema_analysis(
6
+ prices, # Array of prices
7
+ period # Integer number of entries to consider
8
+ )
9
+ return {} if prices.empty? || period <= 0
10
+
11
+ ema_values = []
12
+ ema_values << prices.first
13
+
14
+ multiplier = (2.0 / (period + 1))
15
+
16
+ (1...prices.length).each do |i|
17
+ ema = (prices[i] - ema_values.last) * multiplier + ema_values.last
18
+ ema_values << ema.round(2)
19
+ end
20
+
21
+ analysis = {}
22
+
23
+ analysis[:ema_values] = ema_values
24
+ analysis[:trend] = ema_determine_trend(ema_values)
25
+ analysis[:support] = ema_determine_support(ema_values)
26
+ analysis[:resistance] = ema_determine_resistance(ema_values)
27
+
28
+ analysis
29
+ end
30
+
31
+
32
+ # @param ema_values [Array] An array of EMA values.
33
+ # @return [Symbol] The trend: :up, :down, or :sideways.
34
+ #
35
+ private def ema_determine_trend(ema_values)
36
+ return :sideways if ema_values.empty?
37
+
38
+ last_ema = ema_values.last
39
+ previous_ema = ema_values[-2]
40
+
41
+ if last_ema > previous_ema
42
+ :up
43
+ elsif last_ema < previous_ema
44
+ :down
45
+ else
46
+ :sideways
47
+ end
48
+ end
49
+
50
+
51
+ # @param ema_values [Array] An array of EMA values.
52
+ # @return [Float] The support level.
53
+ #
54
+ private def ema_determine_support(ema_values)
55
+ return 0.0 if ema_values.empty?
56
+
57
+ ema_values.min
58
+ end
59
+
60
+
61
+ # @param ema_values [Array] An array of EMA values.
62
+ # @return [Float] The resistance level.
63
+ private def ema_determine_resistance(ema_values)
64
+ return 0.0 if ema_values.empty?
65
+
66
+ ema_values.max
67
+ end
68
+
69
+ end; end
70
+
@@ -0,0 +1,3 @@
1
+ # Fibonacci Retracement
2
+
3
+ Fibonacci retracement uses Fibonacci ratios to identify potential support and resistance levels based on the price's previous significant moves.
@@ -0,0 +1,25 @@
1
+ # lib/sqa/indicator/fibonacci_retracement.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def fibonacci_retracement(
6
+ start_price, # Float starting price of the range
7
+ end_price # Float ending price of the range
8
+ )
9
+ retracement_levels = []
10
+
11
+ retracement_levels << end_price
12
+ retracement_levels << start_price
13
+
14
+ fibonacci_levels = [0.236, 0.382, 0.5, 0.618, 0.786]
15
+
16
+ fibonacci_levels.each do |level|
17
+ retracement_levels <<= start_price + (end_price - start_price) * level
18
+ end
19
+
20
+ retracement_levels # Array
21
+ end
22
+ alias_method :fr, :fibonacci_retracement
23
+
24
+ end; end
25
+
@@ -0,0 +1,3 @@
1
+ # Head and Shoulders Pattern
2
+
3
+ Checks if a "head and shoulders" pattern is present in the given price data.
@@ -0,0 +1,26 @@
1
+ # lib/sqa/indicator/head_and_shoulders_pattern.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+
6
+ def head_and_shoulders_pattern?(
7
+ prices # Array of prices
8
+ )
9
+
10
+ return false if prices.length < 5
11
+
12
+ data = prices.last(5)
13
+
14
+ left_shoulder = data[0]
15
+ head = data[1]
16
+ right_shoulder = data[2]
17
+ neckline = data[3]
18
+ right_peak = data[4]
19
+
20
+ head > left_shoulder &&
21
+ head > right_shoulder &&
22
+ right_peak < neckline
23
+ end
24
+
25
+ end; end
26
+
@@ -0,0 +1,6 @@
1
+ # Wave Theory
2
+
3
+ Wave theory, such as Elliott Wave Theory, suggests that price movements follow repetitive patterns or waves. It aims to identify and predict these patterns to make trading decisions.
4
+
5
+ Identifies a wave condition in a stock's price history based on a given price series.
6
+
@@ -0,0 +1,40 @@
1
+ # lib/sqa/indicator/identify_wave_condition.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ def identify_wave_condition?(
6
+ prices, # Array of prices
7
+ wave_length, # Integer expected length of a wave pattern
8
+ tolerance # Float delta change in price that would indicate a wave
9
+ )
10
+ return false if prices.length < wave_length
11
+
12
+ wave_start = 0
13
+ wave_end = wave_length - 1
14
+
15
+ while wave_end < prices.length
16
+ wave = prices[wave_start..wave_end]
17
+
18
+ if wave.length == wave_length &&
19
+ wave_pattern?(wave, tolerance)
20
+ return true
21
+ end
22
+
23
+ wave_start += 1
24
+ wave_end += 1
25
+ end
26
+
27
+ false
28
+ end
29
+
30
+
31
+ private def wave_pattern?(wave, tolerance)
32
+ wave.each_cons(2) do |a, b|
33
+ return false if (b - a).abs > tolerance
34
+ end
35
+
36
+ true
37
+ end
38
+
39
+ end; end
40
+
@@ -0,0 +1,8 @@
1
+ # Mean Reversion
2
+
3
+ Determines if a stock exhibits mean reversion behavior based on a given price series.
4
+
5
+ Mean Reversion Strategies: Mean reversion strategies aim to capitalize on the tendency of prices to revert to their mean or average value. These strategies involve identifying overextended price movements and taking positions that anticipate a return to the mean.
6
+
7
+
8
+
@@ -0,0 +1,37 @@
1
+ # lib/sqa/indicator/mean_reversion.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ # @param prices [Array]
6
+ # @param lookback_period [Integer]
7
+ # @param deviation_threshold [Float]
8
+ #
9
+ # @return [Boolean] True if the stock exhibits mean reversion behavior,
10
+ # false otherwise.
11
+ #
12
+ def mean_reversion?(
13
+ prices, # Array of prices
14
+ lookback_period, # Integer number of events to consider
15
+ deviation_threshold # Float delta change at which a price is considered to be over extended
16
+ )
17
+
18
+ return false if prices.length < lookback_period
19
+
20
+ mean = mr_mean(prices, lookback_period)
21
+ deviation = prices[-1] - mean
22
+
23
+ if deviation.abs > deviation_threshold
24
+ return true
25
+ else
26
+ return false
27
+ end
28
+ end
29
+
30
+
31
+ def mr_mean(prices, lookback_period)
32
+ prices.last(lookback_period).sum / lookback_period.to_f
33
+ end
34
+
35
+ end; end
36
+
37
+
@@ -0,0 +1,19 @@
1
+ # Momentum
2
+
3
+ Calculates the momentum of a stock based on the rate of change (ROC).
4
+
5
+ The interpretation of a stock's momentum value in terms of forecasting future price depends on the specific trading strategy or approach being used. However, in general, a positive momentum value indicates that the stock's price has been increasing over the specified period, while a negative momentum value indicates that the stock's price has been decreasing.
6
+
7
+ Here are some common interpretations of momentum values:
8
+
9
+ 1. Positive Momentum: A positive momentum value suggests that the stock's price has been trending upwards. This could indicate that the stock is in an uptrend and may continue to rise in the near future. Traders and investors may interpret this as a bullish signal and consider buying or holding the stock.
10
+
11
+ 2. Negative Momentum: A negative momentum value suggests that the stock's price has been trending downwards. This could indicate that the stock is in a downtrend and may continue to decline in the near future. Traders and investors may interpret this as a bearish signal and consider selling or avoiding the stock.
12
+
13
+ 3. High Momentum: A high positive momentum value indicates a strong upward trend in the stock's price. This could suggest that the stock has significant buying pressure and may continue to rise. Traders and investors may interpret this as a strong bullish signal and consider entering or adding to their positions.
14
+
15
+ 4. Low Momentum: A low positive momentum value suggests a weak upward trend or a sideways movement in the stock's price. This could indicate a lack of significant buying pressure. Traders and investors may interpret this as a neutral signal and may choose to wait for a stronger momentum signal or look for other indicators to make trading decisions.
16
+
17
+ It's important to note that momentum alone may not be sufficient for accurate price forecasting. It is often used in conjunction with other technical indicators, fundamental analysis, or market conditions to make more informed trading decisions.
18
+
19
+ Additionally, the interpretation of momentum values may vary depending on the time frame and the specific trading strategy being employed. Traders and investors should consider their own risk tolerance, investment goals, and trading approach when interpreting momentum values for forecasting future price movements.
@@ -0,0 +1,26 @@
1
+ # lib/sqa/indicator/momentum.rb
2
+
3
+ module SQA::Indicator; class << self
4
+
5
+ # @param prices [Array]
6
+ # @param period [Integer]
7
+ #
8
+ # @return [Float]
9
+ #
10
+ def momentum(
11
+ prices, # Array of prices
12
+ period # Integer number of entries to consider
13
+ )
14
+ return 0.0 if prices.length <= period
15
+
16
+ current_price = prices.last
17
+ past_price = prices.last(period).first
18
+ change = (current_price - past_price) / past_price.to_f
19
+ momentum = change * 100.0
20
+
21
+ momentum # Float expressed as a percentage change
22
+ end
23
+ alias_method :m, :momentum
24
+
25
+ end; end
26
+
@@ -0,0 +1,23 @@
1
+ # Moving Average Convergence Divergence (MACD)
2
+
3
+ The MACD is a trend-following momentum indicator that measures the relationship between two moving averages over a specified time period. The MACD is calculated by subtracting the long-term moving average from the short-term moving average.
4
+
5
+ The method takes in an array of historical prices for a stock, a short period (the number of days to calculate the short-term moving average over), a long period (the number of days to calculate the long-term moving average over), and a signal period (the number of days to calculate the signal line moving average over).
6
+
7
+ The method first calculates the short-term moving average by calling the `moving_averages` method with the `prices` array and the `short_period` parameter. It then calculates the long-term moving average by calling the `moving_averages` method with the `prices` array and the `long_period` parameter.
8
+
9
+ Next, the method calculates the MACD line by subtracting the long-term moving average from the short-term moving average. This is done by taking the last element of the `short_ma` array (which contains the short-term moving averages for each window) and subtracting the last element of the `long_ma` array (which contains the long-term moving averages for each window).
10
+
11
+ Finally, the method calculates the signal line by taking the moving average of the MACD line over the specified `signal_period`. This is done by calling the `moving_averages` method with the `short_ma` array and the `signal_period` parameter, and taking the last element of the resulting array.
12
+
13
+ The method returns an array containing the MACD line and the signal line.
14
+
15
+ Note that this is just a basic implementation of the MACD indicator, and there are many variations and refinements that can be made depending on the specific requirements of your program.
16
+
17
+ The Moving Average Convergence Divergence (MACD) is a technical analysis indicator that is used to identify changes in momentum, direction, and trend for a security. The MACD is calculated by subtracting the 26-period exponential moving average (EMA) from the 12-period EMA.
18
+
19
+ The values 1.8231937142857078 and 164.44427957142855 that you provided are likely the MACD line and the signal line, respectively. The MACD line is the difference between the 12-period EMA and the 26-period EMA, while the signal line is a 9-period EMA of the MACD line.
20
+
21
+ The MACD line crossing above the signal line is often considered a bullish signal, while the MACD line crossing below the signal line is often considered a bearish signal. The distance between the MACD line and the signal line can also provide insight into the strength of the trend.
22
+
23
+ Without additional context, it's difficult to interpret the specific values of 1.8231937142857078 and 164.44427957142855 for the MACD and signal lines of a stock. However, in general, the MACD can be used to identify potential buy and sell signals for a security, as well as to provide insight into the strength of the trend.