June 5

0 comments

Leveraging Voting Mechanisms for Generating Algorithmic Trading Signals in EasyLanguage

By Jeff Swanson

June 5, 2023

Algorithmic Trading, Automated Trading Development, EasyLanguage

Today, I'd like to dive into a topic that can significantly enhance the efficiency of our trading systems: Voting Mechanisms. If you're striving to build a more robust and reliable trading strategy using TradeStation's EasyLanguage, this post is for you.

For those who may not know, a voting mechanism in algorithmic trading is an advanced technique that allows multiple strategies or indicators to 'vote' on whether to execute a trade. This system can lead to a more balanced and resilient approach, giving us more confidence in our trading decisions. You can think of it as a democratic system where every indicator gets a say in decision-making, increasing the overall reliability of the signals generated.

As traders and system developers, many of us have experienced situations where we've had to rely on a single indicator, only to be left wondering if there was a better way. Could we have diversified our decision-making process? Could we have used the combined power of multiple indicators to make a more informed decision? This is where the concept of a voting mechanism shines.

In this post, we'll explore voting mechanisms in detail, understand how they can add value to our trading systems, and learn how to implement them in our EasyLanguage code. Whether you're a beginner just getting your feet wet or an experienced trader looking to refine your strategies, understanding and utilizing voting mechanisms can offer a new perspective.

Let's delve deeper into the democratic world of trading indicators and discover how this collective decision-making tool can take our EasyLanguage strategies to the next level. Buckle up, and let's get started!

What Is A Voting Mechanism in EasyLanguage

A voting mechanism in algorithmic trading is a powerful tool that involves multiple indicators or strategies. Each of these indicators' votes' on whether to execute a trade. The final trading decision is based on these combined votes, which can be either a simple majority or a weighted voting system.

Imagine you have three indicators: A, B, and C. In a simple majority voting mechanism, the trade is executed if two of the three indicators agree on a trading signal. For example, if Indicators A and B signal a 'Buy,' but Indicator C signals a 'Sell,' the trading system would still execute a 'Buy' order because the majority (two out of three indicators) agreed on 'Buy'.

On the other hand, in a weighted voting system, each indicator's 'vote' can have different weights depending on their past performance, reliability, or any other criteria you set. This means some indicators can influence the final decision more than others.

Voting Mechanism Benefits

Here's what a well-crafted voting mechanism can offer:

  1. Increased Robustness: A voting mechanism employs multiple indicators or strategies. As such, it isn't entirely dependent on the performance of a single indicator. This diverse approach can lead to a more robust trading system, which might hold up better under various market conditions.
  2. Reduced Risk: By combining the insights of several indicators, a voting mechanism can reduce the risk associated with false signals from any single indicator. If one indicator gives a false signal, others might not, preventing a potentially disadvantageous trade.
  3. Enhanced Decision-Making: A voting mechanism allows your trading system to make decisions based on a 'committee' of indicators, each providing different insights. This broader perspective can lead to more informed and balanced trading decisions.
  4. Versatility: The versatility of a voting mechanism lies in its customization. You can choose which indicators to include in your voting system, the voting criteria, and whether votes are equal or weighted. This means you can tailor your voting system to match your unique trading strategy and risk tolerance.
  5. Potential for Improved Performance: While not guaranteed, the combination of increased robustness, risk reduction, and better decision-making could lead to an improved trading performance over time. 
  6. Useful for Complex Systems: For those building complex algorithmic systems, voting mechanisms can be crucial in managing multiple strategies and ensuring that the decision-making process is comprehensive and balanced.

Remember, while a voting mechanism can offer several benefits, it's not a silver bullet. It's still crucial to carefully select and fine-tune your indicators and to thoroughly backtest your trading system before going live. However, used wisely, a voting mechanism can be an excellent tool in your trading arsenal.

Voting Mechanism in EasyLanguage
Setting up a primary voting mechanism in EasyLanguage can be a straightforward process, particularly if you already have some familiarity with coding in this language. You must identify indicators for your trading strategy to create a voting mechanism. Each of these indicators will serve as a voting member in your mechanism. You can think of them as a panel of experts, each giving their opinion on whether to execute a trade.

Consider a scenario with three indicators: 

  1. Moving Average (MA)
  2. Relative Strength Index (RSI)
  3. Bollinger Bands (BB) 

EasyLanguage

