abot-whitelist 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|