sqa 0.0.31 → 0.0.32

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/CLAUDE.md +21 -0
  4. data/README.md +56 -32
  5. data/docs/api/dataframe.md +0 -1
  6. data/docs/assets/images/sqa.jpg +0 -0
  7. data/docs/concepts/index.md +2 -10
  8. data/docs/data_frame.md +0 -1
  9. data/docs/getting-started/index.md +0 -16
  10. data/docs/getting-started/installation.md +2 -2
  11. data/docs/getting-started/quick-start.md +4 -4
  12. data/docs/index.md +0 -2
  13. data/docs/strategies/bollinger-bands.md +1 -1
  14. data/docs/strategies/rsi.md +1 -1
  15. data/examples/sinatra_app/Gemfile +20 -0
  16. data/examples/sinatra_app/Gemfile.lock +268 -0
  17. data/examples/sinatra_app/QUICKSTART.md +13 -3
  18. data/examples/sinatra_app/README.md +12 -2
  19. data/examples/sinatra_app/RUNNING_WITHOUT_TALIB.md +90 -0
  20. data/examples/sinatra_app/TROUBLESHOOTING.md +95 -0
  21. data/examples/sinatra_app/app.rb +85 -25
  22. data/examples/sinatra_app/public/css/style.css +101 -37
  23. data/examples/sinatra_app/public/debug_macd.html +82 -0
  24. data/examples/sinatra_app/start.sh +53 -0
  25. data/examples/sinatra_app/views/dashboard.erb +558 -146
  26. data/examples/sinatra_app/views/layout.erb +2 -2
  27. data/lib/sqa/data_frame/alpha_vantage.rb +13 -3
  28. data/lib/sqa/data_frame.rb +21 -15
  29. data/lib/sqa/indicator.rb +17 -4
  30. data/lib/sqa/stock.rb +73 -11
  31. data/lib/sqa/ticker.rb +9 -2
  32. data/lib/sqa/version.rb +1 -1
  33. data/lib/sqa.rb +12 -4
  34. data/mkdocs.yml +4 -40
  35. metadata +7 -21
  36. data/docs/alpha_vantage_technical_indicators.md +0 -62
  37. data/docs/average_true_range.md +0 -9
  38. data/docs/bollinger_bands.md +0 -15
  39. data/docs/candlestick_pattern_recognizer.md +0 -4
  40. data/docs/donchian_channel.md +0 -5
  41. data/docs/double_top_bottom_pattern.md +0 -3
  42. data/docs/exponential_moving_average.md +0 -19
  43. data/docs/fibonacci_retracement.md +0 -30
  44. data/docs/head_and_shoulders_pattern.md +0 -3
  45. data/docs/market_profile.md +0 -4
  46. data/docs/momentum.md +0 -19
  47. data/docs/moving_average_convergence_divergence.md +0 -23
  48. data/docs/peaks_and_valleys.md +0 -11
  49. data/docs/relative_strength_index.md +0 -6
  50. data/docs/simple_moving_average.md +0 -8
  51. data/docs/stochastic_oscillator.md +0 -4
  52. data/docs/ta_lib.md +0 -160
  53. data/docs/true_range.md +0 -12
  54. data/docs/true_strength_index.md +0 -46
  55. data/docs/weighted_moving_average.md +0 -48
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>SQA - Stock Analysis Platform</title>
7
7
 
8
- <!-- Plotly.js for charts -->
9
- <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
8
+ <!-- ApexCharts for charts -->
9
+ <script src="https://cdn.jsdelivr.net/npm/apexcharts@3.45.1/dist/apexcharts.min.js"></script>
10
10
 
11
11
  <!-- Custom CSS -->
12
12
  <link rel="stylesheet" href="/css/style.css">
@@ -35,9 +35,14 @@ class SQA::DataFrame
35
35
 
36
36
  ################################################################
37
37
 
