Compare commits

..

1 Commits
17090 ... 16640

Author SHA1 Message Date
Martin Molinero
9ec60cb994 Improve shutdown 2024-09-19 17:59:04 -03:00
1167 changed files with 18650 additions and 90245 deletions

View File

@@ -1,43 +1,33 @@
{
"name": "Lean Development Container",
"workspaceMount": "source=${localWorkspaceFolder},target=/Lean,type=bind",
"workspaceFolder": "/Lean",
// Use devcontainer Dockerfile that is based on Lean foundation image
"build": {
"dockerfile": "Dockerfile"
},
//See https://containers.dev/implementors/json_reference/ for a comprehensive json schema used to define this file.
"customizations": {
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-dotnettools.csdevkit",
"ms-python.python",
"eamodio.gitlens",
"yzhang.markdown-all-in-one",
"SonarSource.sonarlint-vscode"
],
// Set *default* vscode specific settings.json values on container create.
"settings": {
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash"
}
}
"build": { "dockerfile": "Dockerfile" },
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash"
}
}
},
//use the same network configuration as the host machine, ensuring no problems with firewalls, proxies etc.
"runArgs": [
"--network=host"
],
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["ms-dotnettools.csharp", "ms-python.python", "ms-python.vscode-pylance", "formulahendry.dotnet-test-explorer", "eamodio.gitlens", "yzhang.markdown-all-in-one"],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment the next line to run commands after the container is created - for example installing curl.
"postCreateCommand": "dotnet nuget add source /Lean/LocalPackages;chmod u+x /Lean/.vscode/launch_research.sh;dos2unix /Lean/.vscode/launch_research.sh",
// Add mounts to docker container
"mounts": [
"mounts": [
// Example data mount from local machine, must use target directory in Config.json
// "source=C:/Users/XXXXXXXXXXXX/Lean/Data,target=/Data,type=bind,consistency=cached"
]

View File

@@ -1 +0,0 @@
blank_issues_enabled: false

View File

@@ -1,26 +0,0 @@
---
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 -->

View File

@@ -1,11 +1,4 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
<!--- This template provides sections for bugs and features. Please delete any irrelevant sections before submitting -->
#### Expected Behavior
<!--- Required. Describe the behavior you expect to see for your case. -->
@@ -31,4 +24,4 @@ assignees: ''
<!--- 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 -->

View File

@@ -9,19 +9,14 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.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: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- 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: Run API Tests
uses: addnab/docker-run-action@v3
with:
@@ -32,4 +27,4 @@ jobs:
# Build
dotnet build /p:Configuration=Release /v:quiet /p:WarningLevel=1 QuantConnect.Lean.sln
# Run Projects tests
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --blame-hang-timeout 7minutes --blame-crash --logger "console;verbosity=detailed" --filter "FullyQualifiedName=QuantConnect.Tests.API.ProjectTests|FullyQualifiedName=QuantConnect.Tests.API.ObjectStoreTests" -- TestRunParameters.Parameter\(name=\"log-handler\", value=\"ConsoleErrorLogHandler\"\)
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --blame-hang-timeout 300seconds --blame-crash --filter "FullyQualifiedName=QuantConnect.Tests.API.ProjectTests|ObjectStoreTests" -- TestRunParameters.Parameter\(name=\"log-handler\", value=\"ConsoleErrorLogHandler\"\)

View File

@@ -9,20 +9,12 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0 # Ensures we fetch all history
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- 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
- uses: addnab/docker-run-action@v3
with:
@@ -30,15 +22,9 @@ jobs:
options: --workdir /__w/Lean/Lean -v /home/runner/work:/__w -e GITHUB_REF=${{ github.ref }} -e PYPI_API_TOKEN=${{ secrets.PYPI_API_TOKEN }} -e ADDITIONAL_STUBS_REPOS=${{ secrets.ADDITIONAL_STUBS_REPOS }} -e QC_GIT_TOKEN=${{ secrets.QC_GIT_TOKEN }}
shell: bash
run: |
# Add exception
git config --global --add safe.directory /__w/Lean/Lean
# Get Last Commit of the Current Tag
TAG_COMMIT=$(git rev-parse HEAD) && echo "CURRENT BRANCH LAST COMMIT $TAG_COMMIT"
# Get Last Commit of the master
MASTER_COMMIT=$(git rev-parse origin/master) && echo "MASTER BRANCH LAST COMMIT $MASTER_COMMIT"
# Build
dotnet build /p:Configuration=Release /v:quiet /p:WarningLevel=1 QuantConnect.Lean.sln && \
# Run Tests
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --blame-hang-timeout 300seconds --blame-crash --filter "TestCategory!=TravisExclude&TestCategory!=ResearchRegressionTests" -- TestRunParameters.Parameter\(name=\"log-handler\", value=\"ConsoleErrorLogHandler\"\) && \
# Generate & Publish python stubs
echo "GITHUB_REF $GITHUB_REF" && if [[ $GITHUB_REF = refs/tags/* && "$TAG_COMMIT" = "$MASTER_COMMIT" ]]; then echo "Generating stubs" && (chmod +x ci_build_stubs.sh && ./ci_build_stubs.sh -t -g -p); else echo "Skipping stub generation"; fi
echo "GITHUB_REF $GITHUB_REF" && if [[ $GITHUB_REF = refs/tags/* ]]; then (chmod +x ci_build_stubs.sh && ./ci_build_stubs.sh -t -g -p); else echo "Skipping stub generation"; fi

View File

@@ -7,7 +7,7 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:

View File

@@ -9,17 +9,12 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- 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
- uses: addnab/docker-run-action@v3
with:

View File

@@ -9,17 +9,12 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- 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
- uses: addnab/docker-run-action@v3
with:

View File

@@ -9,17 +9,12 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- 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
- uses: addnab/docker-run-action@v3
with:
@@ -30,7 +25,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.607001
dotnet tool install --global Microsoft.dotnet-interactive --version 1.0.340501
# Add dotnet tools to Path
export PATH="$HOME/.dotnet/tools:$PATH"
# activate kernel for jupyter

View File

@@ -1,32 +0,0 @@
name: Syntax Tests
on:
push:
branches: ['*']
tags: ['*']
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v2
- 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 Syntax Test
uses: addnab/docker-run-action@v3
with:
image: quantconnect/lean:foundation
options: --workdir /__w/Lean/Lean -v /home/runner/work:/__w
shell: bash
run: |
pip install --no-cache-dir quantconnect-stubs types-requests==2.32.* mypy==1.15.0 && \
python run_syntax_check.py

View File

@@ -9,17 +9,12 @@ on:
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Liberate disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: false
docker-images: false
swap-storage: false
- 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
- uses: addnab/docker-run-action@v3
with:
@@ -53,10 +48,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|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
dotnet test ./Tests/bin/Release/QuantConnect.Tests.dll --filter "FullyQualifiedName=QuantConnect.Tests.Python.PythonPackagesTests.ShapTest" --blame-hang-timeout 120seconds --blame-crash

View File

@@ -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/key-concepts/getting-started).
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).
<br />
<h2>Option 2: Install Locally</h2>
1. Install [.Net 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) for the project
1. Install [.Net 6](https://dotnet.microsoft.com/download) for the project
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
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
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/key-concepts/getting-started)
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)
<br />

6
.vscode/readme.md vendored
View File

@@ -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 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) for the project
1. Install [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) for the project
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
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
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

View File

@@ -1,151 +0,0 @@
/*
* 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", "9fce77ef8817cf0159897fc64d01f5e9"}
};
}
}

View File

@@ -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}");

View File

@@ -49,7 +49,7 @@ namespace QuantConnect.Algorithm.CSharp
contractDepthOffset: 0
);
_futureContract = AddFutureContract(FuturesChain(_continuousContract.Symbol).First());
_futureContract = AddFutureContract(FutureChainProvider.GetFutureContractList(_continuousContract.Symbol, Time).First());
}
/// <summary>
@@ -115,12 +115,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 61;
public long DataPoints => 73;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 1;
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm

View File

@@ -164,12 +164,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 311881;
public long DataPoints => 311879;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 2;
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm

View File

@@ -93,12 +93,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 9922;
public long DataPoints => 12169;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 2;
public int AlgorithmHistoryDataPoints => 0;
/// <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", "88398927.578%"},
{"Compounding Annual Return", "386219349.202%"},
{"Drawdown", "5.200%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

@@ -108,7 +108,7 @@ namespace QuantConnect.Algorithm.CSharp
return;
}
foreach (var chain in slice.OptionChains.Values.OrderBy(x => x.Symbol.Underlying.ID.Date))
foreach (var chain in slice.OptionChains.Values)
{
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 => 319494;
public long DataPoints => 608377;
/// <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", "309.669%"},
{"Compounding Annual Return", "347.065%"},
{"Drawdown", "0.900%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

@@ -1,130 +0,0 @@
/*
* 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.Algorithm.Framework.Selection;
using QuantConnect.Interfaces;
using System;
using QuantConnect.Securities;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This example demonstrates how to use the FutureUniverseSelectionModel to select futures contracts for a given underlying asset.
/// The model is set to update daily, and the algorithm ensures that the selected contracts meet specific criteria.
/// This also includes a check to ensure that only future contracts are added to the algorithm's universe.
/// </summary>
public class AddFutureUniverseSelectionModelRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
public override void Initialize()
{
SetStartDate(2013, 10, 08);
SetEndDate(2013, 10, 10);
SetUniverseSelection(new FutureUniverseSelectionModel(
TimeSpan.FromDays(1),
time => new List<Symbol> {
QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME)
}
));
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (changes.AddedSecurities.Count > 0)
{
foreach (var security in changes.AddedSecurities)
{
if (security.Symbol.SecurityType != SecurityType.Future)
{
throw new RegressionTestException($"Expected future security, but found '{security.Symbol.SecurityType}'");
}
if (security.Symbol.ID.Symbol != "ES")
{
throw new RegressionTestException($"Expected future symbol 'ES', but found '{security.Symbol.ID.Symbol}");
}
}
}
}
public override void OnEndOfAlgorithm()
{
if (ActiveSecurities.Count == 0)
{
throw new RegressionTestException("No active securities found. Expected at least one active security");
}
}
/// <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 => 26094;
/// <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", "-66.775"},
{"Tracking Error", "0.243"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -160,7 +160,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$5700000.00"},
{"Lowest Capacity Asset", "AOL VRKS95ENLBYE|AOL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.55%"},
{"OrderListHash", "fc5ab25181a01ca5ce39212f60eb0ecd"}
{"OrderListHash", "24191a4a3bf11c07622a21266618193d"}
};
}
}

View File

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
&& optionContract.ID.OptionStyle == OptionStyle.American);
AddOptionContract(option);
foreach (var symbol in new[] { option.Symbol, option.UnderlyingSymbol })
foreach (var symbol in new[] { option.Symbol, option.Underlying.Symbol })
{
var config = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).ToList();

View File

@@ -1,145 +0,0 @@
/*
* 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.Algorithm.Framework.Selection;
using QuantConnect.Interfaces;
using System;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This example demonstrates how to use the OptionUniverseSelectionModel to select options contracts based on specified conditions.
/// The model is updated daily and selects different options based on the current date.
/// The algorithm ensures that only valid option contracts are selected for the universe.
/// </summary>
public class AddOptionUniverseSelectionModelRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private int _optionCount;
public override void Initialize()
{
SetStartDate(2014, 06, 05);
SetEndDate(2014, 06, 06);
UniverseSettings.Resolution = Resolution.Minute;
SetUniverseSelection(new OptionUniverseSelectionModel(
TimeSpan.FromDays(1),
SelectOptionChainSymbols
));
}
private static IEnumerable<Symbol> SelectOptionChainSymbols(DateTime utcTime)
{
var newYorkTime = utcTime.ConvertFromUtc(TimeZones.NewYork);
if (newYorkTime.Date < new DateTime(2014, 06, 06))
{
yield return QuantConnect.Symbol.Create("TWX", SecurityType.Option, Market.USA);
}
if (newYorkTime.Date >= new DateTime(2014, 06, 06))
{
yield return QuantConnect.Symbol.Create("AAPL", SecurityType.Option, Market.USA);
}
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
if (changes.AddedSecurities.Count > 0)
{
foreach (var security in changes.AddedSecurities)
{
var symbol = security.Symbol.Underlying == null ? security.Symbol : security.Symbol.Underlying;
if (symbol != "AAPL" && symbol != "TWX")
{
throw new RegressionTestException($"Unexpected security {security.Symbol}");
}
_optionCount += (security.Symbol.SecurityType == SecurityType.Option) ? 1 : 0;
}
}
}
public override void OnEndOfAlgorithm()
{
if (ActiveSecurities.Count == 0)
{
throw new RegressionTestException("No active securities found. Expected at least one active security");
}
if (_optionCount == 0)
{
throw new RegressionTestException("The option count should be greater than 0");
}
}
/// <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 => 1658167;
/// <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"}
};
}
}

View File

@@ -59,7 +59,7 @@ namespace QuantConnect.Algorithm.CSharp
var ticket = MarketOrder("AIG", 1);
if (ticket.Status != OrderStatus.Invalid || aig.HasData || aig.Price != 0)
if (ticket.Status != OrderStatus.Invalid)
{
throw new RegressionTestException("Expected order to always be invalid because there is no data yet!");
}

View File

@@ -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 = FuturesChain(SP500).First();
_symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).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 => 85;
public int AlgorithmHistoryDataPoints => 84;
/// <summary>
/// Final status of the algorithm

View File

@@ -82,7 +82,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 18;
public int AlgorithmHistoryDataPoints => 21;
/// <summary>
/// Final status of the algorithm

View File

@@ -339,7 +339,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "17.02%"},
{"OrderListHash", "a7ce5ff2bbe0fe273cf1631ea5a73fa6"}
{"OrderListHash", "b1e5e72fb766ab894204bc4b1300912b"}
};
}
}

View File

@@ -18,6 +18,7 @@ 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;
@@ -117,7 +118,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 162575;
public long DataPoints => 713369;
/// <summary>
/// Data Points count of the algorithm history
@@ -160,7 +161,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$7100000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.33%"},
{"OrderListHash", "223735440010fcec5889bb7becacfa82"}
{"OrderListHash", "9c524830ffc7354327638142ae62acd2"}
};
}
}

View File

@@ -123,7 +123,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 504530;
public long DataPoints => 2217299;
/// <summary>
/// Data Points count of the algorithm history
@@ -166,7 +166,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$890000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "2.32%"},
{"OrderListHash", "1504a8892da8d8c0650018732f315753"}
{"OrderListHash", "f60fc7dcba2c1ff077afeb191aee5008"}
};
}
}

View File

@@ -167,7 +167,11 @@ 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);
}
}
}

View File

@@ -56,7 +56,7 @@ namespace QuantConnect.Algorithm.CSharp
_continuousContract.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(180));
_mappedSymbol = _continuousContract.Mapped;
var benchmark = AddIndex("SX5E");
var benchmark = AddIndex("SX5E", market: Market.EUREX);
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 => 94326;
public long DataPoints => 133945;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 0;
public int AlgorithmHistoryDataPoints => 26;
/// <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", "ac9acc478ba1afe53993cdbb92f8ec6e"}
{"OrderListHash", "54040d29a467becaedcf59d79323321b"}
};
}
}

View File

@@ -176,7 +176,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 727;
public long DataPoints => 1190;
/// <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", "a6ccce3a1a7f549f887d83e84bfa878d"}
{"OrderListHash", "273dd05b937c075b75baf8af46d3c7de"}
};
}
}
}

View File

@@ -149,7 +149,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 40308;
public long DataPoints => 75403;
/// <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.597%"},
{"Compounding Annual Return", "-99.777%"},
{"Drawdown", "4.400%"},
{"Expectancy", "-0.724"},
{"Start Equity", "1000000"},

View File

@@ -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,16 +104,6 @@ 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>
@@ -127,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 5861;
public virtual long DataPoints => 12452;
/// <summary>
/// Data Points count of the algorithm history
@@ -144,33 +134,33 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "34"},
{"Total Orders", "32"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.106%"},
{"Compounding Annual Return", "0.110%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.178"},
{"Expectancy", "0.184"},
{"Start Equity", "1000000"},
{"End Equity", "1001066.2"},
{"Net Profit", "0.107%"},
{"Sharpe Ratio", "-1.695"},
{"Sortino Ratio", "-0.804"},
{"Probabilistic Sharpe Ratio", "14.797%"},
{"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", "9.01"},
{"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.112"},
{"Total Fees", "$76.30"},
{"Treynor Ratio", "-4.099"},
{"Total Fees", "$72.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.92%"},
{"OrderListHash", "ddaa9dd20647fdbc4811d6e64bb30a40"}
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "168731c8f3a19f230cc1410818b3b573"}
};
}
}

View File

@@ -136,7 +136,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 24883;
public virtual long DataPoints => 57759;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -41,7 +41,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 70262;
public override long DataPoints => 163415;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm

View File

@@ -140,12 +140,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 25316;
public virtual long DataPoints => 48690;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public virtual int AlgorithmHistoryDataPoints => 6075;
public virtual int AlgorithmHistoryDataPoints => 5305;
/// <summary>
/// Final status of the algorithm

View File

@@ -47,7 +47,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 76063;
public override long DataPoints => 147771;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -14,7 +14,12 @@
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
@@ -36,40 +41,40 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 25312;
public override long DataPoints => 87289;
/// <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", "718"},
{"Total Orders", "716"},
{"Average Win", "0.03%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "-1.720%"},
{"Compounding Annual Return", "-1.716%"},
{"Drawdown", "1.700%"},
{"Expectancy", "-0.770"},
{"Start Equity", "1000000"},
{"End Equity", "982676.58"},
{"Net Profit", "-1.732%"},
{"Sharpe Ratio", "-8.877"},
{"Sortino Ratio", "-5.476"},
{"End Equity", "982718.38"},
{"Net Profit", "-1.728%"},
{"Sharpe Ratio", "-8.845"},
{"Sortino Ratio", "-5.449"},
{"Probabilistic Sharpe Ratio", "0.000%"},
{"Loss Rate", "96%"},
{"Win Rate", "4%"},
{"Profit-Loss Ratio", "4.90"},
{"Profit-Loss Ratio", "4.89"},
{"Alpha", "-0.018"},
{"Beta", "-0.002"},
{"Annual Standard Deviation", "0.002"},
{"Annual Variance", "0"},
{"Information Ratio", "-1.484"},
{"Information Ratio", "-1.483"},
{"Tracking Error", "0.089"},
{"Treynor Ratio", "9.171"},
{"Total Fees", "$1638.42"},
{"Treynor Ratio", "9.102"},
{"Total Fees", "$1634.12"},
{"Estimated Strategy Capacity", "$8000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "20.14%"},
{"OrderListHash", "f6482c8757f82cb9f4c058e3ed6bc494"}
{"Portfolio Turnover", "20.10%"},
{"OrderListHash", "aa7e574f86b70428ca0afae381be80ba"}
};
}
}

View File

@@ -149,7 +149,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 117079;
public long DataPoints => 224662;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -14,7 +14,14 @@
*
*/
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
{
@@ -36,40 +43,40 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 5965;
public override long DataPoints => 14790;
/// <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", "32"},
{"Total Orders", "36"},
{"Average Win", "0.33%"},
{"Average Loss", "-0.04%"},
{"Compounding Annual Return", "0.110%"},
{"Average Loss", "-0.03%"},
{"Compounding Annual Return", "0.102%"},
{"Drawdown", "0.300%"},
{"Expectancy", "0.184"},
{"Expectancy", "0.171"},
{"Start Equity", "1000000"},
{"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"},
{"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"},
{"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.126"},
{"Total Fees", "$80.60"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "ES VRJST036ZY0X"},
{"Portfolio Turnover", "0.87%"},
{"OrderListHash", "741a26424d2210171ad849d92fc75d23"}
{"Portfolio Turnover", "0.97%"},
{"OrderListHash", "52c852d720692fab1e12212b2aba03d4"}
};
}
}

View File

@@ -41,7 +41,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 67924;
public override long DataPoints => 228834;
/// <summary>
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
@@ -74,7 +74,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$3000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "56.73%"},
{"OrderListHash", "6ce7812de5c98744cc35169a86a24325"}
{"OrderListHash", "424536177e9be5895bab50638ef43a9d"}
};
}
}

View File

@@ -118,7 +118,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$110000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "19.96%"},
{"OrderListHash", "60747dce5c2aed393b7dccc258d2c9b5"}
{"OrderListHash", "966f8355817adbc8c724d1062691a60b"}
};
}
}

View File

@@ -70,7 +70,7 @@ namespace QuantConnect.Algorithm.CSharp
}
var openInterest = Securities[SpxOption].Cache.GetAll<OpenInterest>();
if (openInterest.Single().EndTime != new DateTime(2021, 1, 15, 15, 15, 0))
if (openInterest.Single().EndTime != new DateTime(2021, 1, 15, 23, 0, 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 => 122;
public override long DataPoints => 121;
/// <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", "653.545%"},
{"Compounding Annual Return", "621.484%"},
{"Drawdown", "0%"},
{"Expectancy", "0"},
{"Start Equity", "1000000"},

View File

@@ -66,7 +66,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$300000.00"},
{"Lowest Capacity Asset", "SPX XL80P3GHDZXQ|SPX 31"},
{"Portfolio Turnover", "24.63%"},
{"OrderListHash", "5595ab834c2584c1d124ad575e88cc1a"}
{"OrderListHash", "44325fc1fdebb8e54f64a3f6e8a4bcd7"}
};
}
}

View File

@@ -67,7 +67,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 360;
public override long DataPoints => 356;
/// <summary>
/// Data Points count of the algorithm history
@@ -110,7 +110,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P59H5E6M|SPX 31"},
{"Portfolio Turnover", "0.00%"},
{"OrderListHash", "8340619d603921c1ce261287890b9c1c"}
{"OrderListHash", "285cec32c0947f0e8cf90ccb672cfa43"}
};
}
}

