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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80a8d3dc5f7e4139d0430bea78b74f45c9a03f19
4
- data.tar.gz: edc504b6fc384ec132dad1759313c3a9e3fb8b1b
3
+ metadata.gz: 0314b378b48277538593a755f10a6c11ab6fc30c
4
+ data.tar.gz: 3ecdaabf9c72ab9bac2eefe557bcb065a6c30120
5
5
  SHA512:
6
- metadata.gz: 0aa7b3ef4ac92cd7290efce4ec932c2223ed618e6f3ce0e3a7f76049ffc734d13539d25460df5e59d10724f0ad440db450c0f089fc5790f61aba294df195ab18
7
- data.tar.gz: b4d5f1b942bec8b20a59f71d41a3a87de3457538649ff9c37f08b09612299983284bffa0aa95eb1dba0ee56a58025b1d72b9c74678fc35714e34c24d36a16d65
6
+ metadata.gz: 31501c0a5c52f670ff2b4838e25509deec729cb0b0a24a7b40570f617921a7b14cc5c7d247df5a6e975ac06d0df99f3191bdc060d0aaefd7a462986a00c7d7ca
7
+ data.tar.gz: e545f2e6ca010db9956bb127f683f681006bf50184476a66817a64ea1dd96c12fca065098b35b5a835d65a938fd3027756623be40e524481904ee8dc01a4ac33
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in capwatch.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'coveralls', require: false
8
+ end
data/README.md CHANGED
@@ -1,8 +1,12 @@
1
1
  # Capwatch
2
2
 
3
- Watch you cryptoportfolio in a console
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
- ![Demo](https://i.imgur.com/XioyQQo.png)
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": "My Fund",
18
+ "name": "Basic Fund",
15
19
  "symbols": {
16
- "ETH": 10,
17
- "BTC": 10,
18
- "XRP": 1,
19
- "LTC": 1,
20
- "ETC": 1,
21
- "DASH": 1,
22
- "XEM": 1,
23
- "MIOTA": 1,
24
- "XMR": 1,
25
- "STRAT": 1,
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
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'capwatch/version'
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "Basic Fund",
3
+ "symbols": {
4
+ "MAID": 25452.47,
5
+ "GAME": 22253.51,
6
+ "ANS": 3826.53,
7
+ "FCT": 525.67875,
8
+ "SC": 4152770,
9
+ "DCR": 453.22,
10
+ "BTC": 8.219,
11
+ "ETH": 166.198,
12
+ "KMD": 19056.20,
13
+ "LSK": 5071.42
14
+ }
15
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "Dynamic Fund",
3
+ "symbols": {
4
+ "ANS": 5102.04,
5
+ "GAME": 41952.55,
6
+ "SC": 10341309,
7
+ "DCR": 791.489,
8
+ "ETH": 128.57,
9
+ "BTC": 22.876
10
+ }
11
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "Extreme Fund",
3
+ "symbols": {
4
+ "FLO": 2140.96,
5
+ "DAR": 141.93,
6
+ "UBQ": 141.54,
7
+ "BTC": 0.09,
8
+ "WAVES": 218.18,
9
+ "GUP": 487.56,
10
+ "WINGS": 508.67
11
+ }
12
+ }
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
- module Capwatch
12
- class CoinMarketCap
13
- def self.fetch
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
@@ -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,12 @@
1
+ require 'json'
2
+ require 'open-uri'
3
+
4
+ module Capwatch
5
+ class CoinMarketCap
6
+ URL = 'http://api.coinmarketcap.com/v1/ticker/'.freeze
7
+ def self.fetch
8
+ response = open(URL).read
9
+ JSON.parse response
10
+ end
11
+ end
12
+ 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
@@ -1,3 +1,3 @@
1
1
  module Capwatch
2
- VERSION = '0.1.10'.freeze
2
+ VERSION = '0.1.11'.freeze
3
3
  end
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.10
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-07-17 00:00:00.000000000 Z
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: