gekko 0.8.1 → 0.9.5
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.
- checksums.yaml +4 -4
- data/lib/gekko/book.rb +55 -39
- data/lib/gekko/market_order.rb +5 -7
- data/lib/gekko/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1b1e5234724a55544ac1f4bd8e1df4cf6574772
|
4
|
+
data.tar.gz: 434bf684cc8a837c568317340618c2b346f5471c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97a6e80692ed6b73878a07836b11e333072778f90d3ded6c99c69e696c87f5b1b21f4af37b066289f77f24ace61735bb481980e0bc80603d985ac15d7e806f4c
|
7
|
+
data.tar.gz: fce34e374fd353c296caf2723728b61a45e336d613149d68f983f740641f096cf2f2f8e0f9b69ed734905c664b252b6d7940bc13fcbde4cf2112b601159be3d2
|
data/lib/gekko/book.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/gekko/market_order.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
31
|
-
|
28
|
+
max_precision ||
|
29
|
+
(!size.nil? && remaining.zero?) ||
|
32
30
|
(!quote_margin.nil? && remaining_quote_margin.zero?)
|
33
31
|
end
|
34
32
|
|
data/lib/gekko/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2016-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uuidtools
|