View File

@@ -81,7 +81,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "SPX XL80P59H5E6M|SPX 31"},
{"Portfolio Turnover", "0.00%"},
{"OrderListHash", "1c5f424cfe62777733ee68a20320bb8d"}
{"OrderListHash", "75e6584cb26058b09720c3a828b9fbda"}
};
}
}

View File

@@ -128,7 +128,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "₹61000000000.00"},
{"Lowest Capacity Asset", "YESBANK UL"},
{"Portfolio Turnover", "0.00%"},
{"OrderListHash", "06f782c83dd633dac6f228b91273ba26"}
{"OrderListHash", "7a0257f08e3bb9143b825e07ab47fea0"}
};
}
}

View File

@@ -152,7 +152,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "₹84000.00"},
{"Lowest Capacity Asset", "JUNIORBEES UL"},
{"Portfolio Turnover", "0.04%"},
{"OrderListHash", "8790bec8175539e6d92e01608ac57733"}
{"OrderListHash", "79ab9ec506959c562be8b3cdbb174c39"}
};
}
}

View File

@@ -165,7 +165,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$72000.00"},
{"Lowest Capacity Asset", "AAPL W78ZEO2985GM|AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "0.02%"},
{"OrderListHash", "5e20fad3461ac9998afe8d76ad43b25c"}
{"OrderListHash", "b3125e0af79da0f5eea4cfda09806324"}
};
}
}

