sqa 0.0.22 → 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: d905658af9c43b28516a66c068064fb83391b278885fbc6804a934be463cf316
4
- data.tar.gz: c8b8699dc6209b3370d72a34a43a29de70f6cf4f7e543766b676be6a249e879c
3
+ metadata.gz: 14696fda27b96cdb318de1caa6e155c88e7b8f8dcb42db4a6cdf0efb43799ba9
4
+ data.tar.gz: 9a3aff9d4f3330f5066aba7af7366e12113c72805d626b2941aba8dd79271aa7
5
5
  SHA512:
6
- metadata.gz: 8351015c1c4b75c8b75d2460820d4d162ad51b9e29d60c0989ecd413485670f6c4d55a65a2f52667bcf1c24bda04df3c6fc8bad196a92b2f8c3319c005e977c0
7
- data.tar.gz: 120bef4ce4c29cbf5ab412bb918f710f0875243cefef5bb085bcea8c29080b5754a42a313eb24b5b33aa4d5a3667e2147ceb97567941f528712a7ee42c56b32d
6
+ metadata.gz: 1fa03f64b2ab105ffc0687b46c8a4a58367687900cc01ec30242b075c7c45fa7b0eaa810ea5a10d22abe37b99dd16dca1da9076863a8f7463473d0147a98f563
7
+ data.tar.gz: cb55306dc877c66486f16277aba8d300aa4e092377d13bcdc110f04fe3e0e1e2999dbc347b6a824b2f4a04e1e851c733fc7556389118099c5a6784a3fbdfa209
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,14 +1,41 @@
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
+
7
33
  <!-- Tocer[start]: Auto-generated, don't remove. -->
8
34
 
9
35
  ## Table of Contents
10
36
 
11
37
  - [This is a Work in Progress](#this-is-a-work-in-progress)
38
+ - [Recent Changes](#recent-changes)
12
39
  - [Installation](#installation)
13
40
  - [Semantic Versioning](#semantic-versioning)
14
41
  - [Usage](#usage)
@@ -26,6 +53,8 @@ The BUY/SELL signals that it generates should not be taken seriously. **DO NOT
26
53
  - [Included Program Examples](#included-program-examples)
27
54
  - [Analysis](#analysis)
28
55
  - [Web](#web)
56
+ - [Predicted FAQ](#predicted-faq)
57
+ - [Other Similar Projects](#other-similar-projects)
29
58
  - [Contributing](#contributing)
30
59
  - [License](#license)
31
60
 
@@ -35,6 +64,9 @@ The BUY/SELL signals that it generates should not be taken seriously. **DO NOT
35
64
 
36
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.
37
66
 
67
+ ## Recent Changes
68
+
69
+ * 0.0.24 - Replaced tty-option with dry-cli
38
70
 
39
71
  ## Installation
40
72
 
@@ -183,6 +215,8 @@ The CSV files will be named by the stock's ticker symbol as lower case. For exa
183
215
  require 'sqa'
184
216
  require 'sqa/cli'
185
217
 
218
+ # TODO: Is this still true after the dry-cli integration?
219
+ #
186
220
  # You can pass a set of CLI options in a String
187
221
  SQA.init "-c ~/.sqa.yml"
188
222
 
@@ -342,6 +376,42 @@ Does an analysis of a portfollio of stocks.
342
376
 
343
377
  Provides a browser-based interface to some stuff.
344
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
+
345
415
  ## Contributing
346
416
 
347
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!
@@ -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
+