qc 0.6.5 → 0.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +7 -0
- data/Gemfile.lock +5 -1
- data/README.md +23 -4
- data/lib/qc.rb +1 -0
- data/lib/qc/cli.rb +4 -0
- data/lib/qc/command_runner.rb +69 -4
- data/lib/qc/project_settings.rb +1 -1
- data/lib/qc/tradervue_importer.rb +53 -0
- data/lib/qc/version.rb +1 -1
- data/qc.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44ffb4200efc895ee538c1a4b67ff8802db99daf
|
4
|
+
data.tar.gz: ab800cad8fb56526347d386f5a86f07dab359de1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42931cd82b9d0b590d46b0ba745f0db10f1dabb56edfd543895c18ba20275945745e99c345d53aa4ba184f5badaf2420a06ffef5818585a9884f7e6315cbc586
|
7
|
+
data.tar.gz: ccffcfaab2f6330e262a55a1c46c530ed570fb8a464ce8c33b3620e170690f67136668cd58d2219954e63f669c3f126c7c21cdc54db17000b899d4a6a6d3eac7
|
data/Changelog.md
CHANGED
@@ -10,6 +10,13 @@
|
|
10
10
|
- Wait for the backtest to finish when running `qc backtest`
|
11
11
|
- Shows summary of performance statistics after running backtest
|
12
12
|
|
13
|
+
## 6.0.6
|
14
|
+
|
15
|
+
- Better labeling for backtests. Intead of using the long id, it will use `<project folder name>-<counter>` now.
|
16
|
+
- Add support for importing trades into Tradervue
|
17
|
+
|
18
|
+
|
19
|
+
|
13
20
|
|
14
21
|
|
15
22
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
qc (0.6.
|
4
|
+
qc (0.6.6)
|
5
|
+
httparty (~> 0.15.6)
|
5
6
|
rest-client (~> 2.0.2)
|
6
7
|
vcr (~> 3.0.3)
|
7
8
|
webmock (~> 3.1.0)
|
@@ -19,10 +20,13 @@ GEM
|
|
19
20
|
hashdiff (0.3.7)
|
20
21
|
http-cookie (1.0.3)
|
21
22
|
domain_name (~> 0.5)
|
23
|
+
httparty (0.15.6)
|
24
|
+
multi_xml (>= 0.5.2)
|
22
25
|
mime-types (3.1)
|
23
26
|
mime-types-data (~> 3.2015)
|
24
27
|
mime-types-data (3.2016.0521)
|
25
28
|
minitest (5.10.3)
|
29
|
+
multi_xml (0.6.0)
|
26
30
|
netrc (0.11.0)
|
27
31
|
public_suffix (3.0.1)
|
28
32
|
rake (10.5.0)
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/jorgemanrubia/qc.svg?branch=master)](https://travis-ci.org/jorgemanrubia/qc)
|
4
4
|
|
5
|
-
Qc is a
|
5
|
+
Qc is a command line tool that lets you sync and run your [QuantConnect](https://www.quantconnect.com) backtests.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -33,7 +33,7 @@ qc --open # To open the results in QuantConnect while running the backtest
|
|
33
33
|
|
34
34
|
This is equivalent to executing `qc push`, `qc compile` and `qc backtest` in sequence.
|
35
35
|
|
36
|
-
### Single commands
|
36
|
+
### Single commands
|
37
37
|
|
38
38
|
```shell
|
39
39
|
qc [command]
|
@@ -43,7 +43,7 @@ The supported commands are:
|
|
43
43
|
|
44
44
|
| Command| Description|
|
45
45
|
| -- | -- |
|
46
|
-
| `qc login`| It will ask for the
|
46
|
+
| `qc login`| It will ask for the API credentials you can find in [your QuantConnect account page](https://www.quantconnect.com/account). They will be stored in `~/.qc`. You only need to login once. |
|
47
47
|
| `qc logout`| Logout from QuantConnect clearing the credentials stored locally. |
|
48
48
|
| `qc init`| Initialize the directory of the algo project you are working on. It will ask for a QuantConnect project to link your algo with. You need to run this once for every project you want to sync with QuantConnect. |
|
49
49
|
| `qc push` | Send your local files to QuantConnect. It will only send the files that changed since the last time you run the command |
|
@@ -60,7 +60,26 @@ qc --open
|
|
60
60
|
qc backtest --open
|
61
61
|
```
|
62
62
|
|
63
|
-
**This option only works in MacOS**. quantconnect.com currently doesn't offer an URL endpoint to open backtest results. In MacOS, it will use an Automator workflow that will open the project and show its latest results by simulating a click on the corresponding option. [See this discussion](https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/lean-engine/7AiEl3RVv38/PGnFQzBXAQAJ).
|
63
|
+
**This option only works in MacOS**. quantconnect.com currently doesn't offer an URL endpoint to open backtest results. In MacOS, it will use an Automator workflow that will open the project and show its latest results by simulating a click on the corresponding option. [See this discussion](https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/lean-engine/7AiEl3RVv38/PGnFQzBXAQAJ).
|
64
|
+
|
65
|
+
### Support for importing trades into Tradervue (experimental)
|
66
|
+
|
67
|
+
[Tradervue](https://www.tradervue.com) is a powerful trading journal system. It can be very helpful for analyzing your backtests. In addition to a ton of analytics and reporting features, it lets you see your trade executions in charts.
|
68
|
+
|
69
|
+
Qc lets you import each backtest results into tradervue. In tradervue, it will tag the executions with the backtest name.
|
70
|
+
|
71
|
+
To enable tradervue imports you must:
|
72
|
+
|
73
|
+
- Use the `--tradervue` flag when running your backtest
|
74
|
+
- Set `TRADERVUE_LOGIN` and `TRADERVUE_PASSWORD` as environment variables
|
75
|
+
|
76
|
+
For example:
|
77
|
+
|
78
|
+
```shell
|
79
|
+
TRADERVUE_LOGIN=<your tradervue login> TRADERVUE_PASSWORD=<your tradervue password> qc --tradervue
|
80
|
+
```
|
81
|
+
|
82
|
+
After running the backtest, it will open the results in tradervue automatically (only MacOS).
|
64
83
|
|
65
84
|
## Development
|
66
85
|
|
data/lib/qc.rb
CHANGED
data/lib/qc/cli.rb
CHANGED
@@ -45,6 +45,10 @@ module Qc
|
|
45
45
|
parsed_options.open_results = true
|
46
46
|
end
|
47
47
|
|
48
|
+
options.on("-t", "--tradervue", "Import the results into Tradervue. You must set env vars TRADERVUE_LOGIN and TRADERVUE_PASSWORD") do
|
49
|
+
parsed_options.import_into_tradervue = true
|
50
|
+
end
|
51
|
+
|
48
52
|
options.on("-h", "--help", "Show this message") do
|
49
53
|
puts options
|
50
54
|
exit 0
|
data/lib/qc/command_runner.rb
CHANGED
@@ -50,6 +50,7 @@ module Qc
|
|
50
50
|
|
51
51
|
def create_project_settings
|
52
52
|
Qc::ProjectSettings.new.tap do |project_settings|
|
53
|
+
project_settings.execution_count = 1
|
53
54
|
project_settings.ignored_files = DEFAULT_IGNORED_FILES
|
54
55
|
end
|
55
56
|
end
|
@@ -186,9 +187,11 @@ module Qc
|
|
186
187
|
end
|
187
188
|
|
188
189
|
def do_run_backtest
|
189
|
-
backtest = quant_connect_proxy.create_backtest project_settings.project_id, project_settings.last_compile_id,
|
190
|
-
puts "Backtest for compile #{project_settings.last_compile_id} sent to the queue with id #{backtest.id}"
|
190
|
+
backtest = quant_connect_proxy.create_backtest project_settings.project_id, project_settings.last_compile_id, current_backtest_label
|
191
|
+
puts "Backtest '#{current_backtest_label}' for compile #{project_settings.last_compile_id} sent to the queue with id #{backtest.id}"
|
192
|
+
|
191
193
|
open_results_in_quant_connect if options.open_results
|
194
|
+
|
192
195
|
puts "Waiting for backtest to start..."
|
193
196
|
last_completed_percentage = nil
|
194
197
|
begin
|
@@ -200,12 +203,30 @@ module Qc
|
|
200
203
|
sleep BACKTEST_DELAY_IN_SECONDS unless backtest.completed?
|
201
204
|
end while !backtest.completed?
|
202
205
|
|
203
|
-
show_backtest_results
|
206
|
+
show_backtest_results backtest
|
207
|
+
update_project_settings_after_running_backtest(backtest)
|
208
|
+
import_backtest_results_into_tradervue(backtest) if options.import_into_tradervue
|
204
209
|
|
210
|
+
backtest.success?
|
211
|
+
end
|
212
|
+
|
213
|
+
def update_project_settings_after_running_backtest(backtest)
|
205
214
|
project_settings.last_backtest_id = backtest.id
|
215
|
+
increase_execution_count
|
206
216
|
save_project_settings
|
217
|
+
end
|
207
218
|
|
208
|
-
|
219
|
+
def increase_execution_count
|
220
|
+
project_settings.execution_count ||= 0
|
221
|
+
project_settings.execution_count += 1
|
222
|
+
end
|
223
|
+
|
224
|
+
def current_backtest_label
|
225
|
+
@current_backtest_label ||= "#{project_name}-#{project_settings.execution_count}"
|
226
|
+
end
|
227
|
+
|
228
|
+
def project_name
|
229
|
+
@project_name ||= ::File.basename(::File.expand_path(::File.join(Util.project_dir, '..')))
|
209
230
|
end
|
210
231
|
|
211
232
|
def show_backtest_results(backtest)
|
@@ -316,5 +337,49 @@ module Qc
|
|
316
337
|
def initialized_project?
|
317
338
|
project_settings.project_id
|
318
339
|
end
|
340
|
+
|
341
|
+
def import_backtest_results_into_tradervue(backtest)
|
342
|
+
show_title 'Importing results into Tradervue'
|
343
|
+
|
344
|
+
raise "You need to set TRADERVUE_LOGIN and TRADERVUE_PASSWORD" unless tradervue_login && tradervue_password
|
345
|
+
orders = backtest.result['Orders'].values
|
346
|
+
orders_as_tradervue_executions = orders.collect do |order|
|
347
|
+
{
|
348
|
+
"datetime" => order['Time'],
|
349
|
+
"symbol" => order['Symbol']['Value'],
|
350
|
+
"quantity" => order['Quantity'],
|
351
|
+
"price" => order['Price'],
|
352
|
+
"option" => '',
|
353
|
+
"commission" => '',
|
354
|
+
"transfee" => 0,
|
355
|
+
"ecnfee" => 0
|
356
|
+
}
|
357
|
+
end
|
358
|
+
|
359
|
+
result = tradervue_importer.import_data(orders_as_tradervue_executions, account_tag: current_backtest_label)
|
360
|
+
puts result
|
361
|
+
puts "#{orders_as_tradervue_executions.length} orders imported successfully"
|
362
|
+
open_results_in_tradervue(backtest)
|
363
|
+
end
|
364
|
+
|
365
|
+
def open_results_in_tradervue(backtest)
|
366
|
+
return false unless validate_on_mac!
|
367
|
+
|
368
|
+
url = "https://www.tradervue.com/trades?tag=#{current_backtest_label}"
|
369
|
+
puts "Opening results in tradervue: #{url}"
|
370
|
+
system "open #{url}"
|
371
|
+
end
|
372
|
+
|
373
|
+
def tradervue_importer
|
374
|
+
@tradervue_importer ||= TradervueImporter.new(tradervue_login, tradervue_password)
|
375
|
+
end
|
376
|
+
|
377
|
+
def tradervue_password
|
378
|
+
ENV['TRADERVUE_PASSWORD']
|
379
|
+
end
|
380
|
+
|
381
|
+
def tradervue_login
|
382
|
+
ENV['TRADERVUE_LOGIN']
|
383
|
+
end
|
319
384
|
end
|
320
385
|
end
|
data/lib/qc/project_settings.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Qc
|
2
|
-
class ProjectSettings< Struct.new(:project_id, :file_extensions, :last_sync_at, :last_compile_id, :last_backtest_id, :ignored_files)
|
2
|
+
class ProjectSettings< Struct.new(:project_id, :file_extensions, :last_sync_at, :last_compile_id, :last_backtest_id, :ignored_files, :name, :execution_count)
|
3
3
|
|
4
4
|
end
|
5
5
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Extracted from https://github.com/tradervue/ruby-sample
|
2
|
+
class TradervueImporter
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
base_uri("https://www.tradervue.com/api/v1")
|
6
|
+
|
7
|
+
def initialize(username, password)
|
8
|
+
@auth = { :username => username, :password => password }
|
9
|
+
@user_agent = "Qc - QuantConnect command line tool (https://github.com/jorgemanrubia/qc)"
|
10
|
+
end
|
11
|
+
|
12
|
+
def status
|
13
|
+
opts = {}
|
14
|
+
opts[:headers] = { "User-Agent" => @user_agent }
|
15
|
+
opts[:basic_auth] = @auth
|
16
|
+
resp = self.class.get("/imports", opts)
|
17
|
+
puts resp
|
18
|
+
if resp.code == 401
|
19
|
+
return "access denied"
|
20
|
+
end
|
21
|
+
|
22
|
+
# status details about the last import in resp["info"]
|
23
|
+
|
24
|
+
resp["status"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def import_data(execs, tags: [], account_tag: nil)
|
28
|
+
req = {
|
29
|
+
:allow_duplicates => false,
|
30
|
+
:overlay_commissions => false,
|
31
|
+
:account_tag => account_tag,
|
32
|
+
:tags => tags,
|
33
|
+
:executions => execs
|
34
|
+
}
|
35
|
+
|
36
|
+
opts = {}
|
37
|
+
opts[:headers] = { "User-Agent" => @user_agent }
|
38
|
+
opts[:basic_auth] = @auth
|
39
|
+
opts[:body] = req
|
40
|
+
resp = self.class.post("/imports", opts)
|
41
|
+
|
42
|
+
if resp.code == 401
|
43
|
+
return "access denied"
|
44
|
+
end
|
45
|
+
|
46
|
+
if resp.code == 200
|
47
|
+
resp["status"]
|
48
|
+
else
|
49
|
+
resp["error"]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/qc/version.rb
CHANGED
data/qc.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_runtime_dependency "rest-client", "~> 2.0.2"
|
24
24
|
spec.add_runtime_dependency "vcr", "~> 3.0.3"
|
25
25
|
spec.add_runtime_dependency "webmock", "~> 3.1.0"
|
26
|
+
spec.add_runtime_dependency "httparty", "~> 0.15.6"
|
26
27
|
spec.add_development_dependency "awesome_print"
|
27
28
|
spec.add_development_dependency "bundler", "~> 1.15"
|
28
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jorge Manrubia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.1.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: httparty
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.15.6
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.15.6
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: awesome_print
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,6 +155,7 @@ files:
|
|
141
155
|
- lib/qc/project.rb
|
142
156
|
- lib/qc/project_settings.rb
|
143
157
|
- lib/qc/quant_connect_proxy.rb
|
158
|
+
- lib/qc/tradervue_importer.rb
|
144
159
|
- lib/qc/util.rb
|
145
160
|
- lib/qc/version.rb
|
146
161
|
- qc.gemspec
|