Hi everyone,
First of all i don't really have a background in programming so i really don't know what i'm doing, i only use chatgpt to help me out with understanding the code and trying to fix it if there is an error. I'm trying to import the moroccan all shares index (MASI) from this website https://www.investing.com/indices/masi-historical-data
when i run the code below, it doesn't bring up any error, but it also doesn't show and trading results, it's completey blank. I would really really appreciate if someone can help me out because this is for a project i'm working on for my studies. I'm basically trying to test a pre established Deep Learning protfolio optimization code made by a quantconnect user https://github.com/shilewenuw/deep-learning-portfolio-optimizationhttps://github.com/shilewenuw/deep-learning-portfolio-optimization
Only thing i need to change for my test is the historical data in "main.py" as mentionned previously i want to incorporate the MASI index and test it using the Deep Learning algorithm.
I'm sorry if i sound stupid, i'm a complete noob.
Here is the "main.py" provided my chatgpt that doesn't seem to show any result :
from AlgorithmImports import *
class MASIIndexData(PythonData):
'''MASI Custom Data Class'''
def GetSource(self, config: SubscriptionDataConfig, date: datetime, isLiveMode: bool) -> SubscriptionDataSource:
# Replace this path with the actual path to your CSV file
path = r'C:\users\hp\OneDrive\Documents\Moroccan All Shares Historical Data'
return SubscriptionDataSource(path, SubscriptionTransportMedium.LocalFile)
def Reader(self, config: SubscriptionDataConfig, line: str, date: datetime, isLiveMode: bool) -> BaseData:
if not (line.strip() and line[0].isdigit()): return None
# Create a new MASIIndexData object
masi_data = MASIIndexData()
masi_data.Symbol = config.Symbol
try:
# Example File Format:
# Date Price Open High Low Vol Change
# 2023-09-01 12050.0 12000.0 12100.0 11950.0 12345678 100.0
data = line.split(',')
masi_data.Time = datetime.strptime(data[0], "%Y-%m-%d") # Date format updated
masi_data.EndTime = masi_data.Time + timedelta(days=1)
masi_data.Value = float(data[1]) # Price
masi_data["Open"] = float(data[2])
masi_data["High"] = float(data[3])
masi_data["Low"] = float(data[4])
masi_data["Volume"] = float(data[5])
masi_data["Change"] = float(data[6])
except:
pass
return masi_data
class MyAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2012, 1, 1) # Set Start Date
self.SetEndDate(2023, 9, 7) # Set End Date
self.SetCash(100000) # Set Strategy Cash
# Add the custom data source MASIIndexData
self.AddData(MASIIndexData, "MASI")
n_periods = 50
self.data = RollingWindow[Slice](n_periods)
self.Train(self.DateRules.MonthStart("MASI"), self.TimeRules.Midnight, self.Rebalance)
self.model = None
self.SetWarmup(n_periods)
self.prev_day = -1
def OnData(self, slice):
# this prevents duplicate bars that sometimes occurs because of SetWarmUp
if self.prev_day != self.Time.day:
self.data.Add(slice)
self.prev_day = self.Time.day
def Rebalance(self):
if not self.data.IsReady:
return
try:
# since RollingWindow is recent at top, we need to reverse it
data = self.PandasConverter.GetDataFrame(self.data).iloc[::-1]
except:
return
# No need to turn the closing prices for custom data into columns
# You can access the custom data directly
if self.model is None:
self.model = Model()
# Pass the custom data to your model for optimization
allocations = self.model.get_allocations(data)
self.Log(f'Portfolio Allocations: {allocations}')
# Adjust the code to set holdings based on the custom data
self.SetHoldings("MASI", allocations[0]) # Assuming MASI is the first and only custom data in the listussion
Mia Alissi
Hello Ziyad,
Firstly, don't worry about sounding like a "noob". Everyone starts somewhere, and it's great that you're taking the initiative to learn and apply these concepts.
From the code you've provided, it seems like you're on the right track. You've correctly defined a custom data class (
MASIIndexData
) and are attempting to load data from a local file. However, there are a few things that might be causing issues:Data File Path: In your
GetSource
method, you've provided a path to a directory, not a specific file. You need to provide the full path to the actual CSV file you're trying to load. For example, if your file is namedMASI_data.csv
, your path should look something liker'C:\users\hp\OneDrive\Documents\Moroccan All Shares Historical Data\MASI_data.csv'
.Data File Format: Your
Reader
method assumes a specific format for your data file. Make sure your CSV file has the same format. The expected format based on your code is:Date, Price, Open, High, Low, Volume, Change
.Error Handling: In your
Reader
method, you're using atry/except
block but not doing anything in theexcept
clause. This means if there's an error in reading a line, your program will silently ignore it and move on. This could be why you're not seeing any results. Consider logging the error or the problematic line to help debug issues.Data Availability: You're using a
RollingWindow
of 50 periods and also setting a warm-up period of 50 days. Make sure your data file has at least this many entries, otherwise, your algorithm might not start trading.Model Training: You're checking if
self.model
isNone
and then initializing it. However, it's not clear where and how this model is trained. Make sure your model is properly trained before you try to get allocations from it.Data Access: In your
OnData
method, you're adding the entireslice
object to yourRollingWindow
. IfMASI
is the only data you're interested in, consider adding just that data to the window:self.data.Add(slice["MASI"])
.Remember, you can always use the
self.Debug
orself.Log
methods to print out information and help debug your algorithm.Lastly, it's important to note that QuantConnect does not currently support direct data import from investing.com. You'll need to manually download your data, save it in the correct format, and then provide the path to this file in your algorithm.
I hope this helps! Let me know if you have any other questions.
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.
Ziyad
Hi,
Thank you for your detailled comment.
Here is the updated code that unfortunately doesn't work either, i have fixed some of the issues you mentionned previously. Please let me know what i should do next.
from AlgorithmImports import *
import pandas as pd
class MASIIndexData(PythonData):
'''MASI Custom Data Class'''
def GetSource(self, config: SubscriptionDataConfig, date: datetime, isLiveMode: bool) -> SubscriptionDataSource:
# Provide the full path to your CSV file
file_path = r'C:\users\hp\OneDrive\Documents\Moroccan All Shares Historical Data.csv'
return SubscriptionDataSource(file_path, SubscriptionTransportMedium.LocalFile)
def Reader(self, config: SubscriptionDataConfig, line: str, date: datetime, isLiveMode: bool) -> BaseData:
try:
data = line.split(',')
masi_data = MASIIndexData()
masi_data.Symbol = config.Symbol
masi_data.Time = datetime.strptime(data[0], "%Y-%m-%d")
masi_data.EndTime = masi_data.Time + timedelta(days=1)
masi_data.Value = float(data[1])
masi_data["Open"] = float(data[2])
masi_data["High"] = float(data[3])
masi_data["Low"] = float(data[4])
masi_data["Volume"] = float(data[5])
masi_data["Change"] = float(data[6])
return masi_data
except:
# Log and handle any errors
self.Debug(f'Error reading line: {line}')
return None
class MyAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2012, 1, 1) # Set Start Date
self.SetEndDate(2023, 9, 7) # Set End Date
self.SetCash(100000) # Set Strategy Cash
# Add the custom data source MASIIndexData
self.AddData(MASIIndexData, "MASI")
n_periods = 50
self.data = RollingWindow[Slice](n_periods)
self.Train(self.DateRules.MonthStart("MASI"), self.TimeRules.Midnight, self.Rebalance)
self.model = None
self.SetWarmup(n_periods)
self.prev_day = -1
def OnData(self, slice):
# Add just the MASI data to the rolling window
if "MASI" in slice.Keys:
self.data.Add(slice["MASI"])
def Rebalance(self):
if not self.data.IsReady:
return
try:
# Reverse RollingWindow to have older data at the top
data = self.PandasConverter.GetDataFrame(self.data).iloc[::-1]
except:
return
if self.model is None:
self.model = Model()
allocations = self.model.get_allocations(data)
self.Log(f'Portfolio Allocations: {allocations}')
# Set holdings based on the custom data
self.SetHoldings("MASI", allocations[0]) # Assuming MASI is the first and only custom data in the list
Mia Alissi
Hello Ziyad,
Your updated code looks much better and you've addressed many of the issues I previously mentioned. However, there are still a few things that might be causing problems:
Indentation: Python is sensitive to indentation, and it seems like there might be some issues with your code's indentation. For example, the methods
GetSource
andReader
should be indented to be part of theMASIIndexData
class. Similarly, the lines of code afterself.AddData(MASIIndexData, "MASI")
should be indented to be part of theInitialize
method.Model Training: You're still initializing your model in the
Rebalance
method, but it's not clear where and how this model is trained. TheModel
class and itsget_allocations
method are not defined in the provided code. Make sure your model is properly trained before you try to get allocations from it.Data Access: In your
OnData
method, you're checking if"MASI"
is inslice.Keys
before adding it to yourRollingWindow
. This is a good practice, but remember thatslice.Keys
are symbols, not strings. You should compare it to the symbol of your custom data, not the string"MASI"
. You can save the symbol when you add the data:self.masi = self.AddData(MASIIndexData, "MASI").Symbol
and then checkif self.masi in slice.Keys
.Setting Holdings: In your
Rebalance
method, you're trying to set holdings for"MASI"
. However,SetHoldings
expects a symbol, not a string. You should use the symbol you saved when you added the data:self.SetHoldings(self.masi, allocations[0])
.Remember, you can always use the
self.Debug
orself.Log
methods to print out information and help debug your algorithm.I hope this helps! Let me know if you have any other questions.
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.
Ziyad
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!