chock_a_block 0.1.0 → 0.1.1

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: 61eac32feffc31892a866b93630c02d84274154f
4
- data.tar.gz: 677f850db05f1cb59da016806a43095f0ce4f250
3
+ metadata.gz: 3c31a5f8019fffb3347eca48196a97cfece3af3f
4
+ data.tar.gz: 685411389aaabeef552b82fae307c1881e2ecdf4
5
5
  SHA512:
6
- metadata.gz: a4877e9e853be54c86325aa1e53e97185c06c0bc0ba5f02f6aa5e678fb0feb1d10a0725d900b8a5d363bc50ff29397c43c9d94362c09dd6a0b3f609a6bcae371
7
- data.tar.gz: d259a1b9a20153211ab925f07c1b411ed4bbc8e156a7ed16a18d7f6a0dccaa13af506b1c1ae0139088b34177577c41f25cc22577585debe6a67cf4bd4df0d668
6
+ metadata.gz: 2e5ffb538e95e55736417106d08580fb2f97d44f990553db2760595599cef41a6bf76a1469385525f9d6209e822a95750addb9ce3ec40d02c23c588067bef561
7
+ data.tar.gz: cb4c8e087f44f7424116025b38e1e274b4e2e560cd4b968337e244fd7899de5a9f97797e228e725111aa3961b62ba4e0be8e0d3580846c6370fb8dbab83fc4b7
@@ -37,8 +37,8 @@ module ChockABlock
37
37
  # @return [Hash] representing the best current price/qty offered by bots
38
38
  # or retry if best_bid is nil
39
39
  def best_bidding
40
- @order_book = get_orderbook
41
- best_bid = @order_book['bids']&.last
40
+ order_book = get_orderbook
41
+ best_bid = order_book['bids']&.last
42
42
 
43
43
  return best_bid unless best_bid.nil?
44
44
 
