gekko 0.8.1 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 981305466dff1fb589c97f96fb4be28ca1b4e2ce
4
- data.tar.gz: 123b650f9b0774614710cec547990609786f1dc2
3
+ metadata.gz: d1b1e5234724a55544ac1f4bd8e1df4cf6574772
4
+ data.tar.gz: 434bf684cc8a837c568317340618c2b346f5471c
5
5
  SHA512:
6
- metadata.gz: bf435111f321867abc6d3dc3028e54a8da6791c2dc6b2bd216c45279f5bcc750be54332765d411d11a2486db735e67767d4fb5b0c1291893e8468d5eb9f5843b
7
- data.tar.gz: 33210a4936da0df11359588b54773570a9f12f0002e85ae516931efdc0f763adb236074a7abea5869ac45eb34bd3f38d5763ef89461860af088b2965c23ba6ab
6
+ metadata.gz: 97a6e80692ed6b73878a07836b11e333072778f90d3ded6c99c69e696c87f5b1b21f4af37b066289f77f24ace61735bb481980e0bc80603d985ac15d7e806f4c
7
+ data.tar.gz: fce34e374fd353c296caf2723728b61a45e336d613149d68f983f740641f096cf2f2f8e0f9b69ed734905c664b252b6d7940bc13fcbde4cf2112b601159be3d2
@@ -9,10 +9,13 @@ module Gekko
9
9
  #
10
10
  class Book
11
11
 
12
+ extend Forwardable
12
13
  include Serialization
13
14
 
14
15
  attr_accessor :pair, :bids, :asks, :tape, :received, :base_precision, :multiplier
15
16
 
17
+ def_delegators :@tape, :logger, :logger=
18
+
16
19
  def initialize(pair, opts = {})
17
20
  self.pair = opts[:pair] || pair
18
21
  self.bids = opts[:bids] || BookSide.new(:bid)
@@ -53,45 +56,7 @@ module Gekko
53
56
  next_match = opposite_side.first
54
57
 
55
58
  else
56
- trade_price = next_match.price
57
- max_quote_size = nil
58
-
59
- if order.is_a?(MarketOrder)
60
- max_size_possible_with_quote_margin = order.remaining_quote_margin && (order.remaining_quote_margin * multiplier / trade_price).round
61
- end
62
-
63
- base_size = [
64
- next_match.remaining,
65
- order.remaining,
66
- max_size_possible_with_quote_margin
67
- ].compact.min
68
-
69
- if order.is_a?(LimitOrder)
70
- quote_size = (base_size * trade_price) / multiplier
71
-
72
- elsif order.is_a?(MarketOrder)
73
- if order.ask? || (order.remaining_quote_margin > (trade_price * base_size / multiplier))
74
- quote_size = (trade_price * base_size / multiplier).round
75
- order.remaining_quote_margin -= quote_size if order.quote_margin
76
-
77
- elsif order.bid?
78
- quote_size = order.remaining_quote_margin
79
- order.remaining_quote_margin = 0
80
- end
81
- end
82
-
83
- tape << {
84
- type: :execution,
85
- price: trade_price,
86
- base_size: base_size,
87
- quote_size: quote_size,
88
- maker_order_id: next_match.id.to_s,
89
- taker_order_id: order.id.to_s,
90
- tick: order.bid? ? :up : :down
91
- }
92
-
93
- order.remaining -= base_size if order.remaining
94
- next_match.remaining -= base_size
59
+ execute_trade(next_match, order)
95
60
 
96
61
  if next_match.filled?
97
62
  tape << opposite_side.shift.message(:done, reason: :filled)
@@ -113,6 +78,56 @@ module Gekko
113
78
  end
114
79
  end
115
80
 
