capwatch 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.md +25 -22
- data/capwatch.gemspec +1 -0
- data/funds/demo/basic.json +15 -0
- data/funds/demo/dynamic.json +11 -0
- data/funds/demo/extreme.json +12 -0
- data/lib/capwatch.rb +4 -207
- data/lib/capwatch/calculator.rb +88 -0
- data/lib/capwatch/cli.rb +18 -0
- data/lib/capwatch/coinmarketcap.rb +12 -0
- data/lib/capwatch/console.rb +81 -0
- data/lib/capwatch/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0314b378b48277538593a755f10a6c11ab6fc30c
|
4
|
+
data.tar.gz: 3ecdaabf9c72ab9bac2eefe557bcb065a6c30120
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31501c0a5c52f670ff2b4838e25509deec729cb0b0a24a7b40570f617921a7b14cc5c7d247df5a6e975ac06d0df99f3191bdc060d0aaefd7a462986a00c7d7ca
|
7
|
+
data.tar.gz: e545f2e6ca010db9956bb127f683f681006bf50184476a66817a64ea1dd96c12fca065098b35b5a835d65a938fd3027756623be40e524481904ee8dc01a4ac33
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# Capwatch
|
2
2
|
|
3
|
-
|
3
|
+
[![Build Status](https://travis-ci.org/bugaiov/capwatch.svg?branch=master)](https://travis-ci.org/bugaiov/capwatch)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/github/bugaiov/capwatch/badge.svg?branch=master)](https://coveralls.io/github/bugaiov/capwatch?branch=master)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/capwatch.svg)](https://badge.fury.io/rb/capwatch)
|
4
6
|
|
5
|
-
|
7
|
+
Watch your cryptoportfolio in a console
|
8
|
+
|
9
|
+
![Demo](http://i.imgur.com/ZkrFDtL.png)
|
6
10
|
|
7
11
|
## Installation
|
8
12
|
|
@@ -11,30 +15,29 @@ Watch you cryptoportfolio in a console
|
|
11
15
|
```bash
|
12
16
|
cat <<EOT > ~/.capwatch
|
13
17
|
{
|
14
|
-
"name": "
|
18
|
+
"name": "Basic Fund",
|
15
19
|
"symbols": {
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
21
|
-
"
|
22
|
-
"
|
23
|
-
"
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"BCC": 1,
|
27
|
-
"EOS": 1,
|
28
|
-
"USDT": 1,
|
29
|
-
"ZEC": 1,
|
30
|
-
"ANS": 1,
|
31
|
-
"VERI": 1,
|
32
|
-
"BTS": 1,
|
33
|
-
"STEEM": 1,
|
34
|
-
"BCN": 1
|
20
|
+
"MAID": 25452.47,
|
21
|
+
"GAME": 22253.51,
|
22
|
+
"ANS": 3826.53,
|
23
|
+
"FCT": 525.67875,
|
24
|
+
"SC": 4152770,
|
25
|
+
"DCR": 453.22,
|
26
|
+
"BTC": 8.219,
|
27
|
+
"ETH": 166.198,
|
28
|
+
"KMD": 19056.20,
|
29
|
+
"LSK": 5071.42
|
35
30
|
}
|
36
31
|
}
|
37
32
|
EOT
|
38
33
|
```
|
39
34
|
|
40
35
|
$ capwatch
|
36
|
+
|
37
|
+
## Fund Examples
|
38
|
+
|
39
|
+
Fund examples can be found [here](funds/demo)
|
40
|
+
|
41
|
+
Demo funds taken from www.bluemagic.info
|
42
|
+
|
43
|
+
Data is being processed from from http://coinmarketcap.com
|
data/capwatch.gemspec
CHANGED
data/lib/capwatch.rb
CHANGED
@@ -1,211 +1,8 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'optparse'
|
3
|
-
require 'ostruct'
|
4
|
-
require 'net/http'
|
5
|
-
|
6
1
|
require 'colorize'
|
7
2
|
require 'terminal-table'
|
8
3
|
|
9
4
|
require 'capwatch/version'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
JSON.parse(Net::HTTP.get(URI('http://api.coinmarketcap.com/v1/ticker/')))
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class Calculator
|
19
|
-
def self.fund_hash(fund, coinmarketcap_json)
|
20
|
-
table = []
|
21
|
-
|
22
|
-
title = fund['name']
|
23
|
-
symbols = fund['symbols']
|
24
|
-
fund_keys = symbols.keys
|
25
|
-
|
26
|
-
price_eth_btc = coinmarketcap_json.find do |x|
|
27
|
-
x['symbol'] == 'ETH'
|
28
|
-
end['price_usd'].to_f
|
29
|
-
|
30
|
-
filtered_response_json = coinmarketcap_json.select do |x|
|
31
|
-
fund_keys.include?(x['symbol'])
|
32
|
-
end
|
33
|
-
|
34
|
-
total_value_usd = filtered_response_json.inject(0) do |sum, n|
|
35
|
-
sum + symbols[n['symbol']] * n['price_usd'].to_f
|
36
|
-
end
|
37
|
-
|
38
|
-
total_value_btc = filtered_response_json.inject(0) do |sum, n|
|
39
|
-
sum + symbols[n['symbol']] * n['price_btc'].to_f
|
40
|
-
end
|
41
|
-
|
42
|
-
total_value_eth = filtered_response_json.inject(0) do |sum, n|
|
43
|
-
sum + symbols[n['symbol']] * n['price_usd'].to_f / price_eth_btc
|
44
|
-
end
|
45
|
-
|
46
|
-
distribution_hash = {}
|
47
|
-
|
48
|
-
fund_keys.each do |x|
|
49
|
-
x = filtered_response_json.find { |e| e['symbol'] == x }
|
50
|
-
symbol = x['symbol']
|
51
|
-
asset_name = "#{x['name']} (#{symbol})"
|
52
|
-
quant_value = symbols[symbol]
|
53
|
-
price = x['price_usd'].to_f
|
54
|
-
value_btc = quant_value * x['price_btc'].to_f
|
55
|
-
value_eth = quant_value * x['price_usd'].to_f / price_eth_btc
|
56
|
-
value_usd = quant_value * x['price_usd'].to_f
|
57
|
-
distribution_float = value_usd / total_value_usd
|
58
|
-
distribution_hash[symbol] = distribution_float
|
59
|
-
distribution = distribution_float * 100
|
60
|
-
percent_change_1h = x['percent_change_1h'].to_f || 0
|
61
|
-
percent_change_24h = x['percent_change_24h'].to_f || 0
|
62
|
-
percent_change_7d = x['percent_change_7d'].to_f || 0
|
63
|
-
table << [
|
64
|
-
asset_name,
|
65
|
-
quant_value,
|
66
|
-
price,
|
67
|
-
value_usd,
|
68
|
-
value_btc,
|
69
|
-
value_eth,
|
70
|
-
distribution,
|
71
|
-
percent_change_1h,
|
72
|
-
percent_change_24h,
|
73
|
-
percent_change_7d
|
74
|
-
]
|
75
|
-
end
|
76
|
-
|
77
|
-
a_1h = filtered_response_json.inject(0) do |sum, n|
|
78
|
-
sum + n['percent_change_1h'].to_f * distribution_hash[n['symbol']].to_f
|
79
|
-
end
|
80
|
-
|
81
|
-
a_24h = filtered_response_json.inject(0) do |sum, n|
|
82
|
-
sum + n['percent_change_24h'].to_f * distribution_hash[n['symbol']].to_f
|
83
|
-
end
|
84
|
-
|
85
|
-
a_7d = filtered_response_json.inject(0) do |sum, n|
|
86
|
-
sum + n['percent_change_7d'].to_f * distribution_hash[n['symbol']].to_f
|
87
|
-
end
|
88
|
-
|
89
|
-
footer = [
|
90
|
-
'',
|
91
|
-
'',
|
92
|
-
'',
|
93
|
-
total_value_usd,
|
94
|
-
total_value_btc,
|
95
|
-
total_value_eth,
|
96
|
-
'',
|
97
|
-
a_1h,
|
98
|
-
a_24h,
|
99
|
-
a_7d
|
100
|
-
]
|
101
|
-
|
102
|
-
table.sort_by! { |a| -a[6].to_f } # DIST (%)
|
103
|
-
|
104
|
-
{}
|
105
|
-
.merge(title: title)
|
106
|
-
.merge(table: table)
|
107
|
-
.merge(footer: footer)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
class CLI
|
112
|
-
def self.parse(args)
|
113
|
-
options = OpenStruct.new
|
114
|
-
options.tick = 60 * 5
|
115
|
-
opt_parser = OptionParser.new do |opts|
|
116
|
-
opts.on('-t', '--tick [Integer]', Integer, 'Tick Interval') do |t|
|
117
|
-
options.tick = t
|
118
|
-
end
|
119
|
-
end
|
120
|
-
opt_parser.parse!(args)
|
121
|
-
options
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
module ConsoleFormatter
|
126
|
-
def format_usd(n)
|
127
|
-
'$' + n.round(2).to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
128
|
-
end
|
129
|
-
|
130
|
-
def format_btc(value)
|
131
|
-
format('฿%.2f', value)
|
132
|
-
end
|
133
|
-
|
134
|
-
def format_eth(value)
|
135
|
-
format('Ξ%.2f', value)
|
136
|
-
end
|
137
|
-
|
138
|
-
def format_percent(value)
|
139
|
-
format('%.2f%', value)
|
140
|
-
end
|
141
|
-
|
142
|
-
def condition_color(value)
|
143
|
-
percent_value = value.to_f
|
144
|
-
if percent_value > 1
|
145
|
-
value.green
|
146
|
-
elsif percent_value < 0
|
147
|
-
value.red
|
148
|
-
else
|
149
|
-
value.green
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
class Console
|
155
|
-
extend ConsoleFormatter
|
156
|
-
|
157
|
-
def self.colorize_table(hash)
|
158
|
-
hash[:table].each do |x|
|
159
|
-
x[2] = format_usd(x[2])
|
160
|
-
x[3] = format_usd(x[3])
|
161
|
-
x[4] = format_btc(x[4])
|
162
|
-
x[5] = format_eth(x[5])
|
163
|
-
x[6] = format_percent(x[6])
|
164
|
-
x[7] = condition_color(format_percent(x[7]))
|
165
|
-
x[8] = condition_color(format_percent(x[8]))
|
166
|
-
x[9] = condition_color(format_percent(x[9]))
|
167
|
-
end
|
168
|
-
hash[:footer][3] = format_usd(hash[:footer][3])
|
169
|
-
hash[:footer][4] = format_btc(hash[:footer][4])
|
170
|
-
hash[:footer][5] = format_eth(hash[:footer][5])
|
171
|
-
hash[:footer][7] = condition_color(format_percent(hash[:footer][7]))
|
172
|
-
hash[:footer][8] = condition_color(format_percent(hash[:footer][8]))
|
173
|
-
hash[:footer][9] = condition_color(format_percent(hash[:footer][9]))
|
174
|
-
hash
|
175
|
-
end
|
176
|
-
|
177
|
-
def self.draw_table(hash)
|
178
|
-
hash = colorize_table(hash)
|
179
|
-
table = Terminal::Table.new do |t|
|
180
|
-
t.title = hash[:title].upcase
|
181
|
-
t.style = {
|
182
|
-
border_top: false,
|
183
|
-
border_bottom: false,
|
184
|
-
border_y: '',
|
185
|
-
border_i: '',
|
186
|
-
padding_left: 1,
|
187
|
-
padding_right: 1
|
188
|
-
}
|
189
|
-
t.headings = [
|
190
|
-
'ASSET',
|
191
|
-
'QUANTITY',
|
192
|
-
'PRICE',
|
193
|
-
'VALUE (USD)',
|
194
|
-
'VALUE (BTC)',
|
195
|
-
'VALUE (ETH)',
|
196
|
-
'DIST (%)',
|
197
|
-
'%(1H)',
|
198
|
-
'%(24H)',
|
199
|
-
'%(7D)'
|
200
|
-
]
|
201
|
-
hash[:table].each do |x|
|
202
|
-
t << x
|
203
|
-
end
|
204
|
-
t.add_separator
|
205
|
-
t.add_row hash[:footer]
|
206
|
-
end
|
207
|
-
|
208
|
-
table
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
5
|
+
require 'capwatch/coinmarketcap'
|
6
|
+
require 'capwatch/calculator'
|
7
|
+
require 'capwatch/cli'
|
8
|
+
require 'capwatch/console'
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Capwatch
|
2
|
+
class Calculator
|
3
|
+
def self.fund_hash(fund, coinmarketcap_json)
|
4
|
+
table = []
|
5
|
+
|
6
|
+
title = fund['name']
|
7
|
+
symbols = fund['symbols']
|
8
|
+
fund_keys = symbols.keys
|
9
|
+
|
10
|
+
price_eth_btc = coinmarketcap_json.find do |x|
|
11
|
+
x['symbol'] == 'ETH'
|
12
|
+
end['price_usd'].to_f
|
13
|
+
|
14
|
+
filtered_response_json = coinmarketcap_json.select do |x|
|
15
|
+
fund_keys.include?(x['symbol'])
|
16
|
+
end
|
17
|
+
|
18
|
+
total_value_usd = filtered_response_json.inject(0) do |sum, n|
|
19
|
+
sum + symbols[n['symbol']] * n['price_usd'].to_f
|
20
|
+
end
|
21
|
+
|
22
|
+
total_value_btc = filtered_response_json.inject(0) do |sum, n|
|
23
|
+
sum + symbols[n['symbol']] * n['price_btc'].to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
total_value_eth = filtered_response_json.inject(0) do |sum, n|
|
27
|
+
sum + symbols[n['symbol']] * n['price_usd'].to_f / price_eth_btc
|
28
|
+
end
|
29
|
+
|
30
|
+
distribution_hash = {}
|
31
|
+
|
32
|
+
fund_keys.each do |x|
|
33
|
+
x = filtered_response_json.find { |e| e['symbol'] == x }
|
34
|
+
symbol = x['symbol']
|
35
|
+
asset_name = "#{x['name']} (#{symbol})"
|
36
|
+
quant_value = symbols[symbol]
|
37
|
+
price = x['price_usd'].to_f
|
38
|
+
value_btc = quant_value * x['price_btc'].to_f
|
39
|
+
value_eth = quant_value * x['price_usd'].to_f / price_eth_btc
|
40
|
+
value_usd = quant_value * x['price_usd'].to_f
|
41
|
+
distribution_float = value_usd / total_value_usd
|
42
|
+
distribution_hash[symbol] = distribution_float
|
43
|
+
distribution = distribution_float * 100
|
44
|
+
percent_change_24h = x['percent_change_24h'].to_f || 0
|
45
|
+
percent_change_7d = x['percent_change_7d'].to_f || 0
|
46
|
+
table << [
|
47
|
+
asset_name,
|
48
|
+
price,
|
49
|
+
quant_value,
|
50
|
+
value_usd,
|
51
|
+
value_btc,
|
52
|
+
value_eth,
|
53
|
+
distribution,
|
54
|
+
percent_change_24h,
|
55
|
+
percent_change_7d
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
a_24h = filtered_response_json.inject(0) do |sum, n|
|
60
|
+
sum + n['percent_change_24h'].to_f * distribution_hash[n['symbol']].to_f
|
61
|
+
end
|
62
|
+
|
63
|
+
a_7d = filtered_response_json.inject(0) do |sum, n|
|
64
|
+
sum + n['percent_change_7d'].to_f * distribution_hash[n['symbol']].to_f
|
65
|
+
end
|
66
|
+
|
67
|
+
footer = [
|
68
|
+
'',
|
69
|
+
'',
|
70
|
+
'',
|
71
|
+
total_value_usd,
|
72
|
+
total_value_btc,
|
73
|
+
total_value_eth,
|
74
|
+
'',
|
75
|
+
a_24h,
|
76
|
+
a_7d
|
77
|
+
]
|
78
|
+
|
79
|
+
table.sort_by! { |e| -e[3].to_f }
|
80
|
+
table.each.with_index(1) { |e, i| e[0] = "#{i}. #{e[0]}" }
|
81
|
+
|
82
|
+
{}
|
83
|
+
.merge(title: title)
|
84
|
+
.merge(table: table)
|
85
|
+
.merge(footer: footer)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/capwatch/cli.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Capwatch
|
5
|
+
class CLI
|
6
|
+
def self.parse(args)
|
7
|
+
options = OpenStruct.new
|
8
|
+
options.tick = 60 * 5
|
9
|
+
opt_parser = OptionParser.new do |opts|
|
10
|
+
opts.on('-t', '--tick [Integer]', Integer, 'Tick Interval') do |t|
|
11
|
+
options.tick = t
|
12
|
+
end
|
13
|
+
end
|
14
|
+
opt_parser.parse!(args)
|
15
|
+
options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Capwatch
|
2
|
+
class Console
|
3
|
+
def self.colorize_table(hash)
|
4
|
+
hash[:table].each do |x|
|
5
|
+
x[1] = format_usd(x[1])
|
6
|
+
x[3] = format_usd(x[3])
|
7
|
+
x[4] = format_btc(x[4])
|
8
|
+
x[5] = format_eth(x[5])
|
9
|
+
x[6] = format_percent(x[6])
|
10
|
+
x[7] = condition_color(format_percent(x[7]))
|
11
|
+
x[8] = condition_color(format_percent(x[8]))
|
12
|
+
end
|
13
|
+
hash[:footer][3] = format_usd(hash[:footer][3])
|
14
|
+
hash[:footer][4] = format_btc(hash[:footer][4])
|
15
|
+
hash[:footer][5] = format_eth(hash[:footer][5])
|
16
|
+
hash[:footer][7] = condition_color(format_percent(hash[:footer][7]))
|
17
|
+
hash[:footer][8] = condition_color(format_percent(hash[:footer][8]))
|
18
|
+
hash
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.draw_table(hash)
|
22
|
+
hash = colorize_table(hash)
|
23
|
+
table = Terminal::Table.new do |t|
|
24
|
+
t.title = hash[:title].upcase
|
25
|
+
t.style = {
|
26
|
+
border_top: false,
|
27
|
+
border_bottom: false,
|
28
|
+
border_y: '',
|
29
|
+
border_i: '',
|
30
|
+
padding_left: 1,
|
31
|
+
padding_right: 1
|
32
|
+
}
|
33
|
+
t.headings = [
|
34
|
+
'ASSET',
|
35
|
+
'PRICE',
|
36
|
+
'QUANTITY',
|
37
|
+
'VALUE (USD)',
|
38
|
+
'VALUE (BTC)',
|
39
|
+
'VALUE (ETH)',
|
40
|
+
'DIST %',
|
41
|
+
'24H %',
|
42
|
+
'7D %'
|
43
|
+
]
|
44
|
+
hash[:table].each do |x|
|
45
|
+
t << x
|
46
|
+
end
|
47
|
+
t.add_separator
|
48
|
+
t.add_row hash[:footer]
|
49
|
+
end
|
50
|
+
|
51
|
+
table
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.format_usd(n)
|
55
|
+
'$' + n.round(2).to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.format_btc(value)
|
59
|
+
format('฿%.2f', value)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.format_eth(value)
|
63
|
+
format('Ξ%.2f', value)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.format_percent(value)
|
67
|
+
format('%.2f%', value)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.condition_color(value)
|
71
|
+
percent_value = value.to_f
|
72
|
+
if percent_value > 1
|
73
|
+
value.green
|
74
|
+
elsif percent_value < 0
|
75
|
+
value.red
|
76
|
+
else
|
77
|
+
value.green
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/capwatch/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capwatch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Bugaiov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: terminal-table
|
@@ -100,7 +100,14 @@ files:
|
|
100
100
|
- bin/setup
|
101
101
|
- capwatch.gemspec
|
102
102
|
- exe/capwatch
|
103
|
+
- funds/demo/basic.json
|
104
|
+
- funds/demo/dynamic.json
|
105
|
+
- funds/demo/extreme.json
|
103
106
|
- lib/capwatch.rb
|
107
|
+
- lib/capwatch/calculator.rb
|
108
|
+
- lib/capwatch/cli.rb
|
109
|
+
- lib/capwatch/coinmarketcap.rb
|
110
|
+
- lib/capwatch/console.rb
|
104
111
|
- lib/capwatch/version.rb
|
105
112
|
homepage: https://cryptowatch.one
|
106
113
|
licenses:
|