sqa 0.0.21 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90a60fb96ea11073c750a7e0b36d8a2d8283bbfeff8322907617794b7111502e
4
- data.tar.gz: dbfa9486131b8b39016b46b9ef6188bdfefc279d8a5adc7a79b6c23f1ad1779b
3
+ metadata.gz: 14696fda27b96cdb318de1caa6e155c88e7b8f8dcb42db4a6cdf0efb43799ba9
4
+ data.tar.gz: 9a3aff9d4f3330f5066aba7af7366e12113c72805d626b2941aba8dd79271aa7
5
5
  SHA512:
6
- metadata.gz: 975de4af9b0c063a66b8a2292b99c18859d30d49ab6b7fab82416916a1cbf3685b4c9e5f56ea5e1cbe635ac5e9fb67aacf2432ec95ef74f541da9a0edf1e6c61
7
- data.tar.gz: cf25850a673a96bf60fe40cac0ca488a670c8ba8eb489e7c4502beb3b53bc60d1c716a22c4f5c78ceffd66e6ac92323e13b8278988fa3ffd0e4d26554249b908
6
+ metadata.gz: 1fa03f64b2ab105ffc0687b46c8a4a58367687900cc01ec30242b075c7c45fa7b0eaa810ea5a10d22abe37b99dd16dca1da9076863a8f7463473d0147a98f563
7
+ data.tar.gz: cb55306dc877c66486f16277aba8d300aa4e092377d13bcdc110f04fe3e0e1e2999dbc347b6a824b2f4a04e1e851c733fc7556389118099c5a6784a3fbdfa209
@@ -1,4 +1,5 @@
1
1
  label: "## Table of Contents"
2
2
  patterns:
3
+ - "README.md"
3
4
  - "docs/terms_of_use.md"