38
- # Get recent data from JSON API
38
+ # Get recent data from Alpha Vantage API
39
+ #
39
40
  # ticker String the security to retrieve
40
- # returns a Polars DataFrame
41
+ # full Boolean whether to fetch full history or compact (last 100 days)
42
+ # from_date Date optional date to fetch data after (for incremental updates)
43
+ #
44
+ # Returns: SQA::DataFrame sorted in ASCENDING order (oldest to newest)
45
+ # Note: Alpha Vantage returns data newest-first, but we sort ascending for TA-Lib compatibility
41
46
  def self.recent(ticker, full: false, from_date: nil)
42
47
  response = CONNECTION.get(
43
48
  "/query?" +
@@ -67,7 +72,8 @@ class SQA::DataFrame
67
72
  # Handle date criteria if applicable
68
73
  if from_date
69
74
  # Use Polars.col() to create an expression for filtering
70
- df = df.filter(Polars.col("timestamp") >= from_date.to_s)
75
+ # Use > (not >=) to exclude the from_date itself and prevent duplicates
76
+ df = df.filter(Polars.col("timestamp") > from_date.to_s)
71
77
  end
72
78
 
73
79
  # Wrap in SQA::DataFrame with proper transformers
@@ -80,6 +86,10 @@ class SQA::DataFrame
80
86
  sqa_df.data["close_price"].alias("adj_close_price")
81
87
  )
82
88
 
89
+ # Sort data in ascending chronological order (oldest to newest) for TA-Lib compatibility
90
+ # Alpha Vantage returns data newest-first, but TA-Lib expects oldest-first
91
+ sqa_df.data = sqa_df.data.sort("timestamp", reverse: false)
92
+
83
93
  sqa_df
84
94
  end
85
95
  end
@@ -18,13 +18,6 @@ class SQA::DataFrame
18
18
  def initialize(raw_data = nil, mapping: {}, transformers: {})
19
19
  @data = Polars::DataFrame.new(raw_data || [])
20
20
 
21
- debug_me{[
22
- :raw_data,
23
- :mapping,
24
- :transformers,
25
- '@data'
26
- ]}
27
-
28
21
  # IMPORTANT: Rename columns FIRST, then apply transformers
29
22
  # Transformers expect renamed column names
30
23
  rename_columns!(mapping) unless mapping.empty?
@@ -77,6 +70,27 @@ class SQA::DataFrame
77
70
  end
78
71
  alias concat! append!
79
72
 
73
+ # Concatenate another DataFrame, remove duplicates, and sort
74
+ # This is the preferred method for updating CSV data to prevent duplicates
75
+ #
76
+ # @param other_df [SQA::DataFrame] DataFrame to append
77
+ # @param sort_column [String] Column to use for deduplication and sorting (default: "timestamp")
78
+ # @param descending [Boolean] Sort order - false for ascending (oldest first, TA-Lib compatible), true for descending
79
+ def concat_and_deduplicate!(other_df, sort_column: "timestamp", descending: false)
80
+ # Concatenate the dataframes
81
+ @data = if @data.shape[0] == 0
82
+ other_df.data
83
+ else
84
+ @data.vstack(other_df.data)
85
+ end
86
+
87
+ # Remove duplicates based on sort_column, keeping first occurrence
88
+ @data = @data.unique(subset: [sort_column], keep: "first")
89
+
90
+ # Sort by the specified column (Polars uses 'reverse' for descending)
91
+ @data = @data.sort(sort_column, reverse: descending)
92
+ end
93
+
80
94
  def columns
81
95
  @data.columns
82
96
  end
@@ -196,14 +210,6 @@ class SQA::DataFrame
196
210
 
197
211
 
198
212
  def from_csv_file(source, mapping: {}, transformers: {})
199
- debug_me do
200
- %i[
201
- source
202
- mapping
203
- transformers
204
- ]
205
- end
206
-
207
213
  df = Polars.read_csv(source)