View File

@@ -142,7 +142,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "15.08%"},
{"OrderListHash", "f68f6d64a5721ee148bc3c643f8d1b7f"}
{"OrderListHash", "db6a1134ad325bce31c2bdd2e87ff5f4"}
};
}
}

View File

@@ -182,7 +182,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "13.50%"},
{"OrderListHash", "d40c84371facba5dac8a2c919ea75807"}
{"OrderListHash", "cf14a7ce9c86e6844051820fd4c9394c"}
};
}
}

View File

@@ -121,20 +121,20 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "5"},
{"Average Win", "0.63%"},
{"Average Loss", "-0.03%"},
{"Average Win", "0%"},
{"Average Loss", "-0.69%"},
{"Compounding Annual Return", "54.478%"},
{"Drawdown", "0.400%"},
{"Expectancy", "23.219"},
{"Expectancy", "-0.5"},
{"Start Equity", "1000000"},
{"End Equity", "1006025"},
{"Net Profit", "0.602%"},
{"Sharpe Ratio", "2.62"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "63.221%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "23.22"},
{"Loss Rate", "50%"},
{"Win Rate", "50%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "0.067"},
{"Beta", "-0.013"},
{"Annual Standard Deviation", "0.004"},
@@ -146,7 +146,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$580000.00"},
{"Lowest Capacity Asset", "SPXW 31K54PVWHUJHQ|SPX 31"},
{"Portfolio Turnover", "0.40%"},
{"OrderListHash", "db5e3681c5fa1888262f2370a9b14c11"}
{"OrderListHash", "07a085baedb37bb7c8d460558ea77e88"}
};
}
}

View File

@@ -127,11 +127,11 @@ namespace QuantConnect.Algorithm.CSharp
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "10"},
{"Average Win", "0.46%"},
{"Average Win", "0.47%"},
{"Average Loss", "-0.01%"},
{"Compounding Annual Return", "101.998%"},
{"Drawdown", "0.100%"},
{"Expectancy", "24.137"},
{"Expectancy", "24.484"},
{"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.27"},
{"Profit-Loss Ratio", "49.97"},
{"Alpha", "-2.01"},
{"Beta", "0.307"},
{"Annual Standard Deviation", "0.021"},
@@ -152,7 +152,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$13000000.00"},
{"Lowest Capacity Asset", "SPXW XKX6S2GM9PGU|SPX 31"},
{"Portfolio Turnover", "0.28%"},
{"OrderListHash", "17764ae9e216d003b1f3ce68d15b68ef"}
{"OrderListHash", "c1a9bc141ae25c9542b93a887e79dafe"}
};
}
}

View File

@@ -38,26 +38,6 @@ namespace QuantConnect.Algorithm.CSharp
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>

View File

@@ -1,52 +0,0 @@
/*
* 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.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the Classic Renko Consolidator with future and default tick data.
/// If consolidation does not happen, a RegressionTestException is thrown
/// </summary>
public class ClassicRenkoConsolidatorWithFuturesAndDefaultTickTypeRegressionAlgorithm : ClassicRenkoConsolidatorWithFuturesTickTypesRegressionAlgorithm
{
protected override ClassicRenkoConsolidator GetConsolidator()
{
Func<IBaseData, decimal> selector = data =>
{
var tick = data as Tick;
if (tick.TickType != TickType.Quote)
{
throw new RegressionTestException("The tick type should be quote");
}
WasSelectorExecuted = true;
return tick.AskPrice * 10;
};
var consolidator = new ClassicRenkoConsolidator(BucketSize, selector);
return consolidator;
}
public override void AddConsolidator(ClassicRenkoConsolidator consolidator)
{
SubscriptionManager.AddConsolidator(GoldFuture.Mapped, consolidator);
}
}
}

View File

@@ -1,67 +0,0 @@
/*
* 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.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the Classic Renko Consolidator with future quote tick data.
/// It checks if valid quote data (non-zero Bid/Ask prices) is received during the algorithm's execution.
/// If consolidation does not happen, a RegressionTestException is thrown
/// </summary>
public class ClassicRenkoConsolidatorWithFuturesQuoteTickTypeRegressionAlgorithm : ClassicRenkoConsolidatorWithFuturesTickTypesRegressionAlgorithm
{
private bool _hasNonZeroBidPrice;
private bool _hasNonZeroAskPrice;
protected override TickType TickType => TickType.Quote;
protected override ClassicRenkoConsolidator GetConsolidator()
{
Func<IBaseData, decimal> selector = data =>
{
var tick = data as Tick;
_hasNonZeroBidPrice |= tick.BidPrice != 0;
_hasNonZeroAskPrice |= tick.AskPrice != 0;
if (tick.TickType != TickType)
{
throw new RegressionTestException("The tick type should be quote");
}
WasSelectorExecuted = true;
return tick.AskPrice * 10;
};
var consolidator = new ClassicRenkoConsolidator(BucketSize, selector);
return consolidator;
}
public override void AddConsolidator(ClassicRenkoConsolidator consolidator)
{
SubscriptionManager.AddConsolidator(GoldFuture.Mapped, consolidator, TickType);
}
public override void OnEndOfAlgorithm()
{
if (!_hasNonZeroBidPrice || !_hasNonZeroAskPrice)
{
throw new RegressionTestException("No valid Quote tick data found: fields (Bid/Ask) were zero.");
}
base.OnEndOfAlgorithm();
}
}
}

View File

@@ -1,158 +0,0 @@
/*
* 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.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Interfaces;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm tests the functionality of the Classic Renko Consolidator with future trade tick data.
/// It checks if data consolidation occurs as expected for the given time period. If consolidation does not happen, a RegressionTestException is thrown.
/// </summary>
public class ClassicRenkoConsolidatorWithFuturesTickTypesRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private Dictionary<Symbol, ClassicRenkoConsolidator> _consolidators = new Dictionary<Symbol, ClassicRenkoConsolidator>();
private bool _itWasConsolidated;
protected Future GoldFuture { get; set; }
protected virtual TickType TickType => TickType.Trade;
protected decimal BucketSize { get; set; }
protected bool WasSelectorExecuted { get; set; }
public override void Initialize()
{
SetStartDate(2013, 10, 7);
SetEndDate(2013, 10, 9);
GoldFuture = AddFuture("GC", Resolution.Tick, Market.COMEX);
GoldFuture.SetFilter(0, 180);
BucketSize = 2000m;
}
private void OnConsolidated(object sender, TradeBar bar)
{
_itWasConsolidated = true;
}
public override void OnData(Slice slice)
{
if (!_consolidators.ContainsKey(GoldFuture.Mapped))
{
var consolidator = GetConsolidator();
consolidator.DataConsolidated += OnConsolidated;
AddConsolidator(consolidator);
_consolidators[GoldFuture.Mapped] = consolidator;
}
}
public virtual void AddConsolidator(ClassicRenkoConsolidator consolidator)
{
SubscriptionManager.AddConsolidator(GoldFuture.Mapped, consolidator, TickType);
}
protected virtual ClassicRenkoConsolidator GetConsolidator()
{
Func<IBaseData, decimal> selector = data =>
{
var tick = data as Tick;
if (tick.TickType != TickType)
{
throw new RegressionTestException("The tick type should be trade");
}
WasSelectorExecuted = true;
return tick.Quantity * tick.Price;
};
var consolidator = new ClassicRenkoConsolidator(BucketSize, selector);
return consolidator;
}
public override void OnEndOfAlgorithm()
{
if (!_itWasConsolidated)
{
throw new RegressionTestException("ClassicRenko did not consolidate any data.");
}
if (!WasSelectorExecuted)
{
throw new RegressionTestException("The selector was not executed");
}
}
/// <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 long DataPoints => 1082920;
/// <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.524"},
{"Tracking Error", "0.136"},
{"Treynor Ratio", "0"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", ""},
{"Portfolio Turnover", "0%"},
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
};
}
}

View File

@@ -142,7 +142,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$71000.00"},
{"Lowest Capacity Asset", "BTCUSD 2XR"},
{"Portfolio Turnover", "0.29%"},
{"OrderListHash", "a0058926f4ca5b009cfcc9096506a548"}
{"OrderListHash", "179b672b3c1024bbe49dd3b4974232f1"}
};
}
}

View File

@@ -80,10 +80,8 @@ namespace QuantConnect.Algorithm.CSharp
// Initialize this flag, to check when the ema indicators crosses between themselves
_emaFastIsNotSet = true;
// Disable automatic exports as we manually set them
SignalExport.AutomaticExportTimeSpan = null;
// Set Collective2 signal export provider
SignalExport.AddSignalExportProvider(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
SignalExport.AddSignalExportProviders(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
SetWarmUp(100);
}

View File

@@ -49,16 +49,16 @@ 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),
QuantConnect.Symbol.Create("EURUSD", SecurityType.Forex, Market.Oanda),
QuantConnect.Symbol.CreateFuture("ES", Market.CME, new DateTime(2023, 12, 15)),
{
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),
QuantConnect.Symbol.CreateOption("GOOG", Market.USA, OptionStyle.American, OptionRight.Call, 130, new DateTime(2023, 9, 1)),
};
@@ -95,22 +95,15 @@ namespace QuantConnect.Algorithm.CSharp
// Initialize this flag, to check when the ema indicators crosses between themselves
_emaFastIsNotSet = true;
// Disable automatic exports as we manually set them
SignalExport.AutomaticExportTimeSpan = null;
// 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.AddSignalExportProvider(new Collective2SignalExport(_collective2ApiKey, _collective2SystemId));
// Set Collective2 signal export provider
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>

View File

@@ -1,131 +0,0 @@
/*
* 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"}
};
}
}

View File

@@ -1,166 +0,0 @@
/*
* 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"}
};
}
}

View File

@@ -22,7 +22,6 @@ using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Interfaces;
using QuantConnect.Securities;
using QuantConnect.Securities.Future;
namespace QuantConnect.Algorithm.CSharp
{
@@ -32,83 +31,69 @@ 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 _customDataConsolidatorCount;
private Future _future;
private int _expectedConsolidations;
private int _customDataConsolidator;
private Symbol _symbol;
/// <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(2020, 01, 05);
SetEndDate(2020, 01, 20);
SetStartDate(2013, 10, 08);
SetEndDate(2013, 10, 20);
var SP500 = QuantConnect.Symbol.Create(Futures.Indices.SP500EMini, SecurityType.Future, Market.CME);
var symbol = FuturesChain(SP500).First();
_future = AddFutureContract(symbol);
_symbol = FutureChainProvider.GetFutureContractList(SP500, StartDate).First();
var security = AddFutureContract(_symbol);
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();
_consolidationCounts = Enumerable.Repeat(0, 9).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 customSecurity = AddData<CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute);
Consolidate<TradeBar>(customSecurity.Symbol, TimeSpan.FromDays(1), bar => _customDataConsolidatorCount++);
var symbol = AddData<CustomDataRegressionAlgorithm.Bitcoin>("BTC", Resolution.Minute).Symbol;
Consolidate<TradeBar>(symbol, TimeSpan.FromDays(1), bar => _customDataConsolidator++);
try
{
Consolidate<QuoteBar>(customSecurity.Symbol, TimeSpan.FromDays(1), bar => { UpdateQuoteBar(bar, -1); });
Consolidate<QuoteBar>(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))
@@ -134,27 +119,16 @@ namespace QuantConnect.Algorithm.CSharp
public override void OnEndOfAlgorithm()
{
for (var i = 0; i < _consolidationCounts.Count; i++)
if (_consolidationCounts.Any(i => i != _expectedConsolidations) || _customDataConsolidator == 0)
{
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}");
throw new RegressionTestException("Unexpected consolidation count");
}
for (var i = 0; i < _smas.Count; i++)
{
if (_smas[i].Samples != _expectedConsolidationCounts[i])
if (_smas[i].Samples != _expectedConsolidations)
{
throw new RegressionTestException($"Expected {_expectedConsolidationCounts} samples in each SMA but found {_smas[i].Samples} in SMA in index {i}");
throw new RegressionTestException($"Expected {_expectedConsolidations} samples in each SMA but found {_smas[i].Samples} in SMA in index {i}");
}
if (_smas[i].Current.Time != _lastSmaUpdates[i])
@@ -170,9 +144,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 && _future.HasData)
if (!Portfolio.Invested)
{
SetHoldings(_future.Symbol, 0.5);
SetHoldings(_symbol, 0.5);
}
}
@@ -189,12 +163,12 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 14228;
public long DataPoints => 12244;
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 1;
public int AlgorithmHistoryDataPoints => 0;
/// <summary>
/// Final status of the algorithm
@@ -209,30 +183,30 @@ namespace QuantConnect.Algorithm.CSharp
{"Total Orders", "1"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "665.524%"},
{"Drawdown", "1.500%"},
{"Compounding Annual Return", "6636.699%"},
{"Drawdown", "15.900%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "109332.4"},
{"Net Profit", "9.332%"},
{"Sharpe Ratio", "9.805"},
{"End Equity", "116177.7"},
{"Net Profit", "16.178%"},
{"Sharpe Ratio", "640.313"},
{"Sortino Ratio", "0"},
{"Probabilistic Sharpe Ratio", "93.474%"},
{"Probabilistic Sharpe Ratio", "99.824%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"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"}
{"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"}
};
}
}

View File

@@ -139,7 +139,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 162571;
public long DataPoints => 713369;
/// <summary>
/// Data Points count of the algorithm history
@@ -182,7 +182,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$76000000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "0.91%"},
{"OrderListHash", "a472060eeb87c7474d25f7035fa150c4"}
{"OrderListHash", "7e45786e43b159c7edfcdf0aa0876deb"}
};
}
}

View File

@@ -155,7 +155,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 172698;
public long DataPoints => 723496;
/// <summary>
/// Data Points count of the algorithm history
@@ -198,7 +198,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$230000000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "1.39%"},
{"OrderListHash", "6a5b2e6b3f140e9bb7f32c07cbf5f36c"}
{"OrderListHash", "795bfb3ab8565e759e98e43a49b0a91d"}
};
}
}

View File

@@ -120,7 +120,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public virtual long DataPoints => 5469;
public virtual long DataPoints => 9951;
/// <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", "$130000000.00"},
{"Estimated Strategy Capacity", "$100000000.00"},
{"Lowest Capacity Asset", "ES VP274HSU1AF5"},
{"Portfolio Turnover", "41.23%"},
{"OrderListHash", "b9f8e1a0704c086944e5df07e0ab04d6"}

View File

@@ -34,6 +34,6 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public override long DataPoints => 9079;
public override long DataPoints => 15813;
}
}

View File

@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
}
return universe;
return universe.Select(x => x);
});
_milk.SetFilter(universe =>
@@ -94,7 +94,7 @@ namespace QuantConnect.Algorithm.CSharp
}
}
return universe;
return universe.Select(x => x);
});
}
@@ -184,7 +184,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 445961;
public long DataPoints => 596356;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -78,7 +78,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 10883;
public long DataPoints => 19886;
/// <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.012%"},
{"Compounding Annual Return", "-99.258%"},
{"Drawdown", "6.300%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},

View File

@@ -1,237 +0,0 @@
/*
* 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"}
};
}
}

View File

@@ -19,6 +19,7 @@ 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;
@@ -30,7 +31,7 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public class ContinuousFutureRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private List<Symbol> _previousMappedContractSymbols = new();
private List<SymbolChangedEvent> _mappings = new();
private Symbol _currentMappedSymbol;
private Future _continuousContract;
private DateTime _lastMonth;
@@ -76,7 +77,7 @@ namespace QuantConnect.Algorithm.CSharp
{
if (changedEvent.Symbol == _continuousContract.Symbol)
{
_previousMappedContractSymbols.Add(Symbol(changedEvent.OldSymbol));
_mappings.Add(changedEvent);
Log($"{Time} - SymbolChanged event: {changedEvent}");
if (_currentMappedSymbol == _continuousContract.Mapped)
@@ -143,20 +144,15 @@ namespace QuantConnect.Algorithm.CSharp
public override void OnEndOfAlgorithm()
{
var expectedMappingCounts = 2;
if (_previousMappedContractSymbols.Count != expectedMappingCounts)
if (_mappings.Count != expectedMappingCounts)
{
throw new RegressionTestException($"Unexpected symbol changed events: {_previousMappedContractSymbols.Count}, was expecting {expectedMappingCounts}");
throw new RegressionTestException($"Unexpected symbol changed events: {_mappings.Count}, was expecting {expectedMappingCounts}");
}
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)
var securities = Securities.Total.Where(sec => !sec.IsTradable && !sec.Symbol.IsCanonical() && sec.Symbol.SecurityType == SecurityType.Future).ToList();
if (securities.Count != 1)
{
throw new RegressionTestException($"Not all delisted contracts are properly market as delisted and non-tradable: " +
$"only {markedDelistedSecurities.Count} are marked, was expecting {delistedSecurities.Count}");
throw new RegressionTestException($"We should have a single non tradable future contract security! found: {securities.Count}");
}
}
@@ -173,7 +169,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 162575;
public long DataPoints => 713369;
/// <summary>
/// Data Points count of the algorithm history
@@ -190,18 +186,18 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
{
{"Total Orders", "4"},
{"Average Win", "0.84%"},
{"Total Orders", "3"},
{"Average Win", "1.50%"},
{"Average Loss", "0%"},
{"Compounding Annual Return", "3.380%"},
{"Compounding Annual Return", "3.337%"},
{"Drawdown", "1.600%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "101687.3"},
{"Net Profit", "1.687%"},
{"Sharpe Ratio", "0.605"},
{"Sortino Ratio", "0.202"},
{"Probabilistic Sharpe Ratio", "45.198%"},
{"End Equity", "101666.4"},
{"Net Profit", "1.666%"},
{"Sharpe Ratio", "0.594"},
{"Sortino Ratio", "0.198"},
{"Probabilistic Sharpe Ratio", "44.801%"},
{"Loss Rate", "0%"},
{"Win Rate", "100%"},
{"Profit-Loss Ratio", "0"},
@@ -209,14 +205,14 @@ namespace QuantConnect.Algorithm.CSharp
{"Beta", "0.134"},
{"Annual Standard Deviation", "0.027"},
{"Annual Variance", "0.001"},
{"Information Ratio", "-2.687"},
{"Information Ratio", "-2.69"},
{"Tracking Error", "0.075"},
{"Treynor Ratio", "0.121"},
{"Treynor Ratio", "0.119"},
{"Total Fees", "$6.45"},
{"Estimated Strategy Capacity", "$2600000000.00"},
{"Estimated Strategy Capacity", "$8000000000.00"},
{"Lowest Capacity Asset", "ES VMKLFZIH2MTD"},
{"Portfolio Turnover", "1.88%"},
{"OrderListHash", "1973b0beb9bc5e618e0387d960553d7a"}
{"Portfolio Turnover", "1.39%"},
{"OrderListHash", "40c1137e0bc83b2bc920495af119c8fc"}
};
}
}

View File

@@ -1,262 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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;
}
}

View File

@@ -109,7 +109,7 @@ namespace QuantConnect.Algorithm.CSharp
/// <summary>
/// Data Points count of all timeslices of algorithm
/// </summary>
public long DataPoints => 848;
public long DataPoints => 1267;
/// <summary>
/// Data Points count of the algorithm history

View File

@@ -1,134 +0,0 @@
/*
* 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"}
};
}
}

View File

@@ -117,7 +117,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$66000000.00"},
{"Lowest Capacity Asset", "AAPL R735QTJ8XC9X"},
{"Portfolio Turnover", "20.08%"},
{"OrderListHash", "fa51af977e55213dc007a38a3d681b62"}
{"OrderListHash", "ae85de0e28b44116de68c56ca141c00f"}
};
}
}

View File

@@ -144,7 +144,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$150000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "26.62%"},
{"OrderListHash", "dae7e349316dce7621bc1f8be86ccd0d"}
{"OrderListHash", "c5ca1a8b0ce57cfeadd9eddf8abdd80c"}
};
}
}

View File

@@ -111,7 +111,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$180000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "24.86%"},
{"OrderListHash", "8c07dafc84c73401fa0c7709b6baf802"}
{"OrderListHash", "c07a9cae88eb3f47309fbf18216bc3cf"}
};
public class ExampleCustomData : BaseData

View File

@@ -40,8 +40,8 @@ namespace QuantConnect.Algorithm.CSharp
/// </summary>
public override void Initialize()
{
SetStartDate(2020, 01, 05);
SetEndDate(2020, 01, 10);
SetStartDate(2011, 9, 13);
SetEndDate(2015, 12, 01);
//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 => 57;
public long DataPoints => 10491;
/// <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", "34781.071%"},
{"Drawdown", "4.300%"},
{"Compounding Annual Return", "155.211%"},
{"Drawdown", "84.800%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "110102.2"},
{"Net Profit", "10.102%"},
{"Sharpe Ratio", "283.719"},
{"Sortino Ratio", "1123.876"},
{"Probabilistic Sharpe Ratio", "81.716%"},
{"End Equity", "5223241.65"},
{"Net Profit", "5123.242%"},
{"Sharpe Ratio", "2.058"},
{"Sortino Ratio", "2.492"},
{"Probabilistic Sharpe Ratio", "68.833%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"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"},
{"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"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "BTC.Bitcoin 2S"},
{"Portfolio Turnover", "16.73%"},
{"OrderListHash", "b890a8e73bf118e943ad2f2e712f12d0"}
{"Portfolio Turnover", "0.06%"},
{"OrderListHash", "999305e00ec9861f5ff261794e81213d"}
};
/// <summary>
@@ -168,7 +168,6 @@ 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")]
@@ -218,10 +217,7 @@ 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/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=WyAazVXnq7ATy_fefTqm")
{
Sort = true
};
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);
}
/// <summary>
@@ -252,20 +248,20 @@ namespace QuantConnect.Algorithm.CSharp
}
//Example Line Format:
// 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
//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
try
{
string[] data = line.Split(',');
coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture);
coin.Time = DateTime.Parse(data[0], 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.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.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.Value = coin.Close;
}
catch { /* Do nothing, skip first title row */ }

View File

@@ -33,15 +33,15 @@ namespace QuantConnect.Algorithm.CSharp
/// <meta name="tag" content="regression test" />
public class CustomDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
{
private bool _warmedUpChecked;
private bool _warmedUpChecked = false;
/// <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(2020, 01, 05);
SetEndDate(2020, 01, 10);
SetStartDate(2011, 9, 14);
SetEndDate(2015, 12, 01);
//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 => 50;
public long DataPoints => 8943;
/// <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", "27587.925%"},
{"Drawdown", "4.200%"},
{"Compounding Annual Return", "155.365%"},
{"Drawdown", "84.800%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
{"End Equity", "109685"},
{"Net Profit", "9.685%"},
{"Sharpe Ratio", "238.834"},
{"Sortino Ratio", "945.079"},
{"Probabilistic Sharpe Ratio", "81.660%"},
{"End Equity", "5223170.23"},
{"Net Profit", "5123.170%"},
{"Sharpe Ratio", "2.094"},
{"Sortino Ratio", "2.535"},
{"Probabilistic Sharpe Ratio", "69.967%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"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"},
{"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"},
{"Total Fees", "$0.00"},
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "BTC.Bitcoin 2S"},
{"Portfolio Turnover", "16.03%"},
{"OrderListHash", "dde8821614d33c89e6e75c536447b7da"}
{"Portfolio Turnover", "0.06%"},
{"OrderListHash", "e69e78cd6fe7bc4627da2f51e25539d0"}
};
/// <summary>
@@ -169,8 +169,6 @@ 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")]
@@ -181,6 +179,7 @@ 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)
@@ -219,10 +218,7 @@ 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/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=qAWKpUfmSVFnU3bRQwKy")
{
Sort = true
};
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);
}
/// <summary>
@@ -253,20 +249,20 @@ namespace QuantConnect.Algorithm.CSharp
}
//Example Line Format:
// 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
//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
try
{
string[] data = line.Split(',');
coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture);
coin.Time = DateTime.Parse(data[0], 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.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.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.Value = coin.Close;
}
catch { /* Do nothing, skip first title row */ }

