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()
	{

	}
相关推荐
你的人类朋友14 小时前
✍️记录自己的git分支管理实践
前端·git·后端
多多*15 小时前
分布式系统中的CAP理论和BASE理论
java·数据结构·算法·log4j·maven
sg_knight15 小时前
Docker 实战:如何限制容器的内存使用大小
java·spring boot·spring·spring cloud·docker·容器·eureka
合作小小程序员小小店15 小时前
web网页开发,在线考勤管理系统,基于Idea,html,css,vue,java,springboot,mysql
java·前端·vue.js·后端·intellij-idea·springboot
防火墙在线15 小时前
前后端通信加解密(Web Crypto API )
前端·vue.js·网络协议·node.js·express
Jacky-00815 小时前
Node + vite + React 创建项目
前端·react.js·前端框架
武汉唯众智创16 小时前
高职院校大数据软件教学实训室建设方案
大数据·大数据实训室·大数据实验室·大数据软件教学实训室·大数据教学实训室
CoderYanger16 小时前
前端基础——CSS练习项目:百度热榜实现
开发语言·前端·css·百度·html·1024程序员节
Elastic 中国社区官方博客16 小时前
Elasticsearch:如何为 Elastic Stack 部署 E5 模型 - 下载及隔离环境
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
i_am_a_div_日积月累_16 小时前
10个css更新
前端·css