208
214
  new(df, mapping: mapping, transformers: transformers)
209
215
  end
data/lib/sqa/indicator.rb CHANGED
@@ -1,8 +1,21 @@
1
1
  # lib/sqa/indicator.rb
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'sqa/tai'
4
+ # Try to load TA-Lib indicators, but make them optional
5
+ # This allows the library to work without TA-Lib installed for basic data loading
6
+ begin
7
+ require 'sqa/tai'
5
8
 
6
- # Use SQA::TAI directly for all technical analysis indicators
7
- # SQAI is a shortcut alias for SQA::TAI
8
- SQAI = SQA::TAI
9
+ # Use SQA::TAI directly for all technical analysis indicators
10
+ # SQAI is a shortcut alias for SQA::TAI
11
+ SQAI = SQA::TAI
12
+ rescue LoadError, Fiddle::DLError => e
13
+ # TA-Lib not available - define a stub that gives helpful errors
14
+ warn "Warning: TA-Lib not available (#{e.class}: #{e.message}). Technical indicators will not work." if $VERBOSE
15
+
16
+ module SQAI
17
+ def self.method_missing(method, *args, &block)
18
+ raise "Technical indicators require TA-Lib to be installed. Please install libta-lib system library. Visit: http://ta-lib.org/hdr_dw.html"
19
+ end
20
+ end
21
+ end
data/lib/sqa/stock.rb CHANGED
@@ -11,11 +11,16 @@ class SQA::Stock
11
11
  @ticker = ticker.downcase
12
12
  @source = source
13
13
 
14
- raise "Invalid Ticker #{ticker}" unless SQA::Ticker.valid?(ticker)
15
-
16
14
  @data_path = SQA.data_dir + "#{@ticker}.json"
17
15
  @df_path = SQA.data_dir + "#{@ticker}.csv"
18
16
 
17
+ # Validate ticker if validation data is available and cached data doesn't exist
18
+ unless @data_path.exist? && @df_path.exist?
19
+ unless SQA::Ticker.valid?(ticker)
20
+ warn "Warning: Ticker #{ticker} could not be validated. Proceeding anyway." if $VERBOSE
21
+ end
22
+ end
23
+
19
24
  @klass = "SQA::DataFrame::#{@source.to_s.camelize}".constantize
20
25
  @transformers = "SQA::DataFrame::#{@source.to_s.camelize}::TRANSFORMERS".constantize
21
26
 
@@ -27,8 +32,14 @@ class SQA::Stock
27
32
  if @data_path.exist?
28
33
  @data = SQA::DataFrame::Data.new(JSON.parse(@data_path.read))
29
34
  else
35
+ # Create minimal data structure
30
36
  create_data
37
+
38
+ # Try to fetch overview data, but don't fail if we can't
39
+ # This is optional metadata - we can work with just price data
31
40
  update
41
+
42
+ # Save whatever data we have (even if overview fetch failed)
32
43
  save_data
33
44
  end
34
45
  end
@@ -38,7 +49,13 @@ class SQA::Stock
38
49
  end
39
50
 
40
51
  def update
41
- merge_overview
52
+ begin
53
+ merge_overview
54
+ rescue => e
55
+ # Log warning but don't fail - overview data is optional
56
+ # Common causes: rate limits, network issues, API errors
57
+ warn "Warning: Could not fetch overview data for #{@ticker} (#{e.class}: #{e.message}). Continuing without it."
58
+ end
42
59
  end
43
60
 
44
61
  def save_data
@@ -82,27 +99,72 @@ class SQA::Stock
82
99
  @df.to_csv(@df_path) if migrated
83
100
  else
84
101
  # Fetch fresh data from source (applies transformers and mapping)
85
- @df = @klass.recent(@ticker, full: true)
86
- @df.to_csv(@df_path)
87
- return
102
+ begin
103
+ @df = @klass.recent(@ticker, full: true)
104
+ @df.to_csv(@df_path)
105
+ return
106
+ rescue => e
107
+ # If we can't fetch data, raise a more helpful error
108
+ raise "Unable to fetch data for #{@ticker}. Please ensure API key is set or provide cached CSV file at #{@df_path}. Error: #{e.message}"
109
+ end
88
110
  end
89
111
 
90
112
  update_dataframe_with_recent_data
91
113
  end
92
114
 
93
115
  def update_dataframe_with_recent_data
94
- from_date = Date.parse(@df["timestamp"].to_a.last)
95
- df2 = @klass.recent(@ticker, from_date: from_date)
116
+ return unless should_update?
96
117
 
97
- if df2 && (df2.size > 0)
98
- @df.concat!(df2)
99
- @df.to_csv(@df_path)
118
+ begin
119
+ # CSV is sorted ascending (oldest first, TA-Lib compatible), so .last gets the most recent date
120
+ from_date = Date.parse(@df["timestamp"].to_a.last)
121
+ df2 = @klass.recent(@ticker, from_date: from_date)
122
+
123
+ if df2 && (df2.size > 0)
124
+ # Use concat_and_deduplicate! to prevent duplicate timestamps and maintain ascending sort
125
+ @df.concat_and_deduplicate!(df2)
126
+ @df.to_csv(@df_path)
127
+ end
128
+ rescue => e
129
+ # Log warning but don't fail - we have cached data
130
+ # Common causes: rate limits, network issues, API errors
131
+ warn "Warning: Could not update #{@ticker} from API (#{e.class}: #{e.message}). Using cached data."
100
132
  end
101
133
  end
102
134
 
135
+ def should_update?
136
+ # Don't update if we're in lazy update mode
137
+ return false if SQA.config.lazy_update
138
+
139
+ # Don't update if we don't have an API key (only relevant for Alpha Vantage)
140
+ if @source == :alpha_vantage
141
+ begin
142
+ SQA.av_api_key
143
+ rescue
144
+ return false
145
+ end
146
+ end
147
+
148
+ # Don't update if CSV data is already current (last timestamp is today or later)
149
+ # This prevents unnecessary API calls when we already have today's data
150
+ if @df && @df.size > 0
151
+ begin
152
+ last_timestamp = Date.parse(@df["timestamp"].to_a.last)
153
+ return false if last_timestamp >= Date.today
154
+ rescue => e
155
+ # If we can't parse the date, assume we need to update
156
+ warn "Warning: Could not parse last timestamp for #{@ticker} (#{e.message}). Will attempt update." if $VERBOSE
157
+ end
158
+ end
159
+
160
+ true
161
+ end
162
+
103
163
  def to_s
104
164
  "#{ticker} with #{@df.size} data points from #{@df["timestamp"].to_a.first} to #{@df["timestamp"].to_a.last}"
105
165
  end
166
+ # Note: CSV data is stored in ascending chronological order (oldest to newest)
167
+ # This ensures compatibility with TA-Lib indicators which expect arrays in this order
106
168
  alias_method :inspect, :to_s
107
169
 
108
170
  def merge_overview
data/lib/sqa/ticker.rb CHANGED
@@ -36,14 +36,21 @@ class SQA::Ticker
36
36
  until(found || tries >= 3) do
37
37
  files = Pathname.new(SQA.config.data_dir).children.select{|c| c.basename.to_s.start_with?(FILENAME_PREFIX)}.sort
38
38
  if files.empty?
39
- download
39
+ begin
40
+ download
41
+ rescue => e
42
+ warn "Warning: Could not download ticker list: #{e.message}" if $VERBOSE
43
+ end
40
44
  tries += 1
41
45
  else
42
46
  found = true
43
47
  end
44
48
  end
45
49
 
46
- raise "NoDataError" if files.empty?
50
+ if files.empty?
51
+ warn "Warning: No ticker validation data available. Proceeding without validation." if $VERBOSE
52
+ return {}
53
+ end
47
54
 
