Your Life, In C# and AAAP

Where AAAP means "As Automatically As Possible". In this case, we can assume that our syntactical command of C# is not very high and that we want to translate a straightforward trading algorithm constructed using Quantconnect's Lean Engine. Our example algorithm for this translation will be the simple traditional investment wisdom algorithm shown in this previous post. However, we repeat it here for ease of access:

class YourLife(QCAlgorithm):

    def Initialize(self):
        self.start = datetime(2002, 9, 1)
        # Your initial age in 2002:
         self.INITIAL_AGE = 35self.SetStartDate(self.start)  
         # Set Start Date
         self.SetCash(100000)  
         # Set Strategy Cash
         self.AddEquity("SPY", Resolution.Daily)
         self.AddEquity("TLT", Resolution.Daily)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage,
                               AccountType.Cash)

    def OnData(self, data):              
        # Your age since simulation start, in days and years:
        your_age = (self.Time - self.start).days
        your_years = (your_age/365) + self.INITIAL_AGE        
        ratio = (100 - your_years)/100self.SetHoldings('SPY', ratio)
        self.SetHoldings('TLT', 1-ratio)

As our C# is not good enough, and we undoubtedly know what we want our algorithm to accomplish, we will look for a Python to C# translator. The tool located at https://pythoncsharp.com/ seems reasonable enough. By directly running our exiting Python algorithm through this translator, we obtain the following syntactically correct code:

namespace Namespace {
    
    public static class Module {
        
        public class YourLife : QCAlgorithm {
            
            public virtual object Initialize() {
                this.start = datetime(2002, 9, 1);
                // Your initial age in 2002: this.INITIAL_AGE = 35;
                this.SetStartDate(this.start);
                this.SetCash(100000);
                this.AddEquity("SPY", Resolution.Daily);
                this.AddEquity("TLT", Resolution.Daily);
                this.SetBrokerageModel( 
                BrokerageName.InteractiveBrokersBrokerage,  
                AccountType.Cash); 
            }
            
            public virtual object OnData(object data) {
                // Your age since simulation start, in days and years:
                var your_age = (this.Time - this.start).days;
                var your_years = your_age / 365 + this.INITIAL_AGE;
                var ratio = (100 - your_years) / 100;
                this.SetHoldings("SPY", ratio);
                this.SetHoldings("TLT", 1 - ratio);
            }
        }
    }
}

Of course, when trying to compile, it will not. We have five errors that the automatic translation cannot understand during its work:

The browser IDE integrated into Quantconnect marks the compilation errors as an erroneous declaration of the Initialize method for the QCAlgorith class and the associated missing variable declarations. Remember that in this straightforward trading algorithm, we are trying to balance our portfolio between risky assets represented by SPY and safe assets represented by the TLT EFT according to our age. Therefore, we need our initial age and a starting date as variables that must be declared first in C#. Python allows these variables to appear undeclared in the definition of a class.


We must declare these two new class variables in the class definition first, then override the Initialize function to set and use our new variables while changing the return type to "void". Keeping the inherited objects as virtual is not necessary, and also, our return types must be modified or a "return 0" added to end the OnData method. In this case, it is possibly better to add the void keyword to the method definition than patching it up with a return 0.


We need three total modifications from the translation and no fundamental syntactical changes beyond C# specific declarations. In C#, using anonymous variable types (var declarations) simplifies the work quite a bit too.


Regarding performance, the attached backtest completes in 118 seconds, while the Python code takes 122 seconds. In this case, there is not much internal interaction between variables and data tables, so the C# extra performance is not noted, in line with the lack of optimization effort required by using As Automatic As Possible translations.


This backtest is attached here:


The model in Python is here.


Remember that our publications are not financial advice. Ostirion.net does not hold any positions on any of the mentioned instruments at the time of publication. If you need further information, asset management support, automated trading strategy development, or tactical strategy deployment, you can contact us here.

10 views0 comments