sqa 0.0.24 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/.goose/memory/development.txt +3 -0
  3. data/.semver +6 -0
  4. data/ARCHITECTURE.md +648 -0
  5. data/CHANGELOG.md +82 -0
  6. data/CLAUDE.md +653 -0
  7. data/COMMITS.md +196 -0
  8. data/DATAFRAME_ARCHITECTURE_REVIEW.md +421 -0
  9. data/NEXT-STEPS.md +154 -0
  10. data/README.md +812 -262
  11. data/TASKS.md +358 -0
  12. data/TEST_RESULTS.md +140 -0
  13. data/TODO.md +42 -0
  14. data/_notes.txt +25 -0
  15. data/bin/sqa-console +11 -0
  16. data/data/talk_talk.json +103284 -0
  17. data/develop_summary.md +313 -0
  18. data/docs/advanced/backtesting.md +206 -0
  19. data/docs/advanced/ensemble.md +68 -0
  20. data/docs/advanced/fpop.md +153 -0
  21. data/docs/advanced/index.md +112 -0
  22. data/docs/advanced/multi-timeframe.md +67 -0
  23. data/docs/advanced/pattern-matcher.md +75 -0
  24. data/docs/advanced/portfolio-optimizer.md +79 -0
  25. data/docs/advanced/portfolio.md +166 -0
  26. data/docs/advanced/risk-management.md +210 -0
  27. data/docs/advanced/strategy-generator.md +158 -0
  28. data/docs/advanced/streaming.md +209 -0
  29. data/docs/ai_and_ml.md +80 -0
  30. data/docs/api/dataframe.md +1115 -0
  31. data/docs/api/index.md +126 -0
  32. data/docs/assets/css/custom.css +88 -0
  33. data/docs/assets/js/mathjax.js +18 -0
  34. data/docs/concepts/index.md +68 -0
  35. data/docs/contributing/index.md +60 -0
  36. data/docs/data-sources/index.md +66 -0
  37. data/docs/data_frame.md +317 -97
  38. data/docs/factors_that_impact_price.md +26 -0
  39. data/docs/finviz.md +11 -0
  40. data/docs/fx_pro_bit.md +25 -0
  41. data/docs/genetic_programming.md +104 -0
  42. data/docs/getting-started/index.md +123 -0
  43. data/docs/getting-started/installation.md +229 -0
  44. data/docs/getting-started/quick-start.md +244 -0
  45. data/docs/i_gotta_an_idea.md +22 -0
  46. data/docs/index.md +163 -0
  47. data/docs/indicators/index.md +97 -0
  48. data/docs/indicators.md +110 -24
  49. data/docs/options.md +8 -0
  50. data/docs/strategies/bollinger-bands.md +146 -0
  51. data/docs/strategies/consensus.md +64 -0
  52. data/docs/strategies/custom.md +310 -0
  53. data/docs/strategies/ema.md +53 -0
  54. data/docs/strategies/index.md +92 -0
  55. data/docs/strategies/kbs.md +164 -0
  56. data/docs/strategies/macd.md +96 -0
  57. data/docs/strategies/market-profile.md +54 -0
  58. data/docs/strategies/mean-reversion.md +58 -0
  59. data/docs/strategies/rsi.md +95 -0
  60. data/docs/strategies/sma.md +55 -0
  61. data/docs/strategies/stochastic.md +63 -0
  62. data/docs/strategies/volume-breakout.md +54 -0
  63. data/docs/tags.md +7 -0
  64. data/docs/true_strength_index.md +46 -0
  65. data/docs/weighted_moving_average.md +48 -0
  66. data/examples/README.md +354 -0
  67. data/examples/advanced_features_example.rb +350 -0
  68. data/examples/fpop_analysis_example.rb +191 -0
  69. data/examples/genetic_programming_example.rb +148 -0
  70. data/examples/kbs_strategy_example.rb +208 -0
  71. data/examples/pattern_context_example.rb +300 -0
  72. data/examples/rails_app/Gemfile +34 -0
  73. data/examples/rails_app/README.md +416 -0
  74. data/examples/rails_app/app/assets/javascripts/application.js +107 -0
  75. data/examples/rails_app/app/assets/stylesheets/application.css +659 -0
  76. data/examples/rails_app/app/controllers/analysis_controller.rb +11 -0
  77. data/examples/rails_app/app/controllers/api/v1/stocks_controller.rb +227 -0
  78. data/examples/rails_app/app/controllers/application_controller.rb +22 -0
  79. data/examples/rails_app/app/controllers/backtest_controller.rb +11 -0
  80. data/examples/rails_app/app/controllers/dashboard_controller.rb +21 -0
  81. data/examples/rails_app/app/controllers/portfolio_controller.rb +7 -0
  82. data/examples/rails_app/app/views/analysis/show.html.erb +209 -0
  83. data/examples/rails_app/app/views/backtest/show.html.erb +171 -0
  84. data/examples/rails_app/app/views/dashboard/index.html.erb +118 -0
  85. data/examples/rails_app/app/views/dashboard/show.html.erb +408 -0
  86. data/examples/rails_app/app/views/errors/show.html.erb +17 -0
  87. data/examples/rails_app/app/views/layouts/application.html.erb +60 -0
  88. data/examples/rails_app/app/views/portfolio/index.html.erb +33 -0
  89. data/examples/rails_app/bin/rails +6 -0
  90. data/examples/rails_app/config/application.rb +45 -0
  91. data/examples/rails_app/config/boot.rb +5 -0
  92. data/examples/rails_app/config/database.yml +18 -0
  93. data/examples/rails_app/config/environment.rb +11 -0
  94. data/examples/rails_app/config/routes.rb +26 -0
  95. data/examples/rails_app/config.ru +8 -0
  96. data/examples/realtime_stream_example.rb +274 -0
  97. data/examples/sinatra_app/Gemfile +22 -0
  98. data/examples/sinatra_app/QUICKSTART.md +159 -0
  99. data/examples/sinatra_app/README.md +461 -0
  100. data/examples/sinatra_app/app.rb +344 -0
  101. data/examples/sinatra_app/config.ru +5 -0
  102. data/examples/sinatra_app/public/css/style.css +659 -0
  103. data/examples/sinatra_app/public/js/app.js +107 -0
  104. data/examples/sinatra_app/views/analyze.erb +306 -0
  105. data/examples/sinatra_app/views/backtest.erb +325 -0
  106. data/examples/sinatra_app/views/dashboard.erb +419 -0
  107. data/examples/sinatra_app/views/error.erb +58 -0
  108. data/examples/sinatra_app/views/index.erb +118 -0
  109. data/examples/sinatra_app/views/layout.erb +61 -0
  110. data/examples/sinatra_app/views/portfolio.erb +43 -0
  111. data/examples/strategy_generator_example.rb +346 -0
  112. data/hsa_portfolio.csv +11 -0
  113. data/justfile +0 -0
  114. data/lib/api/alpha_vantage_api.rb +462 -0
  115. data/lib/sqa/backtest.rb +329 -0
  116. data/lib/sqa/data_frame/alpha_vantage.rb +43 -65
  117. data/lib/sqa/data_frame/data.rb +92 -0
  118. data/lib/sqa/data_frame/yahoo_finance.rb +35 -43
  119. data/lib/sqa/data_frame.rb +148 -243
  120. data/lib/sqa/ensemble.rb +359 -0
  121. data/lib/sqa/fpop.rb +199 -0
  122. data/lib/sqa/gp.rb +259 -0
  123. data/lib/sqa/indicator.rb +5 -8
  124. data/lib/sqa/init.rb +15 -8
  125. data/lib/sqa/market_regime.rb +240 -0
  126. data/lib/sqa/multi_timeframe.rb +379 -0
  127. data/lib/sqa/pattern_matcher.rb +497 -0
  128. data/lib/sqa/portfolio.rb +260 -6
  129. data/lib/sqa/portfolio_optimizer.rb +377 -0
  130. data/lib/sqa/risk_manager.rb +442 -0
  131. data/lib/sqa/seasonal_analyzer.rb +209 -0
  132. data/lib/sqa/sector_analyzer.rb +300 -0
  133. data/lib/sqa/stock.rb +67 -125
  134. data/lib/sqa/strategy/bollinger_bands.rb +42 -0
  135. data/lib/sqa/strategy/consensus.rb +5 -2
  136. data/lib/sqa/strategy/kbs_strategy.rb +470 -0
  137. data/lib/sqa/strategy/macd.rb +46 -0
  138. data/lib/sqa/strategy/mp.rb +1 -1
  139. data/lib/sqa/strategy/stochastic.rb +60 -0
  140. data/lib/sqa/strategy/volume_breakout.rb +57 -0
  141. data/lib/sqa/strategy.rb +5 -0
  142. data/lib/sqa/strategy_generator.rb +947 -0
  143. data/lib/sqa/stream.rb +361 -0
  144. data/lib/sqa/version.rb +1 -7
  145. data/lib/sqa.rb +23 -16
  146. data/main.just +81 -0
  147. data/mkdocs.yml +288 -0
  148. data/trace.log +0 -0
  149. metadata +261 -51
  150. data/bin/sqa +0 -6
  151. data/lib/patches/dry-cli.rb +0 -228
  152. data/lib/sqa/activity.rb +0 -10
  153. data/lib/sqa/cli.rb +0 -62
  154. data/lib/sqa/commands/analysis.rb +0 -309
  155. data/lib/sqa/commands/base.rb +0 -139
  156. data/lib/sqa/commands/web.rb +0 -199
  157. data/lib/sqa/commands.rb +0 -22
  158. data/lib/sqa/constants.rb +0 -23
  159. data/lib/sqa/indicator/average_true_range.rb +0 -33
  160. data/lib/sqa/indicator/bollinger_bands.rb +0 -28
  161. data/lib/sqa/indicator/candlestick_pattern_recognizer.rb +0 -60
  162. data/lib/sqa/indicator/donchian_channel.rb +0 -29
  163. data/lib/sqa/indicator/double_top_bottom_pattern.rb +0 -34
  164. data/lib/sqa/indicator/elliott_wave_theory.rb +0 -57
  165. data/lib/sqa/indicator/exponential_moving_average.rb +0 -25
  166. data/lib/sqa/indicator/exponential_moving_average_trend.rb +0 -36
  167. data/lib/sqa/indicator/fibonacci_retracement.rb +0 -23
  168. data/lib/sqa/indicator/head_and_shoulders_pattern.rb +0 -26
  169. data/lib/sqa/indicator/market_profile.rb +0 -32
  170. data/lib/sqa/indicator/mean_reversion.rb +0 -37
  171. data/lib/sqa/indicator/momentum.rb +0 -28
  172. data/lib/sqa/indicator/moving_average_convergence_divergence.rb +0 -29
  173. data/lib/sqa/indicator/peaks_and_valleys.rb +0 -29
  174. data/lib/sqa/indicator/predict_next_value.rb +0 -202
  175. data/lib/sqa/indicator/relative_strength_index.rb +0 -47
  176. data/lib/sqa/indicator/simple_moving_average.rb +0 -24
  177. data/lib/sqa/indicator/simple_moving_average_trend.rb +0 -32
  178. data/lib/sqa/indicator/stochastic_oscillator.rb +0 -68
  179. data/lib/sqa/indicator/true_range.rb +0 -39
  180. data/lib/sqa/trade.rb +0 -26
@@ -0,0 +1,54 @@
1
+ # Market Profile Strategy
2
+
3
+ ## Overview
4
+
5
+ Uses market profile analysis to identify support and resistance levels, generating signals when price reaches these key levels.
6
+
7
+ ## How It Works
8
+
9
+ Analyzes price distribution to find:
10
+ - **Value Area**: Where most trading occurred
11
+ - **Support**: Lower boundary (buy zone)
12
+ - **Resistance**: Upper boundary (sell zone)
13
+
14
+ ## Trading Signals
15
+
16
+ ### Buy Signal
17
+ Price at support level (`:support`).
18
+
19
+ ### Sell Signal
20
+ Price at resistance level (`:resistance`).
21
+
22
+ ### Hold Signal
23
+ Price within value area (`:mixed`).
24
+
25
+ ## Usage Example
26
+
27
+ ```ruby
28
+ # Market profile data typically comes from
29
+ # price/volume distribution analysis
30
+ vector = OpenStruct.new(
31
+ market_profile: :support # or :resistance, :mixed
32
+ )
33
+
34
+ signal = SQA::Strategy::MP.trade(vector)
35
+ ```
36
+
37
+ ## Characteristics
38
+
39
+ - **Complexity**: High
40
+ - **Best Market**: Range-bound
41
+ - **Win Rate**: 55-65%
42
+
43
+ ## Strengths
44
+
45
+ ✅ Identifies key price levels
46
+ ✅ Works well for intraday trading
47
+ ✅ Statistical basis
48
+
49
+ ## Weaknesses
50
+
51
+ ❌ Requires volume profile data
52
+ ❌ Complex to calculate
53
+ ❌ Less effective in trending markets
54
+
@@ -0,0 +1,58 @@
1
+ # Mean Reversion Strategy
2
+
3
+ ## Overview
4
+
5
+ Based on the theory that prices tend to return to their average over time. Buys when price is below average and sells when above.
6
+
7
+ ## How It Works
8
+
9
+ Calculates distance from moving average:
10
+ - **Below average**: Expect price to rise (buy)
11
+ - **Above average**: Expect price to fall (sell)
12
+
13
+ ## Trading Signals
14
+
15
+ ### Buy Signal
16
+ Price significantly below SMA (undervalued).
17
+
18
+ ### Sell Signal
19
+ Price significantly above SMA (overvalued).
20
+
21
+ ## Usage Example
22
+
23
+ ```ruby
24
+ prices = stock.df["adj_close_price"].to_a
25
+ sma = SQAI.sma(prices, period: 20)
26
+
27
+ current_price = prices.last
28
+ current_sma = sma.last
29
+ deviation = ((current_price - current_sma) / current_sma) * 100
30
+
31
+ # Buy if more than 5% below SMA
32
+ signal = if deviation < -5.0
33
+ :buy
34
+ elsif deviation > 5.0
35
+ :sell
36
+ else
37
+ :hold
38
+ end
39
+ ```
40
+
41
+ ## Characteristics
42
+
43
+ - **Complexity**: Low
44
+ - **Best Market**: Range-bound, low volatility
45
+ - **Win Rate**: 55-65%
46
+
47
+ ## Strengths
48
+
49
+ ✅ High win rate in ranging markets
50
+ ✅ Clear mathematical basis
51
+ ✅ Works well with statistical analysis
52
+
53
+ ## Weaknesses
54
+
55
+ ❌ Fails in trending markets
56
+ ❌ Can lead to "catching falling knives"
57
+ ❌ Requires stable market conditions
58
+
@@ -0,0 +1,95 @@
1
+ # RSI Strategy
2
+
3
+ ## Overview
4
+
5
+ The Relative Strength Index (RSI) strategy identifies overbought and oversold conditions using momentum oscillators. It generates signals when RSI crosses key thresholds.
6
+
7
+ ## How It Works
8
+
9
+ RSI is a momentum oscillator that ranges from 0 to 100:
10
+ - **Over 70**: Overbought (sell signal)
11
+ - **Under 30**: Oversold (buy signal)
12
+ - **30-70**: Neutral (hold)
13
+
14
+ ## Trading Signals
15
+
16
+ ### Buy Signal (`rsi.level == :oversold`)
17
+ ```ruby
18
+ SQA::Strategy::RSI.trade(vector) # => :buy when RSI < 30
19
+ ```
20
+
21
+ ### Sell Signal (`rsi.level == :overbought`)
22
+ ```ruby
23
+ SQA::Strategy::RSI.trade(vector) # => :sell when RSI > 70
24
+ ```
25
+
26
+ ## Usage Example
27
+
28
+ ```ruby
29
+ require 'sqa'
30
+ require 'ostruct'
31
+
32
+ stock = SQA::Stock.new(ticker: 'AAPL')
33
+ prices = stock.df["adj_close_price"].to_a
34
+
35
+ # Calculate RSI using TA-Lib
36
+ rsi_values = SQAI.rsi(prices, period: 14)
37
+
38
+ # Create indicator data structure
39
+ rsi_data = {
40
+ value: rsi_values.last,
41
+ trend: rsi_values.last < 30 ? :over_sold :
42
+ rsi_values.last > 70 ? :over_bought : :neutral
43
+ }
44
+
45
+ vector = OpenStruct.new(rsi: rsi_data)
46
+ signal = SQA::Strategy::RSI.trade(vector)
47
+ ```
48
+
49
+ ## Parameters
50
+
51
+ | Parameter | Default | Description |
52
+ |-----------|---------|-------------|
53
+ | Period | 14 | Number of periods for RSI calculation |
54
+ | Oversold | 30 | Lower threshold for buy signals |
55
+ | Overbought | 70 | Upper threshold for sell signals |
56
+
57
+ ## Characteristics
58
+
59
+ | Attribute | Value |
60
+ |-----------|-------|
61
+ | Complexity | Low |
62
+ | Best Market | Range-bound, volatile |
63
+ | Win Rate | 50-60% |
64
+ | Time Horizon | Short to medium term |
65
+
66
+ ## Strengths
67
+
68
+ - ✅ Simple and well-understood
69
+ - ✅ Works in ranging markets
70
+ - ✅ Can identify divergences
71
+ - ✅ Fast response to price changes
72
+
73
+ ## Weaknesses
74
+
75
+ - ❌ Fails in strong trends
76
+ - ❌ Can stay overbought/oversold for extended periods
77
+ - ❌ Generates false signals
78
+
79
+ ## Tips
80
+
81
+ 1. **Combine with Trend**: Only take buy signals in uptrends
82
+ 2. **Adjust Thresholds**: Use 20/80 for more conservative signals
83
+ 3. **Watch Divergences**: Price makes new highs but RSI doesn't (bearish divergence)
84
+ 4. **Volume Confirmation**: Stronger signals with high volume
85
+
86
+ ## Related Strategies
87
+
88
+ - [Stochastic](stochastic.md) - Similar momentum oscillator
89
+ - [MACD](macd.md) - Trend-following momentum
90
+ - [Bollinger Bands](bollinger-bands.md) - Volatility-based signals
91
+
92
+ ## Further Reading
93
+
94
+ - [RSI on Investopedia](https://www.investopedia.com/terms/r/rsi.asp)
95
+ - [Trading with RSI](../concepts/momentum.md)
@@ -0,0 +1,55 @@
1
+ # SMA (Simple Moving Average) Strategy
2
+
3
+ ## Overview
4
+
5
+ The SMA strategy uses crossovers of short-term and long-term simple moving averages to identify trend changes and generate trading signals.
6
+
7
+ ## How It Works
8
+
9
+ Compares two SMAs:
10
+ - **Short SMA**: Faster, more responsive (e.g., 50-day)
11
+ - **Long SMA**: Slower, smoother (e.g., 200-day)
12
+
13
+ ## Trading Signals
14
+
15
+ ### Buy Signal (Golden Cross)
16
+ Short SMA crosses **above** long SMA.
17
+
18
+ ### Sell Signal (Death Cross)
19
+ Short SMA crosses **below** long SMA.
20
+
21
+ ## Usage Example
22
+
23
+ ```ruby
24
+ stock = SQA::Stock.new(ticker: 'AAPL')
25
+ prices = stock.df["adj_close_price"].to_a
26
+
27
+ sma_short = SQAI.sma(prices, period: 50)
28
+ sma_long = SQAI.sma(prices, period: 200)
29
+
30
+ vector = OpenStruct.new(
31
+ sma_short: sma_short,
32
+ sma_long: sma_long
33
+ )
34
+
35
+ signal = SQA::Strategy::SMA.trade(vector)
36
+ ```
37
+
38
+ ## Characteristics
39
+
40
+ - **Complexity**: Low
41
+ - **Best Market**: Trending
42
+ - **Win Rate**: 45-55%
43
+
44
+ ## Strengths
45
+
46
+ ✅ Simple and reliable
47
+ ✅ Filters market noise
48
+ ✅ Identifies major trends
49
+
50
+ ## Weaknesses
51
+
52
+ ❌ Significant lag
53
+ ❌ Late entry/exit
54
+ ❌ Poor in ranging markets
55
+
@@ -0,0 +1,63 @@
1
+ # Stochastic Oscillator Strategy
2
+
3
+ ## Overview
4
+
5
+ Compares closing price to the price range over a period to identify overbought/oversold conditions and momentum changes.
6
+
7
+ ## How It Works
8
+
9
+ Calculates two lines:
10
+ - **%K Line**: (Current Close - Lowest Low) / (Highest High - Lowest Low) × 100
11
+ - **%D Line**: 3-period SMA of %K
12
+
13
+ Range: 0-100
14
+
15
+ ## Trading Signals
16
+
17
+ ### Buy Signal
18
+ - %K crosses above %D
19
+ - Both below 20 (oversold zone)
20
+
21
+ ### Sell Signal
22
+ - %K crosses below %D
23
+ - Both above 80 (overbought zone)
24
+
25
+ ## Usage Example
26
+
27
+ ```ruby
28
+ high = stock.df["high_price"].to_a
29
+ low = stock.df["low_price"].to_a
30
+ close = stock.df["adj_close_price"].to_a
31
+
32
+ stoch_k, stoch_d = SQAI.stoch(
33
+ high, low, close,
34
+ fastk_period: 14,
35
+ slowk_period: 3,
36
+ slowd_period: 3
37
+ )
38
+
39
+ vector = OpenStruct.new(
40
+ stoch_k: stoch_k,
41
+ stoch_d: stoch_d
42
+ )
43
+
44
+ signal = SQA::Strategy::Stochastic.trade(vector)
45
+ ```
46
+
47
+ ## Characteristics
48
+
49
+ - **Complexity**: Medium
50
+ - **Best Market**: Range-bound
51
+ - **Win Rate**: 50-60%
52
+
53
+ ## Strengths
54
+
55
+ ✅ Good for reversals
56
+ ✅ Works in ranging markets
57
+ ✅ Early signals
58
+
59
+ ## Weaknesses
60
+
61
+ ❌ Many false signals in trends
62
+ ❌ Can stay overbought/oversold
63
+
@@ -0,0 +1,54 @@
1
+ # Volume Breakout Strategy
2
+
3
+ ## Overview
4
+
5
+ Identifies price breakouts confirmed by high trading volume for stronger signal reliability.
6
+
7
+ ## How It Works
8
+
9
+ Looks for:
10
+ 1. Price breaking above recent high or below recent low
11
+ 2. Volume exceeding 1.5x the average volume
12
+
13
+ ## Trading Signals
14
+
15
+ ### Buy Signal
16
+ - Price breaks above 20-period high
17
+ - Volume > 1.5× average volume
18
+
19
+ ### Sell Signal
20
+ - Price breaks below 20-period low
21
+ - Volume > 1.5× average volume
22
+
23
+ ## Usage Example
24
+
25
+ ```ruby
26
+ prices = stock.df["adj_close_price"].to_a
27
+ volumes = stock.df["volume"].to_a
28
+
29
+ vector = OpenStruct.new(
30
+ prices: prices,
31
+ volumes: volumes
32
+ )
33
+
34
+ signal = SQA::Strategy::VolumeBreakout.trade(vector)
35
+ ```
36
+
37
+ ## Characteristics
38
+
39
+ - **Complexity**: Medium
40
+ - **Best Market**: Breakout/trending
41
+ - **Win Rate**: 50-60%
42
+
43
+ ## Strengths
44
+
45
+ ✅ Volume confirmation reduces false breakouts
46
+ ✅ Catches strong moves
47
+ ✅ Clear entry points
48
+
49
+ ## Weaknesses
50
+
51
+ ❌ Rare signals
52
+ ❌ Can whipsaw on false breakouts
53
+ ❌ Requires both price and volume data
54
+
data/docs/tags.md ADDED
@@ -0,0 +1,7 @@
1
+ # Documentation Tags
2
+
3
+ Browse documentation by topic.
4
+
5
+ ## Tags
6
+
7
+ This page will be automatically populated with tags from the documentation.
@@ -0,0 +1,46 @@
1
+ # Technical Market Analysis: Understanding the True Strength Index (TSI)
2
+
3
+ The **True Strength Index (TSI)** is a technical momentum oscillator used to identify trends and reversals primarily in the price of a security. It is not directly related to the Relative Strength Index (RSI), although both are momentum indicators.
4
+
5
+ ## How TSI is Calculated
6
+
7
+ The TSI formula is based on double smoothing of price changes:
8
+
9
+ 1. **Calculate the Price Momentum**:
10
+ - Determine the daily price change: Current price minus previous price.
11
+ - Create a 25-period Exponential Moving Average (EMA) of price changes (this period can vary based on the trader's preference).
12
+
13
+ 2. **Calculate the Absolute Price Momentum**:
14
+ - Calculate the absolute value of the daily price change.
15
+ - Create a 25-period EMA of the absolute price changes.
16
+
17
+ 3. **Apply a Secondary Smoothing**:
18
+ - Calculate a 13-period EMA of the 25-period EMA of price changes.
19
+ - Calculate a 13-period EMA of the 25-period EMA of the absolute price changes.
20
+
21
+ 4. **The TSI Formula**:
22
+ - TSI = 100 x (Double Smoothed Price Change / Double Smoothed Absolute Price Change)
23
+
24
+ The most common settings for the TSI are the 25-period EMA for initial smoothing and the 13-period EMA for the second smoothing. These periods can be adjusted to suit different trading styles and timeframes.
25
+
26
+ ## How to Interpret TSI
27
+
28
+ - **Centerline Crossover**:
29
+ - When the TSI crosses above the centerline (0), it is considered bullish.
30
+ - When it crosses below the centerline, it is considered bearish.
31
+
32
+ - **Signal Line Crossover**:
33
+ - Traders often add a signal line, which is an EMA of the TSI (commonly a 7-period EMA).
34
+ - A bullish signal is generated when the TSI crosses above the signal line.
35
+ - A bearish signal is generated when TSI crosses below the signal line.
36
+
37
+ - **Overbought / Oversold Conditions**:
38
+ - The TSI can indicate overbought or oversold conditions. However, unlike RSI, there are no standard levels, such as 70 or 30, to indicate these conditions in TSI.
39
+ - Traders often observe extreme levels or divergence with the price to identify possible reversals.
40
+
41
+ - **Divergences**:
42
+ - Bullish divergence occurs if the price is making new lows while the TSI is failing to make new lows.
43
+ - Bearish divergence occurs if the price is making new highs while the TSI is failing to make new highs.
44
+
45
+ The TSI can be a valuable tool in your technical analysis toolkit. It helps to smooth out the volatility inherent in the market and provides a clearer picture of the price momentum. As with any technical indicator, it is advisable to use the TSI in conjunction with other tools and analysis methods to confirm signals and make informed trading decisions.
46
+
@@ -0,0 +1,48 @@
1
+ ## Weighted Moving Average (WMA)
2
+
3
+ ### What is a Weighted Moving Average?
4
+
5
+ A Weighted Moving Average (WMA) is a type of moving average that assigns more importance to recent prices by giving them greater weights. Unlike a simple moving average (SMA) that treats all values equally, a WMA emphasizes the latest data points, thus responding more quickly to price changes.
6
+
7
+ ### How is a WMA Calculated?
8
+
9
+ To calculate a WMA, you follow these steps:
10
+
11
+ 1. Choose the number of periods (n) for the average.
12
+ 2. Assign weights to each price point, with the most recent price having the highest weight and the oldest price having the lowest. Weights typically decrement by 1 - for example, starting from n down to 1.
13
+ 3. Multiply each price by its corresponding weight.
14
+ 4. Sum up the weighted prices.
15
+ 5. Divide the sum by the total of the weights.
16
+
17
+ The formula for WMA is:
18
+
19
+ WMA = (Price_n * Weight_n + Price_(n-1) * Weight_(n-1) + ... + Price_1 * Weight_1) / (Weight_n + Weight_(n-1) + ... + Weight_1)
20
+
21
+ Where:
22
+ - Price_n is the most recent price,
23
+ - Weight_n is the weight for the most recent price (usually equal to n).
24
+
25
+ ### Using a Weighted Moving Average in Technical Analysis
26
+
27
+ A WMA is used in technical stock market analysis to smooth out price data and help identify trends. Here are some common uses:
28
+
29
+ 1. **Trend Identification**: An upward sloping WMA indicates an uptrend, while a downward sloping WMA suggests a downtrend.
30
+
31
+ 2. **Support and Resistance**: A WMA can act as a potential support or resistance level. Prices often bounce off the WMA line or struggle to break through it.
32
+
33
+ 3. **Crossover Signals**: The crossover of a short-term WMA above a long-term WMA may signal a bullish trend, and vice versa for a bearish trend.
34
+
35
+ 4. **Enhanced Reaction**: WMAs can provide quicker signals than simple moving averages due to their greater emphasis on recent prices, which is useful for short-term traders looking for prompt entry or exit points.
36
+
37
+ 5. **Confluence with Other Indicators**: Traders often use WMAs in conjunction with other indicators, such as the Relative Strength Index (RSI) or Moving Average Convergence Divergence (MACD), to confirm signals or gain additional insights into market momentum.
38
+
39
+ ### Limitations of Weighted Moving Averages
40
+
41
+ 1. **Lagging Indicator**: While WMAs are designed to be more responsive than simple moving averages, they are still lagging indicators and might give signals after a trend has already begun.
42
+
43
+ 2. **Noise**: In highly volatile markets, the WMA might be too reactive to price changes, resulting in false signals.
44
+
45
+ 3. **Subjectivity**: The choice of the period and weight assignment can be subjective and significantly impact the analysis outcomes.
46
+
47
+ Traders should consider these limitations and ideally combine the WMA with other forms of analysis to make informed trading decisions.
48
+