@@ -0,0 +1,41 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://www.stockfighter.io/gm/levels/chock_a_block
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ X-Starfighter-Authorization:
11
+ - API_KEY
12
+ Connection:
13
+ - close
14
+ Host:
15
+ - www.stockfighter.io
16
+ User-Agent:
17
+ - http.rb/1.0.2
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx/1.8.0
25
+ Date:
26
+ - Sun, 21 Feb 2016 19:56:11 GMT
27
+ Content-Type:
28
+ - application/json
29
+ Content-Length:
30
+ - '144'
31
+ Connection:
32
+ - close
33
+ X-Upstream-Debugging:
34
+ - 172.31.134.156:8181
35
+ body:
36
+ encoding: ASCII-8BIT
37
+ string: '{"ok":false,"error":"Auth/auth failed: %!(EXTRA *errors.errorString=Couldn''t
38
+ find that apiKey, service reports: No fighter with that API key.)"}'
39
+ http_version:
40
+ recorded_at: Sun, 21 Feb 2016 19:53:57 GMT
41
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,56 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://www.stockfighter.io/gm/levels/chock_a_block
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ X-Starfighter-Authorization:
11
+ - API_KEY
12
+ Connection:
13
+ - close
14
+ Host:
15
+ - www.stockfighter.io
16
+ User-Agent:
17
+ - http.rb/1.0.2
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Server:
24
+ - nginx/1.8.0
25
+ Date:
26
+ - Sun, 21 Feb 2016 20:00:57 GMT
27
+ Content-Type:
28
+ - application/json
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - close
33
+ X-Upstream-Debugging:
34
+ - 172.31.134.156:8181
35
+ body:
36
+ encoding: ASCII-8BIT
37
+ string: |-
38
+ {
39
+ "ok": true,
40
+ "instanceId": 23585,
41
+ "account": "HAE78360086",
42
+ "instructions": {
43
+ "Instructions": "# Moving up in the world!\n\n**Reminder: These instructions are always available under the Instructions tab if you need to see them again.** \n\nAfter your impressive performance at your last job, you've moved on to Hollings \u0026 Eakins. Warning: **the gloves are off, now**.\nHere is **account HAE78360086** and a mandate from one of our clients, a pension fund: they want you to purchase them 100,000 shares of \nRockDeathBlossomify (*RDB*). (Their asset manager thinks the company will have market-beating performance over the next\nfew years. Maybe they're right, maybe they're not, but either way we get paid and I'm investing my bonus in cat food futures.)\n\nThis is called a **block trade** -- 100,000 shares is a lot of RDB to buy all at once, so the presence of someone wanting to\ndo it suggests that someone who is smart and rich has better-than-market information about the stock. Executing block trades\nis one of the core problems of trading.\n\nWhy? Here's one of the reasons we on the sell-side make the big bucks: the client could try to buy these shares themselves,\n but if they just did the obvious thing and put in an order for 100,000 shares, they'd get shellacked.\n\nWhy? Supply and demand: sudden demand for a product with limited supply, like liquid shares of a stock, makes the market \nclearing price go up. Also, supply and demand: if you supply a sucker who broadcasts his intentions loudly, capitalism demands that the rest of\nthe market eat the sucker alive. So instead you've got to be sneaky-sneaky about how you accumulate those 100,000 shares.\n\nLuckily, this market maker is dumb as a box of rocks. They don't seem to remember prior orders well at all. You could probably \nget the full allocation done just by calling them up all day and ordering a few shares here and a few shares there... \nbut I hear you're a programmer, and the stock exchange has [an API](https://starfighter.readme.io), so why do anything \nmanual and repetitive when you have a for loop available?\n\n## Your Goal\n* Purchase 100,000 shares of RDB.\n* Avoid causing a \"price impact\" -- our client wants these shares for the cheapest price possible, naturally.\n\n## You'll Be Fired If\n\n* You cause an excessive price impact in the stock. What's \"excessive\"? It's up to the risk desk. \n* You take too long. The client doesn't need their shares *this instant* but they want them *quickly*.\n* The market moves against you. What, that's unfair? Welcome to Wall Street, kid.\n\n### A Note From Starfighter:\n\nWe abstract the notion of time in Stockfighter. On this level, one trading day in the simulated world corresponds to about five\nseconds of wall-clock time. In real life, the market generally has off periods between trading days, but most of our levels don't --\nour bots don't need sleep. Well, OK, technically speaking they do sleep() while waiting on you... like right now, because you're\nreading while you could be trading. Get coding!\n",
44
+ "Market Makers": "A **market maker** is a market participant (sometimes a formal role, often not) who provides *liquidity* in a stock, by being willing\nto buy the stock or sell the stock, substantially all of the time. The market maker seeks to make a small amount of money on\na large amount of transactions by, on average, selling for slightly more than their buying price. The difference between the price\nthat they're willing to buy at and the price that they're willing to sell at (at any given moment) is called \"the *spread*\".\n\nMarket makers are crucial to the financial markets. A market without liquidity is a sucky market. The market for houses has very\nlow liquidity: if you want to sell your house on Tuesday, it is unlikely that anyone wants to buy *exactly* your house on *exactly*\nTuesday, so you'd probably get a very, very poor price for it. Similarly, if you wanted to buy *exactly* your dream house on *exactly*\nTuesday, you'd probably have to pay a ridiculous premium to the \"fair value\" of the house.\n\nImagine a world where there was someone you would call, name any address in the country, and immediately receive a buying\nprice and a selling price for that house. That person would be a market maker. They would make it much, much less difficult\nfor you to get into or out of your desired exposure to a house on Tuesday.\n\nMarket makers are the counter-parties to *most* transactions on the stock exchange. That sounds unlikely, but it is true: it is\nhighly unlikely that a pension fund seeking to unload 100,000 shares of Google executes that trade at *the exact instant* where\na stadium full of mom-and-pop investors are seeking to buy 2~5 shares of Google apiece.\n\n## What Do Market Makers Not Like?\n\nMarket makers don't like **inventory risk**. They get paid to take on a small, short-term risk of being long (holding stock) or \nshort (borrowing stock) in the stock they're making a market for, with the intention of quickly having an order in the opposite\ndirection get them out of that position.\n\nIt is dangerous for a market maker to trade with *informed order flow*, i.e. someone with better-than-market understanding of\nthe near term future for a stock. Someone who is trading a block (a lot of stock at once) is automatically informed order flow,\nsince they know that their current transaction for buying 100 shares is going to be followed not by a 50/50 chance of a sell but\nrather with a buy, a buy, another buy, some more buys, followed by more buying.\n\nIf a market maker continues to allow informed order flow to trade with them, they may find themselves with a larger position than\nthey anticipated at a price which is expensive to get out of, given the present state of the market.\n\n## How Do Market Makers Deal With This?\n\n1. *Profile incoming orders.* Market makers, beginning with humans with \"a sense of the flow of the market\" and continuing to\nHFT algorithms in the present day, are in a constant cat-and-mouse game with informed order flow. They'd prefer to transact\nminimally (if at all) with informed orders.\n\n2. *Hedge.* More sophisticated strategies are available after a market maker has multiple instruments they can trade in. For\nexample, they can hedge a long position in a stock with options which synthetically cancel out some features of the position.\nThey could also e.g. hedge a position in a particular stock with an offsetting position in a separate stock believe to be highly\ncorrelated with the original stock (e.g. if you're long Toyota, sell Honda), with indexes/exchange traded funds, or with other\nderivatives.\n\n## How Do I Make Markets?\n\nBuy low. Sell high. Trade frequently.\n\n## No, Really?\n\nObserve what the provided market makers do, in particular how they quote spreads and periodically cancel orders when\nthe market moves in either direction. The provided market makers are as unsophisticated as they can be and possibly work\n(n.b. under 100 lines of Ruby code). You should be able to easily exploit their blind spots. \n\nA freebie, since **people who\nactually read docs should be rewarded**: our least sophisticated market maker has no memory of closed orders and looks\nat the order book every N seconds as if the universe had just sprung into being. That probably suggests at least one way\nto trick it into doing what you want. \n\nBonus points: if what you do to get what you want doesn't leave a signature in the order\nbook, it will *never* catch on. (Note that a dumb market maker with smart participants next to it can function as a smart system\neven if they're not intentionally colluding, however. One of the core insights of markets in general is that they quickly converge\non solutions which are better than individual participants would have come up with. A market maker can surf on the market,\nwhich converges to a solution to your manipulation, without itself understanding that your manipulation even exists.)\n\nIn general, you want to \n\n1. quote a tighter spread (if the bot would quote $10 / $10.50, and you quote $10.05 / $10.45, you'll\nget the fills rather than the bot)\n2. attempt to profile incoming orders, for example by keeping state of your own recent orders and whether you appear to be\nhaving many similar ones happen in the same direction\n3. cancel and re-file your bids/asks when you develop inventory in either direction, potentially at a less favorable price if you're\nscared\n4. look for patterns in the market and in behavior of other participants. Patterns which suggest anomalous behavior, which\nroutinely divulge that an order is from a sophisticated or unsophisticated source, or which allow you to predict the near-term\nbehavior of another participant are *very valuable indeed.*\n\n## Stockfighter Notes\n\nTake a look at the API docs for viewing an order's fills or the details of an execution. Note that we don't expose any identifying\ninformation about your counterparty. Now, try to think of creative ways that one can \"cheat\" the non-availability of that information.\n"
45
+ },
46
+ "tickers": [
47
+ "STK"
48
+ ],
49
+ "venues": [
50
+ "VENUE"
51
+ ],
52
+ "secondsPerTradingDay": 5
53
+ }
54
+ http_version:
55
+ recorded_at: Sun, 21 Feb 2016 19:58:43 GMT
56
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,137 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 21:15:56 GMT
25
+ Content-Type:
26
+ - application/json
27
+ Content-Length:
28
+ - '358'
29
+ Connection:
30
+ - close
31
+ Strict-Transport-Security:
32
+ - max-age=31536000; includeSubdomains
33
+ body:
34
+ encoding: ASCII-8BIT
35
+ string: |-
36
+ {
37
+ "ok": true,
38
+ "venue": "VENUE",
39
+ "symbol": "STK",
40
+ "ts": "2016-02-21T21:14:04.301520932Z",
41
+ "bids": null,
42
+ "asks": [
43
+ {
44
+ "price": 10403,
45
+ "qty": 11898,
46
+ "isBuy": false
47
+ },
48
+ {
49
+ "price": 10454,
50
+ "qty": 11898,
51
+ "isBuy": false
52
+ },
53
+ {
54
+ "price": 10505,
55
+ "qty": 11898,
56
+ "isBuy": false
57
+ }
58
+ ]
59
+ }
60
+ http_version:
61
+ recorded_at: Sun, 21 Feb 2016 21:13:42 GMT
62
+ - request:
63
+ method: get
64
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK
65
+ body:
66
+ encoding: US-ASCII
67
+ string: ''
68
+ headers:
69
+ Connection:
70
+ - close
71
+ Host:
72
+ - api.stockfighter.io
73
+ User-Agent:
74
+ - http.rb/1.0.2
75
+ response:
76
+ status:
77
+ code: 200
78
+ message: OK
79
+ headers:
80
+ Server:
81
+ - nginx/1.8.0
82
+ Date:
83
+ - Sun, 21 Feb 2016 21:15:58 GMT
84
+ Content-Type:
85
+ - application/json
86
+ Content-Length:
87
+ - '579'
88
+ Connection:
89
+ - close
90
+ Strict-Transport-Security:
91
+ - max-age=31536000; includeSubdomains
92
+ body:
93
+ encoding: ASCII-8BIT
94
+ string: |-
95
+ {
96
+ "ok": true,
97
+ "venue": "VENUE",
98
+ "symbol": "STK",
99
+ "ts": "2016-02-21T21:14:07.142397315Z",
100
+ "bids": [
101
+ {
102
+ "price": 9891,
103
+ "qty": 13078,
104
+ "isBuy": true
105
+ },
106
+ {
107
+ "price": 9842,
108
+ "qty": 13078,
109
+ "isBuy": true
110
+ },
111
+ {
112
+ "price": 9793,
113
+ "qty": 13078,
114
+ "isBuy": true
115
+ }
116
+ ],
117
+ "asks": [
118
+ {
119
+ "price": 9989,
120
+ "qty": 11921,
121
+ "isBuy": false
122
+ },
123
+ {
124
+ "price": 10038,
125
+ "qty": 11873,
126
+ "isBuy": false
127
+ },
128
+ {
129
+ "price": 10087,
130
+ "qty": 11873,
131
+ "isBuy": false
132
+ }
133
+ ]
134
+ }
135
+ http_version:
136
+ recorded_at: Sun, 21 Feb 2016 21:13:44 GMT
137
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,79 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 20:56:13 GMT
25
+ Content-Type:
26
+ - application/json
27
+ Content-Length:
28
+ - '574'
29
+ Connection:
30
+ - close
31
+ Strict-Transport-Security:
32
+ - max-age=31536000; includeSubdomains
33
+ body:
34
+ encoding: ASCII-8BIT
35
+ string: |-
36
+ {
37
+ "ok": true,
38
+ "venue": "VENUE",
39
+ "symbol": "STK",
40
+ "ts": "2016-02-21T20:54:21.828875543Z",
41
+ "bids": [
42
+ {
43
+ "price": 2357,
44
+ "qty": 15434,
45
+ "isBuy": true
46
+ },
47
+ {
48
+ "price": 2346,
49
+ "qty": 15434,
50
+ "isBuy": true
51
+ },
52
+ {
53
+ "price": 2335,
54
+ "qty": 15434,
55
+ "isBuy": true
56
+ }
57
+ ],
58
+ "asks": [
59
+ {
60
+ "price": 2437,
61
+ "qty": 9066,
62
+ "isBuy": false
63
+ },
64
+ {
65
+ "price": 2449,
66
+ "qty": 9565,
67
+ "isBuy": false
68
+ },
69
+ {
70
+ "price": 2461,
71
+ "qty": 9565,
72
+ "isBuy": false
73
+ }
74
+ ]
75
+ }
76
+ http_version:
77
+ recorded_at: Sun, 21 Feb 2016 20:53:59 GMT
78
+ recorded_with: VCR 3.0.1
79
+
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 500
19
+ message: Internal Server Error
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 20:47:12 GMT
25
+ Content-Type:
26
+ - text/plain; charset=utf-8
27
+ Content-Length:
28
+ - '65'
29
+ Connection:
30
+ - close
31
+ body:
32
+ encoding: UTF-8
33
+ string: '{"ok":false,"error":"symbol STK does not exist on venue VENUE"}
34
+
35
+ '
36
+ http_version:
37
+ recorded_at: Sun, 21 Feb 2016 20:44:58 GMT
38
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 404
19
+ message: Not Found
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 20:45:37 GMT
25
+ Content-Type:
26
+ - text/plain; charset=utf-8
27
+ Content-Length:
28
+ - '61'
29
+ Connection:
30
+ - close
31
+ body:
32
+ encoding: UTF-8
33
+ string: '{"ok":false,"error":"No venue exists with the symbol VENUE"}
34
+
35
+ '
36
+ http_version:
37
+ recorded_at: Sun, 21 Feb 2016 20:43:23 GMT
38
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,78 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 20:56:13 GMT
25
+ Content-Type:
26
+ - application/json
27
+ Content-Length:
28
+ - '574'
29
+ Connection:
30
+ - close
31
+ Strict-Transport-Security:
32
+ - max-age=31536000; includeSubdomains
33
+ body:
34
+ encoding: ASCII-8BIT
35
+ string: |-
36
+ {
37
+ "ok": true,
38
+ "venue": "VENUE",
39
+ "symbol": "STK",
40
+ "ts": "2016-02-21T20:54:21.828875543Z",
41
+ "bids": [
42
+ {
43
+ "price": 2357,
44
+ "qty": 15434,
45
+ "isBuy": true
46
+ },
47
+ {
48
+ "price": 2346,
49
+ "qty": 15434,
50
+ "isBuy": true
51
+ },
52
+ {
53
+ "price": 2335,
54
+ "qty": 15434,
55
+ "isBuy": true
56
+ }
57
+ ],
58
+ "asks": [
59
+ {
60
+ "price": 2437,
61
+ "qty": 9066,
62
+ "isBuy": false
63
+ },
64
+ {
65
+ "price": 2449,
66
+ "qty": 9565,
67
+ "isBuy": false
68
+ },
69
+ {
70
+ "price": 2461,
71
+ "qty": 9565,
72
+ "isBuy": false
73
+ }
74
+ ]
75
+ }
76
+ http_version:
77
+ recorded_at: Sun, 21 Feb 2016 20:53:59 GMT
78
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK/quote
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 404
19
+ message: Not Found
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 21:01:41 GMT
25
+ Content-Type:
26
+ - text/plain; charset=utf-8
27
+ Content-Length:
28
+ - '61'
29
+ Connection:
30
+ - close
31
+ body:
32
+ encoding: UTF-8
33
+ string: '{"ok":false,"error":"No venue exists with the symbol VENUE"}
34
+
35
+ '
36
+ http_version:
37
+ recorded_at: Sun, 21 Feb 2016 20:59:27 GMT
38
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,53 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.stockfighter.io/ob/api/venues/VENUE/stocks/STK/quote
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - api.stockfighter.io
14
+ User-Agent:
15
+ - http.rb/1.0.2
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx/1.8.0
23
+ Date:
24
+ - Sun, 21 Feb 2016 21:02:32 GMT
25
+ Content-Type:
26
+ - application/json
27
+ Content-Length:
28
+ - '300'
29
+ Connection:
30
+ - close
31
+ Strict-Transport-Security:
32
+ - max-age=31536000; includeSubdomains
33
+ body:
34
+ encoding: ASCII-8BIT
35
+ string: |-
36
+ {
37
+ "ok": true,
38
+ "symbol": "STK",
39
+ "venue": "VENUE",
40
+ "bid": 2630,
41
+ "ask": 2656,
42
+ "bidSize": 14749,
43
+ "askSize": 9912,
44
+ "bidDepth": 44263,
45
+ "askDepth": 30412,
46
+ "last": 2656,
47
+ "lastSize": 338,
48
+ "lastTrade": "2016-02-21T21:00:36.605689657Z",
49
+ "quoteTime": "2016-02-21T21:00:36.605987278Z"
50
+ }
51
+ http_version:
52
+ recorded_at: Sun, 21 Feb 2016 21:00:18 GMT
53
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChockABlock::Stock do
4
+ subject { ChockABlock::Stock.new('VENUE', 'STK') }
5
+
6
+ describe '#get_orderbook' do
7
+ it 'raises VenueNotFoundError', :vcr do
8
+ expect{ subject.get_orderbook }.to raise_error ChockABlock::VenueNotFoundError
9
+ end
10
+
11
+ it 'raises StockNotFoundError', :vcr do
12
+ expect{ subject.get_orderbook }.to raise_error ChockABlock::StockNotFoundError
13
+ end
14
+
15
+ it 'return JSON Hash of the order_book', :vcr do
16
+ order_book = subject.get_orderbook
17
+ expect(order_book).to be_a Hash
18
+ expect(order_book.keys).to\
19
+ include 'ok', 'venue', 'symbol', 'ts', 'bids', 'asks'
20
+ end
21
+ end
22
+
23
+ describe '#get_quote' do
24
+ it 'raises StockNotFoundError', :vcr do
25
+ expect{ subject.get_quote }.to raise_error ChockABlock::StockNotFoundError
26
+ end
27
+
28
+ it 'return JSON Hash of the quote', :vcr do
29
+ quote = subject.get_quote
30
+ expect(quote).to be_a Hash
31
+ expect(quote.keys).to\
32
+ include'ok', 'symbol', 'venue', 'bid', 'ask', 'bidSize', 'askSize',
33
+ 'bidDepth', 'askDepth', 'last', 'lastSize', 'lastTrade', 'quoteTime'
34
+ end
35
+ end
36
+
37
+ describe '#best_bidding' do
38
+ it 'return best_bid', :vcr do
39
+ best_bid = subject.best_bidding
40
+
41
+ expect(best_bid['price']).to be_an Integer
42
+ expect(best_bid['qty']).to be_an Integer
43
+ expect(best_bid['isBuy']).to be true
44
+ end
45
+
46
+ it 'retries again', :vcr do
47
+ expect_any_instance_of(Object).to receive(:sleep).with(2)
48
+ expect(subject).to receive(:best_bidding).twice.and_call_original
49
+ best_bid = subject.best_bidding
50
+
51
+ expect(best_bid['price']).to be_an Integer
52
+ expect(best_bid['qty']).to be_an Integer
53
+ expect(best_bid['isBuy']).to be true
54
+ end
55
+ end
56
+ end
@@ -1,11 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ChockABlock do
4
- it 'has a version number' do
5
- expect(ChockABlock::VERSION).not_to be nil
4
+ it 'BASE_URL' do
5
+ expect(ChockABlock::BASE_URL).not_to be_nil
6
6
  end
7
7
 
8
- it 'does something useful' do
9
- expect(false).to eq(true)
8
+ it 'GAME_URL' do
9
+ expect(ChockABlock::GAME_URL).not_to be_nil
10
+ end
11
+
12
+ describe '.start_level' do
13
+ it 'prints errors about invalid API_KEY', :vcr do
14
+ expect { ChockABlock.start_level('API_KEY') }.to output(
15
+ "\"Invalid API_KEY API_KEY\"\n" +
16
+ "\"Please use a correct API_KEY to start the level\"\n"
17
+ ).to_stdout
18
+ end
19
+
20
+ it 'starts new AlgoTrader', :vcr do
21
+ expect_any_instance_of(ChockABlock::AlgoTrader).to receive(:basic_strategy)
22
+ expect { ChockABlock.start_level('API_KEY') }.to output(
23
+ "\"Game Started\"\n" +
24
+ "\"Please Navigate to:\"\n" +
25
+ "\" https://www.stockfighter.io/ui/play/blotter#chock_a_block\"\n" +
26
+ "\"to see the game in action\"\n" +
27
+ "\"--------------------------------------------------------\"\n"
28
+ ).to_stdout
29
+ end
10
30
  end
11
31
  end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,11 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'chock_a_block'
3
+ require 'vcr'
4
+ require 'webmock/rspec'
5
+
6
+ VCR.configure do |c|
7
+ c.cassette_library_dir = 'spec/cassettes'
8
+ c.hook_into :webmock
9
+ c.allow_http_connections_when_no_cassette = true
10
+ c.configure_rspec_metadata!
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chock_a_block
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmed Abdel-Razzak
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: yard
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: pry-byebug
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +120,16 @@ files:
134
120
  - lib/chock_a_block/broker.rb
