hex_token_bot 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /.idea/
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.7
5
+ before_install: gem install bundler -v 1.15.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at tuminfei1981@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in hex_token_bot.gemspec
6
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Terry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ # HexTokenBot
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/hex_token_bot`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'hex_token_bot'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install hex_token_bot
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/hex_token_bot. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
40
+
41
+ ## Code of Conduct
42
+
43
+ Everyone interacting in the HexTokenBot project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/hex_token_bot/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "hex_token_bot"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,33 @@
1
+ - bot_name: 'bot_auto_trans'
2
+ bot_params:
3
+ tran_amount: 0.0001
4
+ when_ever: 20s
5
+ bot_data_channels:
6
+ - 'bter'
7
+ - 'hex'
8
+ - 'okcoin'
9
+ bot_markets:
10
+ - id: btccny
11
+ name: BTC/CNY
12
+ base_unit: btc
13
+ quote_unit: cny
14
+ tran_price_add: 0.1
15
+ tran_amount: 0.0001
16
+ - id: ethcny
17
+ name: ETH/CNY
18
+ base_unit: eth
19
+ quote_unit: cny
20
+ tran_price_add: 0.1
21
+ tran_amount: 0.0001
22
+ - id: btceth
23
+ name: BTC/ETH
24
+ base_unit: btc
25
+ quote_unit: eth
26
+ tran_price_add: 0.1
27
+ tran_amount: 0.0001
28
+ - id: ethbtc
29
+ name: ETH/BTC
30
+ base_unit: eth
31
+ quote_unit: btc
32
+ tran_price_add: 0.1
33
+ tran_amount: 0.0001
@@ -0,0 +1,28 @@
1
+ bter:
2
+ client: bter
3
+ enabled: true
4
+ access_key: 'B1B68BC5-6A6C-40DC-98B7-C0A95D048533'
5
+ secret_key: '3a6864a81d6569acfa997fb8c8103e5a01a50f135fbb1e721d8f056f7b772b89'
6
+ endpoint: 'http://data.bter.com/'
7
+ timeout: 60
8
+ hex:
9
+ client: bter
10
+ enabled: true
11
+ access_key: 'B1B68BC5-6A6C-40DC-98B7-C0A95D048533'
12
+ secret_key: '3a6864a81d6569acfa997fb8c8103e5a01a50f135fbb1e721d8f056f7b772b89'
13
+ endpoint: 'http://data.bter.com/'
14
+ timeout: 60
15
+ okcoin:
16
+ client: okcoin
17
+ enabled: true
18
+ access_key: '98ce18a1-0e03-47a4-b72e-c48f2f16d46e'
19
+ secret_key: 'A29DE98A0EEF51EFA8372A1B89274B01'
20
+ endpoint: 'https://www.okcoin.cn/api/'
21
+ timeout: 60
22
+ hex_test:
23
+ client: hex
24
+ enabled: true
25
+ access_key: '1ouyUQZzG3dXYWxQCqNxFmQcp1r2mxxZJoqQPu2E'
26
+ secret_key: 'y2LOHy4GC5j5uSXWwSVO7MwMusXfxe0Z5suOciKC'
27
+ endpoint: 'https://hex.chainresearch.org/'
28
+ timeout: 60
@@ -0,0 +1,5 @@
1
+ hex:
2
+ access_key: '1ouyUQZzG3dXYWxQCqNxFmQcp1r2mxxZJoqQPu2E'
3
+ secret_key: 'y2LOHy4GC5j5uSXWwSVO7MwMusXfxe0Z5suOciKC'
4
+ endpoint: 'https://hex.chainresearch.org/'
5
+ timeout: 60
@@ -0,0 +1,26 @@
1
+ - id: btccny
2
+ name: BTC/CNY
3
+ base_unit: btc
4
+ quote_unit: cny
5
+ bots:
6
+ -
7
+ bot_name: 'order_books'
8
+ bot_params:
9
+ tran_amount: 0.0001
10
+ when_ever: 5m
11
+ bot_datas:
12
+ - channel_name: 'bter'
13
+ - channel_name: '58token'
14
+ - id: ethcny
15
+ name: ETH/CNY
16
+ base_unit: eth
17
+ quote_unit: cny
18
+ bots:
19
+ -
20
+ bot_name: 'order_books'
21
+ bot_params:
22
+ tran_amount: 0.0001
23
+ when_ever: 5m
24
+ bot_datas:
25
+ - channel_name: 'bter'
26
+ - channel_name: '58token'
@@ -0,0 +1,12 @@
1
+ buyer:
2
+ user_name: 'tmf'
3
+ access_key: '1ouyUQZzG3dXYWxQCqNxFmQcp1r2mxxZJoqQPu2E'
4
+ secret_key: 'y2LOHy4GC5j5uSXWwSVO7MwMusXfxe0Z5suOciKC'
5
+ endpoint: 'https://hex.chainresearch.org/'
6
+ timeout: 60
7
+ seller:
8
+ user_name: 'wmz'
9
+ access_key: '3f2M7BjndKhTLPWsbxp0MIMeBEWGHXuQq7D5wXlh'
10
+ secret_key: 'Rx7LN57sx3Kr7rA4LORuFhMsUNRxp750zGQfXRwg'
11
+ endpoint: 'https://hex.chainresearch.org/'
12
+ timeout: 60
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Enables UTF-8 compatibility in ruby 1.8.
4
+ $KCODE = 'u' if RUBY_VERSION < '1.9'
5
+
6
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
7
+
8
+ require "hex_token_bot"
9
+ require 'optparse'
10
+ require 'irb'
11
+ require 'yaml'
12
+ require 'rubygems'
13
+
14
+ options = {}
15
+ option_parser = OptionParser.new do |opts|
16
+ opts.banner = 'here is help messages of the command line tool.'
17
+
18
+ opts.on('-v', '--version', 'Prints the version') do
19
+ puts HexTokenBot::VERSION
20
+ exit
21
+ end
22
+
23
+ opts.on('-c FILE_PATH', '--config FILE_PATH', 'Pass-in config path') do |value|
24
+ options[:config_file_path] = value
25
+ end
26
+
27
+ end.parse!
28
+
29
+ puts options.inspect
30
+
31
+ if options[:config_file_path]
32
+ HexTokenBot.bots_yml = {
33
+ :file_bots => File.join(options[:config_file_path], 'bots.yml'),
34
+ :file_data_channels => File.join(options[:config_file_path], 'data_channels.yml'),
35
+ :file_tran_channels => File.join(options[:config_file_path], 'tran_channels.yml'),
36
+ :file_tran_users => File.join(options[:config_file_path], 'tran_users.yml')
37
+ }
38
+ else
39
+ $stderr.puts("To specify a custom config file use `hex_token_bot -c path/to/config_path`.")
40
+ exit
41
+ end
42
+
43
+ cli = HexTokenBot::BotServer.new
44
+ cli.run!
45
+
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "hex_token_bot/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hex_token_bot"
8
+ spec.version = HexTokenBot::VERSION
9
+ spec.authors = ["Terry"]
10
+ spec.email = ["tuminfei1981@gmail.com"]
11
+
12
+ spec.summary = "58token bot."
13
+ spec.description = "58token bot."
14
+ spec.homepage = "https://github.com/tuminfei/hex_token_bot"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against " \
23
+ # "public gem pushes."
24
+ # end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_dependency 'railties', '>= 3.1.0'
34
+ #spec.add_dependency 'ruleby', '~> 0.8'
35
+ spec.add_dependency 'faraday', '~> 0.9.0'
36
+ spec.add_dependency 'peatio_client'
37
+ spec.add_dependency 'okcoin', '~> 0.1.6'
38
+ spec.add_dependency 'rufus-scheduler', '>= 3.4.2'
39
+ spec.add_dependency 'rack', '~> 1.5.5'
40
+
41
+ spec.add_development_dependency "bundler", "~> 1.15"
42
+ spec.add_development_dependency "rake", "~> 10.0"
43
+ spec.add_development_dependency "minitest", "~> 5.0"
44
+ end
@@ -0,0 +1,6 @@
1
+ HexTokenBot.bots_yml = {
2
+ :file_bots => Rails.root.join("config/bots/bots.yml"),
3
+ :file_data_channels => Rails.root.join("config/bots/data_channels.yml"),
4
+ :file_tran_channels => Rails.root.join("config/bots/tran_channels.yml"),
5
+ :file_tran_users => Rails.root.join("config/bots/tran_users.yml")
6
+ }
@@ -0,0 +1,31 @@
1
+ require 'hex_token_bot/version'
2
+ require 'hex_token_bot/channel_api'
3
+ require 'hex_token_bot/channel_client'
4
+ require 'hex_token_bot/bots'
5
+ require 'hex_token_bot/bot_server'
6
+
7
+ require 'yaml'
8
+
9
+ module HexTokenBot
10
+ class<< self
11
+ attr_accessor :bots, :data_channels, :tran_channels, :tran_users
12
+
13
+ def bots_yml=(options = {})
14
+ unless options.empty?
15
+ if options[:file_bots]
16
+ @bots = YAML.load(File.open(options[:file_bots]))
17
+ end
18
+ if options[:file_data_channels]
19
+ @data_channels = YAML.load(File.open(options[:file_data_channels]))
20
+ end
21
+ if options[:file_tran_channels]
22
+ @tran_channels = YAML.load(File.open(options[:file_tran_channels]))
23
+ end
24
+ if options[:file_tran_users]
25
+ @tran_users = YAML.load(File.open(options[:file_tran_users]))
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,34 @@
1
+ require 'rufus-scheduler'
2
+
3
+ module HexTokenBot
4
+ class BotServer
5
+ attr_accessor :scheduler
6
+ attr_accessor :bot_servers
7
+
8
+ def initialize
9
+
10
+ scheduler = Rufus::Scheduler.new
11
+
12
+ HexTokenBot.bots.each do |bot|
13
+ case bot['bot_name']
14
+ when 'bot_auto_trans'
15
+ when_ever = bot['bot_params']['when_ever']
16
+ HexTokenBot::Bots::BotAutoTrans.set(:name, bot['bot_name'])
17
+ scheduler.every when_ever||'3s', :tag => bot['bot_name'] do
18
+ puts 'Hello... Bots'
19
+ HexTokenBot::Bots::BotAutoTrans.set(:channels, bot['bot_data_channels'])
20
+ HexTokenBot::Bots::BotAutoTrans.set(:markets, bot['bot_markets'])
21
+ HexTokenBot::Bots::BotAutoTrans.run!
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def run!
28
+ while true
29
+ puts ".."
30
+ sleep(2)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'bots/base'
2
+ require_relative 'bots/bot_auto_trans'
3
+
4
+ module HexTokenBot
5
+ module Bots
6
+ end
7
+ end
@@ -0,0 +1,69 @@
1
+ require 'logger'
2
+
3
+ module HexTokenBot
4
+ module Bots
5
+ module Info
6
+ def logger_set!(cond)
7
+ @logger = Logger.new STDOUT
8
+ @logger.level = cond ? Logger::DEBUG : Logger::INFO
9
+ end
10
+
11
+ def info(msg)
12
+ @logger.info msg
13
+ end
14
+
15
+ def warn(msg)
16
+ @logger.warn msg
17
+ end
18
+
19
+ def error(msg)
20
+ @logger.error msg
21
+ end
22
+
23
+ def debug(msg)
24
+ @logger.debug msg
25
+ end
26
+ end
27
+
28
+ class Base
29
+ include HexTokenBot::Bots::Info
30
+
31
+ def self.run!
32
+ self.new.run
33
+ end
34
+
35
+ def initialize
36
+ logger_set! debug?
37
+ end
38
+
39
+ def debug?
40
+ nil
41
+ end
42
+
43
+ class << self
44
+ def set(key, value)
45
+ keys = [:name, :debug?, :channels, :markets]
46
+ if keys.include? key
47
+ self.instance_eval do
48
+ define_method key, lambda { value }
49
+ private key
50
+ end
51
+ else
52
+ raise NotImplementedError, "This option is not support, #{key}, #{value}"
53
+ end
54
+ end
55
+
56
+ def set!(key, value)
57
+ keys = [:run?]
58
+ if keys.include? key
59
+ define_singleton_method key, value
60
+ else
61
+ raise NotImplementedError, "This option is not support, #{key}, #{value}"
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,106 @@
1
+ require 'hex_token_bot/bots/base'
2
+
3
+ module HexTokenBot
4
+ module Bots
5
+ class BotAutoTrans < Base
6
+ def run
7
+ info "starting bot for @#{name}"
8
+ begin
9
+ #查询渠道数据
10
+ source_data = {}
11
+ #查询渠道数据-渠道最大值
12
+ source_max_data = {}
13
+ #查询本地数据-本地最大值
14
+ local_max_data = {}
15
+ channels.each do |c|
16
+ channel = HexTokenBot.data_channels[c]
17
+ if channel
18
+ if channel['client'] == HexTokenBot::ChannelClient::CHANNEL_BTER
19
+ client = HexTokenBot::ChannelClient::BterClient.new
20
+ markets.each do |m|
21
+ m_code = m['base_unit'] + '_' + m['quote_unit']
22
+ rep = client.get_order_newest(m_code)
23
+ source_rate = source_data[m['id']] || []
24
+ price = rep.empty? ? 0 : rep[:rate]
25
+ source_rate << price
26
+ source_data.store(m['id'], source_rate)
27
+ end
28
+ end
29
+ if channel['client'] == HexTokenBot::ChannelClient::CHANNEL_HEX
30
+ client = HexTokenBot::ChannelClient::HexClient.new
31
+ markets.each do |m|
32
+ m_code = m['base_unit'] + m['quote_unit']
33
+ rep = client.get_order_newest(m_code)
34
+ source_rate = source_data[m['id']] || []
35
+ price = rep.empty? ? 0 : rep['price'].to_f
36
+ source_rate << price
37
+ source_data.store(m['id'], source_rate)
38
+ end
39
+ end
40
+ if channel['client'] == HexTokenBot::ChannelClient::CHANNEL_OKCOIN
41
+ client = HexTokenBot::ChannelClient::OkcoinClient.new
42
+ markets.each do |m|
43
+ m_code = m['base_unit'] + '_' + m['quote_unit']
44
+ rep = client.get_order_newest(m_code)
45
+ source_rate = source_data[m['id']] || []
46
+ price = rep.empty? ? 0 : rep['price'].to_f
47
+ source_rate << price
48
+ source_data.store(m['id'], source_rate)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ info "抓取渠道数据:#{source_data.to_s}"
55
+
56
+ #查询本地数据
57
+ local = HexTokenBot.tran_channels['hex'].symbolize_keys
58
+ client = HexTokenBot::ChannelClient::HexClient.new(local)
59
+ markets.each do |m|
60
+ market_code = m['id']
61
+ rep = client.get_order_newest(market_code)
62
+ local_rate = rep.empty? ? 0 : rep['price'].to_f
63
+ local_max_data.store(m['id'], local_rate)
64
+ end
65
+
66
+ info "抓取本地数据:#{local_max_data.to_s}"
67
+
68
+ #数据分析处理
69
+ markets.each do |m|
70
+ market_code = m['id']
71
+ source_arr = source_data[market_code] || []
72
+ source_max = source_arr.max
73
+ source_max_data.store(market_code, source_max)
74
+ #如果渠道挂单价格 >= 本地挂单价格,直接生成买单吃用户的单
75
+ #如果渠道挂单价格 < 本地挂单价格,直接生成买单吃用户的单
76
+
77
+ if source_max >= local_max_data[market_code]
78
+ price = local_max_data[market_code]
79
+ #插入数据
80
+ buy = HexTokenBot.tran_users['buyer'].symbolize_keys
81
+ client = HexTokenBot::ChannelClient::HexClient.new(buy)
82
+ rep = client.send_order_buy(market_code, price, m['tran_amount'])
83
+ info "auto_tran:#{rep.to_s}"
84
+ else
85
+ price = local_max_data[m['id']] + m['tran_price_add']
86
+ #插入数据
87
+ buy = HexTokenBot.tran_users['buyer'].symbolize_keys
88
+ client = HexTokenBot::ChannelClient::HexClient.new(buy)
89
+ rep = client.send_order_buy(market_code, price, m['tran_amount'])
90
+ info "auto_tran:#{rep.to_s}"
91
+ seller = HexTokenBot.tran_users['seller'].symbolize_keys
92
+ client = HexTokenBot::ChannelClient::HexClient.new(seller)
93
+ rep = client.send_order_sell(market_code, price, m['tran_amount'])
94
+ info "auto_tran:#{rep.to_s}"
95
+ end
96
+ end
97
+
98
+ rescue Exception => err
99
+ info "exitting bot service for @#{name}..."
100
+ info err.message
101
+ exit 0
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,12 @@
1
+ require 'json'
2
+ require 'httparty'
3
+ require 'openssl'
4
+
5
+ require_relative 'channel_api/bter'
6
+ require_relative 'channel_api/hex'
7
+ require_relative 'channel_api/okcoin'
8
+
9
+ module HexTokenBot
10
+ module ChannelApi
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'bter/public.rb'
2
+ require_relative 'bter/trading.rb'
3
+ require_relative 'bter/request.rb'
4
+
5
+ module HexTokenBot
6
+ module ChannelApi
7
+ module Bter
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'request.rb'
2
+ module HexTokenBot
3
+ module ChannelApi
4
+ module Bter
5
+ class Public
6
+ include Request
7
+
8
+ METHODS = ['pairs', 'ticker', 'tickers', 'marketinfo', 'markelist', 'trade', 'tradeHistory', 'orderBook']
9
+
10
+ METHODS.each do |method|
11
+ define_method(method) do |pair=nil, tid=nil|
12
+ public_request(method, pair, tid)
13
+ end
14
+ end
15
+
16
+ alias_method :info, :marketinfo
17
+ alias_method :details, :markelist
18
+ alias_method :trades, :trade
19
+ alias_method :history, :trade
20
+ alias_method :order_book, :orderBook
21
+ alias_method :trade_history, :tradeHistory
22
+
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,50 @@
1
+ module HexTokenBot
2
+ module ChannelApi
3
+ module Bter
4
+ module Request
5
+ extend self
6
+ PUBLIC_URL = 'https://data.bter.com/api2/1'
7
+ TRADE_URL = 'https://bter.com/api2/1/private'
8
+
9
+ private
10
+ def public_request(method, pair='', tid=nil)
11
+ pair = pair + "/#{tid}" if tid.nil? == false
12
+ response = HTTParty.get("#{PUBLIC_URL}/#{method}/#{pair}").body
13
+ make_hash(response)
14
+ end
15
+
16
+ def trade_request(method, params=nil)
17
+ if params.nil?
18
+ @params = {:method => method}
19
+ else
20
+ @params = {:method => method}
21
+ params.each do |param|
22
+ @params.merge!(param)
23
+ end
24
+ end
25
+ response = HTTParty.post(
26
+ "#{TRADE_URL}/#{method}",
27
+ :body => @params,
28
+ :headers => {
29
+ 'KEY' => @key,
30
+ 'Sign' => sign,
31
+ "Content-type" => "application/x-www-form-urlencoded",
32
+ "Accept" => "application/x-www-form-urlencoded"
33
+ }
34
+ ).body
35
+ make_hash(response)
36
+ end
37
+
38
+ def sign
39
+ hmac = OpenSSL::HMAC.new(@secret,OpenSSL::Digest::SHA512.new)
40
+ @params = @params.collect {|k,v| "#{k}=#{v}"}.join('&')
41
+ hmac.update(@params).to_s
42
+ end
43
+
44
+ def make_hash(json_object)
45
+ JSON.parse(json_object, {:symbolize_names => true})
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'request.rb'
2
+
3
+ module HexTokenBot
4
+ module ChannelApi
5
+ module Bter
6
+ class Trade
7
+ include Request
8
+
9
+ attr_accessor :key, :secret
10
+
11
+ METHODS = ['getfunds', 'orderlist', 'getorder', 'cancelorder', 'mytrades', 'placeorder']
12
+
13
+ METHODS.each do |method|
14
+ define_method(method) do |param=nil|
15
+ if param.is_a? Hash
16
+ trade_request(method, [param])
17
+ elsif param.to_i > 0
18
+ trade_request(method, [{:order_id => param}])
19
+ else
20
+ trade_request(method, [{:pair => param}])
21
+ end
22
+ end
23
+ end
24
+
25
+ ['buy', 'sell'].each do |method|
26
+ define_method(method) do |pair, amount, rate=nil|
27
+ rate ||= get_rate(pair)
28
+ trade({:pair => pair, :type => method.upcase, :rate => rate, :amount => amount})
29
+ end
30
+ end
31
+
32
+ alias_method :get_info, :getfunds
33
+ alias_method :active_orders, :orderlist
34
+ alias_method :order_status, :getorder
35
+ alias_method :cancel_order, :cancelorder
36
+ alias_method :my_trades, :mytrades
37
+ alias_method :trade, :placeorder
38
+
39
+ private
40
+ def get_rate(pair)
41
+ Public.new.ticker(pair).values_at(:last).flatten.first
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,9 @@
1
+ require 'peatio_client'
2
+
3
+ module HexTokenBot
4
+ module ChannelApi
5
+ module Hex
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'okcoin'
2
+
3
+ module HexTokenBot
4
+ module ChannelApi
5
+ module Okcoin
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'channel_client/bter_client'
2
+ require_relative 'channel_client/hex_client'
3
+ require_relative 'channel_client/okcoin_client'
4
+
5
+ module HexTokenBot
6
+ module ChannelClient
7
+ CHANNEL_BTER = 'bter'
8
+ CHANNEL_HEX = 'hex'
9
+ CHANNEL_OKCOIN = 'okcoin'
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ module HexTokenBot
2
+ module ChannelClient
3
+ class BterClient
4
+ attr_accessor :client
5
+
6
+ def initialize(options = {})
7
+ @client = HexTokenBot::ChannelApi::Bter::Public.new
8
+ end
9
+
10
+
11
+ def get_market_order_book(market_code, asks_limit = nil , bids_limit = nil)
12
+ rep = @client.order_book(market_code)
13
+ rep
14
+ end
15
+
16
+ def get_order_newest(market_code)
17
+ rep = @client.trade_history(market_code)
18
+ if !rep.empty? and !rep[:data].nil?
19
+ count = rep[:data].size
20
+ rep[:data][count - 1]
21
+ else
22
+ []
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ module HexTokenBot
2
+ module ChannelClient
3
+ class HexClient
4
+ attr_accessor :client
5
+
6
+ def initialize(options = {})
7
+ client_options = {
8
+ access_key: HexTokenBot.tran_channels['hex']['access_key'],
9
+ secret_key: HexTokenBot.tran_channels['hex']['secret_key'],
10
+ endpoint: HexTokenBot.tran_channels['hex']['endpoint'],
11
+ timeout: HexTokenBot.tran_channels['hex']['timeout']
12
+ }
13
+ @client = PeatioAPI::Client.new client_options.merge(options)
14
+ end
15
+
16
+
17
+ def get_market_order_book(market_code, asks_limit = nil , bids_limit = nil)
18
+ rep = client.get '/api/v2/order_book', market: market_code
19
+ rep
20
+ end
21
+
22
+ def get_order_newest(market_code)
23
+ rep = client.get '/api/v2/trades', market: market_code
24
+ if rep.class == Array and !rep.empty?
25
+ count = rep.size
26
+ rep[count - 1]
27
+ else
28
+ []
29
+ end
30
+ end
31
+
32
+ def send_order(side, market_code, price, volume)
33
+ rep = client.post '/api/v2/orders', market: market_code, price: price, side: side, volume: volume
34
+ rep
35
+ end
36
+
37
+ #orders: [{side: 'buy', volume: '0.15', price: '2955.0'}, {side: 'sell', volume: '0.16', price: '2956'}]
38
+ def send_orders_multi(orders, market_code)
39
+ rep = client.post '/api/v2/orders/multi', market: market_code, orders: orders
40
+ rep
41
+ end
42
+
43
+ def send_order_buy(market_code, price, volume)
44
+ send_order('buy', market_code, price, volume)
45
+ end
46
+
47
+ def send_order_sell(market_code, price, volume)
48
+ send_order('sell', market_code, price, volume)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,51 @@
1
+ module HexTokenBot
2
+ module ChannelClient
3
+ class OkcoinClient
4
+ attr_accessor :client
5
+
6
+ def initialize(options = {})
7
+ url = options['endpoint'] || HexTokenBot.data_channels['okcoin']['endpoint']
8
+ api_key = options['access_key'] || HexTokenBot.data_channels['okcoin']['access_key']
9
+ secret_key = options['secret_key'] || HexTokenBot.data_channels['okcoin']['secret_key']
10
+
11
+ @client = Okcoin::Client.new url: url, api_key: api_key, secret_key: secret_key
12
+ end
13
+
14
+
15
+ def get_market_order_book(market_code, asks_limit = nil , bids_limit = nil)
16
+ rep = client.trades(symbol: market_code, since: nil)
17
+ rep
18
+ end
19
+
20
+ def get_order_newest(market_code)
21
+ rep = client.trades(symbol: market_code, since: nil)
22
+ if rep.class == Array and !rep.empty?
23
+ count = rep.size
24
+ rep[count - 1]
25
+ else
26
+ []
27
+ end
28
+ end
29
+
30
+ def send_order(side, market_code, price, volume)
31
+ rep = client.trade(symbol: market_code, type: side, price: price, amount: volume)
32
+ rep
33
+ end
34
+
35
+ #orders: [{type: 'buy', amount: '0.15', price: '2955.0'}, {side: 'sell', volume: '0.16', price: '2956'}]
36
+ def send_orders_multi(orders, market_code)
37
+ rep = client.batch_trade(symbol: market_code, orders_data: orders)
38
+ rep
39
+ end
40
+
41
+ def send_order_buy(market_code, price, volume)
42
+ send_order('buy', market_code, price, volume)
43
+ end
44
+
45
+ def send_order_sell(market_code, price, volume)
46
+ send_order('sell', market_code, price, volume)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module HexTokenBot
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hex_token_bot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Terry
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2017-09-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: railties
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.1.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: faraday
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.9.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.9.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: peatio_client
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: okcoin
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.1.6
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.1.6
78
+ - !ruby/object:Gem::Dependency
79
+ name: rufus-scheduler
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 3.4.2
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 3.4.2
94
+ - !ruby/object:Gem::Dependency
95
+ name: rack
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.5.5
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.5.5
110
+ - !ruby/object:Gem::Dependency
111
+ name: bundler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '1.15'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.15'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rake
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '10.0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '10.0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: minitest
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '5.0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '5.0'
158
+ description: 58token bot.
159
+ email:
160
+ - tuminfei1981@gmail.com
161
+ executables:
162
+ - hex_token_bot
163
+ extensions: []
164
+ extra_rdoc_files: []
165
+ files:
166
+ - .gitignore
167
+ - .travis.yml
168
+ - CODE_OF_CONDUCT.md
169
+ - Gemfile
170
+ - LICENSE.txt
171
+ - README.md
172
+ - Rakefile
173
+ - bin/console
174
+ - bin/setup
175
+ - config/bots.yml
176
+ - config/data_channels.yml
177
+ - config/tran_channels.yml
178
+ - config/tran_markets.yml.bak
179
+ - config/tran_users.yml
180
+ - exe/hex_token_bot
181
+ - hex_token_bot.gemspec
182
+ - hex_token_bot.rb
183
+ - lib/hex_token_bot.rb
184
+ - lib/hex_token_bot/bot_server.rb
185
+ - lib/hex_token_bot/bots.rb
186
+ - lib/hex_token_bot/bots/base.rb
187
+ - lib/hex_token_bot/bots/bot_auto_trans.rb
188
+ - lib/hex_token_bot/channel_api.rb
189
+ - lib/hex_token_bot/channel_api/bter.rb
190
+ - lib/hex_token_bot/channel_api/bter/public.rb
191
+ - lib/hex_token_bot/channel_api/bter/request.rb
192
+ - lib/hex_token_bot/channel_api/bter/trading.rb
193
+ - lib/hex_token_bot/channel_api/hex.rb
194
+ - lib/hex_token_bot/channel_api/okcoin.rb
195
+ - lib/hex_token_bot/channel_client.rb
196
+ - lib/hex_token_bot/channel_client/bter_client.rb
197
+ - lib/hex_token_bot/channel_client/hex_client.rb
198
+ - lib/hex_token_bot/channel_client/okcoin_client.rb
199
+ - lib/hex_token_bot/version.rb
200
+ homepage: https://github.com/tuminfei/hex_token_bot
201
+ licenses:
202
+ - MIT
203
+ post_install_message:
204
+ rdoc_options: []
205
+ require_paths:
206
+ - lib
207
+ required_ruby_version: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - ! '>='
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ required_rubygems_version: !ruby/object:Gem::Requirement
214
+ none: false
215
+ requirements:
216
+ - - ! '>='
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ requirements: []
220
+ rubyforge_project:
221
+ rubygems_version: 1.8.25
222
+ signing_key:
223
+ specification_version: 3
224
+ summary: 58token bot.
225
+ test_files: []