Compare commits
173 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69d2f5ae82 | ||
|
|
2d7e3297a6 | ||
|
|
57adac59ee | ||
|
|
d57f75ade2 | ||
|
|
bbb72b771c | ||
|
|
1b4613bc75 | ||
|
|
e994562d60 | ||
|
|
057f0b4d9e | ||
|
|
e6f2776fcf | ||
|
|
87a65451ea | ||
|
|
d00ef1c181 | ||
|
|
2e1f28d20d | ||
|
|
d68a41ba73 | ||
|
|
09ca345ae8 | ||
|
|
49265bd773 | ||
|
|
07003af6d5 | ||
|
|
5f8d76f6dd | ||
|
|
bcc53eff3b | ||
|
|
bca9ada795 | ||
|
|
5cba110b64 | ||
|
|
88b32b8352 | ||
|
|
fef5c8e9c8 | ||
|
|
867b7e8eb6 | ||
|
|
f9d84a6893 | ||
|
|
bd144e021d | ||
|
|
1a852d2d45 | ||
|
|
99dc63a08d | ||
|
|
f59fedc042 | ||
|
|
5596295774 | ||
|
|
fabf1191b7 | ||
|
|
9be02d7fa5 | ||
|
|
55c995e13f | ||
|
|
1d169a19ce | ||
|
|
956ffdfa9c | ||
|
|
0b6255c1fc | ||
|
|
6415de83cf | ||
|
|
e38f3f3aaf | ||
|
|
40e887a106 | ||
|
|
8149c291fc | ||
|
|
de9f9bf309 | ||
|
|
077b6e41d8 | ||
|
|
37d0c42149 | ||
|
|
ac1365cd7c | ||
|
|
c3530a6a7f | ||
|
|
7318c6fc7c | ||
|
|
2e0c3a03a5 | ||
|
|
824a754f81 | ||
|
|
1000669975 | ||
|
|
24a1fbba60 | ||
|
|
25d53fe6ff | ||
|
|
cad5f20a3d | ||
|
|
c5c56bf98e | ||
|
|
9b35411f45 | ||
|
|
2fe7f5b457 | ||
|
|
64f848a7b1 | ||
|
|
0937d08aa8 | ||
|
|
8330dd939e | ||
|
|
1ef66a1083 | ||
|
|
0fccf6017d | ||
|
|
41f9d1bd3a | ||
|
|
c35d6ee194 | ||
|
|
1cb8fcf2d9 | ||
|
|
58b7a9d22a | ||
|
|
2d4ca75670 | ||
|
|
cda769df74 | ||
|
|
5accfd6be3 | ||
|
|
265fd8b3b9 | ||
|
|
d633fed3ff | ||
|
|
f689826051 | ||
|
|
af7a2cfc85 | ||
|
|
6982f6713b | ||
|
|
50f887ca64 | ||
|
|
f08eda3bac | ||
|
|
8ad1016710 | ||
|
|
8937995ee4 | ||
|
|
ca7f7710e7 | ||
|
|
0b1b72e921 | ||
|
|
c44819617f | ||
|
|
3569a1f8d0 | ||
|
|
d71dd86ff5 | ||
|
|
96410b57a0 | ||
|
|
f17726b890 | ||
|
|
7ee297ab77 | ||
|
|
94fd3c8f64 | ||
|
|
50a8de5f67 | ||
|
|
af2043d7d3 | ||
|
|
57ce6958dd | ||
|
|
75d8e710d1 | ||
|
|
f75ea380e7 | ||
|
|
f3ea223f2a | ||
|
|
fb49f5da70 | ||
|
|
0cda5c7f0d | ||
|
|
9175b862d0 | ||
|
|
eca4f5b7f2 | ||
|
|
2bdddc94b4 | ||
|
|
12930c444b | ||
|
|
2ec979940c | ||
|
|
edd1aea8b0 | ||
|
|
be4a34c7e4 | ||
|
|
3b559a5f3f | ||
|
|
d4fd936772 | ||
|
|
a0328426d9 | ||
|
|
890a19c871 | ||
|
|
5359561b9d | ||
|
|
a8592e08b5 | ||
|
|
fcb4ce637d | ||
|
|
ec428c5f6c | ||
|
|
2a62f16833 | ||
|
|
f1c50e41a5 | ||
|
|
7445f7ec5a | ||
|
|
8febb9ac45 | ||
|
|
463044b64a | ||
|
|
9865ce9815 | ||
|
|
81d7774c80 | ||
|
|
22e04913a5 | ||
|
|
8e5893b708 | ||
|
|
99558928f0 | ||
|
|
a2efee8be9 | ||
|
|
a1d0b6cde2 | ||
|
|
8123e76e3c | ||
|
|
a28d1f2ffe | ||
|
|
f4314549c3 | ||
|
|
d416580456 | ||
|
|
93ce62536f | ||
|
|
312392d6ae | ||
|
|
01734e1f61 | ||
|
|
124063a2a4 | ||
|
|
b99da54d5a | ||
|
|
bc5d51806d | ||
|
|
f3ed5b1206 | ||
|
|
eb6c5d20f5 | ||
|
|
b70b5bd5fe | ||
|
|
5ac7d00e24 | ||
|
|
469d960f50 | ||
|
|
7eea365aa1 | ||
|
|
760071a2f7 | ||
|
|
fa1ef4f763 | ||
|
|
f7b012aa11 | ||
|
|
725ad73240 | ||
|
|
7bbf42f79b | ||
|
|
f2da037d42 | ||
|
|
5c5c527252 | ||
|
|
71d09a3567 | ||
|
|
085476a222 | ||
|
|
c78774b99a | ||
|
|
d5b2e4d8cc | ||
|
|
828d9238b8 | ||
|
|
f2100adb46 | ||
|
|
159fa5a182 | ||
|
|
8ef0a4977b | ||
|
|
ffdb615a4d | ||
|
|
8f57a8c8ff | ||
|
|
a831adc9c8 | ||
|
|
6b22254924 | ||
|
|
0e61415ce2 | ||
|
|
16c893deb6 | ||
|
|
33048149af | ||
|
|
0a2c05ab1e | ||
|
|
e16b27f089 | ||
|
|
0a9dc2c71c | ||
|
|
7c9aa858c2 | ||
|
|
8fb70b20d0 | ||
|
|
809faa24de | ||
|
|
ad5aa263c0 | ||
|
|
a1bb907e03 | ||
|
|
71540f5015 | ||
|
|
a0055a3695 | ||
|
|
0b285df496 | ||
|
|
4d37096b3f | ||
|
|
7c42ea795f | ||
|
|
f2f1d06237 | ||
|
|
86fd80a31a | ||
|
|
c556d16775 |
@@ -1,4 +1,11 @@
|
||||
<!--- This template provides sections for bugs and features. Please delete any irrelevant sections before submitting -->
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Expected Behavior
|
||||
<!--- Required. Describe the behavior you expect to see for your case. -->
|
||||
@@ -24,4 +31,4 @@
|
||||
<!--- Required for Bugs, feature request can delete the line below. -->
|
||||
- [ ] I have provided detailed steps to reproduce the issue
|
||||
|
||||
<!--- Template inspired by https://github.com/stevemao/github-issue-templates -->
|
||||
<!--- Template inspired by https://github.com/stevemao/github-issue-templates -->
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Expected Behavior
|
||||
<!--- Required. Describe the behavior you expect to see for your case. -->
|
||||
|
||||
#### Actual Behavior
|
||||
<!--- Required. Describe the actual behavior for your case. -->
|
||||
|
||||
#### Potential Solution
|
||||
<!--- Optional. Describe any potential solutions and/or thoughts as to what may be causing the difference between expected and actual behavior. -->
|
||||
|
||||
#### Checklist
|
||||
<!--- Confirm that you've provided all the required information. -->
|
||||
<!--- Required fields --->
|
||||
- [ ] I have completely filled out this template
|
||||
- [ ] I have confirmed that this issue exists on the current `master` branch
|
||||
- [ ] I have confirmed that this is not a duplicate issue by searching [issues](https://github.com/QuantConnect/Lean/issues)
|
||||
|
||||
<!--- Template inspired by https://github.com/stevemao/github-issue-templates -->
|
||||
11
.github/workflows/api-tests.yml
vendored
11
.github/workflows/api-tests.yml
vendored
@@ -9,14 +9,19 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
# Only run on push events (not on pull_request) for security reasons in order to be able to use secrets
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Free space
|
||||
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
|
||||
- name: Liberate disk space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
- name: Run API Tests
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
|
||||
12
.github/workflows/gh-actions.yml
vendored
12
.github/workflows/gh-actions.yml
vendored
@@ -9,12 +9,18 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Free space
|
||||
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
|
||||
|
||||
- name: Liberate disk space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
|
||||
- uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
|
||||
2
.github/workflows/rebase-org-branches.yml
vendored
2
.github/workflows/rebase-org-branches.yml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
||||
11
.github/workflows/regression-tests.yml
vendored
11
.github/workflows/regression-tests.yml
vendored
@@ -9,12 +9,17 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Free space
|
||||
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
|
||||
- name: Liberate disk space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
|
||||
- uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
|
||||
11
.github/workflows/report-generator.yml
vendored
11
.github/workflows/report-generator.yml
vendored
@@ -9,12 +9,17 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Free space
|
||||
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
|
||||
- name: Liberate disk space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
|
||||
- uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
|
||||
13
.github/workflows/research-regression-tests.yml
vendored
13
.github/workflows/research-regression-tests.yml
vendored
@@ -9,12 +9,17 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Free space
|
||||
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
|
||||
- name: Liberate disk space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
|
||||
- uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
@@ -25,7 +30,7 @@ jobs:
|
||||
# install dependencies
|
||||
pip3 install papermill==2.4.0 clr-loader==0.1.6
|
||||
# install kernel
|
||||
dotnet tool install --global Microsoft.dotnet-interactive --version 1.0.340501
|
||||
dotnet tool install --global Microsoft.dotnet-interactive --version 1.0.607001
|
||||
# Add dotnet tools to Path
|
||||
export PATH="$HOME/.dotnet/tools:$PATH"
|
||||
# activate kernel for jupyter
|
||||
|
||||
17
.github/workflows/virtual-environments.yml
vendored
17
.github/workflows/virtual-environments.yml
vendored
@@ -9,12 +9,17 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Free space
|
||||
run: df -h && rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && rm -rf /opt/hostedtoolcache* && df -h
|
||||
- name: Liberate disk space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
|
||||
- uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
@@ -48,10 +53,10 @@ jobs:
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.TensorflowProbabilityTest" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
# Run Hvplot Python Package Test
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.HvplotTest" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
# Run Keras Python Package Test
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.KerasTest" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
# Run Transformers
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Transformers" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.XTransformers" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
# Run Shap
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ShapTest" --blame-hang-timeout 120seconds --blame-crash
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ShapTest|KerasTest|PyvinecopulibTest" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.Mlforecast" --blame-hang-timeout 120seconds --blame-crash && \
|
||||
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.MlxtendTest|Thinc" --blame-hang-timeout 120seconds --blame-crash
|
||||
|
||||
@@ -12,16 +12,16 @@ This document contains information regarding ways to use Visual Studio to work w
|
||||
|
||||
<h2>Option 1: Lean CLI</h2>
|
||||
|
||||
To use Lean CLI follow the instructions for installation and tutorial for usage in our [documentation](https://www.quantconnect.com/docs/v2/lean-cli/getting-started/lean-cli).
|
||||
To use Lean CLI follow the instructions for installation and tutorial for usage in our [documentation](https://www.quantconnect.com/docs/v2/lean-cli/key-concepts/getting-started).
|
||||
|
||||
<br />
|
||||
|
||||
<h2>Option 2: Install Locally</h2>
|
||||
|
||||
1. Install [.Net 6](https://dotnet.microsoft.com/download) for the project
|
||||
1. Install [.Net 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) for the project
|
||||
|
||||
2. (Optional) Get [Python 3.8.13](https://www.python.org/downloads/release/python-3813/) for running Python algorithms
|
||||
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-38) for your platform
|
||||
2. (Optional) Get [Python 3.11.11](https://www.python.org/downloads/release/python-31111/) for running Python algorithms
|
||||
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-311) for your platform
|
||||
|
||||
3. Get [Visual Studio](https://visualstudio.microsoft.com/vs/)
|
||||
|
||||
@@ -35,7 +35,7 @@ Your environment is prepared and ready to run lean
|
||||
|
||||
<h1>How to use Lean</h1>
|
||||
|
||||
This section will cover configuring, launching and debugging lean. This is only applicable to option 2 from above. This does not apply to Lean CLI, please refer to [CLI documentation](https://www.quantconnect.com/docs/v2/lean-cli/getting-started/lean-cli)
|
||||
This section will cover configuring, launching and debugging lean. This is only applicable to option 2 from above. This does not apply to Lean CLI, please refer to [CLI documentation](https://www.quantconnect.com/docs/v2/lean-cli/key-concepts/getting-started)
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
6
.vscode/readme.md
vendored
6
.vscode/readme.md
vendored
@@ -51,10 +51,10 @@ If you would like to mount any additional local files to your container, checkou
|
||||
|
||||
<h2>Option 3: Install Dependencies Locally</h2>
|
||||
|
||||
1. Install [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) for the project
|
||||
1. Install [.NET 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) for the project
|
||||
|
||||
2. (Optional) Get [Python 3.8.13](https://www.python.org/downloads/release/python-3813/) for running Python algorithms
|
||||
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-38) for your platform
|
||||
2. (Optional) Get [Python 3.11.11](https://www.python.org/downloads/release/python-31111/) for running Python algorithms
|
||||
- Follow Python instructions [here](https://github.com/QuantConnect/Lean/tree/master/Algorithm.Python#installing-python-311) for your platform
|
||||
|
||||
3. Get [Visual Studio Code](https://code.visualstudio.com/download)
|
||||
- Get the Extension [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) for C# Debugging
|
||||
|
||||
151
Algorithm.CSharp/AddBetaIndicatorNewAssetsRegressionAlgorithm.cs
Normal file
151
Algorithm.CSharp/AddBetaIndicatorNewAssetsRegressionAlgorithm.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Brokerages;
|
||||
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression test to explain how Beta indicator works
|
||||
/// </summary>
|
||||
public class AddBetaIndicatorNewAssetsRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Beta _beta;
|
||||
private SimpleMovingAverage _sma;
|
||||
private decimal _lastSMAValue;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2015, 05, 08);
|
||||
SetEndDate(2017, 06, 15);
|
||||
SetCash(10000);
|
||||
|
||||
AddCrypto("BTCUSD", Resolution.Daily);
|
||||
AddEquity("SPY", Resolution.Daily);
|
||||
|
||||
EnableAutomaticIndicatorWarmUp = true;
|
||||
_beta = B("BTCUSD", "SPY", 3, Resolution.Daily);
|
||||
_sma = SMA("SPY", 3, Resolution.Daily);
|
||||
_lastSMAValue = 0;
|
||||
|
||||
if (!_beta.IsReady)
|
||||
{
|
||||
throw new RegressionTestException("Beta indicator was expected to be ready");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
var price = Securities["BTCUSD"].Price;
|
||||
|
||||
if (!Portfolio.Invested)
|
||||
{
|
||||
var quantityToBuy = (int)(Portfolio.Cash * 0.05m / price);
|
||||
Buy("BTCUSD", quantityToBuy);
|
||||
}
|
||||
|
||||
if (Math.Abs(_beta.Current.Value) > 2)
|
||||
{
|
||||
Liquidate("BTCUSD");
|
||||
Log("Liquidated BTCUSD due to high Beta");
|
||||
}
|
||||
|
||||
Log($"Beta between BTCUSD and SPY is: {_beta.Current.Value}");
|
||||
}
|
||||
|
||||
public override void OnOrderEvent(OrderEvent orderEvent)
|
||||
{
|
||||
var order = Transactions.GetOrderById(orderEvent.OrderId);
|
||||
var goUpwards = _lastSMAValue < _sma.Current.Value;
|
||||
_lastSMAValue = _sma.Current.Value;
|
||||
|
||||
if (order.Status == OrderStatus.Filled)
|
||||
{
|
||||
if (order.Type == OrderType.Limit && Math.Abs(_beta.Current.Value - 1) < 0.2m && goUpwards)
|
||||
{
|
||||
Transactions.CancelOpenOrders(order.Symbol);
|
||||
}
|
||||
}
|
||||
|
||||
if (order.Status == OrderStatus.Canceled)
|
||||
{
|
||||
Log(orderEvent.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public virtual List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 5798;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 77;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "436"},
|
||||
{"Average Win", "0.28%"},
|
||||
{"Average Loss", "-0.01%"},
|
||||
{"Compounding Annual Return", "1.926%"},
|
||||
{"Drawdown", "1.000%"},
|
||||
{"Expectancy", "1.650"},
|
||||
{"Start Equity", "10000.00"},
|
||||
{"End Equity", "10411.11"},
|
||||
{"Net Profit", "4.111%"},
|
||||
{"Sharpe Ratio", "0.332"},
|
||||
{"Sortino Ratio", "0.313"},
|
||||
{"Probabilistic Sharpe Ratio", "74.084%"},
|
||||
{"Loss Rate", "90%"},
|
||||
{"Win Rate", "10%"},
|
||||
{"Profit-Loss Ratio", "25.26"},
|
||||
{"Alpha", "0.003"},
|
||||
{"Beta", "0.001"},
|
||||
{"Annual Standard Deviation", "0.01"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-0.495"},
|
||||
{"Tracking Error", "0.111"},
|
||||
{"Treynor Ratio", "2.716"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$87000.00"},
|
||||
{"Lowest Capacity Asset", "BTCUSD 2XR"},
|
||||
{"Portfolio Turnover", "2.22%"},
|
||||
{"OrderListHash", "4fcffc45d82203bb6ded8a0e86070b4f"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
if (!_beta.IsReady)
|
||||
{
|
||||
throw new RegressionTestException("_beta indicator was expected to be ready");
|
||||
throw new RegressionTestException("Beta indicator was expected to be ready");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
LimitOrder("IBM", 10, price * 0.1m);
|
||||
StopMarketOrder("IBM", 10, price / 0.1m);
|
||||
}
|
||||
|
||||
|
||||
if (_beta.Current.Value < 0m || _beta.Current.Value > 2.80m)
|
||||
{
|
||||
throw new RegressionTestException($"_beta value was expected to be between 0 and 2.80 but was {_beta.Current.Value}");
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
contractDepthOffset: 0
|
||||
);
|
||||
|
||||
_futureContract = AddFutureContract(FutureChainProvider.GetFutureContractList(_continuousContract.Symbol, Time).First());
|
||||
_futureContract = AddFutureContract(FuturesChain(_continuousContract.Symbol).First());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,12 +115,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 73;
|
||||
public long DataPoints => 61;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -164,12 +164,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 311879;
|
||||
public long DataPoints => 311881;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 2;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -93,12 +93,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 12169;
|
||||
public long DataPoints => 9922;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 2;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -113,7 +113,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "20"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "386219349.202%"},
|
||||
{"Compounding Annual Return", "88398927.578%"},
|
||||
{"Drawdown", "5.200%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var chain in slice.OptionChains.Values)
|
||||
foreach (var chain in slice.OptionChains.Values.OrderBy(x => x.Symbol.Underlying.ID.Date))
|
||||
{
|
||||
var futureInvested = false;
|
||||
var optionInvested = false;
|
||||
@@ -220,7 +220,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 608377;
|
||||
public long DataPoints => 319494;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -240,7 +240,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "2"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "347.065%"},
|
||||
{"Compounding Annual Return", "309.669%"},
|
||||
{"Drawdown", "0.900%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
&& optionContract.ID.OptionStyle == OptionStyle.American);
|
||||
AddOptionContract(option);
|
||||
|
||||
foreach (var symbol in new[] { option.Symbol, option.Underlying.Symbol })
|
||||
foreach (var symbol in new[] { option.Symbol, option.UnderlyingSymbol })
|
||||
{
|
||||
var config = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).ToList();
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
var ticket = MarketOrder("AIG", 1);
|
||||
|
||||
if (ticket.Status != OrderStatus.Invalid)
|
||||
if (ticket.Status != OrderStatus.Invalid || aig.HasData || aig.Price != 0)
|
||||
{
|
||||
throw new RegressionTestException("Expected order to always be invalid because there is no data yet!");
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
SetEndDate(2013, 10, 10);
|
||||
|
||||
var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
|
||||
_symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First();
|
||||
_symbol = FuturesChain(SP500).First();
|
||||
|
||||
// Test case: custom IndicatorBase<QuoteBar> indicator using Future unsubscribed symbol
|
||||
var indicator1 = new CustomIndicator();
|
||||
@@ -151,7 +151,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 84;
|
||||
public int AlgorithmHistoryDataPoints => 85;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 21;
|
||||
public int AlgorithmHistoryDataPoints => 18;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -18,7 +18,6 @@ using QuantConnect.Data;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Securities;
|
||||
@@ -118,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 713369;
|
||||
public long DataPoints => 162575;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -161,7 +160,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Estimated Strategy Capacity", "$7100000.00"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "2.33%"},
|
||||
{"OrderListHash", "9c524830ffc7354327638142ae62acd2"}
|
||||
{"OrderListHash", "04670183a0a4c9160167415aa5102499"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 2217299;
|
||||
public long DataPoints => 504530;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -167,11 +167,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
if (Portfolio.CashBook["LTC"].Amount > 0)
|
||||
{
|
||||
// The following two statements currently behave differently if we have initial holdings:
|
||||
// https://github.com/QuantConnect/Lean/issues/1860
|
||||
|
||||
Liquidate("LTCUSD");
|
||||
// SetHoldings("LTCUSD", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
_continuousContract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(180));
|
||||
_mappedSymbol = _continuousContract.Mapped;
|
||||
|
||||
var benchmark = AddIndex("SX5E", market: Market.EUREX);
|
||||
var benchmark = AddIndex("SX5E");
|
||||
SetBenchmark(benchmark.Symbol);
|
||||
|
||||
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
|
||||
@@ -190,12 +190,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 133945;
|
||||
public long DataPoints => 94326;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 26;
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -233,7 +233,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Estimated Strategy Capacity", "€2300000000.00"},
|
||||
{"Lowest Capacity Asset", "FESX YJHOAMPYKRS5"},
|
||||
{"Portfolio Turnover", "0.40%"},
|
||||
{"OrderListHash", "54040d29a467becaedcf59d79323321b"}
|
||||
{"OrderListHash", "ac9acc478ba1afe53993cdbb92f8ec6e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 1190;
|
||||
public long DataPoints => 727;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -219,7 +219,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "0.13%"},
|
||||
{"OrderListHash", "273dd05b937c075b75baf8af46d3c7de"}
|
||||
{"OrderListHash", "7c8700a9baa24f6f76d866e7d88cc19c"}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 75403;
|
||||
public long DataPoints => 40308;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -169,7 +169,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "2700"},
|
||||
{"Average Win", "0.00%"},
|
||||
{"Average Loss", "0.00%"},
|
||||
{"Compounding Annual Return", "-99.777%"},
|
||||
{"Compounding Annual Return", "-99.597%"},
|
||||
{"Drawdown", "4.400%"},
|
||||
{"Expectancy", "-0.724"},
|
||||
{"Start Equity", "1000000"},
|
||||
|
||||
@@ -18,8 +18,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Future;
|
||||
|
||||
@@ -104,6 +104,16 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSecuritiesChanged(SecurityChanges changes)
|
||||
{
|
||||
if (changes.RemovedSecurities.Count > 0 &&
|
||||
Portfolio.Invested &&
|
||||
Securities.Values.Where(x => x.Invested).All(x => x.Exchange.Hours.IsOpen(Time, true)))
|
||||
{
|
||||
Liquidate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
@@ -117,7 +127,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 12452;
|
||||
public virtual long DataPoints => 5861;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -134,33 +144,33 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// </summary>
|
||||
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "32"},
|
||||
{"Total Orders", "34"},
|
||||
{"Average Win", "0.33%"},
|
||||
{"Average Loss", "-0.04%"},
|
||||
{"Compounding Annual Return", "0.110%"},
|
||||
{"Compounding Annual Return", "0.106%"},
|
||||
{"Drawdown", "0.300%"},
|
||||
{"Expectancy", "0.184"},
|
||||
{"Expectancy", "0.178"},
|
||||
{"Start Equity", "1000000"},
|
||||
{"End Equity", "1001108"},
|
||||
{"Net Profit", "0.111%"},
|
||||
{"Sharpe Ratio", "-1.688"},
|
||||
{"Sortino Ratio", "-0.772"},
|
||||
{"Probabilistic Sharpe Ratio", "14.944%"},
|
||||
{"End Equity", "1001066.2"},
|
||||
{"Net Profit", "0.107%"},
|
||||
{"Sharpe Ratio", "-1.695"},
|
||||
{"Sortino Ratio", "-0.804"},
|
||||
{"Probabilistic Sharpe Ratio", "14.797%"},
|
||||
{"Loss Rate", "88%"},
|
||||
{"Win Rate", "12%"},
|
||||
{"Profit-Loss Ratio", "8.47"},
|
||||
{"Profit-Loss Ratio", "9.01"},
|
||||
{"Alpha", "-0.007"},
|
||||
{"Beta", "0.002"},
|
||||
{"Annual Standard Deviation", "0.004"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-1.353"},
|
||||
{"Tracking Error", "0.089"},
|
||||
{"Treynor Ratio", "-4.099"},
|
||||
{"Total Fees", "$72.00"},
|
||||
{"Treynor Ratio", "-4.112"},
|
||||
{"Total Fees", "$76.30"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
|
||||
{"Portfolio Turnover", "0.87%"},
|
||||
{"OrderListHash", "168731c8f3a19f230cc1410818b3b573"}
|
||||
{"Portfolio Turnover", "0.92%"},
|
||||
{"OrderListHash", "c0713abdc4fb059c2be797fce36e4f36"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 57759;
|
||||
public virtual long DataPoints => 24883;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 163415;
|
||||
public override long DataPoints => 70262;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
|
||||
@@ -140,12 +140,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 48690;
|
||||
public virtual long DataPoints => 25316;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public virtual int AlgorithmHistoryDataPoints => 5305;
|
||||
public virtual int AlgorithmHistoryDataPoints => 6075;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 147771;
|
||||
public override long DataPoints => 76063;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -14,12 +14,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
@@ -41,40 +36,40 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 87289;
|
||||
public override long DataPoints => 25312;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "716"},
|
||||
{"Total Orders", "718"},
|
||||
{"Average Win", "0.03%"},
|
||||
{"Average Loss", "-0.01%"},
|
||||
{"Compounding Annual Return", "-1.716%"},
|
||||
{"Compounding Annual Return", "-1.720%"},
|
||||
{"Drawdown", "1.700%"},
|
||||
{"Expectancy", "-0.770"},
|
||||
{"Start Equity", "1000000"},
|
||||
{"End Equity", "982718.38"},
|
||||
{"Net Profit", "-1.728%"},
|
||||
{"Sharpe Ratio", "-8.845"},
|
||||
{"Sortino Ratio", "-5.449"},
|
||||
{"End Equity", "982676.58"},
|
||||
{"Net Profit", "-1.732%"},
|
||||
{"Sharpe Ratio", "-8.877"},
|
||||
{"Sortino Ratio", "-5.476"},
|
||||
{"Probabilistic Sharpe Ratio", "0.000%"},
|
||||
{"Loss Rate", "96%"},
|
||||
{"Win Rate", "4%"},
|
||||
{"Profit-Loss Ratio", "4.89"},
|
||||
{"Profit-Loss Ratio", "4.90"},
|
||||
{"Alpha", "-0.018"},
|
||||
{"Beta", "-0.002"},
|
||||
{"Annual Standard Deviation", "0.002"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-1.483"},
|
||||
{"Information Ratio", "-1.484"},
|
||||
{"Tracking Error", "0.089"},
|
||||
{"Treynor Ratio", "9.102"},
|
||||
{"Total Fees", "$1634.12"},
|
||||
{"Treynor Ratio", "9.171"},
|
||||
{"Total Fees", "$1638.42"},
|
||||
{"Estimated Strategy Capacity", "$8000.00"},
|
||||
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
|
||||
{"Portfolio Turnover", "20.10%"},
|
||||
{"OrderListHash", "aa7e574f86b70428ca0afae381be80ba"}
|
||||
{"Portfolio Turnover", "20.14%"},
|
||||
{"OrderListHash", "dedcc487d64e2f601990fc70393c89ed"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 224662;
|
||||
public long DataPoints => 117079;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -14,14 +14,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Future;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
@@ -43,40 +36,40 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 14790;
|
||||
public override long DataPoints => 5965;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "36"},
|
||||
{"Total Orders", "32"},
|
||||
{"Average Win", "0.33%"},
|
||||
{"Average Loss", "-0.03%"},
|
||||
{"Compounding Annual Return", "0.102%"},
|
||||
{"Average Loss", "-0.04%"},
|
||||
{"Compounding Annual Return", "0.110%"},
|
||||
{"Drawdown", "0.300%"},
|
||||
{"Expectancy", "0.171"},
|
||||
{"Expectancy", "0.184"},
|
||||
{"Start Equity", "1000000"},
|
||||
{"End Equity", "1001024.4"},
|
||||
{"Net Profit", "0.102%"},
|
||||
{"Sharpe Ratio", "-1.702"},
|
||||
{"Sortino Ratio", "-0.836"},
|
||||
{"Probabilistic Sharpe Ratio", "14.653%"},
|
||||
{"Loss Rate", "89%"},
|
||||
{"Win Rate", "11%"},
|
||||
{"Profit-Loss Ratio", "9.54"},
|
||||
{"End Equity", "1001108"},
|
||||
{"Net Profit", "0.111%"},
|
||||
{"Sharpe Ratio", "-1.688"},
|
||||
{"Sortino Ratio", "-0.772"},
|
||||
{"Probabilistic Sharpe Ratio", "14.944%"},
|
||||
{"Loss Rate", "88%"},
|
||||
{"Win Rate", "12%"},
|
||||
{"Profit-Loss Ratio", "8.47"},
|
||||
{"Alpha", "-0.007"},
|
||||
{"Beta", "0.002"},
|
||||
{"Annual Standard Deviation", "0.004"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-1.353"},
|
||||
{"Tracking Error", "0.089"},
|
||||
{"Treynor Ratio", "-4.126"},
|
||||
{"Total Fees", "$80.60"},
|
||||
{"Treynor Ratio", "-4.099"},
|
||||
{"Total Fees", "$72.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
|
||||
{"Portfolio Turnover", "0.97%"},
|
||||
{"OrderListHash", "52c852d720692fab1e12212b2aba03d4"}
|
||||
{"Portfolio Turnover", "0.87%"},
|
||||
{"OrderListHash", "8b8b733248a21fc717079be54b2e844c"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 228834;
|
||||
public override long DataPoints => 67924;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
}
|
||||
|
||||
var openInterest = Securities[SpxOption].Cache.GetAll<OpenInterest>();
|
||||
if (openInterest.Single().EndTime != new DateTime(2021, 1, 15, 23, 0, 0))
|
||||
if (openInterest.Single().EndTime != new DateTime(2021, 1, 15, 15, 15, 0))
|
||||
{
|
||||
throw new ArgumentException($"Unexpected open interest time: {openInterest.Single().EndTime}");
|
||||
}
|
||||
@@ -106,7 +106,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 121;
|
||||
public override long DataPoints => 122;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -126,7 +126,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "11"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "621.484%"},
|
||||
{"Compounding Annual Return", "653.545%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "1000000"},
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 356;
|
||||
public override long DataPoints => 360;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -121,20 +121,20 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "5"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "-0.69%"},
|
||||
{"Average Win", "0.63%"},
|
||||
{"Average Loss", "-0.03%"},
|
||||
{"Compounding Annual Return", "54.478%"},
|
||||
{"Drawdown", "0.400%"},
|
||||
{"Expectancy", "-0.5"},
|
||||
{"Expectancy", "23.219"},
|
||||
{"Start Equity", "1000000"},
|
||||
{"End Equity", "1006025"},
|
||||
{"Net Profit", "0.602%"},
|
||||
{"Sharpe Ratio", "2.62"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "63.221%"},
|
||||
{"Loss Rate", "50%"},
|
||||
{"Win Rate", "50%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "100%"},
|
||||
{"Profit-Loss Ratio", "23.22"},
|
||||
{"Alpha", "0.067"},
|
||||
{"Beta", "-0.013"},
|
||||
{"Annual Standard Deviation", "0.004"},
|
||||
|
||||
@@ -127,11 +127,11 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "10"},
|
||||
{"Average Win", "0.47%"},
|
||||
{"Average Win", "0.46%"},
|
||||
{"Average Loss", "-0.01%"},
|
||||
{"Compounding Annual Return", "101.998%"},
|
||||
{"Drawdown", "0.100%"},
|
||||
{"Expectancy", "24.484"},
|
||||
{"Expectancy", "24.137"},
|
||||
{"Start Equity", "1000000"},
|
||||
{"End Equity", "1009050"},
|
||||
{"Net Profit", "0.905%"},
|
||||
@@ -140,7 +140,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Probabilistic Sharpe Ratio", "95.546%"},
|
||||
{"Loss Rate", "50%"},
|
||||
{"Win Rate", "50%"},
|
||||
{"Profit-Loss Ratio", "49.97"},
|
||||
{"Profit-Loss Ratio", "49.27"},
|
||||
{"Alpha", "-2.01"},
|
||||
{"Beta", "0.307"},
|
||||
{"Annual Standard Deviation", "0.021"},
|
||||
|
||||
167
Algorithm.CSharp/CallbackCommandRegressionAlgorithm.cs
Normal file
167
Algorithm.CSharp/CallbackCommandRegressionAlgorithm.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using QuantConnect.Commands;
|
||||
using QuantConnect.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm asserting the behavior of different callback commands call
|
||||
/// </summary>
|
||||
public class CallbackCommandRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2013, 10, 07);
|
||||
SetEndDate(2013, 10, 11);
|
||||
|
||||
AddEquity("SPY");
|
||||
AddEquity("BAC");
|
||||
AddEquity("IBM");
|
||||
AddCommand<BoolCommand>();
|
||||
AddCommand<VoidCommand>();
|
||||
|
||||
var potentialCommand = new VoidCommand
|
||||
{
|
||||
Target = new[] { "BAC" },
|
||||
Quantity = 10,
|
||||
Parameters = new() { { "tag", "Signal X" } }
|
||||
};
|
||||
var commandLink = Link(potentialCommand);
|
||||
Notify.Email("email@address", "Trade Command Event", $"Signal X trade\nFollow link to trigger: {commandLink}");
|
||||
|
||||
var commandLink2 = Link(new { Symbol = "SPY", Parameters = new Dictionary<string, int>() { { "Quantity", 10 } } });
|
||||
Notify.Email("email@address", "Untyped Command Event", $"Signal Y trade\nFollow link to trigger: {commandLink2}");
|
||||
|
||||
// We need to create a project on QuantConnect to test the BroadcastCommand method
|
||||
// and use the ProjectId in the BroadcastCommand call
|
||||
ProjectId = 21805137;
|
||||
|
||||
// All live deployments receive the broadcasts below
|
||||
var broadcastResult = BroadcastCommand(potentialCommand);
|
||||
var broadcastResult2 = BroadcastCommand(new { Symbol = "SPY", Parameters = new Dictionary<string, int>() { { "Quantity", 10 } } });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle generic command callback
|
||||
/// </summary>
|
||||
public override bool? OnCommand(dynamic data)
|
||||
{
|
||||
Buy(data.Symbol, data.parameters["quantity"]);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class VoidCommand : Command
|
||||
{
|
||||
public DateTime TargetTime { get; set; }
|
||||
public string[] Target { get; set; }
|
||||
public decimal Quantity { get; set; }
|
||||
public Dictionary<string, string> Parameters { get; set; }
|
||||
public override bool? Run(IAlgorithm algorithm)
|
||||
{
|
||||
if (TargetTime != algorithm.Time)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
((QCAlgorithm)algorithm).Order(Target[0], Quantity, tag: Parameters["tag"]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private class BoolCommand : Command
|
||||
{
|
||||
public bool? Result { get; set; }
|
||||
public override bool? Run(IAlgorithm algorithm)
|
||||
{
|
||||
var shouldTrade = MyCustomMethod();
|
||||
if (shouldTrade.HasValue && shouldTrade.Value)
|
||||
{
|
||||
((QCAlgorithm)algorithm).Buy("IBM", 1);
|
||||
}
|
||||
return shouldTrade;
|
||||
}
|
||||
|
||||
private bool? MyCustomMethod()
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 3943;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "1"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "271.453%"},
|
||||
{"Drawdown", "2.200%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "101691.92"},
|
||||
{"Net Profit", "1.692%"},
|
||||
{"Sharpe Ratio", "8.854"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "67.609%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "-0.005"},
|
||||
{"Beta", "0.996"},
|
||||
{"Annual Standard Deviation", "0.222"},
|
||||
{"Annual Variance", "0.049"},
|
||||
{"Information Ratio", "-14.565"},
|
||||
{"Tracking Error", "0.001"},
|
||||
{"Treynor Ratio", "1.97"},
|
||||
{"Total Fees", "$3.44"},
|
||||
{"Estimated Strategy Capacity", "$56000000.00"},
|
||||
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
|
||||
{"Portfolio Turnover", "19.93%"},
|
||||
{"OrderListHash", "3da9fa60bf95b9ed148b95e02e0cfc9e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -49,13 +49,13 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
private bool _firstCall = true;
|
||||
|
||||
private PortfolioTarget[] _targets = new PortfolioTarget[4];
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Symbols accepted by Collective2. Collective2 accepts stock,
|
||||
/// future, forex and US stock option symbols
|
||||
/// </summary>
|
||||
private List<Symbol> _symbols = new()
|
||||
{
|
||||
{
|
||||
QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA, null, null),
|
||||
QuantConnect.Symbol.Create("EURUSD", SecurityType.Forex, Market.Oanda, null, null),
|
||||
QuantConnect.Symbol.CreateFuture("ES", Market.CME, new DateTime(2023, 12, 15), null),
|
||||
@@ -95,15 +95,19 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
// Initialize this flag, to check when the ema indicators crosses between themselves
|
||||
_emaFastIsNotSet = true;
|
||||
|
||||
// Set Collective2 signal export provider
|
||||
// Set Collective2 signal export provider.
|
||||
// If using the Collective2 white-label API, you can specify it in the constructor with the optional parameter `useWhiteLabelApi`:
|
||||
// e.g. new Collective2SignalExport(_collective2ApiKey, _collective2SystemId, useWhiteLabelApi: true)
|
||||
// The API url can also be overridden by setting the Destination property:
|
||||
// e.g. new Collective2SignalExport(_collective2ApiKey, _collective2SystemId) { Destination = new Uri("your url") }
|
||||
SignalExport.AddSignalExportProviders(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
|
||||
|
||||
SetWarmUp(100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reduce the quantity of holdings for SPY or increase it, depending the case,
|
||||
/// when the EMA's indicators crosses between themselves, then send a signal to
|
||||
/// Reduce the quantity of holdings for SPY or increase it, depending the case,
|
||||
/// when the EMA's indicators crosses between themselves, then send a signal to
|
||||
/// Collective2 API
|
||||
/// </summary>
|
||||
/// <param name="slice"></param>
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Interfaces;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// This algorithm tests the functionality of the CompositeIndicator,
|
||||
/// using either a lambda expression or a method reference.
|
||||
/// </summary>
|
||||
public class CompositeIndicatorWorksAsExpectedRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private CompositeIndicator _compositeMinDirect;
|
||||
private CompositeIndicator _compositeMinMethod;
|
||||
private bool _dataReceived;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2013, 10, 4);
|
||||
SetEndDate(2013, 10, 5);
|
||||
AddEquity("SPY", Resolution.Minute);
|
||||
|
||||
var closePrice = Identity("SPY", Resolution.Minute, Field.Close);
|
||||
var lowPrice = MIN("SPY", 420, Resolution.Minute, Field.Low);
|
||||
|
||||
_compositeMinDirect = new CompositeIndicator("CompositeMinDirect", closePrice, lowPrice, (l, r) => new IndicatorResult(Math.Min(l.Current.Value, r.Current.Value)));
|
||||
_compositeMinMethod = new CompositeIndicator("CompositeMinMethod", closePrice, lowPrice, Composer);
|
||||
|
||||
_dataReceived = false;
|
||||
}
|
||||
|
||||
private IndicatorResult Composer(IndicatorBase l, IndicatorBase r)
|
||||
{
|
||||
return new IndicatorResult(Math.Min(l.Current.Value, r.Current.Value));
|
||||
}
|
||||
|
||||
public override void OnData(Slice data)
|
||||
{
|
||||
_dataReceived = true;
|
||||
|
||||
if (_compositeMinDirect.Current.Value != _compositeMinMethod.Current.Value)
|
||||
{
|
||||
throw new RegressionTestException($"Values of indicators differ: {_compositeMinDirect.Current.Value} | {_compositeMinMethod.Current.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (!_dataReceived)
|
||||
{
|
||||
throw new RegressionTestException("No data was processed during the algorithm execution.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 795;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data.Market;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// This regression algorithm asserts the consolidated US equity daily bars from the hour bars exactly matches
|
||||
/// the daily bars returned from the database
|
||||
/// </summary>
|
||||
public class ConsolidateHourBarsIntoDailyBarsRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Symbol _spy;
|
||||
private RelativeStrengthIndex _rsi;
|
||||
private RelativeStrengthIndex _rsiTimeDelta;
|
||||
private Dictionary<DateTime, decimal> _values = new();
|
||||
private int _count;
|
||||
private bool _indicatorsCompared;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2020, 5, 1);
|
||||
SetEndDate(2020, 6, 5);
|
||||
|
||||
_spy = AddEquity("SPY", Resolution.Hour).Symbol;
|
||||
|
||||
// We will use these two indicators to compare the daily consolidated bars equals
|
||||
// the ones returned from the database. We use this specific type of indicator as
|
||||
// it depends on its previous values. Thus, if at some point the bars received by
|
||||
// the indicators differ, so will their final values
|
||||
_rsi = new RelativeStrengthIndex("FIRST", 15, MovingAverageType.Wilders);
|
||||
RegisterIndicator(_spy, _rsi, Resolution.Daily, selector: (bar) =>
|
||||
{
|
||||
var tradeBar = (TradeBar)bar;
|
||||
return (tradeBar.Close + tradeBar.Open) / 2;
|
||||
});
|
||||
|
||||
// We won't register this indicator as we will update it manually at the end of the
|
||||
// month, so that we can compare the values of the indicator that received consolidated
|
||||
// bars and the values of this one
|
||||
_rsiTimeDelta = new RelativeStrengthIndex("SECOND" ,15, MovingAverageType.Wilders);
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (IsWarmingUp) return;
|
||||
|
||||
if (slice.ContainsKey(_spy) && slice[_spy] != null)
|
||||
{
|
||||
if (Time.Month == EndDate.Month)
|
||||
{
|
||||
var history = History(_spy, _count, Resolution.Daily);
|
||||
foreach (var bar in history)
|
||||
{
|
||||
var time = bar.EndTime.Date;
|
||||
var average = (bar.Close + bar.Open) / 2;
|
||||
_rsiTimeDelta.Update(bar.EndTime, average);
|
||||
if (_rsiTimeDelta.Current.Value != _values[time])
|
||||
{
|
||||
throw new RegressionTestException($"Both {_rsi.Name} and {_rsiTimeDelta.Name} should have the same values, but they differ. {_rsi.Name}: {_values[time]} | {_rsiTimeDelta.Name}: {_rsiTimeDelta.Current.Value}");
|
||||
}
|
||||
}
|
||||
_indicatorsCompared = true;
|
||||
Quit();
|
||||
}
|
||||
else
|
||||
{
|
||||
_values[Time.Date] = _rsi.Current.Value;
|
||||
|
||||
// Since the symbol resolution is hour and the symbol is equity, we know the last bar received in a day will
|
||||
// be at the market close, this is 16h. We need to count how many daily bars were consolidated in order to know
|
||||
// how many we need to request from the history
|
||||
if (Time.Hour == 16)
|
||||
{
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (!_indicatorsCompared)
|
||||
{
|
||||
throw new RegressionTestException($"Indicators {_rsi.Name} and {_rsiTimeDelta.Name} should have been compared, but they were not. Please make sure the indicators are getting SPY data");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 290;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 20;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-5.215"},
|
||||
{"Tracking Error", "0.159"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ using QuantConnect.Data.Market;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Future;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
@@ -31,69 +32,83 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public class ConsolidateRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private List<int> _consolidationCounts;
|
||||
private List<int> _expectedConsolidationCounts;
|
||||
private List<SimpleMovingAverage> _smas;
|
||||
private List<DateTime> _lastSmaUpdates;
|
||||
private int _expectedConsolidations;
|
||||
private int _customDataConsolidator;
|
||||
private Symbol _symbol;
|
||||
private int _customDataConsolidatorCount;
|
||||
private Future _future;
|
||||
|
||||
/// <summary>
|
||||
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2013, 10, 08);
|
||||
SetEndDate(2013, 10, 20);
|
||||
SetStartDate(2020, 01, 05);
|
||||
SetEndDate(2020, 01, 20);
|
||||
|
||||
var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
|
||||
_symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First();
|
||||
var security = AddFutureContract(_symbol);
|
||||
var symbol = FuturesChain(SP500).First();
|
||||
_future = AddFutureContract(symbol);
|
||||
|
||||
_consolidationCounts = Enumerable.Repeat(0, 9).ToList();
|
||||
var tradableDatesCount = QuantConnect.Time.EachTradeableDayInTimeZone(_future.Exchange.Hours,
|
||||
StartDate,
|
||||
EndDate,
|
||||
_future.Exchange.TimeZone,
|
||||
false).Count();
|
||||
_expectedConsolidationCounts = new(10);
|
||||
|
||||
Consolidate<QuoteBar>(symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
|
||||
bar => UpdateQuoteBar(bar, 0));
|
||||
// The consolidator will respect the full 1 day bar span and will not consolidate the last tradable date,
|
||||
// since scan will not be called at 202/01/21 12am
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
Consolidate<QuoteBar>(symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
|
||||
TickType.Quote, bar => UpdateQuoteBar(bar, 1));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
Consolidate<QuoteBar>(symbol, TimeSpan.FromDays(1), bar => UpdateQuoteBar(bar, 2));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
Consolidate(symbol, Resolution.Daily, TickType.Quote, (Action<QuoteBar>)(bar => UpdateQuoteBar(bar, 3)));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount);
|
||||
|
||||
Consolidate(symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 4));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
Consolidate<TradeBar>(symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 5));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
// Test using abstract T types, through defining a 'BaseData' handler
|
||||
|
||||
Consolidate(symbol, Resolution.Daily, null, (Action<BaseData>)(bar => UpdateBar(bar, 6)));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount);
|
||||
|
||||
Consolidate(symbol, TimeSpan.FromDays(1), null, (Action<BaseData>)(bar => UpdateBar(bar, 7)));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
Consolidate(symbol, TimeSpan.FromDays(1), (Action<BaseData>)(bar => UpdateBar(bar, 8)));
|
||||
_expectedConsolidationCounts.Add(tradableDatesCount - 1);
|
||||
|
||||
_consolidationCounts = Enumerable.Repeat(0, _expectedConsolidationCounts.Count).ToList();
|
||||
_smas = _consolidationCounts.Select(_ => new SimpleMovingAverage(10)).ToList();
|
||||
_lastSmaUpdates = _consolidationCounts.Select(_ => DateTime.MinValue).ToList();
|
||||
|
||||
Consolidate<QuoteBar>(_symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
|
||||
bar => UpdateQuoteBar(bar, 0));
|
||||
|
||||
Consolidate<QuoteBar>(_symbol, time => new CalendarInfo(time.RoundDown(TimeSpan.FromDays(1)), TimeSpan.FromDays(1)),
|
||||
TickType.Quote, bar => UpdateQuoteBar(bar, 1));
|
||||
|
||||
Consolidate<QuoteBar>(_symbol, TimeSpan.FromDays(1), bar => UpdateQuoteBar(bar, 2));
|
||||
|
||||
Consolidate(_symbol, Resolution.Daily, TickType.Quote, (Action<QuoteBar>)(bar => UpdateQuoteBar(bar, 3)));
|
||||
|
||||
Consolidate(_symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 4));
|
||||
|
||||
Consolidate<TradeBar>(_symbol, TimeSpan.FromDays(1), bar => UpdateTradeBar(bar, 5));
|
||||
|
||||
// custom data
|
||||
var symbol = AddData<CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute).Symbol;
|
||||
Consolidate<TradeBar>(symbol, TimeSpan.FromDays(1), bar => _customDataConsolidator++);
|
||||
var customSecurity = AddData<CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute);
|
||||
Consolidate<TradeBar>(customSecurity.Symbol, TimeSpan.FromDays(1), bar => _customDataConsolidatorCount++);
|
||||
|
||||
try
|
||||
{
|
||||
Consolidate<QuoteBar>(symbol, TimeSpan.FromDays(1), bar => { UpdateQuoteBar(bar, -1); });
|
||||
Consolidate<QuoteBar>(customSecurity.Symbol, TimeSpan.FromDays(1), bar => { UpdateQuoteBar(bar, -1); });
|
||||
throw new RegressionTestException($"Expected {nameof(ArgumentException)} to be thrown");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// will try to use BaseDataConsolidator for which input is TradeBars not QuoteBars
|
||||
}
|
||||
|
||||
// Test using abstract T types, through defining a 'BaseData' handler
|
||||
Consolidate(_symbol, Resolution.Daily, null, (Action<BaseData>)(bar => UpdateBar(bar, 6)));
|
||||
|
||||
Consolidate(_symbol, TimeSpan.FromDays(1), null, (Action<BaseData>)(bar => UpdateBar(bar, 7)));
|
||||
|
||||
Consolidate(_symbol, TimeSpan.FromDays(1), (Action<BaseData>)(bar => UpdateBar(bar, 8)));
|
||||
|
||||
_expectedConsolidations = QuantConnect.Time.EachTradeableDayInTimeZone(security.Exchange.Hours,
|
||||
StartDate,
|
||||
EndDate,
|
||||
security.Exchange.TimeZone,
|
||||
false).Count();
|
||||
}
|
||||
|
||||
private void UpdateBar(BaseData tradeBar, int position)
|
||||
{
|
||||
if (!(tradeBar is TradeBar))
|
||||
@@ -119,16 +134,27 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (_consolidationCounts.Any(i => i != _expectedConsolidations) || _customDataConsolidator == 0)
|
||||
for (var i = 0; i < _consolidationCounts.Count; i++)
|
||||
{
|
||||
throw new RegressionTestException("Unexpected consolidation count");
|
||||
var consolidationCount = _consolidationCounts[i];
|
||||
var expectedConsolidationCount = _expectedConsolidationCounts[i];
|
||||
|
||||
if (consolidationCount != expectedConsolidationCount)
|
||||
{
|
||||
throw new RegressionTestException($"Expected {expectedConsolidationCount} consolidations for consolidator {i} but received {consolidationCount}");
|
||||
}
|
||||
}
|
||||
|
||||
if (_customDataConsolidatorCount == 0)
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected custom data consolidation count: {_customDataConsolidatorCount}");
|
||||
}
|
||||
|
||||
for (var i = 0; i < _smas.Count; i++)
|
||||
{
|
||||
if (_smas[i].Samples != _expectedConsolidations)
|
||||
if (_smas[i].Samples != _expectedConsolidationCounts[i])
|
||||
{
|
||||
throw new RegressionTestException($"Expected {_expectedConsolidations} samples in each SMA but found {_smas[i].Samples} in SMA in index {i}");
|
||||
throw new RegressionTestException($"Expected {_expectedConsolidationCounts} samples in each SMA but found {_smas[i].Samples} in SMA in index {i}");
|
||||
}
|
||||
|
||||
if (_smas[i].Current.Time != _lastSmaUpdates[i])
|
||||
@@ -144,9 +170,9 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (!Portfolio.Invested)
|
||||
if (!Portfolio.Invested && _future.HasData)
|
||||
{
|
||||
SetHoldings(_symbol, 0.5);
|
||||
SetHoldings(_future.Symbol, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,12 +189,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 12244;
|
||||
public long DataPoints => 14228;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -183,30 +209,30 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "1"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "6636.699%"},
|
||||
{"Drawdown", "15.900%"},
|
||||
{"Compounding Annual Return", "665.524%"},
|
||||
{"Drawdown", "1.500%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "116177.7"},
|
||||
{"Net Profit", "16.178%"},
|
||||
{"Sharpe Ratio", "640.313"},
|
||||
{"End Equity", "109332.4"},
|
||||
{"Net Profit", "9.332%"},
|
||||
{"Sharpe Ratio", "9.805"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "99.824%"},
|
||||
{"Probabilistic Sharpe Ratio", "93.474%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "636.164"},
|
||||
{"Beta", "5.924"},
|
||||
{"Annual Standard Deviation", "1.012"},
|
||||
{"Annual Variance", "1.024"},
|
||||
{"Information Ratio", "696.123"},
|
||||
{"Tracking Error", "0.928"},
|
||||
{"Treynor Ratio", "109.404"},
|
||||
{"Total Fees", "$23.65"},
|
||||
{"Estimated Strategy Capacity", "$210000000.00"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "81.19%"},
|
||||
{"OrderListHash", "dfd9a280d3c6470b305c03e0b72c234e"}
|
||||
{"Alpha", "3.164"},
|
||||
{"Beta", "0.957"},
|
||||
{"Annual Standard Deviation", "0.383"},
|
||||
{"Annual Variance", "0.146"},
|
||||
{"Information Ratio", "8.29"},
|
||||
{"Tracking Error", "0.379"},
|
||||
{"Treynor Ratio", "3.917"},
|
||||
{"Total Fees", "$15.05"},
|
||||
{"Estimated Strategy Capacity", "$2100000000.00"},
|
||||
{"Lowest Capacity Asset", "ES XCZJLC9NOB29"},
|
||||
{"Portfolio Turnover", "64.34%"},
|
||||
{"OrderListHash", "d814db6d5a9c97ee6de477ea06cd3834"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 713369;
|
||||
public long DataPoints => 162571;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 723496;
|
||||
public long DataPoints => 172698;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 9951;
|
||||
public virtual long DataPoints => 5469;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -160,7 +160,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$2.15"},
|
||||
{"Estimated Strategy Capacity", "$100000000.00"},
|
||||
{"Estimated Strategy Capacity", "$130000000.00"},
|
||||
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
|
||||
{"Portfolio Turnover", "41.23%"},
|
||||
{"OrderListHash", "b9f8e1a0704c086944e5df07e0ab04d6"}
|
||||
|
||||
@@ -34,6 +34,6 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 15813;
|
||||
public override long DataPoints => 9079;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
}
|
||||
|
||||
return universe.Select(x => x);
|
||||
return universe;
|
||||
});
|
||||
|
||||
_milk.SetFilter(universe =>
|
||||
@@ -94,7 +94,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
return universe.Select(x => x);
|
||||
return universe;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 596356;
|
||||
public long DataPoints => 445961;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 19886;
|
||||
public long DataPoints => 10883;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -98,7 +98,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "1"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "-99.258%"},
|
||||
{"Compounding Annual Return", "-99.012%"},
|
||||
{"Drawdown", "6.300%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Future;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm reproducing GH issue #8386 and other related bugs.
|
||||
/// It asserts that open positions are liquidated when a contract is delisted, even if the contract was added as an internal subscription.
|
||||
/// It also asserts that the contract is not tradable after being delisted.
|
||||
/// </summary>
|
||||
public class ContinuousFutureOpenPositionsLiquidationOnDelistingRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Future _continuousContract;
|
||||
private Symbol _prevContractSymbol;
|
||||
private bool _traded;
|
||||
private bool _mapped;
|
||||
private bool _delistedContractChecked;
|
||||
private DateTime _firstMappedContractRemovalTime;
|
||||
private int _removalCount;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2013, 10, 08);
|
||||
SetEndDate(2013, 12, 30);
|
||||
|
||||
_continuousContract = AddFuture(Futures.Indices.SP500EMini,
|
||||
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
|
||||
dataMappingMode: DataMappingMode.OpenInterest,
|
||||
contractDepthOffset: 0
|
||||
);
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (!_traded && _continuousContract.HasData)
|
||||
{
|
||||
var ticket = MarketOrder(_continuousContract.Mapped, 1);
|
||||
if (ticket.Status == OrderStatus.Invalid)
|
||||
{
|
||||
throw new RegressionTestException($"Order should be valid: {ticket}");
|
||||
}
|
||||
_traded = true;
|
||||
}
|
||||
|
||||
if (slice.SymbolChangedEvents.Count > 0)
|
||||
{
|
||||
foreach (var change in slice.SymbolChangedEvents.Values)
|
||||
{
|
||||
Debug($"[{Time}] :: Mapping: {change}");
|
||||
_prevContractSymbol = Symbol(change.OldSymbol);
|
||||
_mapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_delistedContractChecked &&
|
||||
_prevContractSymbol != null &&
|
||||
Time.Date > _prevContractSymbol.ID.Date &&
|
||||
IsMarketOpen(_prevContractSymbol))
|
||||
{
|
||||
_delistedContractChecked = true;
|
||||
var delistedContract = Securities.Total.Single(sec => sec.Symbol == _prevContractSymbol);
|
||||
|
||||
if (delistedContract.Invested)
|
||||
{
|
||||
throw new RegressionTestException($"Position should be closed when {_prevContractSymbol} got delisted {_prevContractSymbol.ID.Date}");
|
||||
}
|
||||
|
||||
if (!delistedContract.IsDelisted)
|
||||
{
|
||||
throw new RegressionTestException($"Contract should be delisted: {delistedContract.Symbol}");
|
||||
}
|
||||
|
||||
if (delistedContract.IsTradable)
|
||||
{
|
||||
throw new RegressionTestException($"Contract should not be tradable: {delistedContract.Symbol}");
|
||||
}
|
||||
|
||||
var ticket = MarketOrder(_prevContractSymbol, 1);
|
||||
|
||||
if (ticket.Status != OrderStatus.Invalid)
|
||||
{
|
||||
throw new RegressionTestException($"Delisted contract order should be invalid: {ticket}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSecuritiesChanged(SecurityChanges changes)
|
||||
{
|
||||
if (_prevContractSymbol != null)
|
||||
{
|
||||
if (changes.RemovedSecurities.Any(x => x.Symbol == _prevContractSymbol))
|
||||
{
|
||||
throw new RegressionTestException($"Previous contract symbol {_prevContractSymbol} should not be removed as a non-internal security");
|
||||
}
|
||||
|
||||
changes.FilterInternalSecurities = false;
|
||||
|
||||
if (!changes.RemovedSecurities.Any(x => x.Symbol == _prevContractSymbol))
|
||||
{
|
||||
throw new RegressionTestException($"Previous contract symbol {_prevContractSymbol} should be removed as an internal security");
|
||||
}
|
||||
|
||||
_firstMappedContractRemovalTime = Time;
|
||||
_removalCount++;
|
||||
}
|
||||
|
||||
changes.FilterInternalSecurities = false;
|
||||
Debug($"[{Time}] :: {changes}");
|
||||
}
|
||||
|
||||
public override void OnOrderEvent(OrderEvent orderEvent)
|
||||
{
|
||||
Debug($"[{Time}] :: Order event: {orderEvent}");
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (!_traded)
|
||||
{
|
||||
throw new RegressionTestException("No trades have been made");
|
||||
}
|
||||
|
||||
if (!_mapped)
|
||||
{
|
||||
throw new RegressionTestException("No mapping events have been fired");
|
||||
}
|
||||
|
||||
if (!_delistedContractChecked)
|
||||
{
|
||||
throw new RegressionTestException("No delisted contract has been checked");
|
||||
}
|
||||
|
||||
if (_prevContractSymbol == null)
|
||||
{
|
||||
throw new RegressionTestException("No previous contract symbol has been set");
|
||||
}
|
||||
|
||||
var tradedContract = Securities.Total.Single(sec => sec.Symbol == _prevContractSymbol);
|
||||
if (tradedContract.Invested)
|
||||
{
|
||||
throw new RegressionTestException($"Position should be closed when {_prevContractSymbol} got delisted on {_prevContractSymbol.ID.Date}");
|
||||
}
|
||||
|
||||
if (_firstMappedContractRemovalTime == default || _firstMappedContractRemovalTime >= _prevContractSymbol.ID.Date)
|
||||
{
|
||||
throw new RegressionTestException($"First mapped contract should have been removed before it's expiry date");
|
||||
}
|
||||
|
||||
if (_removalCount != 1)
|
||||
{
|
||||
throw new RegressionTestException($"The mapped contract should have been removed once only");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 159274;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "2"},
|
||||
{"Average Win", "7.02%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "34.386%"},
|
||||
{"Drawdown", "1.500%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "107016.6"},
|
||||
{"Net Profit", "7.017%"},
|
||||
{"Sharpe Ratio", "3.217"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "99.828%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "100%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0.227"},
|
||||
{"Beta", "0.109"},
|
||||
{"Annual Standard Deviation", "0.084"},
|
||||
{"Annual Variance", "0.007"},
|
||||
{"Information Ratio", "-1.122"},
|
||||
{"Tracking Error", "0.112"},
|
||||
{"Treynor Ratio", "2.49"},
|
||||
{"Total Fees", "$2.15"},
|
||||
{"Estimated Strategy Capacity", "$1700000000.00"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "2.01%"},
|
||||
{"OrderListHash", "838e662caaa5a385c43ef27df1efbaf4"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ using QuantConnect.Data;
|
||||
using QuantConnect.Orders;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Data.Market;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Securities.Future;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
@@ -31,7 +30,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// </summary>
|
||||
public class ContinuousFutureRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private List<SymbolChangedEvent> _mappings = new();
|
||||
private List<Symbol> _previousMappedContractSymbols = new();
|
||||
private Symbol _currentMappedSymbol;
|
||||
private Future _continuousContract;
|
||||
private DateTime _lastMonth;
|
||||
@@ -77,7 +76,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
if (changedEvent.Symbol == _continuousContract.Symbol)
|
||||
{
|
||||
_mappings.Add(changedEvent);
|
||||
_previousMappedContractSymbols.Add(Symbol(changedEvent.OldSymbol));
|
||||
Log($"{Time} - SymbolChanged event: {changedEvent}");
|
||||
|
||||
if (_currentMappedSymbol == _continuousContract.Mapped)
|
||||
@@ -144,15 +143,20 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
var expectedMappingCounts = 2;
|
||||
if (_mappings.Count != expectedMappingCounts)
|
||||
if (_previousMappedContractSymbols.Count != expectedMappingCounts)
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected symbol changed events: {_mappings.Count}, was expecting {expectedMappingCounts}");
|
||||
throw new RegressionTestException($"Unexpected symbol changed events: {_previousMappedContractSymbols.Count}, was expecting {expectedMappingCounts}");
|
||||
}
|
||||
|
||||
var securities = Securities.Total.Where(sec => !sec.IsTradable && !sec.Symbol.IsCanonical() && sec.Symbol.SecurityType == SecurityType.Future).ToList();
|
||||
if (securities.Count != 1)
|
||||
var delistedSecurities = _previousMappedContractSymbols
|
||||
.Select(x => Securities.Total.Single(sec => sec.Symbol == x))
|
||||
.Where(x => x.Symbol.ID.Date < Time)
|
||||
.ToList();
|
||||
var markedDelistedSecurities = delistedSecurities.Where(x => x.IsDelisted && !x.IsTradable).ToList();
|
||||
if (markedDelistedSecurities.Count != delistedSecurities.Count)
|
||||
{
|
||||
throw new RegressionTestException($"We should have a single non tradable future contract security! found: {securities.Count}");
|
||||
throw new RegressionTestException($"Not all delisted contracts are properly market as delisted and non-tradable: " +
|
||||
$"only {markedDelistedSecurities.Count} are marked, was expecting {delistedSecurities.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +173,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 713369;
|
||||
public long DataPoints => 162575;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -186,18 +190,18 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "3"},
|
||||
{"Average Win", "1.50%"},
|
||||
{"Total Orders", "4"},
|
||||
{"Average Win", "0.84%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "3.337%"},
|
||||
{"Compounding Annual Return", "3.380%"},
|
||||
{"Drawdown", "1.600%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "101666.4"},
|
||||
{"Net Profit", "1.666%"},
|
||||
{"Sharpe Ratio", "0.594"},
|
||||
{"Sortino Ratio", "0.198"},
|
||||
{"Probabilistic Sharpe Ratio", "44.801%"},
|
||||
{"End Equity", "101687.3"},
|
||||
{"Net Profit", "1.687%"},
|
||||
{"Sharpe Ratio", "0.605"},
|
||||
{"Sortino Ratio", "0.202"},
|
||||
{"Probabilistic Sharpe Ratio", "45.198%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "100%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
@@ -205,14 +209,14 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Beta", "0.134"},
|
||||
{"Annual Standard Deviation", "0.027"},
|
||||
{"Annual Variance", "0.001"},
|
||||
{"Information Ratio", "-2.69"},
|
||||
{"Information Ratio", "-2.687"},
|
||||
{"Tracking Error", "0.075"},
|
||||
{"Treynor Ratio", "0.119"},
|
||||
{"Treynor Ratio", "0.121"},
|
||||
{"Total Fees", "$6.45"},
|
||||
{"Estimated Strategy Capacity", "$8000000000.00"},
|
||||
{"Estimated Strategy Capacity", "$2600000000.00"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "1.39%"},
|
||||
{"OrderListHash", "40c1137e0bc83b2bc920495af119c8fc"}
|
||||
{"Portfolio Turnover", "1.88%"},
|
||||
{"OrderListHash", "1287c3b983c5bac6491bb5ac296c4b55"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Securities;
|
||||
using QuantConnect.Securities.Future;
|
||||
using System;
|
||||
using QuantConnect.Util;
|
||||
using System.Linq;
|
||||
using NodaTime;
|
||||
using QuantConnect.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data, regardless of the
|
||||
/// offset between the exchange time zone and the data time zone.
|
||||
/// </summary>
|
||||
public abstract class ContinuousFutureRolloverBaseRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
const string Ticker = Futures.Indices.SP500EMini;
|
||||
|
||||
private Future _continuousContract;
|
||||
|
||||
private DateTime _rolloverTime;
|
||||
|
||||
private MarketHoursDatabase.Entry _originalMhdbEntry;
|
||||
|
||||
protected abstract Resolution Resolution { get; }
|
||||
|
||||
protected abstract Offset ExchangeToDataTimeZoneOffset { get; }
|
||||
|
||||
private DateTimeZone DataTimeZone => TimeZones.Utc;
|
||||
|
||||
private DateTimeZone ExchangeTimeZone => DateTimeZone.ForOffset(ExchangeToDataTimeZoneOffset);
|
||||
|
||||
private bool RolloverHappened => _rolloverTime != DateTime.MinValue;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2013, 10, 8);
|
||||
SetEndDate(2013, 12, 20);
|
||||
|
||||
_originalMhdbEntry = MarketHoursDatabase.GetEntry(Market.CME, Ticker, SecurityType.Future);
|
||||
var exchangeHours = new SecurityExchangeHours(ExchangeTimeZone,
|
||||
_originalMhdbEntry.ExchangeHours.Holidays,
|
||||
_originalMhdbEntry.ExchangeHours.MarketHours.ToDictionary(),
|
||||
_originalMhdbEntry.ExchangeHours.EarlyCloses,
|
||||
_originalMhdbEntry.ExchangeHours.LateOpens);
|
||||
MarketHoursDatabase.SetEntry(Market.CME, Ticker, SecurityType.Future, exchangeHours, DataTimeZone);
|
||||
|
||||
SetTimeZone(ExchangeTimeZone);
|
||||
|
||||
_continuousContract = AddFuture(Ticker,
|
||||
Resolution,
|
||||
extendedMarketHours: true,
|
||||
dataNormalizationMode: DataNormalizationMode.Raw,
|
||||
dataMappingMode: DataMappingMode.OpenInterest,
|
||||
contractDepthOffset: 0
|
||||
);
|
||||
|
||||
SetBenchmark(x => 0);
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
try
|
||||
{
|
||||
var receivedRollover = false;
|
||||
foreach (var (symbol, symbolChangedEvent) in slice.SymbolChangedEvents)
|
||||
{
|
||||
if (RolloverHappened)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] -- Unexpected symbol changed event for {symbol}. Expected only one mapping.");
|
||||
}
|
||||
|
||||
receivedRollover = true;
|
||||
_rolloverTime = symbolChangedEvent.EndTime;
|
||||
|
||||
var oldSymbol = symbolChangedEvent.OldSymbol;
|
||||
var newSymbol = symbolChangedEvent.NewSymbol;
|
||||
Debug($"[{Time}] -- Rollover: {oldSymbol} -> {newSymbol}");
|
||||
|
||||
if (symbol != _continuousContract.Symbol)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] -- Unexpected symbol changed event for {symbol}");
|
||||
}
|
||||
|
||||
var expectedMappingDate = new DateTime(2013, 12, 18);
|
||||
if (_rolloverTime != expectedMappingDate)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] -- Unexpected date {_rolloverTime}. Expected {expectedMappingDate}");
|
||||
}
|
||||
|
||||
var expectedMappingOldSymbol = "ES VMKLFZIH2MTD";
|
||||
var expectedMappingNewSymbol = "ES VP274HSU1AF5";
|
||||
if (symbolChangedEvent.OldSymbol != expectedMappingOldSymbol || symbolChangedEvent.NewSymbol != expectedMappingNewSymbol)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] -- Unexpected mapping. " +
|
||||
$"Expected {expectedMappingOldSymbol} -> {expectedMappingNewSymbol} " +
|
||||
$"but was {symbolChangedEvent.OldSymbol} -> {symbolChangedEvent.NewSymbol}");
|
||||
}
|
||||
}
|
||||
|
||||
var mappedFuture = Securities[_continuousContract.Mapped];
|
||||
var mappedFuturePrice = mappedFuture.Price;
|
||||
|
||||
var otherFuture = Securities.Values.SingleOrDefault(x => !x.Symbol.IsCanonical() && x.Symbol != _continuousContract.Mapped);
|
||||
var otherFuturePrice = otherFuture?.Price;
|
||||
|
||||
var continuousContractPrice = _continuousContract.Price;
|
||||
|
||||
Debug($"[{Time}] Contracts prices:\n" +
|
||||
$" -- Mapped future: {mappedFuture.Symbol} :: {mappedFuture.Price} :: {mappedFuture.GetLastData()}\n" +
|
||||
$" -- Other future: {otherFuture?.Symbol} :: {otherFuture?.Price} :: {otherFuture?.GetLastData()}\n" +
|
||||
$" -- Mapped future from continuous contract: {_continuousContract.Symbol} :: {_continuousContract.Mapped} :: " +
|
||||
$"{_continuousContract.Price} :: {_continuousContract.GetLastData()}\n");
|
||||
|
||||
if (receivedRollover)
|
||||
{
|
||||
if (continuousContractPrice != otherFuturePrice)
|
||||
{
|
||||
var continuousContractLastData = _continuousContract.GetLastData();
|
||||
throw new RegressionTestException($"[{Time}] -- Prices do not match. " +
|
||||
$"At the time of the rollover, expected continuous future price to be the same as " +
|
||||
$"the previously mapped contract since no data for the new mapped contract has been received:\n" +
|
||||
$" Continuous contract ({_continuousContract.Symbol}) price: " +
|
||||
$"{continuousContractPrice} :: {continuousContractLastData.Symbol.Underlying} :: " +
|
||||
$"{continuousContractLastData.Time} - {continuousContractLastData.EndTime} :: {continuousContractLastData}. \n" +
|
||||
$" Mapped contract ({mappedFuture.Symbol}) price: {mappedFuturePrice} :: {mappedFuture.GetLastData()}. \n" +
|
||||
$" Other contract ({otherFuture?.Symbol}) price: {otherFuturePrice} :: {otherFuture?.GetLastData()}\n");
|
||||
}
|
||||
}
|
||||
else if (mappedFuturePrice != 0 || !RolloverHappened)
|
||||
{
|
||||
if (continuousContractPrice != mappedFuturePrice)
|
||||
{
|
||||
var continuousContractLastData = _continuousContract.GetLastData();
|
||||
throw new RegressionTestException($"[{Time}] -- Prices do not match. " +
|
||||
$"Expected continuous future price to be the same as the mapped contract:\n" +
|
||||
$" Continuous contract ({_continuousContract.Symbol}) price: {continuousContractPrice} :: " +
|
||||
$"{continuousContractLastData.Symbol.Underlying} :: {continuousContractLastData}. \n" +
|
||||
$" Mapped contract ({mappedFuture.Symbol}) price: {mappedFuturePrice} :: {mappedFuture.GetLastData()}. \n" +
|
||||
$" Other contract ({otherFuture?.Symbol}) price: {otherFuturePrice} :: {otherFuture?.GetLastData()}\n");
|
||||
}
|
||||
}
|
||||
// No data for the mapped future yet after rollover
|
||||
else
|
||||
{
|
||||
if (otherFuture == null)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] --" +
|
||||
$" Mapped future price is 0 (no data has arrived) so the previous mapped contract is expected to be there");
|
||||
}
|
||||
|
||||
var continuousContractLastData = _continuousContract.GetLastData();
|
||||
|
||||
if (continuousContractLastData.EndTime > _rolloverTime)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] -- Expected continuous future contract last data to be from the previously " +
|
||||
$"mapped contract until the new mapped contract gets data:\n" +
|
||||
$" Rollover time: {_rolloverTime}\n" +
|
||||
$" Continuous contract ({_continuousContract.Symbol}) last data: " +
|
||||
$"{continuousContractLastData.Symbol.Underlying} :: " +
|
||||
$"{continuousContractLastData.Time} - {continuousContractLastData.EndTime} :: {continuousContractLastData}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ResetMarketHoursDatabase();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
ResetMarketHoursDatabase();
|
||||
|
||||
if (!RolloverHappened)
|
||||
{
|
||||
throw new RegressionTestException($"[{Time}] -- Rollover did not happen.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetMarketHoursDatabase()
|
||||
{
|
||||
MarketHoursDatabase.SetEntry(Market.CME, Ticker, SecurityType.Future, _originalMhdbEntry.ExchangeHours, _originalMhdbEntry.DataTimeZone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the exchange time zone is ahead of the data time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverDailyExchangeTimeZoneAheadOfDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Daily;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(2);
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 483;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the exchange time zone is behind of the data time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverDailyExchangeTimeZoneBehindOfDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Daily;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(-2);
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 479;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the data time zone is the same as the exchange time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverDailyExchangeTimeZoneSameAsDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Daily;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 483;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the exchange time zone is ahead of the data time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverHourExchangeTimeZoneAheadOfDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Hour;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(2);
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 7424;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the exchange time zone is behind of the data time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverHourExchangeTimeZoneBehindOfDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Hour;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(-2);
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 7440;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the data time zone is the same as the exchange time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverHourExchangeTimeZoneSameAsDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Hour;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 7434;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the exchange time zone is ahead of the data time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverMinuteExchangeTimeZoneAheadOfDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Minute;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(2);
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 444159;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the exchange time zone is behind of the data time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverMinuteExchangeTimeZoneBehindOfDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Minute;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.FromHours(-2);
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 445123;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for regression algorithms testing that when a continuous future rollover happens,
|
||||
/// the continuous contract is updated correctly with the new contract data.
|
||||
/// The algorithms asserts the behavior for the case when the data time zone is the same as the exchange time zone.
|
||||
/// </summary>
|
||||
public class ContinuousFutureRolloverMinuteExchangeTimeZoneSameAsDataRegressionAlgorithm
|
||||
: ContinuousFutureRolloverBaseRegressionAlgorithm
|
||||
{
|
||||
protected override Resolution Resolution => Resolution.Minute;
|
||||
|
||||
protected override Offset ExchangeToDataTimeZoneOffset => Offset.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 444757;
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 1267;
|
||||
public long DataPoints => 848;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
134
Algorithm.CSharp/CorrelationTypeComparisonRegressionAlgorithm.cs
Normal file
134
Algorithm.CSharp/CorrelationTypeComparisonRegressionAlgorithm.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Interfaces;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares two correlation types and asserts they are not equal during the algorithm's execution.
|
||||
/// </summary>
|
||||
public class CorrelationTypeComparisonRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Correlation _correlationPearson;
|
||||
private Correlation _correlationSpearman;
|
||||
|
||||
/// <summary>
|
||||
/// Initialise the data and resolution required, as well as the start-end dates for your algorithm. All algorithms must initialized.
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2013, 10, 08); //Set Start Date
|
||||
SetEndDate(2013, 10, 17); //Set End Date
|
||||
var symbol = AddEquity("AAPL", Resolution.Daily).Symbol;
|
||||
var spy = AddEquity("SPY", Resolution.Daily).Symbol;
|
||||
_correlationPearson = C(symbol, spy, 5, CorrelationType.Pearson);
|
||||
_correlationSpearman = C(symbol, spy, 5, CorrelationType.Spearman);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
|
||||
/// </summary>
|
||||
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (_correlationPearson.IsReady && _correlationSpearman.IsReady)
|
||||
{
|
||||
var pearsonValue = _correlationPearson.Current.Value;
|
||||
var spearmanValue = _correlationSpearman.Current.Value;
|
||||
|
||||
// Check that the correlation values are not the same
|
||||
if (pearsonValue == spearmanValue)
|
||||
{
|
||||
// Throw an exception if the correlation values are equal
|
||||
throw new RegressionTestException($"Error: Pearson and Spearman correlation values are the same: Pearson = {pearsonValue}, Spearman = {spearmanValue}. This should not happen.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// End of algorithm run event handler. This method is called at the end of a backtest or live trading operation. Intended for closing out logs.
|
||||
/// </summary>
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (!_correlationPearson.IsReady || !_correlationSpearman.IsReady)
|
||||
{
|
||||
throw new RegressionTestException("Error: Both correlation values should be ready at the end of the algorithm.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally => true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 80;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-19.184"},
|
||||
{"Tracking Error", "0.138"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,8 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2011, 9, 13);
|
||||
SetEndDate(2015, 12, 01);
|
||||
SetStartDate(2020, 01, 05);
|
||||
SetEndDate(2020, 01, 10);
|
||||
|
||||
//Set the cash for the strategy:
|
||||
SetCash(100000);
|
||||
@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 10491;
|
||||
public long DataPoints => 57;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -129,30 +129,30 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "1"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "155.211%"},
|
||||
{"Drawdown", "84.800%"},
|
||||
{"Compounding Annual Return", "34781.071%"},
|
||||
{"Drawdown", "4.300%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "5223241.65"},
|
||||
{"Net Profit", "5123.242%"},
|
||||
{"Sharpe Ratio", "2.058"},
|
||||
{"Sortino Ratio", "2.492"},
|
||||
{"Probabilistic Sharpe Ratio", "68.833%"},
|
||||
{"End Equity", "110102.2"},
|
||||
{"Net Profit", "10.102%"},
|
||||
{"Sharpe Ratio", "283.719"},
|
||||
{"Sortino Ratio", "1123.876"},
|
||||
{"Probabilistic Sharpe Ratio", "81.716%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "1.724"},
|
||||
{"Beta", "0.043"},
|
||||
{"Annual Standard Deviation", "0.841"},
|
||||
{"Annual Variance", "0.707"},
|
||||
{"Information Ratio", "1.902"},
|
||||
{"Tracking Error", "0.848"},
|
||||
{"Treynor Ratio", "40.293"},
|
||||
{"Alpha", "184.11"},
|
||||
{"Beta", "-6.241"},
|
||||
{"Annual Standard Deviation", "0.635"},
|
||||
{"Annual Variance", "0.403"},
|
||||
{"Information Ratio", "260.511"},
|
||||
{"Tracking Error", "0.689"},
|
||||
{"Treynor Ratio", "-28.849"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "BTC.Bitcoin 2S"},
|
||||
{"Portfolio Turnover", "0.06%"},
|
||||
{"OrderListHash", "999305e00ec9861f5ff261794e81213d"}
|
||||
{"Portfolio Turnover", "16.73%"},
|
||||
{"OrderListHash", "b890a8e73bf118e943ad2f2e712f12d0"}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -168,6 +168,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public decimal High { get; set; }
|
||||
[JsonProperty("low")]
|
||||
public decimal Low { get; set; }
|
||||
public decimal Mid { get; set; }
|
||||
[JsonProperty("last")]
|
||||
public decimal Close { get; set; }
|
||||
[JsonProperty("bid")]
|
||||
@@ -217,7 +218,10 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
//return "http://my-ftp-server.com/futures-data-" + date.ToString("Ymd") + ".zip";
|
||||
// OR simply return a fixed small data file. Large files will slow down your backtest
|
||||
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/quandl/api/v3/datasets/BCHARTS/BITSTAMPUSD.csv?order=asc&api_key=WyAazVXnq7ATy_fefTqm", SubscriptionTransportMedium.RemoteFile);
|
||||
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=WyAazVXnq7ATy_fefTqm")
|
||||
{
|
||||
Sort = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -248,20 +252,20 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
}
|
||||
|
||||
//Example Line Format:
|
||||
//Date Open High Low Close Volume (BTC) Volume (Currency) Weighted Price
|
||||
//2011-09-13 5.8 6.0 5.65 5.97 58.37138238, 346.0973893944 5.929230648356
|
||||
// code date high low mid last bid ask volume
|
||||
// BTCUSD 2024-10-08 63248.0 61940.0 62246.5 62245.0 62246.0 62247.0 5.929230648356
|
||||
try
|
||||
{
|
||||
string[] data = line.Split(',');
|
||||
coin.Time = DateTime.Parse(data[0], CultureInfo.InvariantCulture);
|
||||
coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture);
|
||||
coin.EndTime = coin.Time.AddDays(1);
|
||||
coin.Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture);
|
||||
coin.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture);
|
||||
coin.Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture);
|
||||
coin.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
|
||||
coin.VolumeBTC = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
|
||||
coin.VolumeUSD = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
|
||||
coin.WeightedPrice = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
|
||||
coin.Mid = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
|
||||
coin.Close = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
|
||||
coin.Bid = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
|
||||
coin.Ask = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
|
||||
coin.VolumeBTC = Convert.ToDecimal(data[8], CultureInfo.InvariantCulture);
|
||||
coin.Value = coin.Close;
|
||||
}
|
||||
catch { /* Do nothing, skip first title row */ }
|
||||
|
||||
@@ -33,15 +33,15 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <meta name="tag" content="regression test" />
|
||||
public class CustomDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private bool _warmedUpChecked = false;
|
||||
private bool _warmedUpChecked;
|
||||
|
||||
/// <summary>
|
||||
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2011, 9, 14);
|
||||
SetEndDate(2015, 12, 01);
|
||||
SetStartDate(2020, 01, 05);
|
||||
SetEndDate(2020, 01, 10);
|
||||
|
||||
//Set the cash for the strategy:
|
||||
SetCash(100000);
|
||||
@@ -110,7 +110,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 8943;
|
||||
public long DataPoints => 50;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -130,30 +130,30 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "1"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "155.365%"},
|
||||
{"Drawdown", "84.800%"},
|
||||
{"Compounding Annual Return", "27587.925%"},
|
||||
{"Drawdown", "4.200%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "5223170.23"},
|
||||
{"Net Profit", "5123.170%"},
|
||||
{"Sharpe Ratio", "2.094"},
|
||||
{"Sortino Ratio", "2.535"},
|
||||
{"Probabilistic Sharpe Ratio", "69.967%"},
|
||||
{"End Equity", "109685"},
|
||||
{"Net Profit", "9.685%"},
|
||||
{"Sharpe Ratio", "238.834"},
|
||||
{"Sortino Ratio", "945.079"},
|
||||
{"Probabilistic Sharpe Ratio", "81.660%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "1.753"},
|
||||
{"Beta", "0.055"},
|
||||
{"Annual Standard Deviation", "0.84"},
|
||||
{"Annual Variance", "0.706"},
|
||||
{"Information Ratio", "1.942"},
|
||||
{"Tracking Error", "0.848"},
|
||||
{"Treynor Ratio", "32.18"},
|
||||
{"Alpha", "149.482"},
|
||||
{"Beta", "-6.002"},
|
||||
{"Annual Standard Deviation", "0.61"},
|
||||
{"Annual Variance", "0.371"},
|
||||
{"Information Ratio", "218.36"},
|
||||
{"Tracking Error", "0.664"},
|
||||
{"Treynor Ratio", "-24.253"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "BTC.Bitcoin 2S"},
|
||||
{"Portfolio Turnover", "0.06%"},
|
||||
{"OrderListHash", "e69e78cd6fe7bc4627da2f51e25539d0"}
|
||||
{"Portfolio Turnover", "16.03%"},
|
||||
{"OrderListHash", "dde8821614d33c89e6e75c536447b7da"}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -169,6 +169,8 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public decimal High { get; set; }
|
||||
[JsonProperty("low")]
|
||||
public decimal Low { get; set; }
|
||||
public decimal Mid { get; set; }
|
||||
|
||||
[JsonProperty("last")]
|
||||
public decimal Close { get; set; }
|
||||
[JsonProperty("bid")]
|
||||
@@ -179,7 +181,6 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public decimal WeightedPrice { get; set; }
|
||||
[JsonProperty("volume")]
|
||||
public decimal VolumeBTC { get; set; }
|
||||
public decimal VolumeUSD { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The end time of this data. Some data covers spans (trade bars)
|
||||
@@ -218,7 +219,10 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
|
||||
//return "http://my-ftp-server.com/futures-data-" + date.ToString("Ymd") + ".zip";
|
||||
// OR simply return a fixed small data file. Large files will slow down your backtest
|
||||
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/quandl/api/v3/datasets/BCHARTS/BITSTAMPUSD.csv?order=asc&api_key=WyAazVXnq7ATy_fefTqm", SubscriptionTransportMedium.RemoteFile);
|
||||
return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=qAWKpUfmSVFnU3bRQwKy")
|
||||
{
|
||||
Sort = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -249,20 +253,20 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
}
|
||||
|
||||
//Example Line Format:
|
||||
//Date Open High Low Close Volume (BTC) Volume (Currency) Weighted Price
|
||||
//2011-09-13 5.8 6.0 5.65 5.97 58.37138238, 346.0973893944 5.929230648356
|
||||
// code date high low mid last bid ask volume
|
||||
// BTCUSD 2024-10-08 63248.0 61940.0 62246.5 62245.0 62246.0 62247.0 477.91102114
|
||||
try
|
||||
{
|
||||
string[] data = line.Split(',');
|
||||
coin.Time = DateTime.Parse(data[0], CultureInfo.InvariantCulture);
|
||||
coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture);
|
||||
coin.EndTime = coin.Time.AddDays(1);
|
||||
coin.Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture);
|
||||
coin.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture);
|
||||
coin.Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture);
|
||||
coin.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
|
||||
coin.VolumeBTC = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
|
||||
coin.VolumeUSD = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
|
||||
coin.WeightedPrice = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
|
||||
coin.Mid = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture);
|
||||
coin.Close = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture);
|
||||
coin.Bid = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture);
|
||||
coin.Ask = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture);
|
||||
coin.VolumeBTC = Convert.ToDecimal(data[8], CultureInfo.InvariantCulture);
|
||||
coin.Value = coin.Close;
|
||||
}
|
||||
catch { /* Do nothing, skip first title row */ }
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Interfaces;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm asserting that the option chain data has valid open interest values for daily resolution.
|
||||
/// Reproduces GH issue #8421.
|
||||
/// </summary>
|
||||
public class DailyOptionChainOpenInterestDataWithStrictDailyEndTimesRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Symbol _symbol;
|
||||
|
||||
private List<decimal> _openInterests = new();
|
||||
|
||||
public virtual bool DailyPreciseEndTime => true;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
Settings.DailyPreciseEndTime = DailyPreciseEndTime;
|
||||
|
||||
SetStartDate(2014, 06, 01);
|
||||
SetEndDate(2014, 07, 06);
|
||||
|
||||
var option = AddOption("AAPL", Resolution.Daily);
|
||||
option.SetFilter(-5, +5, 0, 365);
|
||||
|
||||
_symbol = option.Symbol;
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (slice.OptionChains.TryGetValue(_symbol, out var chain) && chain.Contracts.Count > 0)
|
||||
{
|
||||
var openInterest = chain.Sum(x => x.OpenInterest);
|
||||
_openInterests.Add(openInterest);
|
||||
Debug($"[{Time}] Sum of open interest: {openInterest}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (_openInterests.Count == 0)
|
||||
{
|
||||
throw new RegressionTestException("No option chain data was received by the algorithm.");
|
||||
}
|
||||
|
||||
if (_openInterests.All(x => x == 0))
|
||||
{
|
||||
throw new RegressionTestException("Contracts received didn't have valid open interest values.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 47132;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-5.732"},
|
||||
{"Tracking Error", "0.05"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm asserting that the option chain data has valid open interest values for daily resolution.
|
||||
/// Reproduces GH issue #8421.
|
||||
/// </summary>
|
||||
public class DailyOptionChainOpenInterestDataWithoutStrictDailyEndTimesRegressionAlgorithm : DailyOptionChainOpenInterestDataWithStrictDailyEndTimesRegressionAlgorithm
|
||||
{
|
||||
public override bool DailyPreciseEndTime => false;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 46264;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests indicator behavior when "DailyPreciseEndTime" is disabled,
|
||||
/// ensuring updates occur at midnight and values remain consistent.
|
||||
/// </summary>
|
||||
public class DailyResolutionVsTimeSpanNoPreciseEndRegressionAlgorithm : DailyResolutionVsTimeSpanRegressionAlgorithm
|
||||
{
|
||||
// Disables precise end time, considering the full day instead.
|
||||
protected override bool DailyPreciseEndTime => false;
|
||||
|
||||
protected override void SetupFirstIndicatorUpdatedHandler()
|
||||
{
|
||||
RelativeStrengthIndex1.Updated += (sender, data) =>
|
||||
{
|
||||
var updatedTime = Time;
|
||||
|
||||
// RSI1 should update at midnight when precise end time is disabled
|
||||
if (updatedTime.TimeOfDay != new TimeSpan(0, 0, 0))
|
||||
{
|
||||
throw new RegressionTestException($"{RelativeStrengthIndex1.Name} must have updated at midnight, but it was updated at {updatedTime}");
|
||||
}
|
||||
|
||||
// Since RSI1 updates before RSI2, it should have exactly one extra sample
|
||||
if (RelativeStrengthIndex1.Samples - 1 != RelativeStrengthIndex2.Samples)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 must have 1 extra sample");
|
||||
}
|
||||
|
||||
// RSI1's previous value should match RSI2's current value, ensuring consistency
|
||||
if (RelativeStrengthIndex1.Previous.Value != RelativeStrengthIndex2.Current.Value)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 and RSI2 must have same value");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (RelativeStrengthIndex1.Current.Value != RelativeStrengthIndex2.Current.Value)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 and RSI2 must have same value");
|
||||
}
|
||||
if (RelativeStrengthIndex1.Samples <= 20 || RelativeStrengthIndex2.Samples != RelativeStrengthIndex1.Samples)
|
||||
{
|
||||
throw new RegressionTestException("The number of samples must be the same and greater than 20");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
210
Algorithm.CSharp/DailyResolutionVsTimeSpanRegressionAlgorithm.cs
Normal file
210
Algorithm.CSharp/DailyResolutionVsTimeSpanRegressionAlgorithm.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data.Market;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Interfaces;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// This algorithm tests the behavior of indicators with different update mechanisms based on resolution and time span.
|
||||
/// </summary>
|
||||
public class DailyResolutionVsTimeSpanRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
protected Symbol Spy { get; set; }
|
||||
protected RelativeStrengthIndex RelativeStrengthIndex1 { get; set; }
|
||||
protected RelativeStrengthIndex RelativeStrengthIndex2 { get; set; }
|
||||
protected virtual bool DailyPreciseEndTime => true;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
InitializeBaseSettings();
|
||||
|
||||
Settings.DailyPreciseEndTime = DailyPreciseEndTime;
|
||||
|
||||
// First RSI: Updates at market close (4 PM) by default
|
||||
// If DailyPreciseEndTime is false, updates at midnight (12:00 AM)
|
||||
RelativeStrengthIndex1 = new RelativeStrengthIndex(14, MovingAverageType.Wilders);
|
||||
RegisterIndicator(Spy, RelativeStrengthIndex1, Resolution.Daily);
|
||||
|
||||
// Second RSI: Updates every 24 hours (from 12:00 AM to 12:00 AM) using a time span
|
||||
RelativeStrengthIndex2 = new RelativeStrengthIndex(14, MovingAverageType.Wilders);
|
||||
RegisterIndicator(Spy, RelativeStrengthIndex2, TimeSpan.FromDays(1));
|
||||
|
||||
// Warm up indicators with historical data
|
||||
var history = History<TradeBar>(Spy, 20, Resolution.Daily).ToList();
|
||||
foreach (var bar in history)
|
||||
{
|
||||
RelativeStrengthIndex1.Update(bar.EndTime, bar.Close);
|
||||
RelativeStrengthIndex2.Update(bar.EndTime, bar.Close);
|
||||
}
|
||||
if (!RelativeStrengthIndex1.IsReady || !RelativeStrengthIndex2.IsReady)
|
||||
{
|
||||
throw new RegressionTestException("Indicators not ready.");
|
||||
}
|
||||
|
||||
SetupFirstIndicatorUpdatedHandler();
|
||||
SetupSecondIndicatorUpdatedHandler();
|
||||
}
|
||||
|
||||
protected virtual void InitializeBaseSettings()
|
||||
{
|
||||
SetStartDate(2013, 01, 01);
|
||||
SetEndDate(2013, 01, 05);
|
||||
Spy = AddEquity("SPY", Resolution.Hour).Symbol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the first RSI indicator
|
||||
/// Validates update timing and sample consistency
|
||||
/// </summary>
|
||||
protected virtual void SetupFirstIndicatorUpdatedHandler()
|
||||
{
|
||||
RelativeStrengthIndex1.Updated += (sender, data) =>
|
||||
{
|
||||
var updatedTime = Time;
|
||||
|
||||
// Ensure RSI1 updates exactly at market close (4 PM)
|
||||
if (updatedTime.TimeOfDay != new TimeSpan(16, 0, 0))
|
||||
{
|
||||
throw new RegressionTestException($"RSI1 must have updated at 4 PM, but it updated at {updatedTime}.");
|
||||
}
|
||||
|
||||
// Since RSI1 updates before RSI2, it should have one extra sample
|
||||
if (RelativeStrengthIndex1.Samples - 1 != RelativeStrengthIndex2.Samples)
|
||||
{
|
||||
throw new RegressionTestException("First RSI indicator should have exactly one more sample than the second indicator.");
|
||||
}
|
||||
|
||||
// RSI1's previous value should match RSI2's current value, ensuring consistency
|
||||
if (RelativeStrengthIndex1.Previous.Value != RelativeStrengthIndex2.Current.Value)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 and RSI2 must have same value");
|
||||
}
|
||||
|
||||
// RSI1's and RSI2's current values should be different
|
||||
if (RelativeStrengthIndex1.Current.Value == RelativeStrengthIndex2.Current.Value)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 and RSI2 must have different values");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the second RSI indicator
|
||||
/// Validates update timing and sample consistency
|
||||
/// </summary>
|
||||
protected virtual void SetupSecondIndicatorUpdatedHandler()
|
||||
{
|
||||
RelativeStrengthIndex2.Updated += (sender, data) =>
|
||||
{
|
||||
var updatedTime = Time;
|
||||
|
||||
// RSI2 updates at midnight, ensure the update time is correct
|
||||
if (updatedTime.TimeOfDay != new TimeSpan(0, 0, 0))
|
||||
{
|
||||
throw new RegressionTestException($"RSI2 must have updated at midnight, but it was updated at {updatedTime}");
|
||||
}
|
||||
|
||||
// Since RSI2 updates later, it must now have the same number of samples as RSI1
|
||||
if (RelativeStrengthIndex1.Samples != RelativeStrengthIndex2.Samples)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 must have same number of samples as RSI2");
|
||||
}
|
||||
|
||||
// At this point, RSI1 and RSI2 should have the same value
|
||||
if (RelativeStrengthIndex1.Current.Value != RelativeStrengthIndex2.Current.Value)
|
||||
{
|
||||
throw new RegressionTestException("RSI1 and RSI2 must have same value");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (RelativeStrengthIndex1.Samples <= 20)
|
||||
{
|
||||
throw new RegressionTestException("The number of samples must be greater than 20");
|
||||
}
|
||||
if (RelativeStrengthIndex1.Samples <= 20)
|
||||
{
|
||||
throw new RegressionTestException("The number of samples must be greater than 20");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages { get; } = new() { Language.CSharp };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 50;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 20;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-38.725"},
|
||||
{"Tracking Error", "0.232"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
public class DailyResolutionVsTimeSpanWithMinuteEquityAlgorithm : DailyResolutionVsTimeSpanRegressionAlgorithm
|
||||
{
|
||||
protected override void InitializeBaseSettings()
|
||||
{
|
||||
SetStartDate(2013, 10, 04);
|
||||
SetEndDate(2013, 10, 05);
|
||||
Spy = AddEquity("SPY", Resolution.Minute).Symbol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 795;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
public class DailyResolutionVsTimeSpanWithSecondResolutionEquityAlgorithm : DailyResolutionVsTimeSpanRegressionAlgorithm
|
||||
{
|
||||
protected override void InitializeBaseSettings()
|
||||
{
|
||||
SetStartDate(2013, 10, 07);
|
||||
SetEndDate(2013, 10, 08);
|
||||
Spy = AddEquity("SPY", Resolution.Second).Symbol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 93622;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
public class DailyResolutionVsTimeSpanWithTickResolutionEquityAlgorithm : DailyResolutionVsTimeSpanRegressionAlgorithm
|
||||
{
|
||||
protected override void InitializeBaseSettings()
|
||||
{
|
||||
SetStartDate(2013, 10, 07);
|
||||
SetEndDate(2013, 10, 08);
|
||||
Spy = AddEquity("SPY", Resolution.Tick).Symbol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 6877089;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 516622;
|
||||
public long DataPoints => 70735;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 1679;
|
||||
public override long DataPoints => 1235;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
@@ -38,30 +38,30 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "2"},
|
||||
{"Average Win", "7.78%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "38.564%"},
|
||||
{"Compounding Annual Return", "38.609%"},
|
||||
{"Drawdown", "0.200%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "107779.1"},
|
||||
{"Net Profit", "7.779%"},
|
||||
{"Sharpe Ratio", "3.132"},
|
||||
{"Sharpe Ratio", "3.128"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "99.474%"},
|
||||
{"Probabilistic Sharpe Ratio", "99.450%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "100%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0.145"},
|
||||
{"Beta", "0.271"},
|
||||
{"Annual Standard Deviation", "0.081"},
|
||||
{"Annual Variance", "0.006"},
|
||||
{"Annual Variance", "0.007"},
|
||||
{"Information Ratio", "-1.459"},
|
||||
{"Tracking Error", "0.099"},
|
||||
{"Treynor Ratio", "0.932"},
|
||||
{"Treynor Ratio", "0.931"},
|
||||
{"Total Fees", "$2.15"},
|
||||
{"Estimated Strategy Capacity", "$150000000000.00"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "1.98%"},
|
||||
{"OrderListHash", "b337ac27f46a6298dd4e9f0f04b49427"}
|
||||
{"OrderListHash", "6365adfc234509e390295a150f25c295"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 525809;
|
||||
public virtual long DataPoints => 288140;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -124,18 +124,18 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "100%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0.228"},
|
||||
{"Beta", "0.108"},
|
||||
{"Alpha", "0.227"},
|
||||
{"Beta", "0.109"},
|
||||
{"Annual Standard Deviation", "0.084"},
|
||||
{"Annual Variance", "0.007"},
|
||||
{"Information Ratio", "-1.122"},
|
||||
{"Tracking Error", "0.112"},
|
||||
{"Treynor Ratio", "2.501"},
|
||||
{"Treynor Ratio", "2.49"},
|
||||
{"Total Fees", "$2.15"},
|
||||
{"Estimated Strategy Capacity", "$1700000000.00"},
|
||||
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
|
||||
{"Portfolio Turnover", "2.01%"},
|
||||
{"OrderListHash", "640ce720644ff0b580687e80105d0a92"}
|
||||
{"OrderListHash", "de82efe4f019a5fa1fb79d111bf15811"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Orders;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
@@ -29,7 +28,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 12251;
|
||||
public override long DataPoints => 3918;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
|
||||
@@ -13,13 +13,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Orders;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
@@ -107,7 +105,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 4632655;
|
||||
public virtual long DataPoints => 761073;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -131,10 +129,10 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Drawdown", "0.100%"},
|
||||
{"Expectancy", "-0.678"},
|
||||
{"Start Equity", "10000000"},
|
||||
{"End Equity", "9988860.24"},
|
||||
{"End Equity", "9988880.24"},
|
||||
{"Net Profit", "-0.111%"},
|
||||
{"Sharpe Ratio", "-10.413"},
|
||||
{"Sortino Ratio", "-0.961"},
|
||||
{"Sharpe Ratio", "-10.416"},
|
||||
{"Sortino Ratio", "-0.959"},
|
||||
{"Probabilistic Sharpe Ratio", "0.000%"},
|
||||
{"Loss Rate", "80%"},
|
||||
{"Win Rate", "20%"},
|
||||
@@ -145,12 +143,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "-1.076"},
|
||||
{"Tracking Error", "0.107"},
|
||||
{"Treynor Ratio", "14.588"},
|
||||
{"Treynor Ratio", "14.634"},
|
||||
{"Total Fees", "$19.76"},
|
||||
{"Estimated Strategy Capacity", "$1300000000.00"},
|
||||
{"Estimated Strategy Capacity", "$1400000000.00"},
|
||||
{"Lowest Capacity Asset", "DC V5E8PHPRCHJ8|DC V5E8P9SH0U0X"},
|
||||
{"Portfolio Turnover", "0.00%"},
|
||||
{"OrderListHash", "7f06f736e2f1294916fb2485519021a2"}
|
||||
{"OrderListHash", "67b64c13cbc4aad88111503cf7b789bc"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using System.Globalization;
|
||||
using QuantConnect.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// The regression algorithm showcases the utilization of a custom data source with the Sort flag set to true.
|
||||
/// This means that the source initially provides data in descending order, which is then organized into ascending order and returned in the <see cref="OnData(Slice)"/> function.
|
||||
/// </summary>
|
||||
public class DescendingCustomDataObjectStoreRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
protected virtual string CustomDataKey => "CustomData/SortCustomData";
|
||||
|
||||
protected readonly static string[] descendingCustomData = new string[]
|
||||
{
|
||||
"2024-10-03 19:00:00,173.5,176.0,172.0,175.2,120195681,4882.29",
|
||||
"2024-10-02 18:00:00,174.0,177.0,173.0,175.8,116275729,4641.97",
|
||||
"2024-10-01 17:00:00,175.0,178.0,172.5,174.5,127707078,6591.27",
|
||||
"2024-09-30 11:00:00,174.8,176.5,172.8,175.0,127707078,6591.27",
|
||||
"2024-09-27 10:00:00,172.5,175.0,171.5,173.5,120195681,4882.29",
|
||||
"2024-09-26 09:00:00,171.0,172.5,170.0,171.8,117516350,4820.53",
|
||||
"2024-09-25 08:00:00,169.5,172.0,169.0,171.0,110427867,4661.55",
|
||||
"2024-09-24 07:00:00,170.0,171.0,168.0,169.5,127624733,4823.52",
|
||||
"2024-09-23 06:00:00,172.0,173.5,169.5,171.5,123586417,4303.93",
|
||||
"2024-09-20 05:00:00,168.0,171.0,167.5,170.5,151929179,5429.87",
|
||||
"2024-09-19 04:00:00,170.5,171.5,166.0,167.0,160523863,5219.24",
|
||||
"2024-09-18 03:00:00,173.0,174.0,169.0,172.0,145721790,5163.09",
|
||||
"2024-09-17 02:00:00,171.0,173.5,170.0,172.5,144794030,5405.72",
|
||||
"2024-09-16 01:00:00,168.0,171.0,167.0,170.0,214402430,8753.33",
|
||||
"2024-09-13 16:00:00,173.5,176.0,172.0,175.2,120195681,4882.29",
|
||||
"2024-09-12 15:00:00,174.5,177.5,173.5,176.5,171728134,7774.83",
|
||||
"2024-09-11 14:00:00,175.0,178.0,174.0,175.5,191516153,8349.59",
|
||||
"2024-09-10 13:00:00,174.5,176.0,173.0,174.0,151162819,5915.8",
|
||||
"2024-09-09 12:00:00,176.0,178.0,175.0,177.0,116275729,4641.97"
|
||||
};
|
||||
|
||||
private Symbol _customSymbol;
|
||||
|
||||
private List<SortCustomData> _receivedData = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2024, 09, 09);
|
||||
SetEndDate(2024, 10, 03);
|
||||
SetCash(100000);
|
||||
|
||||
SetBenchmark(x => 0);
|
||||
|
||||
SortCustomData.CustomDataKey = CustomDataKey;
|
||||
|
||||
_customSymbol = AddData<SortCustomData>("SortCustomData", Resolution.Daily).Symbol;
|
||||
|
||||
// Saving data here for demonstration and regression testing purposes.
|
||||
// In real scenarios, data has to be saved to the object store before the algorithm starts.
|
||||
ObjectStore.Save(CustomDataKey, string.Join("\n", descendingCustomData));
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
if (slice.ContainsKey(_customSymbol))
|
||||
{
|
||||
var sortCustomData = slice.Get<SortCustomData>(_customSymbol);
|
||||
if (sortCustomData.Open == 0 || sortCustomData.High == 0 || sortCustomData.Low == 0 || sortCustomData.Close == 0 || sortCustomData.Price == 0)
|
||||
{
|
||||
throw new RegressionTestException("One or more custom data fields (Open, High, Low, Close, Price) are zero.");
|
||||
}
|
||||
|
||||
_receivedData.Add(sortCustomData);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEndOfAlgorithm()
|
||||
{
|
||||
if (_receivedData.Count == 0)
|
||||
{
|
||||
throw new RegressionTestException("Custom data was not fetched");
|
||||
}
|
||||
|
||||
var history = History<SortCustomData>(_customSymbol, StartDate, EndDate, Resolution.Hour).ToList();
|
||||
|
||||
if (history.Count != _receivedData.Count)
|
||||
{
|
||||
throw new RegressionTestException("History request returned different data than expected");
|
||||
}
|
||||
|
||||
// Iterate through the history collection, checking if the EndTime is in ascending order.
|
||||
for (int i = 0; i < history.Count - 1; i++)
|
||||
{
|
||||
if (history[i].EndTime > history[i + 1].EndTime)
|
||||
{
|
||||
throw new RegressionTestException($"Order failure: {history[i].EndTime} > {history[i + 1].EndTime} at index {i}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally => true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public List<Language> Languages => new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all TimeSlices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 20;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 19;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new ()
|
||||
{
|
||||
{"Total Orders", "0"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "100000"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$0.00"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", ""},
|
||||
{"Portfolio Turnover", "0%"},
|
||||
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
|
||||
};
|
||||
}
|
||||
|
||||
public class SortCustomData : BaseData
|
||||
{
|
||||
public static string CustomDataKey { get; set; }
|
||||
|
||||
public decimal Open { get; set; }
|
||||
public decimal High { get; set; }
|
||||
public decimal Low { get; set; }
|
||||
public decimal Close { get; set; }
|
||||
|
||||
public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
|
||||
{
|
||||
return new SubscriptionDataSource(CustomDataKey, SubscriptionTransportMedium.ObjectStore, FileFormat.Csv)
|
||||
{
|
||||
// Indicate that the data from the subscription will be returned in descending order.
|
||||
Sort = true
|
||||
};
|
||||
}
|
||||
|
||||
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
|
||||
{
|
||||
var csv = line.Split(",");
|
||||
var data = new SortCustomData()
|
||||
{
|
||||
Symbol = config.Symbol,
|
||||
Time = DateTime.ParseExact(csv[0], DateFormat.DB, CultureInfo.InvariantCulture),
|
||||
Value = csv[4].ToDecimal(),
|
||||
Open = csv[1].ToDecimal(),
|
||||
High = csv[2].ToDecimal(),
|
||||
Low = csv[3].ToDecimal(),
|
||||
Close = csv[4].ToDecimal()
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 94731;
|
||||
public long DataPoints => 36213;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -150,7 +150,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "8"},
|
||||
{"Average Win", "0.69%"},
|
||||
{"Average Loss", "-2.47%"},
|
||||
{"Compounding Annual Return", "-99.966%"},
|
||||
{"Compounding Annual Return", "-99.946%"},
|
||||
{"Drawdown", "28.600%"},
|
||||
{"Expectancy", "-0.680"},
|
||||
{"Start Equity", "100000"},
|
||||
|
||||
@@ -117,6 +117,16 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
throw new RegressionTestException("Expected to try to exercise option before and on expiry");
|
||||
}
|
||||
|
||||
var optionHoldings = Securities[_contract.Symbol].Holdings;
|
||||
if (optionHoldings.NetProfit != Portfolio.TotalNetProfit)
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected holdings profit result {optionHoldings.Profit}");
|
||||
}
|
||||
if (Portfolio.Cash != (Portfolio.TotalNetProfit + 200000))
|
||||
{
|
||||
throw new RegressionTestException($"Unexpected portfolio cash {Portfolio.Cash}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -150,8 +160,8 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "2"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "-4.10%"},
|
||||
{"Average Win", "0.68%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "24.075%"},
|
||||
{"Drawdown", "1.900%"},
|
||||
{"Expectancy", "0"},
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 872;
|
||||
public long DataPoints => 852;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using QuantConnect.Data;
|
||||
using System.Globalization;
|
||||
using QuantConnect.Interfaces;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -56,7 +57,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
if (slice.ContainsKey("SPX"))
|
||||
{
|
||||
var spxData = slice.Bars["SPX"];
|
||||
var message = $"{Time} ==== FF {spxData.IsFillForward}. {spxData} {spxData.Time:HH:mm:ss}->{spxData.EndTime:HH:mm:ss}";
|
||||
var message = $"{Time.ToString(CultureInfo.GetCultureInfo("en-US"))} ==== FF {spxData.IsFillForward}. {spxData.ToString().Replace(',', '.')} {spxData.Time:HH:mm:ss}->{spxData.EndTime:HH:mm:ss}";
|
||||
_data.AppendLine(message);
|
||||
Debug(message);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 54138;
|
||||
public long DataPoints => 19043;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
@@ -114,7 +114,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Total Orders", "1"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "-99.310%"},
|
||||
{"Compounding Annual Return", "-98.880%"},
|
||||
{"Drawdown", "4.400%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 13586;
|
||||
public virtual long DataPoints => 91;
|
||||
|
||||
/// </summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -25,21 +25,25 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
protected override bool ExtendedMarketHours => true;
|
||||
protected override List<DateTime> AfterMarketOpen => new List<DateTime>() {
|
||||
new DateTime(2020, 02, 04, 18, 0, 0), // Tuesday
|
||||
new DateTime(2020, 02, 05, 18, 0, 0),
|
||||
new DateTime(2020, 02, 06, 18, 0, 0),
|
||||
new DateTime(2020, 02, 09, 18, 0, 0),
|
||||
new DateTime(2020, 02, 10, 18, 0, 0),
|
||||
new DateTime(2020, 02, 11, 18, 0, 0)
|
||||
new DateTime(2020, 02, 04, 0, 0, 0), // Tuesday
|
||||
new DateTime(2020, 02, 05, 0, 0, 0),
|
||||
new DateTime(2020, 02, 06, 0, 0, 0),
|
||||
new DateTime(2020, 02, 07, 0, 0, 0),
|
||||
new DateTime(2020, 02, 09, 18, 0, 0), // sunday
|
||||
new DateTime(2020, 02, 10, 0, 0, 0),
|
||||
new DateTime(2020, 02, 11, 0, 0, 0),
|
||||
new DateTime(2020, 02, 12, 0, 0, 0)
|
||||
};
|
||||
protected override List<DateTime> BeforeMarketClose => new List<DateTime>()
|
||||
{
|
||||
new DateTime(2020, 02, 04, 17, 0, 0),
|
||||
new DateTime(2020, 02, 05, 17, 0, 0),
|
||||
new DateTime(2020, 02, 06, 17, 0, 0),
|
||||
new DateTime(2020, 02, 07, 17, 0, 0),
|
||||
new DateTime(2020, 02, 10, 17, 0, 0),
|
||||
new DateTime(2020, 02, 11, 17, 0, 0)
|
||||
new DateTime(2020, 02, 04, 0, 0, 0),
|
||||
new DateTime(2020, 02, 05, 0, 0, 0),
|
||||
new DateTime(2020, 02, 06, 0, 0, 0),
|
||||
new DateTime(2020, 02, 07, 0, 0, 0),
|
||||
new DateTime(2020, 02, 07, 17, 0, 0), // friday
|
||||
new DateTime(2020, 02, 10, 0, 0, 0),
|
||||
new DateTime(2020, 02, 11, 0, 0, 0),
|
||||
new DateTime(2020, 02, 12, 0, 0, 0)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -50,7 +54,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 41466;
|
||||
public override long DataPoints => 92;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
SetStartDate(2013, 10, 06);
|
||||
SetEndDate(2013, 10, 14);
|
||||
|
||||
Settings.DailyConsolidationUseExtendedMarketHours = true;
|
||||
var es = AddSecurity(SecurityType.Future, "ES", extendedMarketHours: ExtendedMarketHours);
|
||||
|
||||
_expectedOpensQueue = new Queue<DateTime>(ExpectedOpens);
|
||||
@@ -93,7 +94,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public virtual long DataPoints => 32071;
|
||||
public virtual long DataPoints => 16313;
|
||||
|
||||
/// </summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -29,19 +29,24 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
protected override bool ExtendedMarketHours => true;
|
||||
protected override List<DateTime> ExpectedOpens => new List<DateTime>(){
|
||||
new DateTime(2013, 10, 06, 18, 0, 0), // Sunday
|
||||
new DateTime(2013, 10, 07, 18, 0, 0),
|
||||
new DateTime(2013, 10, 08, 18, 0, 0),
|
||||
new DateTime(2013, 10, 09, 18, 0, 0),
|
||||
new DateTime(2013, 10, 10, 18, 0, 0),
|
||||
// market is open for the whole day, so goes from midnight to midnight
|
||||
new DateTime(2013, 10, 07, 0, 0, 0),
|
||||
new DateTime(2013, 10, 08, 0, 0, 0),
|
||||
new DateTime(2013, 10, 09, 0, 0, 0),
|
||||
new DateTime(2013, 10, 10, 0, 0, 0),
|
||||
new DateTime(2013, 10, 11, 0, 0, 0),
|
||||
new DateTime(2013, 10, 13, 18, 0, 0),
|
||||
new DateTime(2013, 10, 14, 0, 0, 0),
|
||||
};
|
||||
protected override List<DateTime> ExpectedCloses => new List<DateTime>(){
|
||||
new DateTime(2013, 10, 07, 17, 0, 0),
|
||||
new DateTime(2013, 10, 08, 17, 0, 0),
|
||||
new DateTime(2013, 10, 09, 17, 0, 0),
|
||||
new DateTime(2013, 10, 10, 17, 0, 0),
|
||||
new DateTime(2013, 10, 11, 17, 0, 0),
|
||||
new DateTime(2013, 10, 14, 17, 0, 0),
|
||||
new DateTime(2013, 10, 07, 0, 0, 0),
|
||||
new DateTime(2013, 10, 08, 0, 0, 0),
|
||||
new DateTime(2013, 10, 09, 0, 0, 0),
|
||||
new DateTime(2013, 10, 10, 0, 0, 0),
|
||||
new DateTime(2013, 10, 11, 0, 0, 0),
|
||||
new DateTime(2013, 10, 11, 17, 0, 0), // friday
|
||||
new DateTime(2013, 10, 14, 0, 0, 0),
|
||||
new DateTime(2013, 10, 15, 0, 0, 0),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -52,7 +57,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public override long DataPoints => 103816;
|
||||
public override long DataPoints => 51933;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 18492;
|
||||
public long DataPoints => 11768;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
|
||||
@@ -112,12 +112,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 309280;
|
||||
public long DataPoints => 309282;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 2;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -150,7 +150,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Annual Variance", "0.005"},
|
||||
{"Information Ratio", "-0.134"},
|
||||
{"Tracking Error", "0.385"},
|
||||
{"Treynor Ratio", "3.784"},
|
||||
{"Treynor Ratio", "3.785"},
|
||||
{"Total Fees", "$2.84"},
|
||||
{"Estimated Strategy Capacity", "$120000000.00"},
|
||||
{"Lowest Capacity Asset", "ES XFH59UPBIJ7O|ES XFH59UK0MYO1"},
|
||||
|
||||
@@ -200,12 +200,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 212195;
|
||||
public long DataPoints => 212196;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -238,7 +238,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Annual Variance", "0.004"},
|
||||
{"Information Ratio", "-0.226"},
|
||||
{"Tracking Error", "0.378"},
|
||||
{"Treynor Ratio", "-21.838"},
|
||||
{"Treynor Ratio", "-21.841"},
|
||||
{"Total Fees", "$1.42"},
|
||||
{"Estimated Strategy Capacity", "$120000000.00"},
|
||||
{"Lowest Capacity Asset", "ES XFH59UPBIJ7O|ES XFH59UK0MYO1"},
|
||||
|
||||
@@ -165,12 +165,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 212195;
|
||||
public long DataPoints => 212196;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -203,7 +203,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Annual Variance", "0.098"},
|
||||
{"Information Ratio", "-0.649"},
|
||||
{"Tracking Error", "0.483"},
|
||||
{"Treynor Ratio", "-18.589"},
|
||||
{"Treynor Ratio", "-18.59"},
|
||||
{"Total Fees", "$7.10"},
|
||||
{"Estimated Strategy Capacity", "$24000000.00"},
|
||||
{"Lowest Capacity Asset", "ES XFH59UPBIJ7O|ES XFH59UK0MYO1"},
|
||||
|
||||
@@ -176,12 +176,12 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 212195;
|
||||
public long DataPoints => 212196;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 0;
|
||||
public int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
@@ -214,7 +214,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{"Annual Variance", "0.003"},
|
||||
{"Information Ratio", "-0.198"},
|
||||
{"Tracking Error", "0.377"},
|
||||
{"Treynor Ratio", "-23.06"},
|
||||
{"Treynor Ratio", "-23.065"},
|
||||
{"Total Fees", "$1.42"},
|
||||
{"Estimated Strategy Capacity", "$180000000.00"},
|
||||
{"Lowest Capacity Asset", "ES XFH59UPHGV9G|ES XFH59UK0MYO1"},
|
||||
|
||||
127
Algorithm.CSharp/FutureOptionChainFullDataRegressionAlgorithm.cs
Normal file
127
Algorithm.CSharp/FutureOptionChainFullDataRegressionAlgorithm.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm illustrating the usage of the <see cref="QCAlgorithm.OptionChain(Symbol)"/> method
|
||||
/// to get a future option chain.
|
||||
/// </summary>
|
||||
public class FutureOptionChainFullDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Symbol _optionContract;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2020, 1, 6);
|
||||
SetEndDate(2020, 1, 6);
|
||||
|
||||
var futureContract = AddFutureContract(
|
||||
QuantConnect.Symbol.CreateFuture(Futures.Indices.SP500EMini, Market.CME, new DateTime(2020, 3, 20)),
|
||||
Resolution.Minute).Symbol;
|
||||
|
||||
_optionContract = OptionChain(futureContract)
|
||||
// Get contracts expiring within 4 months
|
||||
.Where(contractData => contractData.Expiry - Time <= TimeSpan.FromDays(120))
|
||||
// Get the contract with the latest expiration date, highest strike and lowest price
|
||||
.OrderByDescending(x => x.Expiry)
|
||||
.ThenByDescending(x => x.Strike)
|
||||
.ThenBy(x => x.LastPrice)
|
||||
.First();
|
||||
|
||||
AddFutureOptionContract(_optionContract);
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
// Do some trading with the selected contract for sample purposes
|
||||
if (!Portfolio.Invested)
|
||||
{
|
||||
SetHoldings(_optionContract, 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
Liquidate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public virtual List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 1817;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "450"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "65398.86"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$34601.14"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "ES XCZJLCGM383O|ES XCZJLC9NOB29"},
|
||||
{"Portfolio Turnover", "112.25%"},
|
||||
{"OrderListHash", "f18259d04c2d899e7162b88e10239eb8"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.Market;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression algorithm illustrating the usage of the <see cref="QCAlgorithm.OptionChains(IEnumerable{Symbol})"/> method
|
||||
/// to get multiple future option chains.
|
||||
/// </summary>
|
||||
public class FutureOptionChainsMultipleFullDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
|
||||
{
|
||||
private Symbol _esOptionContract;
|
||||
private Symbol _gcOptionContract;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SetStartDate(2020, 1, 6);
|
||||
SetEndDate(2020, 1, 6);
|
||||
SetCash(100000);
|
||||
|
||||
var esFutureContract = AddFutureContract(
|
||||
QuantConnect.Symbol.CreateFuture(Futures.Indices.SP500EMini, Market.CME, new DateTime(2020, 3, 20)),
|
||||
Resolution.Minute).Symbol;
|
||||
|
||||
var gcFutureContract = AddFutureContract(
|
||||
QuantConnect.Symbol.CreateFuture(Futures.Metals.Gold, Market.COMEX, new DateTime(2020, 4, 28)),
|
||||
Resolution.Minute).Symbol;
|
||||
|
||||
var chains = OptionChains([esFutureContract, gcFutureContract]);
|
||||
|
||||
_esOptionContract = GetContract(chains, esFutureContract);
|
||||
_gcOptionContract = GetContract(chains, gcFutureContract);
|
||||
|
||||
AddFutureOptionContract(_esOptionContract);
|
||||
AddFutureOptionContract(_gcOptionContract);
|
||||
}
|
||||
|
||||
private Symbol GetContract(OptionChains chains, Symbol underlying)
|
||||
{
|
||||
return chains
|
||||
.Where(kvp => kvp.Key.Underlying == underlying)
|
||||
.Select(kvp => kvp.Value)
|
||||
.Single()
|
||||
// Get contracts expiring within 5 months
|
||||
.Where(contractData => contractData.Expiry - Time <= TimeSpan.FromDays(120))
|
||||
// Get the contract with the latest expiration date, highest strike and lowest price
|
||||
.OrderByDescending(x => x.Expiry)
|
||||
.ThenByDescending(x => x.Strike)
|
||||
.ThenBy(x => x.LastPrice)
|
||||
.First();
|
||||
}
|
||||
|
||||
public override void OnData(Slice slice)
|
||||
{
|
||||
// Do some trading with the selected contract for sample purposes
|
||||
if (!Portfolio.Invested)
|
||||
{
|
||||
SetHoldings(_esOptionContract, 0.25);
|
||||
SetHoldings(_gcOptionContract, 0.25);
|
||||
}
|
||||
else
|
||||
{
|
||||
Liquidate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
|
||||
/// </summary>
|
||||
public bool CanRunLocally { get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate which languages this algorithm is written in.
|
||||
/// </summary>
|
||||
public virtual List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of all timeslices of algorithm
|
||||
/// </summary>
|
||||
public long DataPoints => 1819;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public int AlgorithmHistoryDataPoints => 2;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
/// </summary>
|
||||
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
|
||||
{
|
||||
{"Total Orders", "450"},
|
||||
{"Average Win", "0%"},
|
||||
{"Average Loss", "0%"},
|
||||
{"Compounding Annual Return", "0%"},
|
||||
{"Drawdown", "0%"},
|
||||
{"Expectancy", "0"},
|
||||
{"Start Equity", "100000"},
|
||||
{"End Equity", "80983.36"},
|
||||
{"Net Profit", "0%"},
|
||||
{"Sharpe Ratio", "0"},
|
||||
{"Sortino Ratio", "0"},
|
||||
{"Probabilistic Sharpe Ratio", "0%"},
|
||||
{"Loss Rate", "0%"},
|
||||
{"Win Rate", "0%"},
|
||||
{"Profit-Loss Ratio", "0"},
|
||||
{"Alpha", "0"},
|
||||
{"Beta", "0"},
|
||||
{"Annual Standard Deviation", "0"},
|
||||
{"Annual Variance", "0"},
|
||||
{"Information Ratio", "0"},
|
||||
{"Tracking Error", "0"},
|
||||
{"Treynor Ratio", "0"},
|
||||
{"Total Fees", "$19016.64"},
|
||||
{"Estimated Strategy Capacity", "$0"},
|
||||
{"Lowest Capacity Asset", "ES XCZJLCGM383O|ES XCZJLC9NOB29"},
|
||||
{"Portfolio Turnover", "49.52%"},
|
||||
{"OrderListHash", "9b39296a82d51d51fa1df02aad39d804"}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public virtual int AlgorithmHistoryDataPoints => 0;
|
||||
public virtual int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public override int AlgorithmHistoryDataPoints => 0;
|
||||
public override int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Final status of the algorithm
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
{
|
||||
public class FutureOptionIndicatorsRegressionAlgorithm : OptionIndicatorsRegressionAlgorithm
|
||||
{
|
||||
protected override string ExpectedGreeks { get; set; } = "Implied Volatility: 0.14008,Delta: 0.63466,Gamma: 0.00209,Vega: 5.61442,Theta: -0.48254,Rho: 0.03098";
|
||||
protected override string ExpectedGreeks { get; set; } = "Implied Volatility: 0.13941,Delta: 0.63509,Gamma: 0.00209,Vega: 5.64129,Theta: -0.47731,Rho: 0.03145";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -51,6 +51,11 @@ namespace QuantConnect.Algorithm.CSharp
|
||||
/// </summary>
|
||||
public override long DataPoints => 1817;
|
||||
|
||||
/// <summary>
|
||||
/// Data Points count of the algorithm history
|
||||
/// </summary>
|
||||
public override int AlgorithmHistoryDataPoints => 1;
|
||||
|
||||
/// <summary>
|
||||
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
|
||||
/// </summary>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user