huo 0.0.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.
@@ -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: