Hi, I have a question.
Assume I have data for two forex pairs (EURUSD_custom, USDRUR_custom) from some data provider.
I want to use both of them in one strategy for Lean, How can I do this, if in OnData function I can receive only one of them (e.g. public void OnData(Bitcoin data), OnData(EURUSD_custom data) etc. )?
JayJayD
Given the small information you gave, is hard to know. What kind of strategy? What kind of data? What frequency?
Anyway, just for fun I made this toy example, using two custom Quandl data and a CFD.
Hope It helps.
Alexandr Trenkenshu
Hi, JayJay,
thanks for your answer, but I did't understand how you could use the same data class for two custom symbols.
For example, here is the code for reading custom AUDUSD data from my provider:
public class CustomAUD_USD : BaseData
{
public decimal Open = 0;
public decimal High = 0;
public decimal Low = 0;
public decimal Close = 0;
public decimal Volume = 0;
public CustomAUD_USD()
{
this.Symbol = "CustAUDUSD";
}
public override string GetSource(SubscriptionDataConfig config, DateTime date, DataFeedEndpoint datafeed)
{
Assembly asamb = Assembly.GetExecutingAssembly();
string Path = asamb.Location.Substring(0, asamb.Location.LastIndexOf("\\") + 1);
switch (datafeed)
{
//Selecting different source location depending on computer location.
default:
case DataFeedEndpoint.FileSystem:
return "F:\\Visual Studio Projects\\data\\AUDUSD1min.zip";
}
}
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, DataFeedEndpoint datafeed)
{
//Create a new Bitcoin object that we'll return to Lean.
CustomAUD_USD coin = new CustomAUD_USD();
try
{
string[] a_Data = line.Split(',');
string a_strDate = a_Data[0];
int a_Year = Convert.ToInt32(a_strDate.Substring(0, 4));
int a_Month= Convert.ToInt32(a_strDate.Substring(4, 2));
int a_Day= Convert.ToInt32(a_strDate.Substring(6, 2));
string a_strTime = a_Data[1];
string[] a_strTimeArray = a_strTime.Split(':');
int a_Hour =Convert.ToInt32(a_strTimeArray[0]);
int a_Minute = Convert.ToInt32(a_strTimeArray[1]);
DateTime a_CurDateTime = new DateTime(a_Year, a_Month, a_Day, a_Hour, a_Minute, 0);
coin.Time = a_CurDateTime;
coin.Open = Convert.ToDecimal(a_Data[2]);
coin.High = Convert.ToDecimal(a_Data[3]);
coin.Low = Convert.ToDecimal(a_Data[4]);
coin.Close = Convert.ToDecimal(a_Data[5]);
coin.Volume = Convert.ToDecimal(a_Data[6]);
coin.Symbol = "CustAUDUSD";
coin.Value = coin.Close;
}
catch
{
}
return coin;
}
}
I have the same data (in the same format) for USDRUR. Should I create one more class CustomUSD_RUR, or I can create somehow parent class for both symbol, specify the path to the data?
If I have to create one more class which would be similar to the class above, then I do not understand how to use them both in one strategy. Maybe like this:
public override void Initialize ()
{
SetStartDate (new DateTime (2007, 03, 01)); //Set Start Date
//SetEndDate (2014, 12, 15); //Set End Date
SetEndDate (2015, 12, 01); //Set End Date
SetCash (100000); //Set Strategy Cash
AddData<CustomAUD_USD>("CustAUDUSD");
AddData<CustomUSD_RUR>("CustAUDUSD");
}
public void OnData(CustomAUD_USD data)
{}
public void OnData(CustomUSD_RUR data)
{}
?
Alexandre Catarino
JayJayD's answer is great, but let me add some details to make it clear.
When we subscribe to two or more assets from a custom data type, they will arrive at OnData(CustomDataType) in a sequence unlike OnData(Slice) where they packed toguether:
// In Initialize AddData<Yahoo>("INDEX_SPY"); AddData<Yahoo>("INDEX_VIX"); // OnData: public void OnData(Yahoo data) { // Only buy INDEX_VIX if data is from INDEX_VIX // It can be from INDEX_SPY (data.Symbol == "INDEX_SPY") if (!Portfolio.Invested && data.Value > 0 && data.Symbol == "INDEX_VIX") { var quantity = (int) (Portfolio.Cash / data.Value); Order("INDEX_VIX", quantity); } }
In your specific case, you should write one "MyCustomForex" class for both symbols. The difference is their location:
// In GetSource return "F:\\Visual Studio Projects\\data\\" + config.Symbol + "min.zip";
as the config.Symbol is the ticker name you pass on AddData<MyCustomForex>:
// Get data at F:\Visual Studio Projects\data\EURUSDmin.zip AddData<MyCustomForex>("EURUSD"); // Get data at F:\Visual Studio Projects\data\USDRURmin.zip AddData<MyCustomForex>("USDRUR");
Also, you will not assign this.Symbol to any value in the constructor. You can either assign it in GetSource or in Reader, using config.Symbol.
Please checkout the full example below. It can be found at the QuantConnect University.
Alexandr Trenkenshu
Thank you very much, Alexandre, for your answer.
Not it is clear for me how to do it)
Alexandr Trenkenshu
Sorry for slip, now it is clear to me how to do it)
JayJayD
Alexandr Trenkenshu, Please, read the documentation.
If the problem is the Symbol, in the docs example you can see how the symbol is retrieved from the SubscriptionDataConfig.
Or even you can use:
coin.Symbol = this.Symbol;
because, as the docs says:
During initialize your algorithm must use AddData<T>(string ticker, Resolution resolution = Resolution.Daily). This gives LEAN the T-type factory to create the objects, the name of the data and the resolution at which to poll the data to check for updates.
Of course, you have to store your data in a way you can reach the correct observations from the ticker.
Like:
And so on….
Please note that the AddData also defines the data Resolution!
If you implement the BaseData correctly, you can add all your data as:
AddData<MyCustomData>("AUDUSD"); AddData<MyCustomData>("USDRUR");
Good luck!
Alexandr Trenkenshu
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!