TB实现简单横截面策略

一. 横截面策略简介

横截面策略来源于股票多因子体系,多因子选股的逻辑一般是:

  1. 输入因子值,通过模型得到预测值,对预测值进行排序。
  2. 做多预测值前N个标的,做空预测值最后N个标的,即多强空弱。

当然多因子体系中还涉及到很多因子挖掘的内容,这里不展开论述。

二. TBQuant代码实现
  1. 策略内容:通过对比股指IF(沪深300),IH(上证50),IC(中证500), IM(中证1000)前一天的涨跌幅,然后做多涨跌幅最大的股指,做空涨跌幅最小的股指。

本策略仅用来演示TBQuant中横截面策略的一般实现方法,不保证盈利。

  1. 代码实现
cpp 复制代码
//------------------------------------------------------------------------
// 简称: xxx
// 名称: 
// 类别: 公式应用
// 类型: 用户应用
// 输出: Void
//------------------------------------------------------------------------
Params
	//此处添加参数
	Numeric millsecs(1000);
Vars
	//此处添加变量
	Numeric avg;
	Global Integer timerId;
	
	// 涨跌幅
	Series<Numeric> pricePct;
	// 记录每个图层的涨跌幅
	Series<Array<Numeric>> pricePctArray;

Defs
	//此处添加公式函数
	Numeric calcAvg(Numeric a,Numeric b)
	{
		return (a+b)/2;
	}

Events
	//此处实现事件函数
	
	//初始化事件函数,策略运行期间,首先运行且只有一次,应用在订阅数据等操作
	OnInit()
	{
		timerId=createTimer(millsecs);
		//与数据源有关
		Range[0:DataCount-1]
		{
			//=========数据源相关设置==============
			AddDataFlag(Enum_Data_RolloverBackWard());	//设置后复权

			AddDataFlag(Enum_Data_RolloverRealPrice());	//设置映射真实价格

			AddDataFlag(Enum_Data_AutoSwapPosition());	//设置自动换仓

			AddDataFlag(Enum_Data_IgnoreSwapSignalCalc());	//设置忽略换仓信号计算

			//AddDataFlag(Enum_Data_OnlyDay());		//设置仅日盘
			
			//AddDataFlag(Enum_Data_OnlyNight());	//设置仅夜盘
			
			//AddDataFlag(Enum_Data_NotGenReport());	//设置数据源不参与生成报告标志
			
			//=========交易相关设置==============
            //MarginRate rate;
            //rate.ratioType = Enum_Rate_ByFillAmount; //设置保证金费率方式为成交金额百分比
            //rate.longMarginRatio = 0.1; //设置保证金率为10%
            //rate.shortMarginRatio = 0.2; //设置保证金率为20%
			//SetMarginRate(rate);	
			
			//CommissionRate tCommissionRate;
			//tCommissionRate.ratioType = Enum_Rate_ByFillAmount;
			//tCommissionRate.openRatio = 5; //设置开仓手续费为成交金额的5%%
			//tCommissionRate.closeRatio = 2; //设置平仓手续费为成交金额的2%%
			//tCommissionRate.closeTodayRatio = 0; //设置平今手续费为0
			//SetCommissionRate(tCommissionRate); //设置手续费率
			
			//SetSlippage(Enum_Rate_PointPerHand,2);	//设置滑点为2跳/手
			
			//SetOrderPriceOffset(2);	//设置委托价为叫买/卖价偏移2跳
			
			//SetOrderMap2MainSymbol();	//设置委托映射到主力
			
			//SetOrderMap2AppointedSymbol(symbols, multiples); 	//设置委托映射到指定合约,symbols是映射合约数组,multiples是映射倍数数组
		}
		//与数据源无关
		//SetBeginBarMaxCount(10);	//设置最大起始bar数为10
			
		//SetBackBarMaxCount(10);	//设置最大回溯bar数为10
		
		//=========交易相关设置==============
		//SetInitCapital(1000000);	//设置初始资金为100万
		
		//AddTradeFlag(Enum_Trade_Ignore_Buy());	//设置忽略多开
			
		//AddTradeFlag(Enum_Trade_Ignore_Sell());	//设置忽略多平
			
		//AddTradeFlag(Enum_Trade_Ignore_SellShort());	//设置忽略空开
			
		//AddTradeFlag(Enum_Trade_Ignore_Buy2Cover());	//设置忽略空平
	}

	//在所有的数据源准备完成后调用,应用在数据源的设置等操作
	OnReady()
	{

	}

	//基础数据更新事件函数
	OnDic(StringRef dicName,StringRef dicSymbol,DicDataRef dicValue)
	{
		
	}

	//在新bar的第一次执行之前调用一次,参数为新bar的图层数组
	OnBarOpen(ArrayRef<Integer> indexs)
	{

	}

	//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
	OnBar(ArrayRef<Integer> indexs)
	{
		avg=calcAvg(high,low);
		if(DataCount -1 <= 1)
		{
			Return;
		}
		
		Numeric i;
		// 计算每个品种的涨跌幅
		Range[i = 0: DataCount - 1]
		{
			pricePct = (Close - Close[1]) / Close[1] * 100;
			Commentary("当日涨跌幅: " + Text(pricePct));
			Data0.pricePctArray[0][i] = pricePct;
		}
		
		
		// 构建图层id
		Array<Integer> id;
		for i = 0 to Datacount - 1
		{
			id[i] = i;
		}

		// 根据涨跌幅进行排序(倒序)
		Array<Numeric> arr = pricePctArray[1];
		Commentary("未排序前: id = " + TextArray(id) + ", arr = " + TextArray(arr));
		Na1Sort2(arr, id, 0, GetArraySize(arr) - 1, False);
		Commentary("排序后: id = " + TextArray(id) + ", arr = " + TextArray(arr));
	
		// 根据排序结果,执行信号
		for i = 0 to DataCount - 1
		{
			if(i == 0) 
			{
				// 如果没有多头持仓则买入,如果有多头持仓,则继续持有
				if (Data[id[i]].MarketPosition <= 0) 
				{
					Data[id[i]].Buy(1, Open);
				}
			} else if (i == DataCount - 1)
			{
				// 如果没有空头持仓则卖出,如果有空头持仓,则继续持有
				if (Data[id[i]].MarketPosition >= 0)
				{
					Data[id[i]].SellShort(1, Open);
				}
			} else 
			{
				// 平掉所有中间名次的仓位
				Data[id[i]].Sell(0, Open);
				Data[id[i]].BuyToCover(0, Open);
			}		
		}
	}

	//下一个Bar开始前,重新执行当前bar最后一次,参数为当前bar的图层数组
	OnBarClose(ArrayRef<Integer> indexs)
	{

	}

	//Tick更新事件函数,需要SubscribeTick函数订阅后触发,参数evtTick表示更新的tick结构体
	OnTick(TickRef evtTick)
	{

	}

	//持仓更新事件函数,参数pos表示更新的持仓结构体
	OnPosition(PositionRef pos)
	{
		
	}

	//策略账户仓更新事件函数,参数pos表示更新的账户仓结构体
	OnStrategyPosition(PositionRef pos)
	{
		
	}

	//委托更新事件函数,参数ord表示更新的委托结构体
	OnOrder(OrderRef ord)
	{
		
	}

	//成交更新事件函数,参数ordFill表示更新的成交结构体
	OnFill(FillRef ordFill)
	{
		
	}

	//定时器更新事件函数,参数id表示定时器的编号,millsecs表示定时间的间隔毫秒值
	OnTimer(Integer id,Integer intervalMillsecs)
	{
		
	}

	//通用事件触发函数,参数evtName为事件名称,参数evtValue为事件内容
	OnEvent(StringRef evtName,MapRef<String,String> evtValue) 
	{
		
	}

	//当前策略退出时触发
	OnExit()
	{

	}
相关推荐
zandy10111 天前
企业合同管理系统选型全指南:专业 CLM 系统选型核心逻辑与实操框架
大数据·人工智能
数据小玩子1 天前
精准归因:如何量化分析光伏电站的每一分发电损失?
大数据·人工智能·数据可视化·助睿数智·光伏电站运营
金牌归来发现妻女流落街头1 天前
【用 Java API Client 操作 Elasticsearch】
java·elasticsearch·jenkins
Seven971 天前
调试排错 - 线程Dump分析
java
恋猫de小郭1 天前
Flutter Beta 版本引入 ScrollCacheExtent ,并修复长久存在的 shrinkWrap NaN 问题
android·前端·flutter
Liu.7741 天前
vscode前端实用插件
前端·vscode
Z...........1 天前
Spring日志管理
java·后端·spring
lj850861 天前
性能测试总结
java·开发语言·spring
TDengine (老段)1 天前
TDengine IDMP 组态面板 —— 连线
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
Zzj_tju1 天前
AI+医疗进阶:多智能体系统怎么协作做诊断、总结与质控?
大数据·人工智能