inputs: MA_length(20), RSI_length(14), BB_length(20);
variables: MA_val(0), RSI_val(0), BB_val(0), Buy_Signal(0), Sell_Signal(0);

// Calculate indicator values
MA_val = Average(Close, MA_length);
RSI_val = RSI(Close, RSI_length);
BB_val = BollingerBand(Close, BB_length, 2); // Using 2 standard deviations

// Generate Buy signals
Buy_Signal = iff(Close > MA_val, 1, 0) + iff(RSI_val < 30, 1, 0) + iff(Close < LowerBand(BB_val), 1, 0);

// Generate Sell signals
Sell_Signal = iff(Close < MA_val, 1, 0) + iff(RSI_val > 70, 1, 0) + iff(Close > UpperBand(BB_val), 1, 0);

if Buy_Signal >= 2 then Buy("Majority Buy") next bar at market;
if Sell_Signal >= 2 then SellShort("Majority Sell") next bar at market;

In this EasyLanguage code, we first calculated the values for our three indicators. We then generate Buy and Sell signals based on certain conditions for each indicator. If two out of three (or more) conditions are met, the system will execute a Buy or Sell order.

Remember, using a voting mechanism is all about bringing more diversity and robustness into your decision-making process. It's about going beyond relying on a single indicator and instead using the combined power of multiple indicators to make more balanced trading decisions. And as we've seen, this can be accomplished quite effectively with EasyLanguage.

Simple Example of Voting System in EasyLanguage

Let's create a simple voting system for the ES market. Let's start with three indicators we can use on the ES market that we know work. Using indicators that work for your market and time frames is essential. A voting scheme will not work if you build it from indicators that don't work. How do you know an indicator works? You must test it.

  1. Two Period Relative Strength Indicator (RSI2)
  2. Average Directional Index (ADX)
  3. Internal Bar Strength (IBS)

Below are the rules for each of the individual indicators. 

Relative Strength Indicator:

  • Buy when the indicator is less than 25
  • Sell when the indicator is greater than 75

Average Directional Index:

  • Buy when ADX(5) greater than 30
  • Sell when ADX(5) less than 30

Internal Bar Strength:

  • Buy when IBS is less than 30
  • Sell when IBS greater than 95

I loaded these on the daily chart of the E-mini S&P futures market and tested them individually. I wanted to see how each rule performs on its own.

Testing Environment

Unless otherwise stated, all the tests in this post will have the following assumptions.

  • Testing dates: January 1, 2006, to December 31, 2019. 
  • $30 deducted per round trip trade
  • $50,000 starting capital
  • Only one contract will be traded per signal.

 The results are in the following table.

RSI

IBS

ADX

Net Profit

$79,275

$72,293

$81,912

Profit Factor

1.63

1.41

1.86

Total Trades

250

484

175

Avg.Trade Net Profit

$317

$149

$478

Annual Rate of Return

7.20%

6.77%

7.35%

Max Drawdown

$36,663

$32,510

$30,760

Creating The Voting System in EasyLanguage

Now let's create a simple voting system. Here is the code.

Inputs:
BuyCount(2),
SellCount(1),
ADX_Length(5),
ADX_Theshold(30),
RSI_Buy_Threshold(25),
RSI_Sell_Threshold(75),
IBS_Buy_Threshold(30),
IBS_Sell_Threshold(95);

Variables:
ADX_val(0),
RSI_val(0),
IBS_val(0),
Buy_Signal(0),
Sell_Signal(0);

// Calculate indicator values
ADX_val = ADX(ADX_Length);
RSI_val = RSI(Close,2);
IBS_val = IBS;

// Count Buy Signals
Buy_Signal = iff(ADX_val > ADX_Theshold, 1, 0) + 
             iff(RSI_val < RSI_Buy_Threshold, 1, 0) +
             iff(IBS_val < IBS_Buy_Threshold, 1, 0);

// Count Sell Signals
Sell_Signal = iff(ADX_val <= ADX_Theshold, 1, 0) + 
              iff(RSI_val >= RSI_Sell_Threshold, 1, 0) +
              iff(IBS_val >= IBS_Sell_Threshold, 1, 0);

Notice that two of the three indicators must trigger before issuing a buy signal. However, only one signal is required to exit. I like my strategies to get out quickly; thus, the threshold to exit is lower.

Here is the performance compared to the signals individually.

TradeStation Performance Report

Performance Report (click to enlarge)

TradeStation equity curve