135
121
  - lib/chock_a_block/errors.rb
136
122
  - lib/chock_a_block/stock.rb
123
+ - spec/cassettes/ChockABlock/_start_level/prints_errors_about_invalid_API_KEY.yml
124
+ - spec/cassettes/ChockABlock/_start_level/starts_new_AlgoTrader.yml
125
+ - spec/cassettes/ChockABlock_Stock/_best_bidding/retries_again.yml
126
+ - spec/cassettes/ChockABlock_Stock/_best_bidding/return_best_bid.yml
127
+ - spec/cassettes/ChockABlock_Stock/_get_orderbook/raises_StockNotFoundError.yml
128
+ - spec/cassettes/ChockABlock_Stock/_get_orderbook/raises_VenueNotFoundError.yml
129
+ - spec/cassettes/ChockABlock_Stock/_get_orderbook/return_JSON_Hash_of_the_order_book.yml
130
+ - spec/cassettes/ChockABlock_Stock/_get_quote/raises_StockNotFoundError.yml
131
+ - spec/cassettes/ChockABlock_Stock/_get_quote/return_JSON_Hash_of_the_quote.yml
132
+ - spec/chock_a_block/stock_spec.rb
137
133
  - spec/chock_a_block_spec.rb
138
134
  - spec/spec_helper.rb
139
135
  homepage: https://github.com/artmees/chock_a_block
@@ -161,4 +157,3 @@ signing_key:
161
157
  specification_version: 4
162
158
  summary: Solution to chock_a_block
163
159
  test_files: []
164
- has_rdoc: