delta_exchange 0.1.2
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 +7 -0
- data/.cursor/.gitignore +1 -0
- data/CHANGELOG.md +11 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +253 -0
- data/Rakefile +12 -0
- data/docs/AUTHENTICATION.md +49 -0
- data/docs/GETTING_STARTED.md +67 -0
- data/docs/RAILS_INTEGRATION.md +135 -0
- data/docs/REST_API_GUIDE.md +150 -0
- data/docs/STANDALONE_RUBY_GUIDE.md +73 -0
- data/docs/WEBSOCKET_GUIDE.md +160 -0
- data/exe/delta_exchange +4 -0
- data/lib/delta_exchange/auth.rb +12 -0
- data/lib/delta_exchange/client.rb +196 -0
- data/lib/delta_exchange/configuration.rb +40 -0
- data/lib/delta_exchange/constants.rb +72 -0
- data/lib/delta_exchange/contracts/order_contract.rb +24 -0
- data/lib/delta_exchange/contracts/position_contract.rb +21 -0
- data/lib/delta_exchange/contracts/wallet_transfer_contract.rb +16 -0
- data/lib/delta_exchange/core/base_model.rb +54 -0
- data/lib/delta_exchange/core/error_handler.rb +16 -0
- data/lib/delta_exchange/error.rb +37 -0
- data/lib/delta_exchange/helpers/attribute_helper.rb +22 -0
- data/lib/delta_exchange/helpers/validation_helper.rb +34 -0
- data/lib/delta_exchange/models/asset.rb +23 -0
- data/lib/delta_exchange/models/fee_tier.rb +19 -0
- data/lib/delta_exchange/models/fill.rb +20 -0
- data/lib/delta_exchange/models/funding_rate.rb +19 -0
- data/lib/delta_exchange/models/index.rb +23 -0
- data/lib/delta_exchange/models/open_interest.rb +19 -0
- data/lib/delta_exchange/models/order.rb +34 -0
- data/lib/delta_exchange/models/position.rb +43 -0
- data/lib/delta_exchange/models/product.rb +43 -0
- data/lib/delta_exchange/models/profile.rb +20 -0
- data/lib/delta_exchange/models/ticker.rb +26 -0
- data/lib/delta_exchange/models/trading_preferences.rb +27 -0
- data/lib/delta_exchange/models/wallet_balance.rb +23 -0
- data/lib/delta_exchange/models/wallet_transaction.rb +20 -0
- data/lib/delta_exchange/resources/account.rb +53 -0
- data/lib/delta_exchange/resources/assets.rb +11 -0
- data/lib/delta_exchange/resources/base.rb +37 -0
- data/lib/delta_exchange/resources/fills.rb +15 -0
- data/lib/delta_exchange/resources/heartbeat.rb +20 -0
- data/lib/delta_exchange/resources/indices.rb +11 -0
- data/lib/delta_exchange/resources/market_data.rb +56 -0
- data/lib/delta_exchange/resources/orders.rb +76 -0
- data/lib/delta_exchange/resources/positions.rb +47 -0
- data/lib/delta_exchange/resources/products.rb +39 -0
- data/lib/delta_exchange/resources/wallet.rb +45 -0
- data/lib/delta_exchange/version.rb +5 -0
- data/lib/delta_exchange/websocket/client.rb +55 -0
- data/lib/delta_exchange/websocket/connection.rb +114 -0
- data/lib/delta_exchange.rb +39 -0
- data/sig/delta_exchange.rbs +4 -0
- metadata +231 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7e237fcff01ceb49340e97b9488881c8db98854360a69d44f809bb7eb2714dac
|
|
4
|
+
data.tar.gz: 10f2351163211453f02454f6d1b22d53dbea71d6ec4e3b26de7479720438ac1b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 28e3ed680eaa5d5f88cfb715eb3f4288b9b71657801a0237c608d1bbb307a89b1c8610d5e8a3fe2cfe407237edd1d39a79a1758f36518fb475c324ee17ee6047
|
|
7
|
+
data.tar.gz: bb3e23553b102c42264682ff961ca427179fc39d8e1302020e94a352c71380a87f1aed032cfab5f0aa9b8eae9bcc8e61dc117aed5a965a050062846cd75eaad8
|
data/.cursor/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
plans/
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
## [0.1.2] - 2026-03-25
|
|
4
|
+
### Changed
|
|
5
|
+
- Refactored `Models` namespace wrapper classes to invoke resource dependencies through a global lazy `DeltaExchange.client` factory, enforcing Dependency Injection boundaries natively and patching `ArgumentError` crashes.
|
|
6
|
+
- Hardened WebSockets `Faye` bindings and stabilized internal EventMachine reactor loops bridging payload sockets directly over Testnet domain gateways.
|
|
7
|
+
- Expanded core client capabilities utilizing dynamic `set_leverage` modifiers, VCR-tested Dry-Validation wrappers, and exhaustive test coverage matrices shielding internal `raise ApiError` resolutions.
|
|
8
|
+
|
|
9
|
+
## [0.1.1] - 2026-03-21
|
|
10
|
+
|
|
11
|
+
- Initial release
|
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
"delta_exchange" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
|
+
|
|
5
|
+
* Participants will be tolerant of opposing views.
|
|
6
|
+
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
|
7
|
+
* When interpreting the words and actions of others, participants should always assume good intentions.
|
|
8
|
+
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
|
9
|
+
|
|
10
|
+
If you have any concerns about behaviour within this project, please contact us at ["shubhamtaywade82@gmail.com"](mailto:"shubhamtaywade82@gmail.com").
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shubham Taywade
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# DeltaExchange
|
|
2
|
+
|
|
3
|
+
A Ruby client for the Delta Exchange API.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Quick Links
|
|
9
|
+
|
|
10
|
+
| Resource | Document | Description |
|
|
11
|
+
|----------|----------|-------------|
|
|
12
|
+
| **Orders** | [REST API Guide](docs/REST_API_GUIDE.md#orders) | Create, manage, and cancel orders |
|
|
13
|
+
| **Products** | [REST API Guide](docs/REST_API_GUIDE.md#products) | Fetch trading pairs and market specs |
|
|
14
|
+
| **WebSocket** | [WebSocket Guide](docs/WEBSOCKET_GUIDE.md) | Real-time data streams |
|
|
15
|
+
| **Auth** | [Authentication](docs/AUTHENTICATION.md) | API Key & Signature management |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Add this line to your application's Gemfile:
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
gem 'delta_exchange'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
And then execute:
|
|
28
|
+
|
|
29
|
+
$ bundle install
|
|
30
|
+
|
|
31
|
+
Or install it yourself as:
|
|
32
|
+
|
|
33
|
+
$ gem install delta_exchange
|
|
34
|
+
|
|
35
|
+
## Releasing
|
|
36
|
+
|
|
37
|
+
Publishing is handled by GitHub Actions when a version tag is pushed.
|
|
38
|
+
|
|
39
|
+
### One-time RubyGems setup
|
|
40
|
+
|
|
41
|
+
Configure `delta_exchange` as a trusted publisher on RubyGems.org:
|
|
42
|
+
|
|
43
|
+
1. Open the gem page on RubyGems.org and manage trusted publishers.
|
|
44
|
+
2. Add this GitHub repository:
|
|
45
|
+
- Owner: `shubhamtaywade82`
|
|
46
|
+
- Repository: `delta_exchange`
|
|
47
|
+
- Workflow file: `release.yml`
|
|
48
|
+
- Environment: `release`
|
|
49
|
+
3. Save the publisher configuration.
|
|
50
|
+
|
|
51
|
+
This uses GitHub OIDC trusted publishing, so the workflow does not need a long-lived `RUBYGEMS_API_KEY` or OTP secret. RubyGems must match all four values exactly.
|
|
52
|
+
|
|
53
|
+
### Release a new version
|
|
54
|
+
|
|
55
|
+
1. Update `lib/delta_exchange/version.rb`.
|
|
56
|
+
2. Update `CHANGELOG.md`.
|
|
57
|
+
3. Merge the changes to `main`.
|
|
58
|
+
4. Create and push a matching tag:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git tag v0.1.2
|
|
62
|
+
git push origin v0.1.2
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The release workflow validates that the tag matches `DeltaExchange::VERSION` before publishing the gem to RubyGems.org.
|
|
66
|
+
|
|
67
|
+
## Documentation
|
|
68
|
+
|
|
69
|
+
For detailed guides and examples, see:
|
|
70
|
+
|
|
71
|
+
* [Getting Started](docs/GETTING_STARTED.md)
|
|
72
|
+
* [Authentication Guide](docs/AUTHENTICATION.md)
|
|
73
|
+
* [REST API Guide](docs/REST_API_GUIDE.md)
|
|
74
|
+
* [WebSocket Guide](docs/WEBSOCKET_GUIDE.md)
|
|
75
|
+
* [Rails Integration](docs/RAILS_INTEGRATION.md)
|
|
76
|
+
* [Standalone Ruby Guide](docs/STANDALONE_RUBY_GUIDE.md)
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
### Configuration
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
DeltaExchange.configure do |config|
|
|
84
|
+
config.api_key = ENV['DELTA_API_KEY'] || 'YOUR_API_KEY'
|
|
85
|
+
config.api_secret = ENV['DELTA_API_SECRET'] || 'YOUR_API_SECRET'
|
|
86
|
+
config.testnet = true # Optional, defaults to false
|
|
87
|
+
config.websocket_reconnect_delay = 5 # Optional, defaults to 5 seconds
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Note:** If you are testing the client via `./bin/console`, it will automatically load any variables from a `.env` file in the root directory into `ENV`.
|
|
92
|
+
|
|
93
|
+
### REST API
|
|
94
|
+
|
|
95
|
+
The client employs a highly robust **ActiveRecord**-style abstraction via the `DeltaExchange::Models::` namespace. Rather than interacting with raw unstructured JSON payloads via `Client.new`, you query the platform utilizing structured properties and class-level queries.
|
|
96
|
+
|
|
97
|
+
#### 1. Products & Market Data
|
|
98
|
+
Retrieve available trading pairs, orderbooks, and option chains natively.
|
|
99
|
+
```ruby
|
|
100
|
+
# Get all products (returns array of Models::Product)
|
|
101
|
+
DeltaExchange::Models::Product.all
|
|
102
|
+
|
|
103
|
+
product = DeltaExchange::Models::Product.find('BTCUSD')
|
|
104
|
+
puts product.contract_type # "perpetual_futures"
|
|
105
|
+
|
|
106
|
+
# Get all live tickers and access price via .close (India API standard)
|
|
107
|
+
ticker = DeltaExchange::Models::Ticker.find('BTCUSD')
|
|
108
|
+
puts "Current Price: #{ticker.close}"
|
|
109
|
+
|
|
110
|
+
# Get all live tickers
|
|
111
|
+
DeltaExchange::Models::Ticker.all
|
|
112
|
+
|
|
113
|
+
# Mutating methods like set_leverage return the raw API response hash
|
|
114
|
+
response = product.set_leverage(50)
|
|
115
|
+
puts "New Leverage: #{response[:leverage]}"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### 2. Orders
|
|
119
|
+
Create, manage, and cancel your active orders.
|
|
120
|
+
```ruby
|
|
121
|
+
# Create a new order (Returns a Models::Order)
|
|
122
|
+
order = DeltaExchange::Models::Order.create({
|
|
123
|
+
product_id: 1,
|
|
124
|
+
size: 10,
|
|
125
|
+
side: 'buy',
|
|
126
|
+
order_type: 'limit_order',
|
|
127
|
+
limit_price: '50000'
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
# Access properties
|
|
131
|
+
puts order.status # "open"
|
|
132
|
+
|
|
133
|
+
# List your active orders
|
|
134
|
+
DeltaExchange::Models::Order.all
|
|
135
|
+
|
|
136
|
+
# Cancel the order directly from its instance
|
|
137
|
+
order.cancel
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### 3. Positions & Fills
|
|
141
|
+
Track open derivatives positions and execution histories cleanly.
|
|
142
|
+
|
|
143
|
+
You can instantly execute commands atop the models natively using class methods. This bypasses structural scaffolding because the library manages connections globally by default!
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
# Retrieve Native Ruby Objects instead of messy Array Hashes
|
|
147
|
+
orders = DeltaExchange::Models::Order.all
|
|
148
|
+
|
|
149
|
+
# Manipulate endpoints using direct class directives
|
|
150
|
+
DeltaExchange::Models::Position.close_all(
|
|
151
|
+
product_id: 27 # BTCUSD testnet
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Find an isolated position by Product ID
|
|
155
|
+
position = DeltaExchange::Models::Position.find(1)
|
|
156
|
+
|
|
157
|
+
# Modify your isolated positions natively
|
|
158
|
+
position.adjust_margin('150.5', type: 'add')
|
|
159
|
+
position.set_auto_topup(true)
|
|
160
|
+
|
|
161
|
+
# Retrieve recent trade fills (Returns an array of Models::Fill)
|
|
162
|
+
DeltaExchange::Models::Fill.all(product_id: 1, limit: 50)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### 4. Account & Wallet
|
|
166
|
+
Monitor balances and configure account-level preferences.
|
|
167
|
+
```ruby
|
|
168
|
+
# Get wallet balances across all assets
|
|
169
|
+
DeltaExchange::Models::WalletBalance.all
|
|
170
|
+
|
|
171
|
+
# Isolate a specific currency balance
|
|
172
|
+
btc_balance = DeltaExchange::Models::WalletBalance.find_by_asset('BTC')
|
|
173
|
+
|
|
174
|
+
# List recent wallet transactions
|
|
175
|
+
DeltaExchange::Models::WalletTransaction.all
|
|
176
|
+
|
|
177
|
+
# View your user profile details
|
|
178
|
+
profile = DeltaExchange::Models::Profile.fetch
|
|
179
|
+
puts "Hello #{profile.first_name}!"
|
|
180
|
+
|
|
181
|
+
# Update trading preferences natively
|
|
182
|
+
prefs = DeltaExchange::Models::TradingPreferences.fetch
|
|
183
|
+
puts "User ID: #{prefs.user_id}"
|
|
184
|
+
prefs.update(cancel_on_disconnect: true)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### 5. Assets & Indices
|
|
188
|
+
Pull infrastructure parameters mapping indices to component assets.
|
|
189
|
+
```ruby
|
|
190
|
+
# Get all platform assets
|
|
191
|
+
DeltaExchange::Models::Asset.all
|
|
192
|
+
|
|
193
|
+
# Get all tracked indices
|
|
194
|
+
DeltaExchange::Models::Index.all
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Error Handling
|
|
198
|
+
|
|
199
|
+
The gem wraps network and API responses within native Ruby classes.
|
|
200
|
+
|
|
201
|
+
```ruby
|
|
202
|
+
begin
|
|
203
|
+
client.orders.create({ product_id: 999999, size: 10 })
|
|
204
|
+
rescue DeltaExchange::RateLimitError => e
|
|
205
|
+
puts "Rate limited! Retry after #{e.retry_after_seconds} seconds"
|
|
206
|
+
rescue DeltaExchange::ApiError => e
|
|
207
|
+
puts "API rejected the request: #{e.message} (Code: #{e.code})"
|
|
208
|
+
rescue DeltaExchange::NetworkError => e
|
|
209
|
+
puts "Could not connect: #{e.message}"
|
|
210
|
+
end
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### WebSocket
|
|
214
|
+
|
|
215
|
+
> [!IMPORTANT]
|
|
216
|
+
> The WebSocket client uses EventMachine in a detached thread. While the gem handles automatic reconnections, you must ensure your main process remains alive (e.g., via `loop { sleep 1 }` or joining the EM thread).
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
ws = DeltaExchange::Websocket::Client.new
|
|
220
|
+
|
|
221
|
+
ws.on :open do |event|
|
|
222
|
+
puts "Connected!"
|
|
223
|
+
ws.subscribe([
|
|
224
|
+
{ name: "v2/ticker", symbols: ["BTCUSD"] }
|
|
225
|
+
])
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
ws.on :message do |data|
|
|
229
|
+
puts "Received: #{data}"
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
ws.connect!
|
|
233
|
+
|
|
234
|
+
# Keep the main thread alive if necessary
|
|
235
|
+
loop { sleep 1 }
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Debugging
|
|
239
|
+
|
|
240
|
+
You can enable HTTP traffic logging via the command-line environment variables.
|
|
241
|
+
The `api-key` and `signature` headers are **automatically redacted** during debug rendering to protect your credentials.
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
DELTA_DEBUG=true ruby app.rb
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Contributing
|
|
248
|
+
|
|
249
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/shubhamtaywade82/delta_exchange.
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Authentication Details
|
|
2
|
+
|
|
3
|
+
DeltaExchange v2 uses a signature-based authentication method (HMAC-SHA256).
|
|
4
|
+
|
|
5
|
+
## Credentials Needed
|
|
6
|
+
|
|
7
|
+
1. **API Key**: A unique key provided by Delta Exchange.
|
|
8
|
+
2. **API Secret**: Used to sign requests (never share this!).
|
|
9
|
+
|
|
10
|
+
## Configuration Methods
|
|
11
|
+
|
|
12
|
+
### Block-style (Recommended for Initializers)
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
DeltaExchange.configure do |config|
|
|
16
|
+
config.api_key = ENV['DELTA_API_KEY']
|
|
17
|
+
config.api_secret = ENV['DELTA_API_SECRET']
|
|
18
|
+
config.testnet = true # Set to false for production
|
|
19
|
+
end
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Direct Initialization
|
|
23
|
+
|
|
24
|
+
You can also pass credentials directly when creating a client:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
client = DeltaExchange::Client.new(
|
|
28
|
+
api_key: 'custom_key',
|
|
29
|
+
api_secret: 'custom_secret',
|
|
30
|
+
testnet: false
|
|
31
|
+
)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Security Best Practices
|
|
35
|
+
|
|
36
|
+
* **Environment Variables**: Never hardcode your API keys in the source code. Use gems like `dotenv` or Rails Credentials.
|
|
37
|
+
* **IP Whitelisting**: For production, it is highly recommended to whitelist your server's IP in your Delta Exchange API settings.
|
|
38
|
+
* **Permissions**: Only enable the permissions your bot needs (e.g., "Read" and "Trade"). Avoid "Withdrawal" permissions unless necessary.
|
|
39
|
+
|
|
40
|
+
## How the Gem Signs Requests
|
|
41
|
+
|
|
42
|
+
The gem handles signature generation automatically for every authenticated request. The pre-hash string follows the format:
|
|
43
|
+
`method + timestamp + path + query_string + payload`
|
|
44
|
+
|
|
45
|
+
Example internal logic:
|
|
46
|
+
```ruby
|
|
47
|
+
signature = OpenSSL::HMAC.hexdigest("SHA256", secret, prehash_string)
|
|
48
|
+
```
|
|
49
|
+
This is fully encapsulated in the `DeltaExchange::Auth` module.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Getting Started with DeltaExchange
|
|
2
|
+
|
|
3
|
+
DeltaExchange is a powerful Ruby gem designed for algorithmic trading on the Delta Exchange India platform. It provides a clean, model-based interface for REST API v2 and a real-time WebSocket client.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'delta_exchange'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Basic Configuration
|
|
20
|
+
|
|
21
|
+
The gem needs to be configured with your API credentials. You can do this in an initializer (for Rails) or at the top of your script.
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
require 'delta_exchange'
|
|
25
|
+
|
|
26
|
+
DeltaExchange.configure do |config|
|
|
27
|
+
config.api_key = 'YOUR_API_KEY'
|
|
28
|
+
config.api_secret = 'YOUR_API_SECRET'
|
|
29
|
+
config.testnet = true # Use Delta Testnet for testing
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start Example
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
# 1. Initialize the client
|
|
37
|
+
client = DeltaExchange::Client.new
|
|
38
|
+
|
|
39
|
+
# 2. Fetch all products
|
|
40
|
+
products = client.products.all
|
|
41
|
+
|
|
42
|
+
# 3. Find a specific product (e.g., BTCUSD perpetual)
|
|
43
|
+
btc_perp = products.find { |p| p[:symbol] == 'BTCUSD' }
|
|
44
|
+
puts "Trading #{btc_perp[:symbol]} with ID: #{btc_perp[:id]}"
|
|
45
|
+
|
|
46
|
+
# 4. Check your balance
|
|
47
|
+
balances = client.wallet.balances
|
|
48
|
+
puts "Available USDT: #{balances.find { |b| b[:asset_symbol] == 'USDT' }[:available_balance]}"
|
|
49
|
+
|
|
50
|
+
# 5. Place a limit order
|
|
51
|
+
order = client.orders.create(
|
|
52
|
+
product_id: btc_perp[:id],
|
|
53
|
+
size: 10,
|
|
54
|
+
side: 'buy',
|
|
55
|
+
order_type: 'limit_order',
|
|
56
|
+
limit_price: '50000.0'
|
|
57
|
+
)
|
|
58
|
+
puts "Order placed! ID: #{order[:id]}"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Next Steps
|
|
62
|
+
|
|
63
|
+
* [Authentication Details](./AUTHENTICATION.md)
|
|
64
|
+
* [REST API Guide](./REST_API_GUIDE.md)
|
|
65
|
+
* [WebSocket Guide](./WEBSOCKET_GUIDE.md)
|
|
66
|
+
* [Rails Integration](./RAILS_INTEGRATION.md)
|
|
67
|
+
* [Standalone Ruby Guide](./STANDALONE_RUBY_GUIDE.md)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Rails Integration Guide
|
|
2
|
+
|
|
3
|
+
Integrating the DeltaExchange gem into a Rails application is simple.
|
|
4
|
+
|
|
5
|
+
## Step 1: Add the Gem
|
|
6
|
+
|
|
7
|
+
Add the gem to your `Gemfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'delta_exchange'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Step 2: Configure with Initializer
|
|
20
|
+
|
|
21
|
+
Create `config/initializers/delta_exchange.rb`:
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
# frozen_string_literal: true
|
|
25
|
+
|
|
26
|
+
DeltaExchange.configure do |config|
|
|
27
|
+
config.api_key = Rails.application.credentials.dig(:delta, :api_key)
|
|
28
|
+
config.api_secret = Rails.application.credentials.dig(:delta, :api_secret)
|
|
29
|
+
config.testnet = Rails.env.development? || Rails.env.test?
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Step 3: Use in Models or Services
|
|
34
|
+
|
|
35
|
+
For best practices, wrap the client in a service class:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
# app/services/trading_service.rb
|
|
39
|
+
class TradingService
|
|
40
|
+
def initialize
|
|
41
|
+
@client = DeltaExchange::Client.new
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def place_btc_limit_order(price, size)
|
|
45
|
+
@client.orders.create(
|
|
46
|
+
product_id: 1, # BTCUSD
|
|
47
|
+
size: size,
|
|
48
|
+
side: 'buy',
|
|
49
|
+
order_type: 'limit_order',
|
|
50
|
+
limit_price: price.to_s
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Step 4: Background Jobs for WebSocket
|
|
57
|
+
|
|
58
|
+
Since WebSockets need a persistent connection, it's best to run them in a separate process. You can use a custom rake task or a background job (like Sidekiq) to manage the stream.
|
|
59
|
+
|
|
60
|
+
**Example Rake Task (`lib/tasks/trading.rake`):**
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
namespace :trading do
|
|
64
|
+
desc "Start the Delta Exchange WebSocket stream"
|
|
65
|
+
task stream: :environment do
|
|
66
|
+
ws = DeltaExchange::Websocket::Client.new
|
|
67
|
+
|
|
68
|
+
ws.on :message do |data|
|
|
69
|
+
# Handle live updates and maybe update your database
|
|
70
|
+
if data['type'] == 'v2/ticker'
|
|
71
|
+
MarketPrice.update_price(data['symbol'], data['last_price'])
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
ws.on :open do
|
|
76
|
+
puts "Market stream active..."
|
|
77
|
+
ws.subscribe([{ name: "v2/ticker", symbols: ["BTCUSD"] }])
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
ws.connect!
|
|
81
|
+
|
|
82
|
+
# Keep the task alive
|
|
83
|
+
loop { sleep 1 }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Step 5: Real-time UI with ActionCable
|
|
89
|
+
|
|
90
|
+
You can broadcast the incoming WebSocket data from the Rake task to your frontend using Rails ActionCable:
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
# inside the rake task's :message block
|
|
94
|
+
ActionCable.server.broadcast('price_channel', { symbol: data['symbol'], price: data['last_price'] })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Step 6: Caching Real-time Data (Redis/Rails Cache)
|
|
98
|
+
|
|
99
|
+
For high-frequency data like LTP (Last Traded Price), you typically want to store the latest value in a fast cache so that your controllers, models, or other background jobs can access it instantly without hitting the database.
|
|
100
|
+
|
|
101
|
+
### Using Rails.cache
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
# inside the rake task's :message block
|
|
105
|
+
if data['type'] == 'v2/ticker'
|
|
106
|
+
Rails.cache.write("ltp:#{data['symbol']}", data['last_price'])
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# accessing it anywhere else in Rails
|
|
110
|
+
ltp = Rails.cache.read("ltp:BTCUSD")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Using Redis Directly (Recommended for Performance)
|
|
114
|
+
|
|
115
|
+
If you have a dedicated Redis instance for market data:
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
# inside the rake task's :message block
|
|
119
|
+
$redis.hset("delta:ltp", data['symbol'], data['last_price'])
|
|
120
|
+
|
|
121
|
+
# accessing it elsewhere
|
|
122
|
+
ltp = $redis.hget("delta:ltp", "BTCUSD")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Pattern: Fetcher Helper
|
|
126
|
+
|
|
127
|
+
It's common to create a helper in your `MarketPrice` model or a specific service:
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
class MarketPrice
|
|
131
|
+
def self.ltp(symbol)
|
|
132
|
+
Rails.cache.read("ltp:#{symbol}") || DeltaExchange::Models::Ticker.find(symbol)&.last_price
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
```
|