Equity Curve (click to enlarge)

Voting System Trades on ES

Voting System Trades on ES (click to enlarge)

RSI

IBS

ADX

VOTING

Net Profit

$79,275

$72,293

$81,912

$100,820

Profit Factor

1.63

1.41

1.86

2.96

Total Trades

250

484

175

121

Avg.Trade Net Profit

$317

$149

$478

$833

Annual Rate of Return

7.20%

6.77%

7.35%

8.36%

Max Drawdown

$36,663

$32,510

$30,760

$25,063


So, how did the voting system hold up?

Rather well!

The Voting mechanism has fewer trades because we need two signals to trigger before taking a trade. But with fewer trades, we are also making more money. Our strategy has become more effective.

The Voting strategy has increased the net profit, profit factor, and average profit per trade. It has also reduced the Max Drawdown. This is excellent!

Remember, this is not a complete trading system, as this strategy has no stops.
Now that you know how to create a simple voting strategy, let's look at a slightly more complex example.

A Voting System With Weights

Let's dive deeper into the world of voting mechanisms and explore the concept of weighted votes.

In a basic voting mechanism, each indicator's vote has equal weight. But in some scenarios, you might want some indicators to influence the trading decision more. This is where weighted votes come into play. By assigning different weights to different indicators, you can fine-tune your trading system to prioritize specific signals over others.

Let's use the same example, but we'll add weights to our indicators this time. For instance, we might assign a weight of 50% to the Moving Average (MA), 30% to the Relative Strength Index (RSI), and 20% to the Bollinger Bands (BB). Now, the trading decision isn't just about the majority; it's about where most of the 'weight' lies.

In EasyLanguage, this might look like the following:

EasyLanguage

Inputs: Length(14), OverSold(30), OverBought(70), MA_weight(0.5), RSI_weight(0.3), BB_weight(0.2);
Vars: MA_val(0), RSI_val(0), BB_val(0), Buy_Score(0), Sell_Score(0);

MA_val = Average(Close, Length);
RSI_val = RSI(C, Length);
BB_val = BollingerBand(Close, Length, 2);

Buy_Score = IFF(Close > MA_val, 1, 0) * MA_weight + IFF(RSI_val < Oversold, 1, 0) * RSI_weight + IFF(Close < LowerBand(BB_val), 1, 0) * BB_weight;

Sell_Score = IFF(Close < MA_val, 1, 0) * MA_weight + IFF(RSI_val > OverBought, 1, 0) * RSI_weight + IFF(Close > UpperBand(BB_val), 1, 0) * BB_weight;

If Buy_Score > 0.5 then 
    Buy ("Weighted Buy") next bar at market
else if Sell_Score > 0.5 then 
    SellShort ("Weighted Sell") next bar at market;


In this code, we calculate a 'Buy_Score' and a 'Sell_Score' based on the weights of each indicator. If the 'Buy_Score' is greater than 0.5 (50%), we execute a 'Buy' order. Likewise, if the 'Sell_Score' is greater than 0.5, we perform a 'Sell' order.

Remember, the weights you assign should reflect the reliability and importance of each indicator in your trading strategy. Determining these weights requires trial and error and, indeed, a lot of backtesting. But with patience and persistence, a well-optimized weighted voting mechanism can significantly enhance your trading system.

As always, feel free to experiment, tweak, and ask questions. EasyLanguage Mastery is here to support your journey in algorithmic trading. I'm not going to test the weighted version of this strategy. I'll leave that as an exercise for you.

Let's now turn to a big problem for all system traders. The problem of curve fitting.

How To Avoid Overfitting (Curve Fitting)

Overfitting is a common pitfall in algorithmic trading, where a trading system is excessively tailored to match past data. While this might lead to impressive results in backtesting, the performance often deteriorates when the system is applied to new, unseen data. This is because an overfit system needs to be more specific to past market conditions, which may not repeat themselves in the future.

When using voting mechanisms, you risk overfitting your trading system by adding too many indicators or assigning overly specific weights. You might be tempted to keep adding indicators until you find a combination that performs extraordinarily well on historical data. Similarly, fine-tune the weights of these indicators until you achieve impressive backtest results. But remember, this could lead to overfitting.

Overfitting can give a false sense of security, as the system performs exceptionally well on past data. However, when applied to new data, an overfit system can often perform poorly, leading to unexpected losses. This is because the 'noise' or random fluctuations in past data, which the overfit system has learned as patterns, may not exist in future data.

Here are a few tips to avoid overfitting when using voting mechanisms:

1. Keep it Simple: Resist the urge to include too many indicators in your voting mechanism. A more straightforward system with fewer indicators is often more robust and less prone to overfitting.

2. Use Out-of-Sample Testing: Always validate your system using out-of-sample data. Remember, out-of-sample data was not used during the system development process. A system that performs well both in-sample and out-of-sample is less likely to overfit.

3. Avoid Excessive Fine-Tuning: Be cautious when adjusting the weights of your indicators. It's okay to fine-tune them, but avoid making them overly specific to past data.

4. Regular Reviews: Review and update your system as new data becomes available. This can help ensure that it remains adequate and relevant.

Remember, creating a robust trading system involves a delicate balance. It's about making the system specific enough to identify profitable opportunities yet general enough to work under different market conditions. This gives you a good understanding of overfitting and how to avoid it when using voting mechanisms.

Troubleshooting Common Issues

Let's discuss troubleshooting common issues you might encounter while implementing a voting mechanism in your trading system.

When working with EasyLanguage and voting mechanisms, you might encounter a few hiccups along the way. But don't worry - most of these issues can be resolved by troubleshooting.

Incorrect Indicator Values: If you're not getting the expected trading signals, first check the values of your indicators. Ensure that they are being calculated correctly and that the conditions for your Buy and Sell signals are set up correctly.

Order Execution Problems: If your orders aren't being executed as expected, review the conditions for your Buy and Sell signals and ensure they are triggering at the right time. Also, verify the order execution commands (e.g., `Buy` or `SellShort`) to ensure they are correct.

Weighting Issues: If you're using a weighted voting system, ensure the weights for each indicator add up to 1 (or 100%). If the total is less than 1, you might have skewed results.

Overfitting: As discussed earlier, overfitting is a common problem where your system needs to be more fine-tuned to past data. If your system performs exceptionally well on historical data but fails on new data, it might be overfitting. Consider simplifying your system, using out-of-sample testing, and avoiding excessive fine-tuning.

Runtime Errors: If you encounter runtime errors, check your code for syntax errors, incorrect function usage, or improper variable references. EasyLanguage has an excellent debugging tool to help identify and fix these issues.

Remember, running into issues when coding is normal, especially when just starting out. Use these problems as learning opportunities. With some patience and persistence, you'll overcome these hurdles and be on your way to mastering EasyLanguage and developing your robust trading system.

Best Practices

Indeed, adopting best practices can make your journey with voting mechanisms smoother and more successful. Here are a few guidelines that I suggest:

Keep it Simple: Start with a simple majority voting system. Once comfortable with this, you can gradually move towards more complex systems such as weighted voting.

Use Reliable Indicators: Use indicators that have shown reliable results. While no indicator is foolproof, starting with established and tested indicators can provide a solid foundation for your voting mechanism.

Avoid overfitting: Avoid overfitting by keeping your system general enough to work under different market conditions. This involves resisting the temptation to add too many indicators or excessively fine-tuning their weights.

Backtest Thoroughly: Backtest your system thoroughly to ensure it's reliable and profitable. And not just with in-sample data but with out-of-sample data as well.

Stay Updated: Keep updated with the latest developments in algorithmic trading and EasyLanguage. This can provide new ideas and techniques to improve your voting mechanism.

Regularly Review and Adjust: No trading system is perfect. It's essential to periodically review and adjust your system based on new data and market conditions.

Never Stop Learning: The field of algorithmic trading is vast and constantly evolving. Keep learning, experimenting, and improving. Consider every setback as a learning opportunity and every success as motivation to achieve more.

Remember, these are guidelines, not rules. What works best for you will depend on your trading strategy, risk tolerance, and personal preferences. The key is to be patient, persistent, and always open to learning. With time and experience, you'll find the best approach for your unique trading journey.

That's it for now. Remember, the strategy code and TradeStation WorkSpace are available for download within our private member area. It's free to join!


Jeff Swanson

About the author

Jeff has built and traded automated trading systems for the futures markets since 2008. He is the creator of the online courses System Development Master Class and Alpha Compass. Jeff is also the founder of EasyLanguage Mastery - a website and mission to empower the EasyLanguage trader with the proper knowledge and tools to become a profitable trader.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Learn To Code & Build Strategies
Using EasyLanguage. 

>