abot-whitelist 0.2.0 → 0.3.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 +4 -4
- data/Gemfile +1 -0
- data/abot-whitelist.gemspec +1 -0
- data/lib/abot/whitelist/abot_config_site.rb +22 -0
- data/lib/abot/whitelist/base.rb +38 -0
- data/lib/abot/whitelist/binance.rb +40 -0
- data/lib/abot/whitelist/coingecko.rb +83 -0
- data/lib/abot/whitelist/version.rb +1 -1
- data/lib/abot/whitelist.rb +30 -5
- metadata +20 -4
- data/lib/abot/whitelist/base_whitelist.rb +0 -24
- data/lib/abot/whitelist/binance_cap.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d399811d901d4890fefcd6db8442638ee60e3bd05cf37daab990813e0a630fed
|
4
|
+
data.tar.gz: ee0dce6fb6bf1d9e444d43ec3a6bf63123b84135b26c1a54c6dfb5acbe1e0958
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7788fdefec41dc9397e9a494f674e0e49da88aebf547b129c6a7090745cba60c9ad68447f02a24e4797c5339e2bc0e3c383682908ad10d75a4321273f289f92b
|
7
|
+
data.tar.gz: d836ccacf75442c67dba3ba95c2e1c0db0f4d6d39ab518d2af1517a0f160358e5ca8fa5e589788e8939aca8797723255981f39d899a6f26b96033d78aebb73d0
|
data/Gemfile
CHANGED
data/abot-whitelist.gemspec
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abot
|
4
|
+
module Whitelist
|
5
|
+
class AbotConfigSite
|
6
|
+
include HTTParty
|
7
|
+
|
8
|
+
base_uri 'https://abot-config.ru'
|
9
|
+
|
10
|
+
def list(list_number)
|
11
|
+
path = "/coins/whitelist-#{list_number}.txt"
|
12
|
+
response = self.class.get(path)
|
13
|
+
|
14
|
+
if response.code == 200
|
15
|
+
response.body.split(' ') || ''
|
16
|
+
else
|
17
|
+
raise "get base whitelist from #{self.class.base_uri} error"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abot
|
4
|
+
module Whitelist
|
5
|
+
class Base
|
6
|
+
attr_reader :top, :list_number
|
7
|
+
|
8
|
+
DEFAULT_COINS = %w[one unfi sol].freeze
|
9
|
+
FIAT = %w[usdt busd aud bidr brl eur gbr rub try tusd usdc dai idrt pax uah ngn vai bvnd].freeze
|
10
|
+
BLACK_LIST = %w[fun xvs aion btc].freeze
|
11
|
+
|
12
|
+
def self.black_coins
|
13
|
+
FIAT + BLACK_LIST
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(options)
|
17
|
+
@top = options[:top]
|
18
|
+
@list_number = options[:list_number]
|
19
|
+
end
|
20
|
+
|
21
|
+
def process!
|
22
|
+
coins_list = top_list
|
23
|
+
if list_number
|
24
|
+
base_list = Abot::Whitelist::AbotConfigSite.new.list(list_number)
|
25
|
+
coins_list = coins_list.map { |m| base_list.include?(m) ? m : nil }.compact
|
26
|
+
|
27
|
+
puts "base list: #{base_list}\n"
|
28
|
+
puts "coins (count = #{coins_list.count}) from the base list in the top #{top} by capitalization:"
|
29
|
+
else
|
30
|
+
puts "coins (count = #{coins_list.count}) in the top #{top} by capitalization:"
|
31
|
+
end
|
32
|
+
|
33
|
+
puts coins_list.join(' ')
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abot
|
4
|
+
module Whitelist
|
5
|
+
class Binance < Base
|
6
|
+
attr_reader :top, :list_number
|
7
|
+
|
8
|
+
include HTTParty
|
9
|
+
base_uri 'https://www.binance.com'
|
10
|
+
|
11
|
+
def self.list_all_usdt_coins
|
12
|
+
usdt_coins.map { |m| black_coins.include?(m[:b].downcase) ? nil : m[:b].downcase }.compact
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.usdt_coins
|
16
|
+
begin
|
17
|
+
JSON.parse(products, symbolize_names: true)[:data].select { |s| s[:q] == 'USDT' }
|
18
|
+
rescue JSON::ParserError => error
|
19
|
+
# binance 500 errors are html format
|
20
|
+
raise Error.new(message: error)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.products
|
25
|
+
path = '/exchange-api/v2/public/asset-service/product/get-products'
|
26
|
+
get(path).body
|
27
|
+
end
|
28
|
+
|
29
|
+
def top_list
|
30
|
+
all_coins = self.class.usdt_coins.map { |s| [s[:b], (s[:cs].to_f * s[:c].to_f)] }
|
31
|
+
.sort_by { |s| s[1] }
|
32
|
+
.reverse
|
33
|
+
.map { |m| m[0] }
|
34
|
+
result = (all_coins - FIAT - BLACK_LIST - DEFAULT_COINS)[0..((top - 1) - DEFAULT_COINS.count)]
|
35
|
+
(result + DEFAULT_COINS).map(&:upcase)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'abot_config_site'
|
4
|
+
require 'coingecko_ruby'
|
5
|
+
|
6
|
+
module Abot
|
7
|
+
module Whitelist
|
8
|
+
class Coingecko < Base
|
9
|
+
attr_reader :client, :top, :list_number
|
10
|
+
|
11
|
+
DIF_COINS = {
|
12
|
+
'iota' => 'miota',
|
13
|
+
'data' => 'xdata',
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
def initialize(options)
|
17
|
+
@client = CoingeckoRuby::Client.new
|
18
|
+
|
19
|
+
super(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def top_list
|
23
|
+
coins_ids = []
|
24
|
+
list_all_usdt_coins = Binance.list_all_usdt_coins.map do |m|
|
25
|
+
DIF_COINS.find { |k, v| k == m }&.dig(1) || m
|
26
|
+
end
|
27
|
+
|
28
|
+
list_all_usdt_coins.each do |coin|
|
29
|
+
decorated_all_coins[coin]&.each { |e| coins_ids << e }
|
30
|
+
decorated_all_coins[coin.upcase]&.each { |e| coins_ids << e }
|
31
|
+
end
|
32
|
+
info = coins_info(coins_ids)
|
33
|
+
info.keys[0...top].map(&:upcase)
|
34
|
+
end
|
35
|
+
|
36
|
+
def coins_info(coins)
|
37
|
+
info = client.markets(coins.join(', '), vs_currency: 'gbp')
|
38
|
+
result = {}
|
39
|
+
info.each do |m|
|
40
|
+
if result[m['symbol']].nil? || (!m['market_cap_rank'].nil? && result[m['symbol']].to_i > m['market_cap_rank'].to_i)
|
41
|
+
result[m['symbol'].downcase] = m['market_cap_rank']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
DIF_COINS.each { |k, v| result[k] = result.delete v }
|
46
|
+
result = result.sort_by { |_, v| v.nil? ? 100_000 : v }.to_h
|
47
|
+
|
48
|
+
no_rank_coins(result)
|
49
|
+
all_usdt_coins(result)
|
50
|
+
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def all_coins
|
55
|
+
@all_coins ||= client.coins_list
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def no_rank_coins(list)
|
61
|
+
puts "No rank coins: #{list.select { |_, v| v.nil? }.keys.map(&:upcase).join(', ')}\n\n"
|
62
|
+
end
|
63
|
+
|
64
|
+
def all_usdt_coins(list)
|
65
|
+
puts "Rank all Binance USDT coins : #{list.map { |k, v| "#{k.upcase}-#{v}" }.join('; ')}\n\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
def decorated_all_coins
|
69
|
+
return @decorated_all_coins if @decorated_all_coins
|
70
|
+
|
71
|
+
@decorated_all_coins = {}
|
72
|
+
all_coins.each do |m|
|
73
|
+
@decorated_all_coins["#{m['symbol']}"] ||= []
|
74
|
+
unless @decorated_all_coins["#{m['symbol']}"].include?(m['id'])
|
75
|
+
(@decorated_all_coins["#{m['symbol']}"] << m['id'])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
@decorated_all_coins
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/abot/whitelist.rb
CHANGED
@@ -3,8 +3,11 @@
|
|
3
3
|
require 'active_record'
|
4
4
|
require 'binance-ruby'
|
5
5
|
|
6
|
+
require_relative 'whitelist/abot_config_site'
|
6
7
|
require_relative 'whitelist/option_parser'
|
7
|
-
require_relative 'whitelist/
|
8
|
+
require_relative 'whitelist/base'
|
9
|
+
require_relative 'whitelist/binance'
|
10
|
+
require_relative 'whitelist/coingecko'
|
8
11
|
require_relative 'whitelist/version'
|
9
12
|
|
10
13
|
module Abot
|
@@ -27,15 +30,37 @@ module Abot
|
|
27
30
|
:top, '--top=number',
|
28
31
|
'Число монет (ТОП по капитализации)',
|
29
32
|
)
|
33
|
+
|
34
|
+
parser.add_option(
|
35
|
+
:api, '--api=string',
|
36
|
+
'Api: Binance, Coingecko',
|
37
|
+
)
|
30
38
|
end.final!
|
31
39
|
|
32
|
-
|
33
|
-
|
40
|
+
case opts[:api].downcase
|
41
|
+
when 'binance'
|
42
|
+
Abot::Whitelist::Binance.new(opts).process!
|
43
|
+
when 'coingecko'
|
44
|
+
Abot::Whitelist::Coingecko.new(opts).process!
|
45
|
+
else
|
46
|
+
# nothing
|
47
|
+
end
|
48
|
+
end
|
34
49
|
|
50
|
+
private
|
51
|
+
|
52
|
+
def opts
|
53
|
+
top_number = (Whitelist::OptionParser.instance.options[:top] || 150).to_i
|
35
54
|
raise 'top is wrong' unless top_number.positive?
|
36
55
|
|
37
|
-
|
38
|
-
|
56
|
+
api = Whitelist::OptionParser.instance.options[:api]&.downcase || 'coingecko'
|
57
|
+
raise 'api must be Binance, Coingecko' unless ['binance', 'coingecko'].include?(api)
|
58
|
+
|
59
|
+
{
|
60
|
+
list_number: Whitelist::OptionParser.instance.options[:list_number],
|
61
|
+
top: top_number,
|
62
|
+
api: api,
|
63
|
+
}
|
39
64
|
end
|
40
65
|
end
|
41
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abot-whitelist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- w_dmitrii
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.3.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: coingecko_ruby
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.4.2
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.4.2
|
83
97
|
description:
|
84
98
|
email:
|
85
99
|
- wiz.work2021@gmail.com
|
@@ -95,8 +109,10 @@ files:
|
|
95
109
|
- abot-whitelist.gemspec
|
96
110
|
- exe/abot-whitelist
|
97
111
|
- lib/abot/whitelist.rb
|
98
|
-
- lib/abot/whitelist/
|
99
|
-
- lib/abot/whitelist/
|
112
|
+
- lib/abot/whitelist/abot_config_site.rb
|
113
|
+
- lib/abot/whitelist/base.rb
|
114
|
+
- lib/abot/whitelist/binance.rb
|
115
|
+
- lib/abot/whitelist/coingecko.rb
|
100
116
|
- lib/abot/whitelist/option_parser.rb
|
101
117
|
- lib/abot/whitelist/version.rb
|
102
118
|
- spec/abot/whitelist_spec.rb
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Abot
|
4
|
-
module Whitelist
|
5
|
-
class BaseWhitelist
|
6
|
-
include HTTParty
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def base_whitelist(list_number:)
|
10
|
-
self.base_uri 'https://abot-config.ru'
|
11
|
-
|
12
|
-
path = "/coins/whitelist-#{list_number}.txt"
|
13
|
-
response = get(path)
|
14
|
-
|
15
|
-
if response.code == 200
|
16
|
-
response.body.split(' ') || ''
|
17
|
-
else
|
18
|
-
raise "get base whitelist from #{base_uri} error"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require_relative 'base_whitelist'
|
3
|
-
|
4
|
-
module Abot
|
5
|
-
module Whitelist
|
6
|
-
class BinanceCap
|
7
|
-
include HTTParty
|
8
|
-
|
9
|
-
DEFAULT_COINS = %w[ONE UNFI SOL].freeze
|
10
|
-
FIAT = %w[USDT BUSD AUD BIDR BRL EUR GBR RUB TRY TUSD USDC DAI IDRT PAX UAH NGN VAI BVND].freeze
|
11
|
-
BLACK_LIST = %w[FUN XVS AION BTC].freeze
|
12
|
-
|
13
|
-
class << self
|
14
|
-
def send_req(base_list:, top_number:)
|
15
|
-
self.base_uri 'https://www.binance.com'
|
16
|
-
|
17
|
-
path = '/exchange-api/v2/public/asset-service/product/get-products'
|
18
|
-
response = get(path)
|
19
|
-
process!(response: response || '{}', base_list: base_list, top_number: top_number)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def process!(response:, base_list:, top_number:)
|
25
|
-
result = top(response: response, top_number: top_number)
|
26
|
-
if base_list
|
27
|
-
result = result.map { |m| base_list.include?(m) ? m : nil }.compact
|
28
|
-
|
29
|
-
puts "base list: #{base_list}"
|
30
|
-
puts '+++++++++++++++++++++++++++++++++++++++++++++'
|
31
|
-
puts "coins (count = #{result.count}) from the base list in the top #{top_number} by capitalization:"
|
32
|
-
else
|
33
|
-
puts "coins (count = #{result.count}) in the top #{top_number} by capitalization:"
|
34
|
-
end
|
35
|
-
|
36
|
-
puts result.join(' ')
|
37
|
-
end
|
38
|
-
|
39
|
-
def top(response:, top_number:)
|
40
|
-
all_coins = usdt_coins(response: response).map { |s| [s[:b], (s[:cs].to_f * s[:c].to_f)] }
|
41
|
-
.sort_by { |s| s[1] }
|
42
|
-
.reverse
|
43
|
-
.map { |m| m[0] }
|
44
|
-
result = (all_coins - FIAT - BLACK_LIST)[0..((top_number - 1) - DEFAULT_COINS.count)]
|
45
|
-
result + DEFAULT_COINS
|
46
|
-
end
|
47
|
-
|
48
|
-
def usdt_coins(response:)
|
49
|
-
serialized_response(response: response)[:data].select { |s| s[:q] == 'USDT' }
|
50
|
-
end
|
51
|
-
|
52
|
-
def serialized_response(response:)
|
53
|
-
begin
|
54
|
-
JSON.parse(response.body, symbolize_names: true)
|
55
|
-
rescue JSON::ParserError => error
|
56
|
-
# binance 500 errors are html format
|
57
|
-
raise Error.new(message: error)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|