huo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 36f03c83926d4cf08e53e1a0a7e8e8999d1ebcba
4
+ data.tar.gz: d4ab97bb58b58501dbe94d2438263eb03b3a730e
5
+ SHA512:
6
+ metadata.gz: b8767ad3abaf6e65f44020e6f735f8238a81ad6bb8fe83a52d6bd240183517d9d49f6739646916a81460ddd508245a867e8578663fefd4c8b043e088569abcd7
7
+ data.tar.gz: 04caf012fa9da168abad4bc550f2ae520dd76cde1af07307713aeb671cf68f86379ea73266b94efd8f8a93a6e03b27b378cb7f7a42c37085e8e2720325cfc3c0
@@ -0,0 +1,2 @@
1
+ spec/examples.txt
2
+ config/tokens.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rest-client'
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ gem 'pry'
8
+ gem 'awesome_print'
9
+ end
@@ -0,0 +1,50 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ awesome_print (1.6.1)
5
+ coderay (1.1.0)
6
+ diff-lcs (1.2.5)
7
+ domain_name (0.5.25)
8
+ unf (>= 0.0.5, < 1.0.0)
9
+ http-cookie (1.0.2)
10
+ domain_name (~> 0.5)
11
+ method_source (0.8.2)
12
+ mime-types (2.99)
13
+ netrc (0.11.0)
14
+ pry (0.10.3)
15
+ coderay (~> 1.1.0)
16
+ method_source (~> 0.8.1)
17
+ slop (~> 3.4)
18
+ rest-client (1.8.0)
19
+ http-cookie (>= 1.0.2, < 2.0)
20
+ mime-types (>= 1.16, < 3.0)
21
+ netrc (~> 0.7)
22
+ rspec (3.3.0)
23
+ rspec-core (~> 3.3.0)
24
+ rspec-expectations (~> 3.3.0)
25
+ rspec-mocks (~> 3.3.0)
26
+ rspec-core (3.3.2)
27
+ rspec-support (~> 3.3.0)
28
+ rspec-expectations (3.3.1)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.3.0)
31
+ rspec-mocks (3.3.2)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.3.0)
34
+ rspec-support (3.3.0)
35
+ slop (3.6.0)
36
+ unf (0.1.4)
37
+ unf_ext
38
+ unf_ext (0.0.7.1)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ awesome_print
45
+ pry
46
+ rest-client
47
+ rspec
48
+
49
+ BUNDLED WITH
50
+ 1.10.6
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'huo'
3
+ s.version = '0.0.1'
4
+ s.date = '2015-12-27'
5
+ s.summary = 'huo'
6
+ s.description = 'Huobi SDK for Ruby'
7
+ s.authors = ['Ming Qu']
8
+ s.email = 'qucool@gmail.com'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.test_files = `git ls-files -- spec/*`.split("\n")
11
+ s.homepage = 'http://rubygems.org/gems/huo'
12
+ s.license = 'MIT'
13
+ end
14
+
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/huo/trade'
2
+ require File.dirname(__FILE__) + '/huo/market'
3
+
4
+ module Huo
5
+ end
@@ -0,0 +1,38 @@
1
+ require 'rest-client'
2
+
3
+ module Huo
4
+ class Market
5
+ DETAIL_API_PATH = 'http://api.huobi.com/staticmarket/detail_btc_json.js'
6
+ SIMPLE_API_PATH = 'http://api.huobi.com/staticmarket/ticker_btc_json.js'
7
+
8
+ def get_simple_data
9
+ json = nil
10
+ begin
11
+ json = RestClient.get(SIMPLE_API_PATH)
12
+ rescue SocketError
13
+ return nil
14
+ end
15
+ JSON.parse(json).tap { |h| h['time'] = Time.at(h['time'].to_i) }
16
+ end
17
+
18
+ def get_detail_data
19
+ json = RestClient.get(DETAIL_API_PATH)
20
+ JSON.parse(json)
21
+ end
22
+
23
+ def api_path_for(param = '1min')
24
+ period = case param
25
+ when '1min' then '001'
26
+ when '5min' then '005'
27
+ when '15min' then '015'
28
+ when '30min' then '030'
29
+ when '60min' then '060'
30
+ when 'day' then '100'
31
+ when 'week' then '200'
32
+ when 'month' then '300'
33
+ when 'year' then '400'
34
+ end
35
+ "http://api.huobi.com/staticmarket/btc_kline_#{period}_json.js"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,121 @@
1
+ require 'digest'
2
+ require 'yaml'
3
+ require 'rest-client'
4
+
5
+ module Huo
6
+ REQUEST_URL = 'https://api.huobi.com/apiv3'
7
+ REQUEST_HEADER = {
8
+ 'Content-Type' => 'application/x-www-form-urlencoded'
9
+ }
10
+
11
+ class Trade
12
+ def initialize(options = {})
13
+ path = options[:tokens_path]
14
+ config = path ? YAML.load_file(path) : {}
15
+ @access_key = config['access_key'] || options[:access_key]
16
+ @secret_key = config['secret_key'] || options[:secret_key]
17
+ end
18
+
19
+ def get_account_info
20
+ get(method: __method__)
21
+ end
22
+
23
+ def get_orders(options = {})
24
+ get(method: __method__, coin_type: 1)
25
+ end
26
+
27
+ def order_info
28
+ end
29
+
30
+ def buy(options = {})
31
+ args = {
32
+ method: __method__,
33
+ coin_type: 1,
34
+ price: options.fetch(:price),
35
+ amount: options.fetch(:btc_amount, 0.001)
36
+ }
37
+ get(args)
38
+ end
39
+
40
+ def buy_market(options = {})
41
+ args = {
42
+ method: __method__,
43
+ coin_type: 1,
44
+ amount: options.fetch(:rmb_amount, 1)
45
+ }
46
+ get(args)
47
+ end
48
+
49
+ def sell(options = {})
50
+ args = {
51
+ method: __method__,
52
+ coin_type: 1,
53
+ price: options.fetch(:price),
54
+ amount: options.fetch(:amount, 0.001)
55
+ }
56
+ get(args)
57
+ end
58
+
59
+ def sell_market(options = {})
60
+ args = {
61
+ method: __method__,
62
+ coin_type: 1,
63
+ amount: options.fetch(:btc_amount, 0.001)
64
+ }
65
+ get(args)
66
+ end
67
+
68
+ def get(options)
69
+ params = options.fetch(:params, options)
70
+ digest = options.fetch(:digest, params)
71
+ digest_keys = digest.is_a?(Hash) ? digest.keys : digest
72
+
73
+ rest_options = {
74
+ params: pack_params(params, digest_keys),
75
+ header: REQUEST_HEADER,
76
+ accept: :json
77
+ }
78
+ response = RestClient.get(REQUEST_URL, rest_options)
79
+ normalize_json(response)
80
+ end
81
+
82
+ private
83
+
84
+ def to_param(hash)
85
+ hash.sort.map {|a| "#{a[0]}=#{a[1]}"}.join('&')
86
+ end
87
+
88
+ def normalize_json(json)
89
+ object = JSON.parse(json)
90
+ return object if object.is_a? Array
91
+ new_hash = {}
92
+ object.each do |key, value|
93
+ if value.is_a?(String) && value.match(/\A\d+\.\d+\z/)
94
+ new_hash[key] = value.to_f
95
+ else
96
+ new_hash[key] = value
97
+ end
98
+ end
99
+ new_hash
100
+ end
101
+
102
+ def pack_params(params, digest_keys)
103
+ with_signature(with_tokens(with_created_at params), digest_keys)
104
+ end
105
+
106
+ def with_created_at(params)
107
+ params.merge(created: Time.now.to_i)
108
+ end
109
+
110
+ def with_tokens(params)
111
+ params.merge(access_key: @access_key, secret_key: @secret_key)
112
+ end
113
+
114
+ def with_signature(params, digest_keys)
115
+ digest_keys << :access_key << :secret_key << :created
116
+ digest_params = params.select { |k, v| digest_keys.include?(k) }
117
+ sign = Digest::MD5.hexdigest(to_param(digest_params))
118
+ params.merge(sign: sign)
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,76 @@
1
+ RSpec.configure do |config|
2
+ # rspec-expectations config goes here. You can use an alternate
3
+ # assertion/expectation library such as wrong or the stdlib/minitest
4
+ # assertions if you prefer.
5
+ config.expect_with :rspec do |expectations|
6
+ # This option will default to `true` in RSpec 4. It makes the `description`
7
+ # and `failure_message` of custom matchers include text for helper methods
8
+ # defined using `chain`, e.g.:
9
+ # be_bigger_than(2).and_smaller_than(4).description
10
+ # # => "be bigger than 2 and smaller than 4"
11
+ # ...rather than:
12
+ # # => "be bigger than 2"
13
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
14
+ end
15
+
16
+ # rspec-mocks config goes here. You can use an alternate test double
17
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
18
+ config.mock_with :rspec do |mocks|
19
+ # Prevents you from mocking or stubbing a method that does not exist on
20
+ # a real object. This is generally recommended, and will default to
21
+ # `true` in RSpec 4.
22
+ mocks.verify_partial_doubles = true
23
+ end
24
+
25
+ # The settings below are suggested to provide a good initial experience
26
+ # with RSpec, but feel free to customize to your heart's content.
27
+ # These two settings work together to allow you to limit a spec run
28
+ # to individual examples or groups you care about by tagging them with
29
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
30
+ # get run.
31
+ config.filter_run :focus
32
+ config.run_all_when_everything_filtered = true
33
+
34
+ # Allows RSpec to persist some state between runs in order to support
35
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
36
+ # you configure your source control system to ignore this file.
37
+ config.example_status_persistence_file_path = "spec/examples.txt"
38
+
39
+ # Limits the available syntax to the non-monkey patched syntax that is
40
+ # recommended. For more details, see:
41
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
42
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
43
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
44
+ config.disable_monkey_patching!
45
+
46
+ # This setting enables warnings. It's recommended, but in some cases may
47
+ # be too noisy due to issues in dependencies.
48
+ # config.warnings = true
49
+
50
+ # Many RSpec users commonly either run the entire suite or an individual
51
+ # file, and it's useful to allow more verbose output when running an
52
+ # individual spec file.
53
+ # if config.files_to_run.one?
54
+ # Use the documentation formatter for detailed output,
55
+ # unless a formatter has already been configured
56
+ # (e.g. via a command-line flag).
57
+ # config.default_formatter = 'doc'
58
+ # end
59
+
60
+ # Print the 10 slowest examples and example groups at the
61
+ # end of the spec run, to help surface which specs are running
62
+ # particularly slow.
63
+ # config.profile_examples = 10
64
+
65
+ # Run specs in random order to surface order dependencies. If you find an
66
+ # order dependency and want to debug it, you can fix the order by providing
67
+ # the seed, which is printed after each run.
68
+ # --seed 1234
69
+ config.order = :random
70
+
71
+ # Seed global randomization in this process using the `--seed` CLI option.
72
+ # Setting this allows you to use `--seed` to deterministically reproduce
73
+ # test failures related to randomization by passing the same `--seed` value
74
+ # as the one that triggered the failure.
75
+ Kernel.srand config.seed
76
+ end
@@ -0,0 +1,18 @@
1
+ require 'pry'
2
+ require 'awesome_print'
3
+ require_relative '../spec_helper'
4
+ require_relative '../../lib/huo/market'
5
+
6
+ RSpec.describe Huo::Market do
7
+ let(:market) { Huo::Market.new }
8
+
9
+ it '#get_detail_data' do
10
+ response = market.get_detail_data
11
+ expect(response['top_buy'].count).to eq 5
12
+ end
13
+
14
+ it '#get_simple_data' do
15
+ response = market.get_simple_data
16
+ expect(response['ticker']['last']).not_to be_nil
17
+ end
18
+ end
@@ -0,0 +1,46 @@
1
+ require 'pry'
2
+ require 'awesome_print'
3
+ require_relative '../spec_helper'
4
+ require_relative '../../lib/huo/trade'
5
+
6
+ RSpec.describe Huo::Trade do
7
+ let(:trade) do
8
+ path = File.expand_path('../../../config/tokens.yml', __FILE__)
9
+ Huo::Trade.new(tokens_path: path)
10
+ end
11
+
12
+ it '#get_account_info' do
13
+ response = trade.get_account_info
14
+ ap response
15
+ expect(response['available_cny_display']).to be_a Float
16
+ end
17
+
18
+ it '#get_orders' do
19
+ response = trade.get_orders
20
+ expect(response).to be_a Array
21
+ end
22
+
23
+ it '#buy_market', :skip do
24
+ response = trade.buy_market
25
+ expect(response['result']).to eq 'success'
26
+ expect(response['id']).to be_a Fixnum
27
+ end
28
+
29
+ it '#sell_market', :skip do
30
+ response = trade.sell_market
31
+ expect(response['result']).to eq 'success'
32
+ expect(response['id']).to be_a Fixnum
33
+ end
34
+
35
+ it '#buy', :skip do
36
+ response = trade.buy(price: 2995)
37
+ expect(response['result']).to eq 'success'
38
+ expect(response['id']).to be_a Fixnum
39
+ end
40
+
41
+ it '#sell', :skip do
42
+ response = trade.sell(price: 2998)
43
+ expect(response['result']).to eq 'success'
44
+ expect(response['id']).to be_a Fixnum
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: huo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ming Qu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Huobi SDK for Ruby
14
+ email: qucool@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".gitignore"
20
+ - ".rspec"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - huo.gemspec
24
+ - lib/huo.rb
25
+ - lib/huo/market.rb
26
+ - lib/huo/trade.rb
27
+ - spec/spec_helper.rb
28
+ - spec/unit/market_spec.rb
29
+ - spec/unit/trade_spec.rb
30
+ homepage: http://rubygems.org/gems/huo
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.4.5.1
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: huo
54
+ test_files:
55
+ - spec/spec_helper.rb
56
+ - spec/unit/market_spec.rb
57
+ - spec/unit/trade_spec.rb
58
+ has_rdoc: