polygon-i 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6cf3e4dd5c6c9dead72511b8f4d85d19c073461d9668fa06e34d62621a9234ec
4
+ data.tar.gz: 527f49c742dafb1df16ba162ef277df758b87819842ecd8b44bb2b741b175378
5
+ SHA512:
6
+ metadata.gz: 2b2b0f29dba0b7a107e2b9f06831d906a3c5e246d6816a950a80c3c80b099b8c78c1b9cf0b5f76b15bdd04d2e7a08c745bc78d9e54e374d5defe853e39511a34
7
+ data.tar.gz: 2f53cee059a1cb35a04e0db29fd8ec30234a8ba0b598b70771c3551e0ab959fabd50abb1e56fc218fcd030db6dd32f435efea7cc93d7682f57dd65537f790388
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /test/secrets.json
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'redis'
4
+ gem 'faye-websocket'
5
+ gem 'pry'
6
+
7
+ # Specify your gem's dependencies in polygon.gemspec
8
+ gemspec
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ polygon (0.1.0)
5
+ faye-websocket
6
+ redis
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ coderay (1.1.3)
12
+ eventmachine (1.2.7)
13
+ faye-websocket (0.10.9)
14
+ eventmachine (>= 0.12.0)
15
+ websocket-driver (>= 0.5.1)
16
+ method_source (1.0.0)
17
+ pry (0.13.1)
18
+ coderay (~> 1.1)
19
+ method_source (~> 1.0)
20
+ rake (10.5.0)
21
+ redis (4.1.4)
22
+ websocket-driver (0.7.2)
23
+ websocket-extensions (>= 0.1.0)
24
+ websocket-extensions (0.1.5)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ bundler (~> 2.0)
31
+ faye-websocket
32
+ polygon!
33
+ pry
34
+ rake (~> 10.0)
35
+ redis
36
+
37
+ BUNDLED WITH
38
+ 2.0.2
@@ -0,0 +1,35 @@
1
+ # Polygon
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/polygon`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'polygon'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install polygon
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/polygon.
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "polygon"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,39 @@
1
+ require "polygon/version"
2
+ require 'net/http'
3
+ require 'pry'
4
+
5
+ module Polygon
6
+ Dir[__dir__ + '/polygon/*.rb'].each do |f|
7
+ #puts f
8
+ eval File.read(f)
9
+ end
10
+
11
+ class<<self
12
+ def config
13
+ Config
14
+ end
15
+ end
16
+
17
+ class Error < StandardError; end
18
+ # Your code goes here...
19
+
20
+ class Stream
21
+ DEFAULT_WATCH = "MSFT TSLA AAPL AMZN GOOGL BRK.A FB BABA TCEHY JPM JNJ V XOM IDCBF".split(' ')
22
+
23
+ def initialize auth, stream='stocks'
24
+ @pi = PolygonInterface.new auth, stream
25
+ end
26
+
27
+ def listen
28
+ @pi.run
29
+ @pi.sub DEFAULT_WATCH
30
+ @pi.thread.join
31
+ end
32
+ end
33
+ end
34
+
35
+
36
+ Polygon.config.setKey 'POLYGON', '123'
37
+
38
+ r = Polygon::Ticker.last_trade 'AAPL'
39
+ puts r
@@ -0,0 +1,46 @@
1
+ require "redis"
2
+ require 'time'
3
+ require 'polygon/pub_sub'
4
+
5
+ class Cache
6
+ TTL = 60 # seconds
7
+
8
+ @@redis = Redis.new
9
+
10
+ def initialize name_map
11
+
12
+ $ps.sub 'on_trade', ->(data) {
13
+ key = "T_#{data['sym']}"
14
+ t = data['t']
15
+
16
+ if expired? t
17
+
18
+ else
19
+ hmset key, data.to_a
20
+ end
21
+ }
22
+ end
23
+
24
+ def refresh
25
+ # grab and set
26
+ end
27
+
28
+ def expired? timestamp # ms
29
+ ts = Time.strptime(timestamp, '%Q')
30
+
31
+ Time.now.to_i - ts.to_i >= TTL
32
+ end
33
+
34
+ def hmset name, key_vals
35
+ @@redis.hmset name, *key_vals
36
+ end
37
+
38
+ def hmget name, keys
39
+ @@redis.hmget name, *keys
40
+ end
41
+
42
+ def delete names
43
+ @@redis.del *names
44
+ end
45
+
46
+ end
@@ -0,0 +1,15 @@
1
+ module Config
2
+ @@keys = {}
3
+
4
+ def self.keys
5
+ @@keys
6
+ end
7
+
8
+ def self.setKey key, val
9
+ @@keys[key] = val
10
+ end
11
+
12
+ def self.getKey key
13
+ @@keys[key]
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ class PubSub
2
+
3
+ def initialize
4
+ @subs = {}
5
+ end
6
+
7
+ def sub chan, clbk
8
+ @subs[chan] ||= []
9
+ @subs[chan] << clbk
10
+ end
11
+
12
+ def pub chan, data
13
+ @subs[chan] ||= []
14
+
15
+ @subs[chan].each do |ch|
16
+ ch.call(data)
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ $ps = PubSub.new
@@ -0,0 +1,127 @@
1
+ require 'faye/websocket'
2
+ require 'eventmachine'
3
+ require 'json'
4
+ require 'set'
5
+
6
+ require 'polygon/pub_sub'
7
+
8
+ class PolygonInterface
9
+ attr_accessor :thread
10
+
11
+ def initialize auth, stream
12
+ @auth = auth
13
+ @stream = stream
14
+ @ws = nil
15
+ @subs = Set.new
16
+ @ready = false
17
+ @thread = nil
18
+ end
19
+
20
+ def subs
21
+ @subs
22
+ end
23
+
24
+ def run
25
+ @thread = Thread.new do
26
+ EM.run {
27
+ @ws = Faye::WebSocket::Client.new("wss://socket.polygon.io/#{@stream}")
28
+
29
+ @ws.on :open do |event|
30
+ p [:open]
31
+ @ws.send('{"action":"auth","params":"' + @auth + '"}')
32
+ end
33
+
34
+ @ws.on :message do |event|
35
+ p [:message, event.data]
36
+
37
+ msgs = JSON.parse event.data
38
+ msgs.each do |msg|
39
+ case msg['ev']
40
+ when 'T'
41
+ on_T(msg)
42
+ when 'status'
43
+ on_connected if msg['status'] == 'connected'
44
+ on_auth if msg['status'] == 'auth_success'
45
+
46
+ ms = msg['message'].split(': ')
47
+ on_subscribed(ms.last.strip) if ms.first == 'subscribed to'
48
+ on_unsubscribed(ms.last.strip) if ms.first == 'unsubscribed to'
49
+ end
50
+ end
51
+ end
52
+
53
+ @ws.on :close do |event|
54
+ p [:close, event.code, event.reason]
55
+ @ws = nil
56
+ end
57
+ }
58
+ end
59
+
60
+ nil until @ready
61
+ end
62
+
63
+ def sub tickers
64
+ tp = tickers.map {|t| "T.#{t}"}.join ','
65
+
66
+ @ws.send('{"action":"subscribe","params": "' + tp + '"}')
67
+ end
68
+
69
+ def unsub tickers
70
+ tp = tickers.map {|t| "T.#{t}"}.join ','
71
+
72
+ @ws.send('{"action":"unsubscribe","params": "' + tp + '"}')
73
+ end
74
+
75
+ private
76
+ def on_connected
77
+ #@ws.send('{"action":"auth","params":"' + @auth + '"}')
78
+ end
79
+
80
+ def on_auth
81
+ @ready = true
82
+ #@ws.send('{"action":"subscribe","params": "T.MSFT"}')
83
+ end
84
+
85
+ def on_subscribed ticker
86
+ puts "watching #{ticker}"
87
+ # add ticker
88
+ @subs.add(ticker)
89
+ end
90
+
91
+ def on_unsubscribed ticker
92
+ puts "unwatching #{ticker}"
93
+ @subs.delete ticker
94
+ end
95
+
96
+ def on_T data
97
+ puts data.inspect
98
+ $ps.pub 'on_trade', data
99
+ end
100
+
101
+ end
102
+
103
+ #pi.run
104
+
105
+ # pi.sub ['MSFT', 'TSLA']
106
+ # sleep 2
107
+ # pi.unsub ['MSFT', 'TSLA']
108
+ # sleep 2
109
+
110
+ # puts pi.subs
111
+ #nil until false
112
+
113
+
114
+
115
+ =begin
116
+ {
117
+ "ev": "T", // Event Type
118
+ "sym": "MSFT", // Symbol Ticker
119
+ "x": 4, // Exchange ID
120
+ "i": "12345", // Trade ID
121
+ "z": 3, // Tape ( 1=A 2=B 3=C)
122
+ "p": 114.125, // Price
123
+ "s": 100, // Trade Size
124
+ "c": [0, 12], // Trade Conditions
125
+ "t": 1536036818784 // Trade Timestamp ( Unix MS )
126
+ }
127
+ =end
@@ -0,0 +1,43 @@
1
+ # Indices, Crypto, FX, and Stocks/Equities
2
+ class Ticker
3
+ DOMAIN = 'https://api.polygon.io'
4
+ BASE_URL = 'https://api.polygon.io/v1'
5
+
6
+ class<<self
7
+ def get base, path
8
+ uri = URI(base + path)
9
+
10
+ req = Net::HTTP::Get.new(uri)
11
+
12
+ res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) {|http|
13
+ http.request(req)
14
+ }
15
+
16
+ JSON.parse res.body
17
+ end
18
+
19
+ def last_trade symbol
20
+ r = get BASE_URL, "/last/stocks/#{symbol}?apiKey=#{Config.keys['POLYGON']}"
21
+ r['status'] == 'success' ? r : nil
22
+ end
23
+
24
+ def last_quote symbol
25
+ r = get BASE_URL, "/last_quote/stocks/#{symbol}?apiKey=#{Config.keys['POLYGON']}"
26
+ r['status'] == 'success' ? r : nil
27
+ end
28
+
29
+ def prev_close symbol
30
+ r = get DOMAIN, "/v2/aggs/ticker/#{symbol}/prev?apiKey=#{Config.keys['POLYGON']}"
31
+ #binding.pry
32
+ r['status'] == 'OK' ? r : nil
33
+ end
34
+
35
+ def aggregate_bars ticker, multiplier, timespan, from, to
36
+ r = get DOMAIN, "/v2/aggs/ticker/#{ticker}/range/#{multiplier}/#{timespan}/#{from}/#{to}?apiKey=#{Config.keys['POLYGON']}"
37
+ #binding.pry
38
+ r['status'] == 'OK' ? r : nil
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1 @@
1
+ VERSION = "0.1.0"
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "polygon/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "polygon-i"
7
+ spec.version = VERSION
8
+ spec.authors = ["iodevel"]
9
+ spec.email = ["cbrandt92@gmail.com"]
10
+
11
+ spec.summary = 'polygon.io interface'
12
+ #spec.description = %q{TODO: Write a longer description or delete this line.}
13
+ #spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
+
15
+ #spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
16
+
17
+ #pec.metadata["homepage_uri"] = spec.homepage
18
+ #spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
19
+ #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 2.0"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_runtime_dependency "redis"
33
+ spec.add_runtime_dependency "faye-websocket"
34
+ end
data/todo ADDED
@@ -0,0 +1 @@
1
+ remove fucking key from main.rb file in test
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: polygon-i
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - iodevel
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redis
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faye-websocket
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - cbrandt92@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - README.md
80
+ - Rakefile
81
+ - bin/console
82
+ - bin/setup
83
+ - lib/polygon.rb
84
+ - lib/polygon/cache.rb
85
+ - lib/polygon/config.rb
86
+ - lib/polygon/pub_sub.rb
87
+ - lib/polygon/socket.rb
88
+ - lib/polygon/tickers.rb
89
+ - lib/polygon/version.rb
90
+ - polygon.gemspec
91
+ - todo
92
+ homepage:
93
+ licenses: []
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubygems_version: 3.0.3
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: polygon.io interface
114
+ test_files: []