81
+ #
82
+ # Executes a trade between two orders
83
+ #
84
+ # @param maker [Gekko::LimitOrder] The order in the book providing liquidity
85
+ # @param taker [Gekko::Order] The order being executed
86
+ #
87
+ def execute_trade(maker, taker)
88
+ trade_price = maker.price
89
+ max_quote_size = nil
90
+
91
+ # Rounding direction depends on the takers direction
92
+ rounding = (taker.bid? ? :floor : :ceil)
93
+
94
+ if taker.is_a?(MarketOrder)
95
+ max_size_with_quote_margin = taker.remaining_quote_margin &&
96
+ (taker.remaining_quote_margin * multiplier / trade_price).send(rounding)
97
+ end
98
+
99
+ base_size = [
100
+ maker.remaining,
101
+ taker.remaining,
102
+ max_size_with_quote_margin
103
+ ].compact.min
104
+
105
+ if taker.is_a?(LimitOrder)
106
+ quote_size = (base_size * trade_price) / multiplier
107
+
108
+ elsif taker.is_a?(MarketOrder)
109
+ if base_size == max_size_with_quote_margin
110
+ taker.max_precision = true
111
+ end
112
+
113
+ quote_size = [(trade_price * base_size / multiplier).round, taker.remaining_quote_margin].compact.min
114
+ taker.remaining_quote_margin -= quote_size if taker.quote_margin
115
+ end
116
+
117
+ tape << {
118
+ type: :execution,
119
+ price: trade_price,
120
+ base_size: base_size,
121
+ quote_size: quote_size,
122
+ maker_id: maker.id.to_s,
123
+ taker_id: taker.id.to_s,
124
+ tick: taker.bid? ? :up : :down
125
+ }
126
+
127
+ taker.remaining -= base_size if taker.remaining
128
+ maker.remaining -= base_size
129
+ end
130
+
116
131
  #
117
132
  # Cancels an order given an ID
118
133
  #
@@ -229,6 +244,7 @@ module Gekko
229
244
  asks: BookSide.new(:ask, orders: hsh[:asks].map { |o| symbolize_keys(o) }.sort { |a, b| a[:price] <=> b[:price] }),
230
245
  })
231
246
 
247
+ [:bids, :asks].each { |s| book.send(s).each { |ord| book.received[ord.id.to_s] = ord } }
232
248
  book.tape = Tape.from_hash(symbolize_keys(hsh[:tape])) if hsh[:tape]
233
249
 
234
250
  book
@@ -6,7 +6,7 @@ module Gekko
6
6
  #
7
7
  class MarketOrder < Order
8
8
 
9
- attr_accessor :quote_margin, :remaining_quote_margin
9
+ attr_accessor :quote_margin, :remaining_quote_margin, :max_precision
10
10
 
11
11
  def initialize(side, id, size, quote_margin, expiration = nil)
12
12
  super(side, id, size, expiration)
@@ -15,11 +15,9 @@ module Gekko
15
15
  @remaining_quote_margin = @quote_margin
16
16
 
17
17
  if bid?
18
- quote_margin.nil? &&
19
- raise('Quote currency margin must be provided for a market bid')
18
+ quote_margin.nil? && raise('Quote currency margin must be provided for a market bid')
20
19
  elsif ask?
21
- (quote_margin.nil? ^ size.nil?) ||
22
- raise('Quote currency margin and size can not be both specified for a market ask')
20
+ size.nil? && raise('Size must be provided for a market ask')
23
21
  end
24
22
  end
25
23
 
@@ -27,8 +25,8 @@ module Gekko
27
25
  # Returns +true+ if the order is filled
28
26
  #
29
27
  def filled?
30
- #binding.pry
31
- (!size.nil? && remaining.zero?) ||
28
+ max_precision ||
29
+ (!size.nil? && remaining.zero?) ||
32
30
  (!quote_margin.nil? && remaining_quote_margin.zero?)
33
31
  end
34
32
 
@@ -1,6 +1,6 @@
1
1
  module Gekko
2
2
 
3
3
  # The Gekko version string
4
- VERSION = '0.8.1'
4
+ VERSION = '0.9.5'
5
5
 
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gekko
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David FRANCOIS
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-05 00:00:00.000000000 Z
11
+ date: 2016-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuidtools