Drafts
CrunchDAO
Introduction
CrunchDAO is a service that connects strategy developers and capital allocators. With our CrunchDAO integration, you can send trading signals from your live algorithms to the CrunchDAO.
Add Providers
To export signals to CrunchDAO from your algorithm, during initialization, add a CrunchDAO signal export provider.
SignalExport.AddSignalExportProviders(new CrunchDAOSignalExport(apiKey, model, submissionName, comment));
self.signal_export.add_signal_export_providers(CrunchDAOSignalExport(apiKey, model, submissionName, comment))
The CrunchDAOSignalExport
constructor accepts the following arguments:
Argument: |
Argument: |
Argument: |
Argument: |
You can add multiple signal export providers to a single algorithm.
Asset Classes
Our CrunchDAO integration supports signals for US Equities.
Universe Selection
The CrunchDAO skeleton contains the universe constituents. To load it into your algorithm, follow these steps:
- Define a custom universe type.
- In the
Initialize
initialize
method, initialize the universe. - In the algorithm class, define the selector function to select all of the securities in the skeleton file.
class CrunchDaoSkeleton(PythonData): def get_source(self, config, date, isLive): return SubscriptionDataSource("https://tournament.crunchdao.com/data/skeleton.csv", SubscriptionTransportMedium.REMOTE_FILE) def reader(self, config, line, date, isLive): if not line[0].isdigit(): return None skeleton = CrunchDaoSkeleton() skeleton.symbol = config.symbol try: csv = line.split(',') skeleton.end_time = (datetime.strptime(csv[0], "%Y-%m-%d")).date() skeleton.symbol = Symbol(SecurityIdentifier.generate_equity(csv[1], Market.USA, mapping_resolve_date=skeleton.time), csv[1]) skeleton["Ticker"] = csv[1] except ValueError: # Do nothing return None return skeleton
self.add_universe(CrunchDaoSkeleton, "CrunchDaoSkeleton", Resolution.DAILY, self.select_symbols)
def select_symbols(self, data: List[CrunchDaoSkeleton]) -> List[Symbol]: return [x.Symbol for x in data]
Schedule Submissions
CrunchDAO provides a new skeleton every Saturday at 6 PM Coordinated Universal Time (UTC). To schedule your submissions for before the market opens each week, during initialization, you can create a Scheduled Event.
self.week = -1 self.schedule.on( self.date_rules.every([DayOfWeek.monday, DayOfWeek.tuesday, DayOfWeek.wednesday, DayOfWeek.thursday, DayOfWeek.friday]), self.time_rules.at(13, 15, TimeZones.UTC), self.submit_signals)
The preceding Scheduled Event calls the submit_signals
method every weekday at 1:15 PM UTC. Define this method to create and send portfolio targets to CrunchDAO.
def submit_signals(self): if self.IsWarmingUp: return # Submit signals once per week week_num = self.Time.isocalendar()[1] if self.week == week_num: return self.week = week_num symbols = [security.Symbol for security in self.crunch_universe if security.Price > 0] # Get historical price data # close_prices = self.History(symbols, 22, Resolution.Daily).close.unstack(0) # Create portfolio targets weight_by_symbol = {symbol: 1/len(symbols) for symbol in symbols} # Add your logic here targets = [PortfolioTarget(symbol, weight) for symbol, weight in weight_by_symbol.items()] # (Optional) Place trades self.SetHoldings(targets) # Send signals to CrunchDAO success = self.SignalExport.SetTargetPortfolio(targets) if not success: self.Debug(f"Couldn't send targets at {self.Time}")
For more information about requesting historical price and alternative data, see History Requests.
Send Portfolio Targets
To send your current portfolio holdings, call the SetTargetPortfolioFromPortfolio
set_target_portfolio_from_portfolio
method. The method returns a boolean that represents if the targets were successfully sent to CrunchDAO.
var success = SignalExport.SetTargetPortfolioFromPortfolio();
success = self.signal_export.set_target_portfolio_from_portfolio()
To send targets that aren't based on your current portfolio holdings, pass a PortfolioTarget
object or an arraya list of PortfolioTarget
objects to the SetTargetPortfolio
set_target_portfolio
method. In this situation, the number you pass to the PortfolioTarget
constructor represents the portfolio weight. Don't use the PortfolioTarget.Percent
PortfolioTarget.percent
method.
var target = new PortfolioTarget(_symbol, weight); var success = SignalExport.SetTargetPortfolio(target);
target = PortfolioTarget(self._symbol, weight) success = self.signal_export.set_target_portfolio(target)
Signal Requirements
When you submit signals to CrunchDAO, abide by the following rules:
- All signals must have a quantity between 0 and 1 (inclusive).
- Submit one signal per round. If you submit more than one signal in a round, your new submission overwrites the previous one.
- Send signals for at least half of the investment universe.