/// <summary> /// Create a trading rule from AST to the model /// </summary> /// <param name="tradingStrategyAstNode"></param> /// <param name="tradingStrategyModel"></param> private void AddTradingRuleToModel(TradingStrategyAstNode tradingStrategyAstNode, TradingStrategy tradingStrategyModel) { foreach (var tradingRuleAst in tradingStrategyAstNode.TradingRules) { if (tradingRuleAst is ConditionalRuleAstNode) { var stopLossAstRule = tradingRuleAst as ConditionalRuleAstNode; tradingStrategyModel.TradingRules.Add(new StopLossRule( stopLossAstRule.Name, ConvertExecutionFrequency(stopLossAstRule.ExecuteFrequency), new Variable("position"), ConvertStatementAst(stopLossAstRule.Statements), (BooleanExpression)ConvertExpressionAst(stopLossAstRule.Condition), CreateVariable(stopLossAstRule.PositionSet.PositionSetName))); } else if (tradingRuleAst is GeneralRuleAstNode) { tradingStrategyModel.TradingRules.Add(new TradingRule( tradingRuleAst.Name, ConvertExecutionFrequency(tradingRuleAst.ExecuteFrequency), ConvertStatementAst(tradingRuleAst.Statements)) ); } } }
/// <summary> /// The method for executing the trading strategy. /// The result are the position records that located in the position sets /// </summary> /// <param name="tradingStrategy">the trading strategy</param> /// <param name="startDate">start date of back-testing</param> /// <param name="endDate">end date of back-testing</param> public void Execute(TradingStrategy tradingStrategy, DateTime startDate, DateTime endDate) { Currency baseCurrency = _currencyTable[tradingStrategy.Portfolio.HomeCurrency]; // initialize evaluation context var collectionDataContainer = new PredefinedDataContainer(); collectionDataContainer.Add(new Top3Currencies(_currencyDataSource, baseCurrency)); // predefined data set "Top3Currencies" collectionDataContainer.Add(new Bottom3Currencies(_currencyDataSource, baseCurrency)); // predefine data set "Bottom3Currencies" _evaluationContext = new Context(_currencyDataSource, collectionDataContainer, new ValuesTable(10), startDate); // Add the current date of execution into values table _evaluationContext.ValuesTable.Add(TODAY_STR, startDate); // Add base currency as a variable _evaluationContext.ValuesTable.Add(BASE_CURRENCY_STR, baseCurrency.Name); // put all the paramter definitions into the table foreach (var param in tradingStrategy.ConstantVariableDefinitions) { _evaluationContext.ValuesTable.Add(param.Variable.Name, param.Constant.Eval(_evaluationContext)); } // initialize position set foreach (var positionDef in tradingStrategy.Portfolio.PositionSets) { PositionType type = (positionDef.PositionType == FXStrategy.MetaModel.PositionType.Long)?PositionType.Long:PositionType.Short; CreatePositionSet(positionDef.Name, baseCurrency, (int)positionDef.Number.Eval(_evaluationContext), type); } // initialize execute frequency tradingStrategy.TradingRules.ForEach(t => t.ExecuteFrequency.Initialize(startDate, endDate,_evaluationContext)); // add predefined data set into collection data container for(DateTime currentDate = startDate; currentDate <= endDate; currentDate = currentDate.AddDays(1)) { // No activities on weekend if (DateTimeHelper.IsWeekEnd(currentDate)) continue; _evaluationContext.ValuesTable[TODAY_STR] = currentDate; _evaluationContext.CurrentDate = currentDate; foreach (TradingRule rule in tradingStrategy.TradingRules) { // evaluate the rule inner statement // only if current date fit to its execution frequency if (rule.ExecuteFrequency.CanExecute(currentDate)) EvaluateStatement(rule.InnerStatement); } } }
/// <summary> /// Handles global identifier /// </summary> /// <param name="tradingStrategyAstNode"></param> /// <param name="tradingStrategyModel"></param> private void AddGlobalIdentifierToModel(TradingStrategyAstNode tradingStrategyAstNode, TradingStrategy tradingStrategyModel) { foreach (var globalVariable in tradingStrategyAstNode.GlobalIdentifierDef) { var exprAst = globalVariable.ExpressionAstNode; tradingStrategyModel.ConstantVariableDefinitions.Add( new GlobalIdentifier() { Variable = CreateVariable(globalVariable.VariableName, exprAst.GetType()), Constant = ConvertExpressionAst(exprAst) } ); } }
/// <summary> /// Start transform an abstract syntax tree into the model /// </summary> /// <param name="tradingStrategyAstNode">the node on abstract syntax represents trading strategy</param> /// <returns>model of a trading strategy</returns> public TradingStrategy Transform(TradingStrategyAstNode tradingStrategyAstNode) { if (tradingStrategyAstNode == null) throw new ArgumentException("tradingStrategyAstNode cannot be null."); TradingStrategy tradingStrategyModel = new TradingStrategy(); AddGlobalIdentifierToModel(tradingStrategyAstNode, tradingStrategyModel); AddPositionSetDefToModel(tradingStrategyAstNode, tradingStrategyModel); AddPortfolioParamToModel(tradingStrategyAstNode, tradingStrategyModel); AddTradingRuleToModel(tradingStrategyAstNode, tradingStrategyModel); return tradingStrategyModel; }
private static TradingStrategy ConstructTradingStrategy() { TradingStrategy tradingStrategy = new TradingStrategy() { ConstantVariableDefinitions = new System.Collections.Generic.List<GlobalIdentifier>(){ new GlobalIdentifier(){ Variable = new Variable("reEntryExRatePercent", typeof(int)), Constant = new Constant(typeof(decimal),0.05)}, new GlobalIdentifier(){ Variable = new Variable("noOfLongPosition",typeof(int)), Constant = new Constant(typeof(int),3)}, new GlobalIdentifier(){ Variable = new Variable("noOfShortPosition",typeof(int)), Constant = new Constant(typeof(int),3)} }, Portfolio = new Portfolio() { HomeCurrency = "EUR", PositionSets = new List<PositionSet>() { new PositionSet(){ Name = "LongPositions", Number = new Variable("noOfLongPosition",typeof(int)), PositionType = FXStrategy.MetaModel.PositionType.Long }, new PositionSet(){ Name = "ShortPositions", Number = new Variable("noOfShortPosition", typeof(int)), PositionType = FXStrategy.MetaModel.PositionType.Short } } }, TradingRules = new System.Collections.Generic.List<TradingRule>() { //new StopLossRule( // "Stop loss rule", // new PeriodicTimeDefinition(1, PeriodicType.Day), // new Variable("position",typeof(Position)), // new CompositeStatement( // new List<Statement>{ // new Assignment(new Variable("exRateOverTime",typeof(TimeSeriesData)), // new PropertyAccessor( // new ArgumentedVariable("CurrencyPairSet", typeof(CurrencyPair), // new Expression[]{ new Constant(typeof(string), "EUR"), // new PropertyAccessor( new Variable("position"),"Currency") // }), // "ExchangeRates") // ), // new Assignment(new Variable("currentExRate"), // new MethodAccessor(new Variable("exRateOverTime",typeof(TimeSeriesData)), // "At", new Expression[]{new Variable("TODAY")})), // new Assignment(new Variable("movingAVG"), // new MethodAccessor(new Variable("exRateOverTime",typeof(TimeSeriesData)), // "MovingAvg", new Expression[]{new Variable("TODAY"),new Constant(typeof(int),14)})) // } // ), // new LessThan{ // LeftExpression = new Variable("currentExRate"), // RightExpression = new Variable("movingAVG") // }, // new Variable("LongPositions",typeof(PositionSet)) // ), //new TradingRule( // "Close Position after a term", // new PeriodicTimeDefinition( 3, // PeriodicType.Month // ), // new ForAllStatement( // new Variable( "position",typeof(string)), // new Variable("LongPositions",typeof(PositionSet)), // new ClosePosition( // new Variable("position",typeof(Position)) // ) // ) // ), new TradingRule( "reallocation", new WeekDayTimeDefinition(){ DayOfWeek = DayOfWeek.Friday }, new CompositeStatement(new System.Collections.Generic.List<Statement>(){ new ForAllStatement( new Variable("position",typeof(Position)), new Variable("LongPositions",typeof(PositionSet)), new IfStatement( new IsNotInSet(){ LeftExpression = new PropertyAccessor( new Variable("position",typeof(Position)), "Currency") , RightExpression = new Variable("Top3Currencies",typeof(PredefinedDataSet)) }, new ClosePosition(new Variable("position",typeof(Position))) ) ), new ForAllStatement( new Variable("currency", typeof(string)), new Variable("Top3Currencies",typeof(PredefinedDataSet)), new IfStatement( new IsNotInSet(){ LeftExpression = new Variable("currency",typeof(string)), RightExpression = new CollectionPropertiesAccessor( new Variable("LongPositions",typeof(PositionSet)), "Currency" ) }, new OpenPosition( new Variable("LongPositions", typeof(PositionSet)), new Variable("currency",typeof(string)) ) ) ), new ForAllStatement( new Variable("position",typeof(Position)), new Variable("ShortPositions",typeof(PositionSet)), new IfStatement( new IsNotInSet(){ LeftExpression = new PropertyAccessor(new Variable("position",typeof(Position)), "Currency") , RightExpression = new Variable("Bottom3Currencies",typeof(PredefinedDataSet)) }, new ClosePosition(new Variable("position",typeof(Position))) ) ) , new ForAllStatement( new Variable( "currency",typeof(string)), new Variable("Bottom3Currencies",typeof(PredefinedDataSet)), new IfStatement( new IsNotInSet(){ LeftExpression = new Variable("currency",typeof(Position)), RightExpression = new CollectionPropertiesAccessor( new Variable("ShortPositions",typeof(PositionSet)), "Currency" ) }, new OpenPosition( new Variable("ShortPositions",typeof(PositionSet)), new Variable("currency",typeof(string)) ) ) ) } )) } }; return tradingStrategy; }
public void ExchangeRateAccessorTest() { TradingStrategy tradingStrategy = new TradingStrategy() { ConstantVariableDefinitions = new System.Collections.Generic.List<GlobalIdentifier>(){ new GlobalIdentifier(){ Variable = new Variable("reEntryExRatePercent", typeof(int)), Constant = new Constant(typeof(decimal),0.05)}, new GlobalIdentifier(){ Variable = new Variable("noOfLongPosition",typeof(int)), Constant = new Constant(typeof(int),3)}, new GlobalIdentifier(){ Variable = new Variable("noOfShortPosition",typeof(int)), Constant = new Constant(typeof(int),3)} }, Portfolio = new Portfolio() { HomeCurrency = "EUR", PositionSets = new List<PositionSet>() { new PositionSet(){ Name = "LongPositions", Number = new Variable("noOfLongPosition",typeof(int)), PositionType = FXStrategy.MetaModel.PositionType.Long }, new PositionSet(){ Name = "ShortPositions", Number = new Variable("noOfShortPosition", typeof(int)), PositionType = FXStrategy.MetaModel.PositionType.Short } } }, TradingRules = new System.Collections.Generic.List<TradingRule>() { new TradingRule("test", new ConcreteTimeDefinition(){ ExecuteTime = new DateTime(2006,1,30) }, new Assignment( new Variable("exRateMVG", typeof(decimal)), new AtTime( new ExchangeRateAccessor( new Constant(typeof(string), "EUR"), new Constant(typeof(string), "USD")) , new Constant(typeof(DateTime), new DateTime(2006,1,30))))) } }; FXEntities.FXEntities fxEntities = new FXEntities.FXEntities(); CurrencyDataSource currencyDataSource = new CurrencyDataSource(fxEntities); StrategyInterpreter target = new StrategyInterpreter(fxEntities, currencyDataSource); DateTime startDate = new DateTime(2006, 1, 29); DateTime endDate = new DateTime(2006, 1, 31); target.Execute(tradingStrategy, startDate, endDate); }
/// <summary> /// Handles parameters in the trading strategy AST node /// </summary> /// <param name="tradingStrategyAstNode"></param> /// <param name="tradingStrategyModel"></param> private void AddPortfolioParamToModel(TradingStrategyAstNode tradingStrategyAstNode, TradingStrategy tradingStrategyModel) { foreach (var parameter in tradingStrategyAstNode.StrategyParameters) { Type type = null; object value = null; string parameterName = null; if (parameter.Value is StringAstNode) { var strAst = parameter.Value as StringAstNode; type = typeof(string); value = strAst.Value; parameterName = parameter.Name; } if (parameterName != null) { if (parameterName.ToLower() == "homecurrency") tradingStrategyModel.Portfolio.HomeCurrency = (string)value; else { throw new Exception("Unknown strategy parameter: " + parameterName); } } } }
/// <summary> /// Handles transformation of position set /// </summary> /// <param name="tradingStrategyAstNode"></param> /// <param name="tradingStrategyModel"></param> private void AddPositionSetDefToModel(TradingStrategyAstNode tradingStrategyAstNode, TradingStrategy tradingStrategyModel) { foreach (var positionSetDef in tradingStrategyAstNode.PositionSets) { CreateVariable(positionSetDef.Name, typeof(PositionSet)); tradingStrategyModel.Portfolio.PositionSets.Add(new PositionSet() { Name = positionSetDef.Name, Number = ConvertExpressionAst(positionSetDef.Number), PositionType = ConvertPositionTypeAst(positionSetDef.PositionType) }); } }