48
55
  load_from_csv files.last
49
56
  end
data/lib/sqa/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SQA
4
- VERSION = '0.0.31'
4
+ VERSION = '0.0.32'
5
5
  end
data/lib/sqa.rb CHANGED
@@ -20,13 +20,21 @@ if defined?(DebugMe)
20
20
  unless respond_to?(:debug_me)
21
21
  include DebugMe
22
22
  end
23
+ $DEBUG_ME = true
23
24
  else
24
- require 'debug_me'
25
- include DebugMe
25
+ begin
26
+ require 'debug_me'
27
+ include DebugMe
28
+ $DEBUG_ME = true
29
+ rescue LoadError
30
+ # debug_me is optional - define a no-op if not available
31
+ def debug_me(tag = nil, &block)
32
+ # No-op when debug_me gem is not available
33
+ end
34
+ $DEBUG_ME = false
35
+ end
26
36
  end
27
37
 
28
- $DEBUG_ME = true
29
-
30
38
  #############################################
31
39
  ## Additional Libraries
32
40
 
data/mkdocs.yml CHANGED
@@ -179,42 +179,18 @@ nav:
179
179
  - getting-started/index.md
180
180
  - Installation: getting-started/installation.md
181
181
  - Quick Start: getting-started/quick-start.md
182
- - Configuration: getting-started/configuration.md
183
- - Console Usage: getting-started/console-usage.md
184
182
 
185
183
  - Core Concepts:
186
184
  - concepts/index.md
187
- - Stock Objects: concepts/stock.md
188
185
  - DataFrames: data_frame.md
189
- - Technical Indicators: concepts/indicators.md
186
+ - Technical Indicators: indicators/index.md
190
187
  - Trading Strategies: strategy.md
191
188
 
192
189
  - Technical Indicators:
193
190
  - indicators/index.md
194
191
  - Overview: indicators.md
195
- - Moving Averages:
196
- - Simple Moving Average: simple_moving_average.md
197
- - Exponential Moving Average: exponential_moving_average.md
198
- - Weighted Moving Average: weighted_moving_average.md
199
- - Momentum Indicators:
200
- - RSI (Relative Strength Index): relative_strength_index.md
201
- - Momentum: momentum.md
202
- - Stochastic Oscillator: stochastic_oscillator.md
203
- - True Strength Index: true_strength_index.md
204
- - Volatility Indicators:
205
- - Bollinger Bands: bollinger_bands.md
206
- - Average True Range: average_true_range.md
207
- - True Range: true_range.md
208
- - Donchian Channel: donchian_channel.md
209
- - Trend Indicators:
210
- - MACD: moving_average_convergence_divergence.md
211
- - Market Profile: market_profile.md
212
- - Pattern Recognition:
213
- - Fibonacci Retracement: fibonacci_retracement.md
214
- - Peaks and Valleys: peaks_and_valleys.md
215
- - Candlestick Patterns: candlestick_pattern_recognizer.md
216
- - Double Top/Bottom: double_top_bottom_pattern.md
217
- - Head and Shoulders: head_and_shoulders_pattern.md
192
+ - sqa-tai Gem: https://github.com/MadBomber/sqa-tai
193
+ - TA-Lib Documentation: https://ta-lib.org/
218
194
 
219
195
  - Trading Strategies:
220
196
  - strategies/index.md
@@ -249,25 +225,17 @@ nav:
249
225
 
250
226
  - AI & Machine Learning:
251
227
  - ai_and_ml.md
228
+ - Mean Reversion: mean_reversion.md
252
229
  - Predict Next Value: predict_next_value.md
253
230
  - Identify Wave Condition: identify_wave_condition.md
254
231
  - LIBSVM Format: libsvm_file_format.md
255
232
 
256
233
  - API Reference:
257
234
  - api/index.md