View File

@@ -162,7 +162,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$0"},
{"Lowest Capacity Asset", "NWSA.CustomDataUsingMapping T3MO1488O0H0"},
{"Portfolio Turnover", "16.62%"},
{"OrderListHash", "fe95edf1a3eabc0ac044b85eb833da5a"}
{"OrderListHash", "a605ae85beeb854fde8d7b7eff9040ac"}
};
/// <summary>

View File

@@ -159,7 +159,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$150000000.00"},
{"Lowest Capacity Asset", "SPY R735QTJ8XC9X"},
{"Portfolio Turnover", "3.19%"},
{"OrderListHash", "c0205e9d3d1bfdee958fecccb36413ec"}
{"OrderListHash", "91660550269bce594c61fbf9159807d2"}
};
}
}

View File

@@ -85,7 +85,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$4800000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WHPNQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "26.72%"},
{"OrderListHash", "fb2bef182af109f6441ae739d826f39f"}
{"OrderListHash", "a0e8659f340ecf7faa1cc5a0da2760ba"}
};
}
}

View File

@@ -93,7 +93,7 @@ namespace QuantConnect.Algorithm.CSharp
{"Estimated Strategy Capacity", "$87000.00"},
{"Lowest Capacity Asset", "GOOCV 305RBQ20WHPNQ|GOOCV VP83T1ZUHROL"},
{"Portfolio Turnover", "10.93%"},
{"OrderListHash", "8133cb99a1a9f9e9335bc98def3cc624"}
{"OrderListHash", "3c5f9544f697725475491434f18803e6"}
};
}
}

