portfolio-maker 1.0.1
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.
- checksums.yaml +7 -0
- data/config/environment.rb +10 -0
- data/lib/portfolio_maker.rb +15 -0
- data/lib/portfolio_maker/command_line_interface.rb +196 -0
- data/lib/portfolio_maker/portfolio.rb +83 -0
- data/lib/portfolio_maker/scraper.rb +60 -0
- data/lib/portfolio_maker/stock.rb +118 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d3329b493b1cb3aa4bb30c974ec26c5864df25a24c19111650fea50ba5c45665
|
4
|
+
data.tar.gz: fda677c74e000dad5226cbd718e610eab6aff8db03d0dad71887f22a0d4e65aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5fcf3da5253920b730101ee5a4b3980174c056867da01518aa82279c55775bb9ab6f5506be80397c2985087f919d04af882c583146efa4b6dccd102c833d963e
|
7
|
+
data.tar.gz: 54401d1175591fb54cc9c9e397ce3c79ea276bc2ee6167206b820ebef895b75c77484c7348a53a4e39ed9d8cb0dfc4e129f3feecdb0602093ccd56d6e23dfc49
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'colorize'
|
5
|
+
|
6
|
+
require_relative '../lib/portfolio_maker/scraper'
|
7
|
+
require_relative '../lib/portfolio_maker/portfolio'
|
8
|
+
require_relative '../lib/portfolio_maker/command_line_interface'
|
9
|
+
require_relative '../lib/portfolio_maker/stock'
|
10
|
+
require_relative '../lib/portfolio_maker/version'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PortfolioMaker
|
2
|
+
end
|
3
|
+
|
4
|
+
require 'pry'
|
5
|
+
require 'nokogiri'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'colorize'
|
8
|
+
|
9
|
+
require_relative '../lib/portfolio_maker/scraper'
|
10
|
+
require_relative '../lib/portfolio_maker/portfolio'
|
11
|
+
require_relative '../lib/portfolio_maker/command_line_interface'
|
12
|
+
require_relative '../lib/portfolio_maker/stock'
|
13
|
+
require_relative '../lib/portfolio_maker/version'
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,196 @@
|
|
1
|
+
class PortfolioMaker::CommandLineInterface
|
2
|
+
|
3
|
+
attr_accessor :user_portfolio
|
4
|
+
|
5
|
+
def run
|
6
|
+
capital = 0
|
7
|
+
loop do
|
8
|
+
puts "How much would you like to deposit into your account?"
|
9
|
+
capital = gets.chomp
|
10
|
+
break if ((capital.to_i > 0) && capital.scan(/\D/).empty?)
|
11
|
+
puts "Please enter correct value"
|
12
|
+
end
|
13
|
+
@user_portfolio = Portfolio.new(capital.to_i)
|
14
|
+
main_menu
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def user_portfolio
|
19
|
+
|
20
|
+
@user_portfolio
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def main_menu
|
26
|
+
|
27
|
+
main_menu_loop_bool = true
|
28
|
+
loop do
|
29
|
+
puts "Select one of the following options by entering one of the below option number in your ternminal:"
|
30
|
+
puts "1. Manually enter stock ticker"
|
31
|
+
puts "2. Top 10 most active stocks"
|
32
|
+
puts "3. My portfolio"
|
33
|
+
puts "4. Quit"
|
34
|
+
|
35
|
+
input = menu_input(4)
|
36
|
+
|
37
|
+
case input
|
38
|
+
when 1
|
39
|
+
stock_find
|
40
|
+
when 2
|
41
|
+
most_active
|
42
|
+
when 3
|
43
|
+
portfolio_menu
|
44
|
+
when 4
|
45
|
+
main_menu_loop_bool = false
|
46
|
+
end
|
47
|
+
break if !(main_menu_loop_bool)
|
48
|
+
end
|
49
|
+
abort("Thank you for using this portfolio interface!")
|
50
|
+
end
|
51
|
+
|
52
|
+
def stock_find
|
53
|
+
|
54
|
+
stock_info = {}
|
55
|
+
#binding.pry
|
56
|
+
loop do
|
57
|
+
puts "Please enter stock ticker"
|
58
|
+
|
59
|
+
ticker = gets.chomp
|
60
|
+
|
61
|
+
if (!Stock.find_stock_with_ticker(ticker))
|
62
|
+
stock_info = Scraper.scrape_stock_page("https://finance.yahoo.com/quote/" + ticker)
|
63
|
+
else
|
64
|
+
stock_info = Stock.find_stock_with_ticker(ticker).make_hash_from_stock
|
65
|
+
end
|
66
|
+
break if (stock_info != nil)
|
67
|
+
puts "Please enter a proper stock ticker (No ETFs, Crypto, Indexes etc.)"
|
68
|
+
end
|
69
|
+
|
70
|
+
puts "Name: #{stock_info[:name]}, Price: $#{stock_info[:price]}, market cap: $#{stock_info[:market_cap]}"
|
71
|
+
puts "Select one of the following options by entering one of the below option number in your ternminal:"
|
72
|
+
puts "1. Add stock to portfolio or buy more"
|
73
|
+
puts "2. Return to main menu"
|
74
|
+
|
75
|
+
input = menu_input(2)
|
76
|
+
#binding.pry
|
77
|
+
case input
|
78
|
+
when 1
|
79
|
+
amount = 0
|
80
|
+
loop do
|
81
|
+
puts "Select what amount would you like to buy?\n current cash = $#{user_portfolio.cash}"
|
82
|
+
amount = gets.chomp
|
83
|
+
|
84
|
+
break if (!(amount.to_i > user_portfolio.cash || amount.to_i <= 0) && amount.scan(/\D/).empty?)
|
85
|
+
|
86
|
+
puts "Please enter valid amount within availible cash"
|
87
|
+
|
88
|
+
end
|
89
|
+
#binding.pry
|
90
|
+
user_portfolio.create_or_buy_more(stock_info, amount.to_i)
|
91
|
+
#binding.pry
|
92
|
+
puts "Bought #{amount.to_i / stock_info[:price].gsub(/[\s,]/ ,"").to_f} shares of #{stock_info[:name]}"
|
93
|
+
when 2
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def most_active
|
99
|
+
|
100
|
+
puts "Printing top 10 trending stocks"
|
101
|
+
|
102
|
+
Scraper.scrap_trending_stocks_page
|
103
|
+
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
def portfolio_menu
|
108
|
+
|
109
|
+
portfolio_loop_bool = true
|
110
|
+
loop do
|
111
|
+
puts "Manage your portfolio by entering one of the below option number in your ternminal:"
|
112
|
+
puts "1. View my portfolio"
|
113
|
+
puts "2. Sell stock"
|
114
|
+
puts "3. Add funds"
|
115
|
+
puts "4. Withdraw funds"
|
116
|
+
puts "5. Return to main menu"
|
117
|
+
|
118
|
+
input = menu_input(5)
|
119
|
+
|
120
|
+
case input
|
121
|
+
when 1
|
122
|
+
user_portfolio.display
|
123
|
+
when 2
|
124
|
+
if(user_portfolio.stocks.empty?)
|
125
|
+
puts "Porfolio is empty"
|
126
|
+
else
|
127
|
+
ticker = ""
|
128
|
+
amount = 0
|
129
|
+
loop do
|
130
|
+
break if (Stock.find_stock_with_ticker(ticker))
|
131
|
+
puts "Enter ticker for stock you want to sell or enter ""cancel"" to return to portfolio menu"
|
132
|
+
puts "Tickers:"
|
133
|
+
Stock.display_tickers
|
134
|
+
ticker = gets.chomp
|
135
|
+
|
136
|
+
break if ((Stock.find_stock_with_ticker(ticker)) || ticker == "cancel")
|
137
|
+
|
138
|
+
puts "Please enter a valid ticker"
|
139
|
+
|
140
|
+
end
|
141
|
+
if !(ticker == "cancel")
|
142
|
+
loop do
|
143
|
+
#binding.pry
|
144
|
+
puts "How much would you like to sell of $#{Stock.find_stock_with_ticker(ticker).update_stock_price} of the stock or enter ""cancel"" to return to portfolio menu"
|
145
|
+
amount = gets.chomp
|
146
|
+
|
147
|
+
break if ((!(amount.to_i <= 0 || amount.to_i > Stock.find_stock_with_ticker(ticker).equity.to_f) && amount.scan(/\D/).empty?) || amount == "cancel")
|
148
|
+
|
149
|
+
puts "Please input correct value"
|
150
|
+
end
|
151
|
+
user_portfolio.sell_stock(ticker, amount.to_i) if !(amount == "cancel" )
|
152
|
+
puts "Sold $#{amount} of #{ticker}" if !(amount == "cancel")
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
when 3
|
157
|
+
amount = ""
|
158
|
+
loop do
|
159
|
+
puts "How much would you like to deposit or enter ""cancel"" to return to portfolio menu"
|
160
|
+
amount = gets.chomp
|
161
|
+
|
162
|
+
break if ((!(amount.to_i <= 0) && amount.scan(/\D/).empty?) || amount == "cancel")
|
163
|
+
|
164
|
+
puts "Please input correct value"
|
165
|
+
end
|
166
|
+
user_portfolio.deposit(amount.to_i) if !(amount == "cancel")
|
167
|
+
when 4
|
168
|
+
loop do
|
169
|
+
puts "How much would you like to withdraw or enter ""cancel"" to return to portfolio menu \n current cash = $#{user_portfolio.cash}"
|
170
|
+
amount = gets.chomp
|
171
|
+
|
172
|
+
break if ((!(amount.to_i <= 0 || amount.to_i > user_portfolio.cash) && amount.scan(/\D/).empty?) || amount == "cancel")
|
173
|
+
|
174
|
+
puts "Please input correct value"
|
175
|
+
end
|
176
|
+
user_portfolio.withdraw(amount.to_i) if !(amount == "cancel")
|
177
|
+
when 5
|
178
|
+
portfolio_loop_bool = false
|
179
|
+
end
|
180
|
+
break if !(portfolio_loop_bool)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
def menu_input(max)
|
186
|
+
input = ""
|
187
|
+
loop do
|
188
|
+
input = gets.chomp
|
189
|
+
break if (input.to_i.between?(1,max) && input.scan(/\D/).empty?)
|
190
|
+
puts "Please enter an integer number between than 1 and #{max}:"
|
191
|
+
end
|
192
|
+
|
193
|
+
return input.to_i
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class Portfolio
|
2
|
+
|
3
|
+
attr_accessor :capital, :cash, :invested
|
4
|
+
|
5
|
+
def initialize(capital)
|
6
|
+
|
7
|
+
@capital = capital
|
8
|
+
@cash = capital
|
9
|
+
invested
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def stocks
|
14
|
+
|
15
|
+
Stock.all
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
|
21
|
+
if !(stocks.empty?)
|
22
|
+
value_change = Stock.update_stocks
|
23
|
+
@invested += value_change
|
24
|
+
@capital += value_change
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def invested
|
31
|
+
|
32
|
+
@invested = 0
|
33
|
+
stocks.each{|stock| @invested+=stock.equity}
|
34
|
+
@invested
|
35
|
+
end
|
36
|
+
|
37
|
+
def display
|
38
|
+
|
39
|
+
self.update
|
40
|
+
puts "Amount invested = $#{self.invested}"
|
41
|
+
puts "Cash availible = $#{self.cash}"
|
42
|
+
if (!stocks.empty?)
|
43
|
+
|
44
|
+
stocks.each{|stock|stock.display}
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
def create_or_buy_more(stock_hash, amount)
|
51
|
+
|
52
|
+
@cash -= amount
|
53
|
+
@invested += amount
|
54
|
+
Stock.create_or_buy_more(stock_hash, amount)
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def sell_stock(ticker, amount)
|
59
|
+
|
60
|
+
|
61
|
+
Stock.sell(ticker, amount)
|
62
|
+
@invested -= amount
|
63
|
+
@cash += amount
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def deposit(amount)
|
68
|
+
|
69
|
+
@cash += amount
|
70
|
+
@capital += amount
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
def withdraw(amount)
|
75
|
+
|
76
|
+
@cash -= amount
|
77
|
+
@capital -= amount
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
class Scraper
|
5
|
+
|
6
|
+
def self.scrap_trending_stocks_page
|
7
|
+
|
8
|
+
stock_hash_arr = []
|
9
|
+
|
10
|
+
doc = Nokogiri::HTML(open("https://www.investing.com/equities/trending-stocks"))
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
top_stocks = doc.css('table tbody tr td a')
|
15
|
+
|
16
|
+
i = 0
|
17
|
+
|
18
|
+
10.times do |index|
|
19
|
+
|
20
|
+
stock_url = "https://www.investing.com" + top_stocks[i].attribute("href").value
|
21
|
+
stock_ticker = Nokogiri::HTML(open(stock_url)).css(".instrumentHeader h2").text.split(" ")[0]
|
22
|
+
|
23
|
+
#puts {:ticker => stock_ticker, :name => top_stocks[i].text}
|
24
|
+
puts "#{index + 1}. #{stock_ticker} #{top_stocks[i].text}"
|
25
|
+
|
26
|
+
i+=1
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
#binding.pry
|
31
|
+
stock_hash_arr
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.scrape_stock_page(stock_url)
|
36
|
+
|
37
|
+
begin
|
38
|
+
doc = Nokogiri::HTML(open(stock_url))
|
39
|
+
|
40
|
+
rescue
|
41
|
+
return nil
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
#binding.pry
|
46
|
+
stock = {}
|
47
|
+
|
48
|
+
stock_name = doc.css("#quote-header-info div div div")[0].text.split(" ")
|
49
|
+
stock[:ticker] = stock_name.pop.split(/[()]/)[1]
|
50
|
+
stock[:name] = stock_name.join(" ")
|
51
|
+
stock[:price] = doc.css("#quote-header-info div div div span")[3].text
|
52
|
+
stock[:market_cap] = doc.css("#quote-summary div span")[13].text
|
53
|
+
|
54
|
+
stock
|
55
|
+
#binding.pry
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class Stock
|
2
|
+
|
3
|
+
attr_accessor :name, :ticker, :price, :quantity, :equity, :market_cap
|
4
|
+
|
5
|
+
@@all = []
|
6
|
+
|
7
|
+
def initialize(stock_hash)
|
8
|
+
|
9
|
+
stock_hash.each {|key, value| self.send(("#{key}="), value)}
|
10
|
+
@quantity = self.update_quantity
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.sell(ticker, amount)
|
15
|
+
|
16
|
+
self.find_stock_with_ticker(ticker).equity -= amount
|
17
|
+
if (self.find_stock_with_ticker(ticker).equity == 0)
|
18
|
+
@@all.delete(self.find_stock_with_ticker(ticker))
|
19
|
+
else
|
20
|
+
self.find_stock_with_ticker(ticker).update_quantity
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def make_hash_from_stock
|
26
|
+
|
27
|
+
stock_info = {}
|
28
|
+
|
29
|
+
stock_info[:name] = self.name
|
30
|
+
stock_info[:price] = self.price
|
31
|
+
stock_info[:market_cap] = self.market_cap
|
32
|
+
|
33
|
+
stock_info
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def update_quantity
|
38
|
+
|
39
|
+
@quantity = @equity/(self.price.to_f)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def curr_equity
|
44
|
+
|
45
|
+
@equity = @quantity * (self.price.to_f)
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_stock_price
|
50
|
+
|
51
|
+
self.price = Scraper.scrape_stock_page("https://finance.yahoo.com/quote/" + self.ticker)[:price]
|
52
|
+
self.curr_equity
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def price=(price)
|
57
|
+
|
58
|
+
@price = price
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def self.find_stock_with_ticker(ticker)
|
64
|
+
|
65
|
+
stock = @@all.select{|stock|stock.ticker == ticker}
|
66
|
+
|
67
|
+
stock == [] ? nil : stock[0]
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
def price
|
72
|
+
|
73
|
+
@price.gsub(/[\s,]/ ,"").to_f
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
def display
|
78
|
+
|
79
|
+
puts "#{@name} (#{@ticker}): stocks: #{@quantity} shares, equity: $#{self.curr_equity}"
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.display_tickers
|
84
|
+
|
85
|
+
@@all.each {|stock| print "|#{stock.ticker}"}
|
86
|
+
puts "|"
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.update_stocks
|
90
|
+
|
91
|
+
#binding.pry
|
92
|
+
price_update = 0
|
93
|
+
@@all.each do |stock|
|
94
|
+
curr_price = stock.price
|
95
|
+
stock.update_stock_price
|
96
|
+
price_update = stock.price - price_update
|
97
|
+
end
|
98
|
+
price_update
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.create_or_buy_more(stock_hash, amount)
|
102
|
+
|
103
|
+
if (!self.find_stock_with_ticker(stock_hash[:ticker]))
|
104
|
+
stock_hash[:equity] = amount
|
105
|
+
new_stock = self.new(stock_hash)
|
106
|
+
@@all << new_stock
|
107
|
+
else
|
108
|
+
updating_stock = self.find_stock_with_ticker(stock_hash[:ticker])
|
109
|
+
updating_stock.update_stock_price
|
110
|
+
updating_stock.quantity += (amount/updating_stock.price)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.all
|
115
|
+
@@all
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: portfolio-maker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "'Sumer Gaikwad'"
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.2'
|
83
|
+
description: portfolio simulator
|
84
|
+
email:
|
85
|
+
- "'sg.comparch@gmail.com'"
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- config/environment.rb
|
91
|
+
- lib/portfolio_maker.rb
|
92
|
+
- lib/portfolio_maker/command_line_interface.rb
|
93
|
+
- lib/portfolio_maker/portfolio.rb
|
94
|
+
- lib/portfolio_maker/scraper.rb
|
95
|
+
- lib/portfolio_maker/stock.rb
|
96
|
+
homepage: http://rubygems.org
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata:
|
100
|
+
allowed_push_host: https://rubygems.org
|
101
|
+
homepage_uri: http://rubygems.org
|
102
|
+
source_code_uri: https://github.com/RSigmaSG/portfolio_maker
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 2.3.0
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubygems_version: 3.0.8
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: portfolio simulator
|
122
|
+
test_files: []
|