258
- - SQA Module: api/sqa.md
259
- - Stock Class: api/stock.md
260
235
  - DataFrame Class: api/dataframe.md
261
- - Strategy Framework: api/strategy.md
262
- - Portfolio Class: api/portfolio.md
263
- - Backtest Class: api/backtest.md
264
- - Stream Class: api/stream.md
265
236
 
266
237
  - Data Sources:
267
238
  - data-sources/index.md
268
- - Alpha Vantage: alpha_vantage_technical_indicators.md
269
- - Data Format: data-sources/format.md
270
- - Custom Data: data-sources/custom.md
271
239
 
272
240
  - Resources:
273
241
  - Tags: tags.md
@@ -276,13 +244,9 @@ nav:
276
244
  - Trading Ideas: i_gotta_an_idea.md
277
245
  - Factor Analysis: factors_that_impact_price.md
278
246
  - External Tools:
279
- - TA-Lib: ta_lib.md
280
247
  - FinViz: finviz.md
281
248
  - FX Pro Bit: fx_pro_bit.md
282
249
  - Options Trading: options.md
283
250
 
284
251
  - Contributing:
285
252
  - contributing/index.md
286
- - Development Setup: contributing/setup.md
287
- - Testing: contributing/testing.md
288
- - Code Style: contributing/style.md
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.31
4
+ version: 0.0.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -411,47 +411,32 @@ files:
411
411
  - docs/advanced/strategy-generator.md
412
412
  - docs/advanced/streaming.md
413
413
  - docs/ai_and_ml.md
414
- - docs/alpha_vantage_technical_indicators.md
415
414
  - docs/api/dataframe.md
416
415
  - docs/api/index.md
417
416
  - docs/assets/css/custom.css
417
+ - docs/assets/images/sqa.jpg
418
418
  - docs/assets/js/mathjax.js
419
- - docs/average_true_range.md
420
- - docs/bollinger_bands.md
421
- - docs/candlestick_pattern_recognizer.md
422
419
  - docs/concepts/index.md
423
420
  - docs/contributing/index.md
424
421
  - docs/data-sources/index.md
425
422
  - docs/data_frame.md
426
- - docs/donchian_channel.md
427
- - docs/double_top_bottom_pattern.md
428
- - docs/exponential_moving_average.md
429
423
  - docs/factors_that_impact_price.md
430
- - docs/fibonacci_retracement.md
431
424
  - docs/finviz.md
432
425
  - docs/fx_pro_bit.md
433
426
  - docs/genetic_programming.md
434
427
  - docs/getting-started/index.md
435
428
  - docs/getting-started/installation.md
436
429
  - docs/getting-started/quick-start.md
437
- - docs/head_and_shoulders_pattern.md
438
430
  - docs/i_gotta_an_idea.md
439
431
  - docs/identify_wave_condition.md
440
432
  - docs/index.md
441
433
  - docs/indicators.md
442
434
  - docs/indicators/index.md
443
435
  - docs/libsvm_file_format.md
444
- - docs/market_profile.md
445
436
  - docs/mean_reversion.md
446
- - docs/momentum.md
447
- - docs/moving_average_convergence_divergence.md
448
437
  - docs/options.md
449
- - docs/peaks_and_valleys.md
450
438
  - docs/predict_next_value.md
451
- - docs/relative_strength_index.md
452
439
  - docs/requirements.md
453
- - docs/simple_moving_average.md
454
- - docs/stochastic_oscillator.md
455
440
  - docs/strategies/bollinger-bands.md
456
441
  - docs/strategies/consensus.md
457
442
  - docs/strategies/custom.md
@@ -466,12 +451,8 @@ files:
466
451
  - docs/strategies/stochastic.md
467
452
  - docs/strategies/volume-breakout.md
468
453
  - docs/strategy.md
469
- - docs/ta_lib.md
470
454
  - docs/tags.md
471
455
  - docs/terms_of_use.md
