6. How Composer Symphonies Work
A Composer symphony is an automated trading algorithm that executes trades based on parameters of your choice.. Some symphonies are simple—like holding one ETF in normal conditions and rotating to a different ETF when the S&P 500 drops by at least 5% over five days—while others use complex rules with dozens of triggers.
However, complex doesn’t always mean better. A simple, well-structured symphony can be just as effective as an intricate one.
Let’s explore how Composer symphonies work in a step-by-step walkthrough, to help you understand what happens with your money once you’ve set a symphony to manage it.
Key Building Blocks of a Symphony
WEIGHT Block - How Funds are Allocated
When viewing a symphony’s factsheet or editor, you’ll see its functions and conditions collapsed under a green WEIGHT block, which controls asset allocation.
WEIGHT determines how a symphony distributes investments among different assets. The three main types are:
- Equal weighting – Invests evenly across selected assets.
- Specified weightings – Allocates set percentages to each asset.
- Inverse volatility weighting – Allocates more to less volatile assets.
Here’s an example of a popular symphony’s WEIGHT blocks—with additional settings added beyond the original “TQQQ For the Long Term” symphony.
If a symphony selects the top three tickers and you invest $1,000, the allocation will be approximately $333.33 per ticker, with any remainder held in cash.
Most symphonies use equal weighting by default, but more advanced strategies may apply customized weightings to optimize allocations. For instance, in the image above, an Inverse Volatility weighting strategy assigns a larger portion of the symphony’s allocation to the least volatile tickers in its selection, based on the relative volatility of each asset.
IF / ELSE Conditional Block - Making Decisions Based on Market Data
The most fundamental function of any Composer symphony is the IF / ELSE check. These blocks are always added to symphonies in pairs, but once they’re added to a symphony, you can nest all sorts of sub-blocks underneath either the IF check, the ELSE condition, or to both.
This is the decision-making engine of a symphony. It checks real-time market data from Xignite and follows different paths based on conditions like:
- Current price
- Cumulative return
- Exponential moving average (EMA) of price
- Maximum drawdown
- Moving average of price
- Moving average of return
- Relative strength index (RSI)
- Standard deviation of price
- Standard deviation of return
All of these conditions can be selected from the editing window that opens when you click the pencil icon next to any IF block:
These metrics are evaluated over a customizable range of trading days, from as short as one day to over 200 days. For example, an IF conditional that analyzes the “10-day cumulative return of QQQ” will determine the appropriate branch based on whether the ETF’s 10-day cumulative return (representing its total gain or loss over the past 10 trading days) exceeds or falls below the specified threshold.
Each IF/ELSE conditional block checks whether the assessed metric is “greater than” or “less than” the designated value. This comparison can be made using either fixed numerical thresholds or by dynamically evaluating the first IF condition against a second IF condition, which follows the same configuration options. Use the dropdown in the second row to specify whether your condition should compare metrics greater than or less than your benchmark ticker.
Continuing with our earlier example of QQQ’s 10-day cumulative return, the first approach within this block would use a predefined percentage ranging from 0 to 100. This percentage represents potential extremes in 10-day gains that could signal a need to adjust allocations. In the symphony view, it would appear as follows:
“If 10d Cumulative Return of QQQ is greater than 7%”
The outcome of this condition is straightforward. If QQQ’s 10-day cumulative return exceeds 7% when the symphony begins its trading period at the execution time, the IF block will evaluate as true, and the symphony will follow the logic nested within that IF block. If QQQ’s cumulative return is 6.99% or lower, the symphony will instead follow the conditions outlined in the ELSE block.
You can set the threshold as high as you like, but certain conditions, such as Cumulative Return tend to perform better within narrower ranges. For instance, it is highly unlikely that QQQ will gain 50% in 10 trading days, and even a 10% gain over that period is considered extreme. However, a 7% gain over 10 trading days has occurred multiple times in QQQ’s history.
Alternatively, a dynamic IF check for Cumulative Return might be structured as follows:
“If 10d Cumulative Return of QQQ is greater than 20d Cumulative Return of SPY”
With this check, the symphony continuously evaluates whether QQQ’s 10-day cumulative return is higher (at execution time) than SPY’s 20-day cumulative return. By analyzing a period twice as long for SPY as for QQQ, this logic is designed to identify instances where QQQ exhibits significantly stronger short-term growth than SPY in half the time.
This condition will rarely trigger, as SPY and QQQ tend to perform similarly over time and share many of the same component tickers. However, it serves as an example of how a symphony can respond to “extreme” market conditions.
Dynamic IF checks function by replacing the fixed value in the third row of the editing window with the real-time value of a second ticker at execution. To set a dynamic IF check, toggle off the Fixed Value option, allowing you to select any of the same IF conditions for your benchmark ticker:
However, just because a symphony can compare two tickers using dynamic checks does not necessarily mean that every comparison is logical or meaningful within symphony logic.
For example, it would be impractical to compare QQQ’s 10-day Cumulative Return to SPY’s 10-day Relative Strength Index (RSI), as these metrics assess different aspects of performance and operate on distinct measurement scales. In contrast, comparing QQQ’s 10-day Cumulative Return to SPY’s 10-day Max Drawdown may be more useful, as both metrics are evaluated over the same timeframe and share a common measurement scale (0-100%).
Nesting Blocks in Composer Symphonies
Many symphony builders create Matryoshka-style nesting structures within their IF/ELSE conditionals, where one IF check leads into multiple subsequent IF checks before ultimately reaching blocks with investable tickers. This approach is often considered to produce more robust algorithms, enabling them to respond more effectively to a broader range of market conditions and potential price-moving events.
A symphony can contain dozens, or even hundreds, of nested child blocks. Some symphonies function as highly intricate systems, with hundreds of interwoven blocks working together to analyze and adapt to a wide array of possible market conditions.
A Composer symphony can continue following nested conditions through many checks, but every branch of a symphony reaches its end when it reaches an Asset and/or Filter block.
Asset Block – Selecting What to Trade
When a symphony reaches an Asset Block, it chooses specific stocks, ETFs, or crypto to invest in. A symphony may:
- Invest fully in one asset
- Allocate across multiple tickers using a Weight Block
Here’s the final set of Asset blocks in our TQQQ For the Long Term copy:
A symphony ending with a single ticker is designed to confidently select the best investment based on preceding IF/ELSE conditions. Others use the WEIGHT block to distribute funds across multiple tickers, either equally or at set ratios. But when a symphony needs to pick the best options from a larger list, the Filter block comes into play.
Filter Block – Sorting and Selecting Assets
Composer’s Filter block creates a SORT condition, under which can be nested any number of tickers:
This screenshot displays one of the simplest implementations of a Filter block, offering a basic choice between two tickers—often used as a safeguard against downtrends.
A Filter block utilizes the same metrics available in IF/ELSE blocks for conditional checks but is specifically designed to sort a list of tickers based on a selected metric and timeframe. It then selects a specified number of tickers from either the top or bottom of the sorted list.
For example, if you wanted to identify the top five tickers based on their 10-day Cumulative Returns, you would configure the Filter block as follows:
“SORT 10d Cumulative Return” and “SELECT Top 5”
Naturally, the number of tickers selected by a Filter block cannot exceed the number of tickers in the list nested beneath it. However, setting the selection size equal to the total number of tickers will simply result in the Filter block selecting every ticker in the list each time the symphony reaches that branch.
Filter blocks are often used in symphonies designed to first identify and react to broad market conditions or trends, and then select investments from a larger list of assets whose movements may not directly correlate with the conditions checked by IF/ELSE blocks.
For example, if an earlier condition evaluates the 10-day RSI of QQQ, a nested Filter block could then sort and select stocks from a basket of biotech or oil and gas tickers, as these industries typically do not move in tandem with tech indices. While it may not always seem logical to sort oil and gas stocks based on the strength of a tech index, unexpected combinations of logic can sometimes yield superior results.
That said, unlikely logic pairings can also lead to significant portfolio risks if misused. This is why it is crucial to analyze the performance of any symphony before investing. In most cases, this evaluation is done through the symphony’s backtest results.
The Group Block - Building More Complex Strategies
A Group block (or simply a Group of blocks) allows multiple conditions to be combined into a single, selectable Composer block. These blocks can be renamed, copied, and pasted anywhere within the Composer symphony editor for easier organization and reuse.
Most symphonies use Group blocks to consolidate multiple named strategies into a single, overarching strategy. In fact, every symphony’s top-level block is a Group block, enabling entire symphonies to be copied and integrated into other symphonies seamlessly.
Additionally, child blocks can also be Group blocks, allowing symphonies to nest large sections of conditions at any level—provided there is sufficient space within the symphony. While it is rare for a symphony to become too large for Composer to save and execute, it is possible if it contains hundreds or thousands of highly complex, nested conditions.
Group blocks are often used as shortcuts to replicate large sections of symphony logic with a single click—essentially functioning as Composer’s version of a template. These reusable blocks explain why you may encounter unusual or unexpected names assigned to component blocks within symphonies. In most cases, these names are simply inherited from the original Block or symphony being duplicated.
When you see symphonies with multiple blocks bearing custom names, they are almost always Group blocks containing entire branches of logic or, in some cases, entirely separate symphonies nested within them.
But what do many of Composer’s unusual and obscure symphony names actually mean?
Understanding Symphony Names
Symphony names often follow developer-style versioning (e.g., 1.0.3), reference specific assets (like “TQQQ For the Long Term”), or include inside jokes from the Composer community. Some common abbreviations include:
- FTLT = For The Long Term
- JRT = Just Run This
- WMDYN = What More Do You Need?
- BB = Beta Baller (one of the more unpredictable symphony designs)
- YFR = You’ll Friggin’ Regret (running this symphony)
- OOS = Out of Sample (a backtest-related term further defined in the next section)
- BT = Backtest
Many symphony also names attempt to describe, in a very general high-level way, that symphony’s asset focus, particularly if a symphony is focused on trading a single ticker, like TQQQ, around a range of possible market conditions.
For example, the “TQQQ For the Long Term (Reddit Post Link)” symphony, which we’ve used as an example in this guide, has been enduringly popular with our Composer community. This is one of the earlier community symphonies on the Discover page, and it was also shared widely on Reddit in early-mid 2023. This name is fairly simple to decipher.
“TQQQ” here simply refers to the TQQQ ticker, which provides 3x the return of QQQ, which tracks the Nasdaq 100 index of technology stocks. “For the Long Term” was eventually shortened into one of the acronyms popularized by the Composer community, FTLT.
Names don’t determine performance, so always check the logic and backtested results before investing.
OOS Start Date – Why It Matters
When viewing a symphony’s factsheet on the Discover or Portfolio pages, you may notice a vertical white line on the chart’s Y-axis, labeled “OOS Start Date.” But what does this mean, and what does OOS stand for?
The Out of Sample (OOS) Start Date marks the last time a symphony was edited. This distinction is important because:
- Before the OOS date – Performance results are based on historical backtests.
- After the OOS date – Performance reflects real-world market conditions.
A symphony cannot be overfit into the future. Even if a symphony appears to have been overfitted to past data, its post-OOS results can indicate whether its logic remains effective in real-world conditions—though likely with slightly diminished performance compared to the optimized backtest.
Why does the OOS date matter?
The earlier a symphony’s OOS start date, the more real-world performance data it has available for analysis.
For example, the TQQQ FTLT symphony discussed in the previous section has undergone multiple modifications. However, one of its most popular versions, “TQQQ For The Long Term (Reddit Post Link),” has been OOS since January 24, 2023. This means that any results after that date reflect real-world conditions, rather than backtest optimizations.
Notably, this symphony has continued to outperform its benchmarks (SPY and QQQ) since its OOS date nearly two years ago. While past performance never guarantees future results, symphonies with longer periods of OOS outperformance tend to attract less speculative investors.
How does editing affect OOS?
Each time a symphony is edited and saved, its OOS date resets to the current day. This is why experienced symphony builders often clone existing symphonies instead of modifying the original. By keeping the original symphony unchanged, they can preserve a continuous record of live performance data, even if they believe improvements could be made.
It’s also important to note that the OOS date does not mean a symphony has been actively running in a portfolio with real money since that date. It simply indicates that no changes have been made to the symphony’s logic since then—ensuring that its post-OOS results are not influenced by any retrospective optimizations.