View File

@@ -1,113 +0,0 @@
/*
* 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 Newtonsoft.Json;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Portfolio.SignalExports;
using QuantConnect.Api;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm sends a list of portfolio targets to custom endpoint
/// </summary>
/// <meta name="tag" content="using data" />
/// <meta name="tag" content="using quantconnect" />
/// <meta name="tag" content="securities and portfolio" />
public class CustomSignalExportDemonstrationAlgorithm : QCAlgorithm
{
/// <summary>
/// Initialize the date and add all equity symbols present
/// </summary>
public override void Initialize()
{
SetStartDate(2013, 10, 07);
SetEndDate(2013, 10, 11);
/// Our custom signal export accepts all asset types
AddEquity("SPY", Resolution.Second);
AddCrypto("BTCUSD", Resolution.Second);
AddForex("EURUSD", Resolution.Second);
AddFutureContract(QuantConnect.Symbol.CreateFuture("ES", Market.CME, new DateTime(2023, 12, 15), null));
AddOptionContract(QuantConnect.Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Call, 130, new DateTime(2023, 9, 1)));
// Set CustomSignalExport signal export provider.
SignalExport.AddSignalExportProvider(new CustomSignalExport());
}
/// <summary>
/// Buy and hold EURUSD and SPY
/// </summary>
/// <param name="slice"></param>
public override void OnData(Slice slice)
{
foreach (var ticker in new[] { "SPY", "EURUSD", "BTCUSD" })
{
if (!Portfolio[ticker].Invested && Securities[ticker].HasData)
{
SetHoldings(ticker, 0.5m);
}
}
}
}
internal class CustomSignalExport : ISignalExportTarget
{
private readonly Uri _requestUri = new ("http://localhost:5000/");
private readonly HttpClient _httpClient = new();
public bool Send(SignalExportTargetParameters parameters)
{
object SimplePayload(PortfolioTarget target)
{
var newTarget = PortfolioTarget.Percent(parameters.Algorithm, target.Symbol, target.Quantity);
return new { symbol = newTarget.Symbol.Value, quantity = newTarget.Quantity };
};
var message = JsonConvert.SerializeObject(parameters.Targets.Select(SimplePayload));
using var httpMessage = new StringContent(message, Encoding.UTF8, "application/json");
using HttpResponseMessage response = _httpClient.PostAsync(_requestUri, httpMessage).Result;
var result = response.Content.ReadFromJsonAsync<RestResponse>().Result;
parameters.Algorithm.Log($"Send #{parameters.Targets.Count} targets. Success: {result.Success}");
return result.Success;
}
public void Dispose() => _httpClient.Dispose();
}
}
/*
# To test the algorithm, you can create a simple Python Flask application (app.py) and run flask
# $ flask --app app run
# app.py:
from flask import Flask, request, jsonify
from json import loads
app = Flask(__name__)
@app.post('/')
def handle_positions():
result = loads(request.data)
print(result)
return jsonify({'success': True,'message': f'{len(result)} positions received'})
if __name__ == '__main__':
app.run(debug=True)
*/

View File

@@ -1,130 +0,0 @@
/*
* 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"}
};
}
}

View File

@@ -1,31 +0,0 @@
/*
* 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;
}
}

View File

@@ -1,67 +0,0 @@
/*
* 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");
}
}
}
}

View File

@@ -1,210 +0,0 @@
/*
* 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"}
};
}
}

View File

@@ -1,68 +0,0 @@
/*
* 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"}
};
}
}

Some files were not shown because too many files have changed in this diff Show More