472
- - docs/true_range.md
473
- - docs/true_strength_index.md
474
- - docs/weighted_moving_average.md
475
456
  - examples/README.md
476
457
  - examples/advanced_features_example.rb
477
458
  - examples/fpop_analysis_example.rb
@@ -504,12 +485,17 @@ files:
504
485
  - examples/rails_app/config/routes.rb
505
486
  - examples/realtime_stream_example.rb
506
487
  - examples/sinatra_app/Gemfile
488
+ - examples/sinatra_app/Gemfile.lock
507
489
  - examples/sinatra_app/QUICKSTART.md
508
490
  - examples/sinatra_app/README.md
491
+ - examples/sinatra_app/RUNNING_WITHOUT_TALIB.md
492
+ - examples/sinatra_app/TROUBLESHOOTING.md
509
493
  - examples/sinatra_app/app.rb
510
494
  - examples/sinatra_app/config.ru
511
495
  - examples/sinatra_app/public/css/style.css
496
+ - examples/sinatra_app/public/debug_macd.html
512
497
  - examples/sinatra_app/public/js/app.js
498
+ - examples/sinatra_app/start.sh
513
499
  - examples/sinatra_app/views/analyze.erb
514
500
  - examples/sinatra_app/views/backtest.erb
515
501
  - examples/sinatra_app/views/dashboard.erb