4
5
  root_dir: "."
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.24] - 2023-11-08
4
+
5
+ - replaced [tty-option gem](https://github.com/piotrmurach/tty-option) with [dry-cli gem](https://github.com/dry-rb/dry-cli)
6
+
3
7
  ## [0.0.1] - 2023-08-10
4
8
 
5
9
  - Planting the Flag
data/README.md CHANGED
@@ -1,13 +1,72 @@
1
1
  # SQA - Simple Qualitative Analysis
2
2
 
3
+ [![Badges?](https://img.shields.io/badge/Badge-We%20don't%20need%20no%20stinkin'%20badges!-red)](https://www.youtube.com/watch?v=VqomZQMZQCQ)
4
+
3
5
  This is a very simplistic set of tools for running technical analysis (quantitative and qualitative) on a stock portfolio. Simplistic means it is not reliable nor intended for any kind of mission-critical financial use. Think of it as a training tool. I do. Its helping me understand why I need professional help from people who know what they are doing.
4
6
 
5
7
  The BUY/SELL signals that it generates should not be taken seriously. **DO NOT USE** this library when real money is at stake. If you lose your shirt playing in the stock market don't come crying to me. I think playing in the market is like playing in the street. You are going to get run over.
6
8
 
9
+ <!-- TODO: Consider these gems ...
10
+
11
+ This one is most likely out of date:
12
+ yahoofinance-ruby: This gem provides a simple Ruby interface to Yahoo Finance's historical quote data. If you're looking to add more data sources to your project, this could be a useful addition. yahoofinance-ruby
13
+
14
+ Worth Looking at:
15
+ ruby-technical-analysis: This gem provides various technical analysis calculations. It includes over 60 technical analysis functions and indicators like RSI, EMA, SMA, Bollinger Bands, MACD, and more. ruby-technical-analysis
16
+
17
+ Maybe later if I want to add an ability to make a live trade from within the SQA context...
18
+ ib-ruby: This gem provides a Ruby interface to Interactive Brokers' Trader Workstation (TWS) API, allowing you to build algorithmic trading strategies in Ruby. ib-ruby
19
+
20
+ Definitely looking for a plotting package.
21
+ plottable: If you're looking to add more visualization capabilities to your project, this gem could be useful. It provides a simple and flexible API for creating plots and charts in Ruby. plottable
22
+
23
+ Currently using CSV files; maybe switch to an RDBMS ...
24
+ activerecord-import: If you're dealing with large amounts of data, this gem could help improve performance. It adds methods to ActiveRecord for bulk inserting data into the database. activerecord-import
25
+
26
+ Could spawn off separate agents for each stock within a portfolio for analysis ...
27
+ parallel: This gem can help improve performance by allowing you to run code in parallel. This could be useful if you're running complex calculations on large datasets. parallel
28
+
29
+ -->
30
+
31
+
32
+
33
+ <!-- Tocer[start]: Auto-generated, don't remove. -->
34
+
35
+ ## Table of Contents
36
+
37
+ - [This is a Work in Progress](#this-is-a-work-in-progress)
38
+ - [Recent Changes](#recent-changes)
39
+ - [Installation](#installation)
40
+ - [Semantic Versioning](#semantic-versioning)
41
+ - [Usage](#usage)
42
+ - [Setup a Config File](#setup-a-config-file)
43
+ - [AlphaVantage](#alphavantage)
44
+ - [TradingView](#tradingview)
45
+ - [Yahoo Finance](#yahoo-finance)
46
+ - [Playing in IRB](#playing-in-irb)
47
+ - [With Stocks and Indicators](#with-stocks-and-indicators)
48
+ - [Get Historical Prices](#get-historical-prices)
49
+ - [Playing in the IRB - Setup](#playing-in-the-irb---setup)
50
+ - [Playing in the IRB - Statistics](#playing-in-the-irb---statistics)
51
+ - [Playing in the IRB - Indicators](#playing-in-the-irb---indicators)
52
+ - [Playing in the IRB - Strategies](#playing-in-the-irb---strategies)
53
+ - [Included Program Examples](#included-program-examples)
54
+ - [Analysis](#analysis)
55
+ - [Web](#web)
56
+ - [Predicted FAQ](#predicted-faq)
57
+ - [Other Similar Projects](#other-similar-projects)
58
+ - [Contributing](#contributing)
59
+ - [License](#license)
60
+
61
+ <!-- Tocer[finish]: Auto-generated, don't remove. -->
62
+
7
63
  ## This is a Work in Progress
8
64
 
9
65
  I am experimenting with different gems to support various functionality. Sometimes they do not work out well. For example I've gone through two different gems to implement the data frame capability. Neither did what I wanted so I ended up creating my own data frame class based upon the old tried and true [Hashie](https://github.com/intridea/hashie) library.
10
66
 
67
+ ## Recent Changes
68
+
69
+ * 0.0.24 - Replaced tty-option with dry-cli
11
70
 
12
71
  ## Installation
13
72
 
@@ -19,7 +78,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
19
78
 
20
79
  gem install sqa
21
80
 
22
- ### Semantic Versioning
81
+ ## Semantic Versioning
23
82
 
24
83
  `sqa` uses the [sem_version](https://github.com/canton7/sem_version) gem to provide a semantic version object. Sure its old; but, so am I. Doesn't mean we can't do the job.
25
84
 
@@ -31,6 +90,10 @@ sqa --version
31
90
 
32
91
  SQA.version # returns SemVersion object
33
92
  exit(1) unless SQA.version >= SemVersion("1.0.0")
93
+
94
+ # Okay, you're right, you could put that kind of version
95
+ # constraint in a Gemfile and let bundler handle the
96
+ # dependencies for you.
34
97
  ```
35
98
 
36
99
  ## Usage
@@ -72,6 +135,9 @@ Examples:
72
135
 
73
136
  WARNING: This is a toy, a play thing, not intended for serious use.
74
137
  ```
138
+
139
+ More about the two included programs `analysis` and `web` later.
140
+
75
141
  ### Setup a Config File
76
142
 
77
143
  You will need to create a directory to store the `sqa` data and a configuration file. You can start by doing this:
@@ -96,7 +162,7 @@ You can also have one data directory and multiple portfolio and trades files wit
96
162
 
97
163
  Put your API key in the system environment variable `AV_API_KEY`
98
164
 
99
- TODO why is it not part of the configuration? ought to be.
165
+ <!-- TODO: why is it not part of the configuration? ought to be. -->
100
166
 
101
167
 
102
168
  ### TradingView
@@ -105,10 +171,23 @@ TODO why is it not part of the configuration? ought to be.
105
171
 
106
172
  Put your API key in the system environment variable `TV_API_KEY`
107
173
 
108
- TODO why is it not part of the configuration? ought to be.
174
+ <!-- TODO: why is it not part of the configuration? ought to be. -->
109
175
 
110
176
  I kinda like their Terms of Use. I've started crafting an [SQA Terms of Use](docs/terms_of_use.md) document based on theirs. I specifically like sections 7 and 8.
111
177
 
178
+ ### Yahoo Finance
179
+
180
+ The finance.yahoo.com website no longer supports an API. To get information from this website you must scrape it. That is how historical / receint stock prices are being obtained in the DataFrame::YahooFinance class. I do not like doing this and do not necessarily recommend using YahooFinance as a source for stock price data.
181
+
182
+ In the SQA::Stock class the default source is AlphaVantage which has its own limitations.
183
+
184
+ This is not to say that finance.yahoo.com has no use. In fact is is the perfect place to go to manually download CSV files of historical stock price data. When you do that through your browser, the CSV file will be placed in your default downloads directory.
185
+
186
+ To use this downed file within the SQA environment it must be moved into your `SQA.`data_dir` with a filename that is all lowercase. The filename must be the stock's symbol with a `.csv` extension. For example if you downloaded the entire historical stock price data for Apple Computer (AAPL) the filename in the SQA.data_dir should be "aapl.csv"
187
+
188
+ You can manually go to the Yahoo Finance website at [https://finance.yahoo.com/quote/AAPL/history?p=AAPL](https://finance.yahoo.com/quote/AAPL/history?p=AAPL)
189
+
190
+
112
191
  ## Playing in IRB
113
192
 
114
193
  You can play around in IRB with the SQA framework.
@@ -124,7 +203,9 @@ Historical price data is kept in the `SQA.data_dir` in a CSV file whose name is
124
203
 
125
204
  Go to [https::/finance.yahoo.com](https::/finance.yahoo.com) and down some historical price data for your favorite stocks. Put those CSV files into the `SQA.data_dir`.
126
205
 
127
- You may need to create a `portfolio.csv` file or you may not. TODO
206
+ You may need to create a `portfolio.csv` file or you may not.
207
+
208
+ <!-- TODO: Add a section on how to create a portfolio fCSV file -->
128
209
 
129
210
  The CSV files will be named by the stock's ticker symbol as lower case. For example: `aapl.csv`
130
211
 
@@ -134,6 +215,8 @@ The CSV files will be named by the stock's ticker symbol as lower case. For exa
134
215
  require 'sqa'
135
216
  require 'sqa/cli'
136
217
 
218
+ # TODO: Is this still true after the dry-cli integration?
219
+ #
137
220
  # You can pass a set of CLI options in a String
138
221
  SQA.init "-c ~/.sqa.yml"
139
222
 
@@ -275,6 +358,60 @@ Any specific strategy may not work on every stock. Using the historical data, it
275
358
 
276
359
  The strategies that come with the `SQA::Strategy` class are examples only. Its expected that you will come up with your own. If you do, consider sharing them.
277
360
 
361
+ ## Included Program Examples
362
+
363
+ <!-- TODO: What is the name of these things? From the help text they are called commands. They are treated in the code base as a class under the SQA module. Its easy to change the CLI help text to call these programs rather than commands. -->
364
+
365
+ There are at least two included programs that make use of the `SQA` library.
366
+
367
+ <!-- TODO: These kinds of things need to be in their own repository. -->
368
+
369
+ <!-- TODO: Need to complete the API for invoking one of these "programs" from the sqa cli. -->
370
+
371
+ ### Analysis
372
+
373
+ Does an analysis of a portfollio of stocks.
374
+
375
+ ### Web
376
+
377
+ Provides a browser-based interface to some stuff.
378
+
379
+ ## Predicted FAQ
380
+
381
+ What is the purpose of the SQA project? The madbomber/sqa project is a set of tools for running technical analysis on a stock portfolio. It's intended as a learning tool to help understand stock market analysis. It's not intended for real-world trading or financial use.
382
+
383
+ How do I install and use SQA? You can install the gem by running gem install sqa or adding gem 'sqa' to your Gemfile and running bundle install. The project can be used from the command line or as a library in your own application. More details can be found in the README.md file.
384
+
385
+ What technical indicators does SQA support? The project includes a variety of technical indicators such as Average True Range, Bollinger Bands, Candlestick Patterns, Donchian Channel, Double Top Double Bottom Pattern, Exponential Moving Average, Fibonacci Retracement, Head and Shoulders Pattern, Elliott Wave Theory, Market Profile Analysis, Mean Reversion, Momentum, Moving Average Convergence Divergence, Peaks and Valleys, Predict Next Value, Relative Strength Index, Simple Moving Average, and Stochastic Oscillator.
386
+
387
+ What data sources does SQA support? The project supports data from AlphaVantage and Yahoo Finance. You will need an API key for AlphaVantage to use this functionality.
388
+
389
+ What are the risks of using SQA for real-world trading? The madbomber/sqa project is intended as a learning tool and is not reliable for any kind of mission-critical financial use. The BUY/SELL signals that it generates should not be taken seriously. If you lose money in the stock market as a result of using this library, the project is not responsible.
390
+
391
+ Can I contribute to the SQA project? Yes, contributions are welcome. You can submit bug reports and pull requests on the GitHub repository.
392
+
393
+ What license does SQA use? The project is available as open source under the terms of the MIT License.
394
+
395
+ What is the current state of the project? The project is a work in progress. The developer is experimenting with different gems to support various functionalities. Some features may not be fully implemented or may need further refinement.
396
+
397
+
398
+ ## Other Similar Projects
399
+
400
+ There are several other (prehaps more mature) projects and libraries that provide similar capabilities to the SQA. Here are a few examples:
401
+
402
+ TA-Lib (Technical Analysis Library): This is a popular open-source software library that provides tools for technical analysis of financial markets. It includes over 150 functions for various types of analysis including pattern recognition, moving averages, oscillators, and more. It's available in several programming languages including Python, Java, Perl, and more. TA-Lib
403
+
404
+ Pandas TA: This is a Python library that provides comprehensive functionalities for technical analysis. It's an extension of the popular data analysis library Pandas and includes a wide range of financial indicators. Pandas TA
405
+
406
+ Backtrader: This is a Python library for backtesting trading strategies. It supports a wide range of trading concepts including trading calendars, multiple data feeds, and order execution types. Backtrader
407
+
408
+ PyAlgoTrade: This is another Python library for backtesting stock trading strategies. It supports Yahoo! Finance, Google Finance, and others as data sources, and has a focus on simplicity and flexibility. PyAlgoTrade
409
+
410
+ QuantLib: This is a comprehensive software framework for quantitative finance, it provides tools for many aspects of quantitative finance including trading and risk management, financial instruments, mathematics, numerical methods, and model calibration. QuantLib
411
+
412
+ zipline: This is a Python library for algorithmic trading. It allows strategy testing and supports live-trading and backtesting, and includes a number of financial computations to aid in trading decisions. zipline
413
+
414
+
278
415
  ## Contributing
279
416
 
280
417
  I can always use some help on this stuff. Got an idea for a new indicator or strategy? Want to improve the math? Make the signals better? Let's collaborate!
@@ -1 +1 @@
1
- bd37c208c9c593043ac51fd79e3cf45eac2d432109b13773af13a534b833bbe5277002f03567d2659bc70150593f084db025d8cd08bed3f803db4db7809e7128
1
+ 5e682462398140077e381829872acc847ce0f2a391af4ab7d66c94f8bebf05dc29a760fcdfecfe07886ad23440496973e6f6cdd7012d6db577b923281e1f67b7
@@ -0,0 +1 @@
1
+ 053cf9a393976ae5292918cd7386b9c2e0567788f43525b77ca06ee574a98b39c3d81d43d65358d2d8cf896060e576897484945c119f1f2d57480d9407c0555a
@@ -0,0 +1 @@
1
+ 0206661c9e8d7fd3f5aebabada6410fee92383ea925a8045a697c181f8aed3fa0a7f3f51b29c399a6c9ff1bc98ed09e02d1fb1396bb1789b1db053e7c8ef0038
@@ -0,0 +1 @@
1
+ 3afd55963fbffbaa1633e2c7c4b606fd10ccc76def48a490121243a201d9e0f71bc42b2a53a6028580350fe4c0157a1cc97b9bbbfd9dc77976b02aad9b7f5ac5
data/docs/ta_lib.md ADDED
@@ -0,0 +1,160 @@
1
+ # TA-Lib
2
+
3
+ `SQA` does not use the `ta-lib` but is considering it. Currently there are no ruby wrappers. There is a Java implementation and a Python wrapper.
4
+
5
+ The `ta-lib` library is a C/C++ implementation of about 200 technical analysis indicators which has been around since a little after the turn of the century. | It supports the follow indicators:
6
+
7
+ | TA Function | Name |
8
+ | ----------- | ---- |
9
+ | AD | Chaikin A/D Line |
10
+ | ADOSC | Chaikin A/D Oscillator |
11
+ | ADX | Average Directional Movement Index |
12
+ | ADXR | Average Directional Movement Index Rating |
13
+ | APO | Absolute Price Oscillator |
14
+ | AROON | Aroon |
15
+ | AROONOSC | Aroon Oscillator |
16
+ | ATR | Average True Range |
17
+ | AVGPRICE | Average Price |
18
+ | BBANDS | Bollinger Bands |
19
+ | BETA | Beta |
20
+ | BOP | Balance Of Power |
21
+ | CCI | Commodity Channel Index |
22
+ | CDL2CROWS | Two Crows |
23
+ | CDL3BLACKCROWS | Three Black Crows |
24
+ | CDL3INSIDE | Three Inside Up/Down |
25
+ | CDL3LINESTRIKE | Three Outside Up/Down |
26
+ | CDL3STARSINSOUTH | Three Stars In The South |
27
+ | CDL3WHITESOLDIERS | Three Advancing White Soldiers |
28
+ | CDLABANDONEDBABY | Abandoned Baby |
29
+ | CDLADVANCEBLOCK | Advance Block |
30
+ | CDLBELTHOLD | Belt-hold |
31
+ | CDLBREAKAWAY | Breakaway |
32
+ | CDLCLOSINGMARUBOZU | Closing Marubozu |
33
+ | CDLCONCEALBABYSWALL | Concealing Baby Swallow |
34
+ | CDLCOUNTERATTACK | Counterattack |
35
+ | CDLDARKCLOUDCOVER | Dark Cloud Cover |
36
+ | CDLDOJI | Doji |
37
+ | CDLDOJISTAR | Doji Star |
38
+ | CDLDRAGONFLYDOJI | Dragonfly Doji |
39
+ | CDLENGULFING | Engulfing Pattern |
40
+ | CDLEVENINGDOJISTAR | Evening Doji Star |
41
+ | CDLEVENINGSTAR | Evening Star |
42
+ | CDLGAPSIDESIDEWHITE | Up/Down-gap side-by-side white lines |
43
+ | CDLGRAVESTONEDOJI | Gravestone Doji |
44
+ | CDLHAMMER | Hammer |
45
+ | CDLHANGINGMAN | Hanging Man |
46
+ | CDLHARAMI | Harami Pattern |
47
+ | CDLHARAMICROSS | Harami Cross Pattern |
48
+ | CDLHIGHWAVE | High-Wave Candle |
49
+ | CDLHIKKAKE | Hikkake Pattern |
50
+ | CDLHIKKAKEMOD | Modified Hikkake Pattern |
51
+ | CDLHOMINGPIGEON | Homing Pigeon |
52
+ | CDLIDENTICAL3CROWS | Identical Three Crows |
53
+ | CDLINNECK | In-Neck Pattern |
54
+ | CDLINVERTEDHAMMER | Inverted Hammer |
55
+ | CDLKICKING | Kicking |
56
+ | CDLKICKINGBYLENGTH | Kicking - bull/bear determined by the longer marubozu |
57
+ | CDLLADDERBOTTOM | Ladder Bottom |
58
+ | CDLLONGLEGGEDDOJI | Long Legged Doji |
59
+ | CDLLONGLINE | Long Line Candle |
60
+ | CDLMARUBOZU | Marubozu |
61
+ | CDLMATCHINGLOW | Matching Low |
62
+ | CDLMATHOLD | Mat Hold |
63
+ | CDLMORNINGDOJISTAR | Morning Doji Star |
64
+ | CDLMORNINGSTAR | Morning Star |
65
+ | CDLONNECK | On-Neck Pattern |
66
+ | CDLPIERCING | Piercing Pattern |
67
+ | CDLRICKSHAWMAN | Rickshaw Man |
68
+ | CDLRISEFALL3METHODS | Rising/Falling Three Methods |
69
+ | CDLSEPARATINGLINES | Separating Lines |
70
+ | CDLSHOOTINGSTAR | Shooting Star |
71
+ | CDLSHORTLINE | Short Line Candle |
72
+ | CDLSPINNINGTOP | Spinning Top |
73
+ | CDLSTALLEDPATTERN | Stalled Pattern |
74
+ | CDLSTICKSANDWICH | Stick Sandwich |
75
+ | CDLTAKURI | Takuri (Dragonfly Doji with very long lower shadow) |
76
+ | CDLTASUKIGAP | Tasuki Gap |
77
+ | CDLTHRUSTING | Thrusting Pattern |
78
+ | CDLTRISTAR | Tristar Pattern |
79
+ | CDLUNIQUE3RIVER | Unique 3 River |
80
+ | CDLUPSIDEGAP2CROWS | Upside Gap Two Crows |
81
+ | CDLXSIDEGAP3METHODS | Upside/Downside Gap Three Methods |
82
+ | CMO | Chande Momentum Oscillator |
83
+ | CORREL | Pearson's Correlation Coefficient ® |
84
+ | DEMA | Double Exponential Moving Average |
85
+ | DX | Directional Movement Index |
86
+ | EMA | Exponential Moving Average |
87
+ | HT_DCPERIOD | Hilbert Transform - Dominant Cycle Period |
88
+ | HT_DCPHASE | Hilbert Transform - Dominant Cycle Phase |
89
+ | HT_PHASOR | Hilbert Transform - Phasor Components |
90
+ | HT_SINE | Hilbert Transform - SineWave |
91
+ | HT_TRENDLINE | Hilbert Transform - Instantaneous Trendline |
92
+ | HT_TRENDMODE | Hilbert Transform - Trend vs Cycle Mode |
93
+ | KAMA | Kaufman Adaptive Moving Average |
94
+ | LINEARREG | Linear Regression |
95
+ | LINEARREG_ANGLE | Linear Regression Angle |
96
+ | LINEARREG_INTERCEPT | Linear Regression Intercept |
97
+ | LINEARREG_SLOPE | Linear Regression Slope |
98
+ | MA | All Moving Average |
99
+ | MACD | Moving Average Convergence/Divergence |
100
+ | MACDEXT | MACD with controllable MA type |
101
+ | MACDFIX | Moving Average Convergence/Divergence Fix 12/26 |
102
+ | MAMA | MESA Adaptive Moving Average |
103
+ | MAX | Highest value over a specified period |
104
+ | MAXINDEX | Index of highest value over a specified period |
105
+ | MEDPRICE | Median Price |
106
+ | MFI | Money Flow Index |
107
+ | MIDPOINT | MidPoint over period |
108
+ | MIDPRICE | Midpoint Price over period |
109
+ | MIN | Lowest value over a specified period |
110
+ | MININDEX | Index of lowest value over a specified period |
111
+ | MINMAX | Lowest and highest values over a specified period |
112
+ | MINMAXINDEX | Indexes of lowest and highest values over a specified period |
113
+ | MINUS_DI | Minus Directional Indicator |
114
+ | MINUS_DM | Minus Directional Movement |
115
+ | MOM | Momentum |
116
+ | NATR | Normalized Average True Range |
117
+ | OBV | On Balance Volume |
118
+ | PLUS_DI | Plus Directional Indicator |
119
+ | PLUS_DM | Plus Directional Movement |
120
+ | PPO | Percentage Price Oscillator |
121
+ | ROC | Rate of change |
122
+ | ROCP | Rate of change Percentage |
123
+ | ROCR | Rate of change ratio |
124
+ | ROCR100 | Rate of change ratio 100 scale |
125
+ | RSI | Relative Strength Index |
126
+ | SAR | Parabolic SAR |
127
+ | SAREXT | Parabolic SAR - Extended |
128
+ | SMA | Simple Moving Average |
129
+ | STDDEV | Standard Deviation |
130
+ | STOCH | Stochastic |
131
+ | STOCHF | Stochastic Fast |
132
+ | STOCHRSI | Stochastic Relative Strength Index |
133
+ | SUM | Summation |
134
+ | T3 | Triple Exponential Moving Average (T3) |
135
+ | TEMA | Triple Exponential Moving Average |
136
+ | TRANGE | True Range |
137
+ | TRIMA | Triangular Moving Average |
138
+ | TRIX | 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA |
139
+ | TSF | Time Series Forecast |
140
+ | TYPPRICE | Typical Price |
141
+ | ULTOSC | Ultimate Oscillator |
142
+ | VAR | Variance |
143
+ | WCLPRICE | Weighted Close Price |
144
+ | WILLR | Williams' %R |
145
+ | WMA | Weighted Moving Average |
146
+
147
+
148
+ Rate of Change Implementation Definitions:
149
+
150
+ ROC - Rate of Change
151
+ > `((price/prevPrice)-1)*100`
152
+
153
+ ROCP - Rate of Change Precentage
154
+ > `(price-prevPrice)/prevPrice`
155
+
156
+ ROCR - Rate of Change Ratio
157
+ > `(price/prevPrice)`
158
+
159
+ ROCR100 - Rate of Change Ration on 100 Scale
160
+ > `(price/prevPrice)*100`
@@ -0,0 +1,228 @@
1
+ # sqa/lib/patches/dry-cli.rb
2
+
3
+ #####################################################################
4
+ ###
5
+ ## File: dry-cli.rb
6
+ ## Desc: Monkey around with the Dry::CLI class.
7
+ #
8
+
9
+
10
+ =begin
11
+ This monkey patch adds four new class methods to the Command class:
12
+
13
+ global_header .. Program/Glocal context custom header/footer
14
+ global_footer ..
15
+ header ......... Command context custom header / footer
16
+ footer .........
17
+
18
+ In addition to the new commands, tail-patched call methods in the
19
+ Banner and Usage modules wrap the existing help text formatting
20
+ with the appropriate global and command level header and footer
21
+ text.
22
+
23
+ The expected usage pattern is to have the global customerized
24
+ header / footer help text defined in the Base command class
25
+ for an application. All other commands inherent from this
26
+ Base class.
27
+
28
+ The header / footer class methods are used to wrap the command
29
+ help text. When "--help" is used on a command, the customerized
30
+ global header and footer text are on the outside of the help text.
31
+ The customized command header / footer are inside of the
32
+ global context but still wrap the original help text
33
+
34
+ Here is an example help output:
35
+
36
+ $ ./bin_cli.rb start --help
37
+ == Base Global Header ==
38
+ == Start Header ==
39
+ Command:
40
+ bin_cli.rb start
41
+
42
+ Usage:
43
+ bin_cli.rb start ROOT | bin_cli.rb start SUBCOMMAND
44
+
45
+ Description:
46
+ Start Foo machinery
47
+
48
+ Subcommands:
49
+ version # Print version
50
+
51
+ Arguments:
52
+ ROOT # REQUIRED Root directory
53
+
54
+ Options:
55
+ --[no-]debug, -d, --debug # Print debug information, default: false
56
+ --[no-]verbose, -v, --verbose # Print verbose information, default: false
57
+ --[no-]xyzzy, -x, --xyzzy # Magic, default: false
58
+ --help, -h # Print this help
59
+
60
+ Examples:
61
+ bin_cli.rb start path/to/root # Start Foo at root directory
62
+ == Start Footer ==
63
+ == Base Global Footer ==
64
+
65
+
66
+ =end
67
+
68
+
69
+ module Dry::CLI::Banner
70
+ class << self
71
+ alias_method :original_call, :call
72
+
73
+ # Overwrites the original 'call' method to accommodate a custom header and footer
74
+ # for the help text.
75
+ # @param command [Class] the the command class
76
+ # @param name [String] command line without help option
77
+ # @return [String] modified help text
78
+
79
+ def call(command, name)
80
+ help_text = original_call(command, name)
81
+
82
+ my_header, my_footer = command_help_wrapper(command)
83
+
84
+ help_text.prepend(my_header)
85
+ help_text += my_footer
86
+
87
+ help_text
88
+ end
89
+
90
+
91
+ # Provides the header and footer for the received command.
92
+ # @param command [Class] the command class
93
+ # @return [Array<String>] an array with the header at the 0 index and
94
+ # the footer at the 1 index
95
+
96
+ def command_help_wrapper(command)
97
+ global_header = Dry::CLI::Command.global_header
98
+ global_footer = Dry::CLI::Command.global_footer
99
+ command_header = command.header
100
+ command_footer = command.footer
101
+
102
+ my_header = ""
103
+ my_header += global_header + "\n" unless (global_header.nil? || global_header.empty?)
104
+ my_header += command_header+ "\n" unless (command_header.nil?|| command_header.empty?)
105
+
106
+ my_footer = ""
107
+ my_footer += "\n" + command_footer unless (command_footer.nil?|| command_footer.empty?)
108
+ my_footer += "\n" + global_footer unless (global_footer.nil? || global_footer.empty?)
109
+
110
+ [my_header, my_footer]
111
+ end
112
+ end
113
+ end
114
+
115
+
116
+ module Dry::CLI::Usage
117
+ class << self
118
+ alias_method :original_call, :call
119
+
120
+ # Overwrites the original 'call' method to allow a global header
121
+ # and footer wrap for the help text.
122
+ # @return [String] modified help text
123
+
124
+ def call(result)
125
+ help_text = original_call(result)
126
+
127
+ global_header = Dry::CLI::Command.global_header
128
+ global_footer = Dry::CLI::Command.global_footer
129
+
130
+ help_text.prepend(global_header + "\n") unless (global_header.nil? || global_header.empty?)
131
+ help_text += "\n" + global_footer unless (global_footer.nil? || global_footer.empty?)
132
+
133
+ help_text
134
+ end
135
+ end
136
+ end
137
+
138
+
139
+ class Dry::CLI::Command
140
+ # Provides a way to set a custom, command specific header.
141
+ # @param a_string [String] optional, header text
142
+ # @return [String] header text
143
+
144
+ def self.header(a_string=nil)
145
+ if a_string.nil?
146
+ @header_string
147
+ else
148
+ @header_string = a_string
149
+ end
150
+ end
151
+
152
+
153
+ # Provides a way to set a custom, command specific footer.
154
+ # @param a_string [String] optional, footer text
155
+ # @return [String] footer text
156
+
157
+ def self.footer(a_string=nil)
158
+ if a_string.nil?
159
+ @footer_string
160
+ else
161
+ @footer_string = a_string
162
+ end
163
+ end
164
+
165
+
166
+ # Provides a way to set a global custom header to overwrite the default one.
167
+ # @param a_string [String] optional, global header text
168
+ # @return [String] global header text
169
+
170
+ def self.global_header(a_string=nil)
171
+ if a_string.nil?
172
+ @@global_header_string
173
+ else
174
+ @@global_header_string = a_string
175
+ end
176
+ end
177
+
178
+
179
+ # Provides a way to set a global custom footer to overwrite the default one.
180
+ # @param a_string [String] optional, global footer text
181
+ # @return [String] global footer text
182
+
183
+ def self.global_footer(a_string=nil)
184
+ if a_string.nil?
185
+ @@global_footer_string
186
+ else
187
+ @@global_footer_string = a_string
188
+ end
189
+ end
190
+ end
191
+
192
+
193
+ # Add option value transformation based upon the value of the
194
+ # option's "type:" parameter.
195
+
196
+ module Dry::CLI::Parser
197
+ TRANSFORMERS = {
198
+ integer: -> (v) { v&.to_i },
199
+ float: -> (v) { v&.to_f }
200
+ }
201
+
202
+ def self.call(command, arguments, prog_name)
203
+ original_arguments = arguments.dup
204
+ parsed_options = {}
205
+
206
+ OptionParser.new do |opts|
207
+ command.options.each do |option|
208
+ opts.on(*option.parser_options) do |value|
209
+ if TRANSFORMERS.has_key?(option.options[:type])
210
+ value = TRANSFORMERS[option.options[:type]].call(value)
211
+ end
212
+
213
+ parsed_options[option.name.to_sym] = value
214
+ end
215
+ end
216
+
217
+ opts.on_tail("-h", "--help") do
218
+ return Result.help
219
+ end
220
+ end.parse!(arguments)
221
+
222
+ parsed_options = command.default_params.merge(parsed_options)
223
+ parse_required_params(command, arguments, prog_name, parsed_options)
224
+ rescue ::OptionParser::ParseError
225
+ Result.failure("ERROR: \"#{prog_name}\" was called with arguments \"#{original_arguments.join(" ")}\"") # rubocop:disable Metrics/LineLength
226
+ end
227
+ end
228
+