Hi, I found an example which use nasdaq rank to long top ranked stocks. I wonder can I long top ranked stocks, meanwhile short bottom ranked stocks.
To do that, I have to let my algorithm know which one I want to long and which one I want to short.
Can you guys point out how to change the original one?
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using System;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// This algorithm shows how to grab symbols from an external api each day
/// and load data using the universe selection feature. In this example we
/// define a custom data type for the NYSE top gainers and then short the
/// top 2 gainers each day
/// </summary>
public class tradingStocksWithOptionSelection : QCAlgorithm
{
private SecurityChanges _changes;
public override void Initialize()
{
UniverseSettings.Resolution = Resolution.Daily;
SetStartDate(2015, 01, 05);
SetEndDate(2015, 07, 01);
SetCash(100000);
AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily);
SetBenchmark("SPY");
// add a custom universe data source (defaults to usa-equity)
AddUniverse<NyseTopGainers>("universe-nyse-top-gainers", Resolution.Daily, data =>
{
// define our selection criteria
return from d in data
// pick top 2 gainers to bet against
where d.TopGainersRank <= 2
select d.Symbol;
});
}
public override void OnData(Slice slice)
{
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
_changes = changes;
foreach (var security in changes.RemovedSecurities)
{
// liquidate securities that have been removed
if (security.Invested)
{
Liquidate(security.Symbol);
Log("Exit " + security.Symbol + " at " + security.Close);
}
}
foreach (var security in changes.AddedSecurities)
{
// enter short positions on new securities
if (!security.Invested && security.Close != 0)
{
var qty = CalculateOrderQuantity(security.Symbol, -0.25m);
MarketOnOpenOrder(security.Symbol, qty);
Log("Enter " + security.Symbol + " at " + security.Close);
}
}
}
/// <summary>
/// Custom data type that uses the wall street journal's top 100 nyse gainers
/// html page as a live data source, and a csv file that contains the top 10
/// nyse gainers since the beginning of 2009 until 2015/10/19
/// </summary>
public class NyseTopGainers : BaseData
{
public int TopGainersRank;
public override DateTime EndTime
{
// define end time as exactly 1 day after Time
get { return Time + QuantConnect.Time.OneDay; }
set { Time = value - QuantConnect.Time.OneDay; }
}
private int count;
private DateTime lastDate;
public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
{
// if (isLiveMode)
// {
// // this is actually an html file, we'll handle the parsing accordingly
// return new SubscriptionDataSource(@"http://www.wsj.com/mdc/public/page/2_3021-gainnyse-gainer.html", SubscriptionTransportMedium.RemoteFile);
// }
//return option datasource
return new SubscriptionDataSource(@"https://www.dropbox.com/s/vrn3p38qberw3df/nyse-gainers.csv?dl=1", SubscriptionTransportMedium.RemoteFile);
}
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
{
if (!isLiveMode)
{
// backtest gets data from csv file in dropbox
var csv = line.Split(',');
return new NyseTopGainers
{
Time = DateTime.ParseExact(csv[0], "yyyyMMdd", null),
Symbol = Symbol.Create(csv[1], SecurityType.Equity, Market.USA),
TopGainersRank = int.Parse(csv[2])
};// get time, symbol and rank
}
if (lastDate != date)
{
// reset our counter for the new day
lastDate = date;
count = 0;
}
// parse the html into a symbol
if (!line.StartsWith(@"<a href=""/public/quotes/main.html?symbol="))
{
// we're only looking for lines that contain the symbols
return null;
}
var lastCloseParen = line.LastIndexOf(")", StringComparison.Ordinal);
var lastOpenParen = line.LastIndexOf("(", StringComparison.Ordinal);
if (lastOpenParen == -1 || lastCloseParen == -1)
{
return null;
}
var symbolString = line.Substring(lastOpenParen + 1, lastCloseParen - lastOpenParen - 1);
return new NyseTopGainers
{
Symbol = Symbol.Create(symbolString, SecurityType.Equity, Market.USA),
Time = date,
// the html has these in order, so we'll keep incrementing until a new day
TopGainersRank = ++count
};
}
}
}
}
QQQ VVV
Would like to see if anyone makes it work... trying to do the same thing...
Jared Broad
This has been answered many times in different variations; what specifically are you seeking QQ?
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
QQQ VVV
Jared Broad
Hi, thanks for your attention. Basically, I wanted to pass a table from day to day which shows the status in the portfolio. The table could have a structure like this:
symbol,status
AAPL,long
IBM,short
Regarding taking input from external file, it is related to extend the universe of the algo which can be reflected in the table above. For example, on day 1 the table is like above, in day 2, the extenal file contains a new symbol (say EBAY), after reading the external file, the table is now
symbol,status
AAPL,long
IBM,short
EBAY,new
The ultimate goal is that my algo will be able to take corresponding actions for each stock in the table based on their status.
I guess my questions are:
1. How can I maintain such a table from day to day in backtest and live trading?
2. What should I do regarding the extenal file?
Sorry to make my questions look lengthy. I am new to QC and just moved from Quantopian. On Quantopian, I was able to make my algo work exactly like that.
To be more specific,
1. How can I maintain such a table from day to day in backtest and live trading?
I make a dataframe under context in the initialize function, like context.df = pd.DataFrame(), which is passed day to day as context in Quantopian is not deleted.
2. What should I do regarding the extenal file?
I was able to do in Quantopian using their fetch_csv function in initialize function as long as the extenal file has the specific structure required.
Thanks!
QQQ VVV
Bump for answers. Thanks!
Lifan
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!