@@ -1,62 +0,0 @@
1
- # Alpha Vantage
2
- ## Technical Indicators
3
-
4
- The following technical indicators are available from Alpha Vantage
5
- using a free API key.
6
-
7
- | Acronym | Indicator Description |
8
- |-----------|----------------------------------------------------------|
9
- | AD | Accumulation/Distribution |
10
- | ADOSC | Accumulation/Distribution Oscillator |
11
- | ADX | Average Directional Index |
12
- | ADXR | Average Directional Movement Rating |
13
- | APO | Absolute Price Oscillator |
14
- | AROON | Aroon Indicator |
15
- | AROONOSC | Aroon Oscillator |
16
- | ATR | Average True Range |
17
- | BBANDS | Bollinger Bands |
18
- | BOP | Balance of Power |
19
- | CCI | Commodity Channel Index |
20
- | CMO | Chande Momentum Oscillator |
21
- | DEMA | Double Exponential Moving Average |
22
- | DX | Directional Movement Index |
23
- | EMA | Exponential Moving Average |
24
- | HT_DCPERIOD | Hilbert Transform - Dominant Cycle Period |
25
- | HT_DCPHASE | Hilbert Transform - Dominant Cycle Phase |
26
- | HT_PHASOR | Hilbert Transform - Phasor Components |
27
- | HT_SINE | Hilbert Transform - SineWave |
28
- | HT_TRENDLINE | Hilbert Transform - Instantaneous Trendline |
29
- | HT_TRENDMODE | Hilbert Transform - Trend vs Cycle Mode |
30
- | KAMA | Kaufman Adaptive Moving Average |
31
- | MACD | Moving Average Convergence Divergence |
32
- | MACDEXT | MACD with controllable MA type |
33
- | MAMA | MESA Adaptive Moving Average |
34
- | MFI | Money Flow Index |
35
- | MIDPOINT | MidPoint over period |
36
- | MIDPRICE | Midpoint Price over period |
37
- | MINUS_DI | Minus Directional Indicator |
38
- | MINUS_DM | Minus Directional Movement |
39
- | MOM | Momentum |
40
- | NATR | Normalized Average True Range |
41
- | OBV | On Balance Volume |
42
- | PLUS_DI | Plus Directional Indicator |
43
- | PLUS_DM | Plus Directional Movement |
44
- | PPO | Percentage Price Oscillator |
45
- | ROC | Rate of Change |
46
- | ROCR | Rate of Change Ratio |
47
- | RSI | Relative Strength Index |
48
- | SAR | Parabolic SAR |
49
- | SMA | Simple Moving Average |
50
- | STOCH | Stochastic Oscillator |
51
- | STOCHF | Stochastic Fast |
52
- | STOCHRSI | Stochastic Relative Strength Index |
53
- | T3 | Triple Exponential Moving Average (T3) |
54
- | TEMA | Triple Exponential Moving Average |
55
- | TRANGE | True Range |
56
- | TRIMA | Triangular Moving Average |
57
- | TRIX | 1-day Rate of Change of a Triple Smooth EMA |
58
- | ULTOSC | Ultimate Oscillator |
59
- | VWAP | Volume Weighted Average Price |
60
- | WILLR | Williams' %R |
61
- | WMA | Weighted Moving Average |
62
-
@@ -1,9 +0,0 @@
1
- # Average True Range (ATR)
2
-
3
- See: https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/atr
4
-
5
- The ATR 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 ATR 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.
@@ -1,15 +0,0 @@
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.
@@ -1,4 +0,0 @@
1
- # Candlestick Chart Pattern
2
-
3
- Recognizes common candlestick chart patterns in the given price data.
4
-
@@ -1,5 +0,0 @@
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.
@@ -1,3 +0,0 @@
1
- # Double Top Double Bottom Pattern
2
-
3
- Checks if a "double top" or "double bottom" pattern is present in the given price data.
@@ -1,19 +0,0 @@
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.
@@ -1,30 +0,0 @@
1
- # Fibonacci Retracement
2
-
3
- Fibonacci retracement is a popular technical analysis tool used to identify potential levels of support and resistance in a financial market. It is based on the theory that markets tend to move in a series of retracements and expansions, which follow a specific mathematical ratio derived from the Fibonacci sequence.
4
-
5
- ### How it's Used
6
-
7
- Traders and analysts use Fibonacci retracement levels to determine potential areas where the price of an asset may reverse or continue its existing trend. The most commonly used Fibonacci retracement levels are 23.6%, 38.2%, 50%, 61.8%, and 78.6%.
8
-
9
- When a market is trending, a trader would plot the Fibonacci retracement levels on the chart to identify potential areas where the price may pull back and find support (in an uptrend) or resistance (in a downtrend).
10
-
11
- If the price retraces to one of these levels and finds support or resistance, it can be seen as an opportunity to enter a trade in the direction of the prevailing trend. Traders often use other technical analysis tools, such as trend lines, moving averages, or candlestick patterns, in combination with Fibonacci retracement to confirm potential trade setups.
12
-
13
- ### How it's Calculated
14
-
15
- The calculation of Fibonacci retracement levels involves using the Fibonacci ratio of 0.236, 0.382, 0.500, 0.618, and 0.786.
16
-
17
- To plot Fibonacci retracement levels, two points on a chart are required: a swing high and a swing low. A swing high is a peak in an uptrend, while a swing low is a trough in a downtrend.
18
-
19
- The retracement levels are calculated by subtracting the percentage ratios (23.6%, 38.2%, etc.) from the difference between the swing high and the swing low. The resulting levels are then plotted on the chart.
20
-
21
- For example, to calculate the 38.2% retracement level, the formula would be:
22
-
23
- ```
24
- Retracement Level = (Swing High - Swing Low) * 0.382 + Swing Low
25
- ```
26
-
27
- Traders commonly use charting software or online tools that automatically calculate and plot Fibonacci retracement levels. This makes it easier for traders to visualize and analyze potential trading opportunities based on these levels.
28
-
29
- Overall, Fibonacci retracement is a valuable technical analysis technique that can assist traders in identifying key support and resistance levels in a trending market. By understanding and correctly utilizing this tool, traders can enhance their decision-making process and potentially improve their trading outcomes.
30
-
@@ -1,3 +0,0 @@
1
- # Head and Shoulders Pattern
2
-
3
- Checks if a "head and shoulders" pattern is present in the given price data.