系统概述 Last updated: 2020-05-25

策略在ViperStudio实现非常简单,用户只需要任意创建一个Java类,然后继承BaseStrategy,通过eclipse的quick fix(快捷键为control + 1),直接添加未实现函数即可。


Note

欢迎访问Viper量化投研平台!本文档预计阅读时长18分钟.

创建空策略

/**
     * 演示:添加自定义事件
     * 
     * @author kaizhang
     *
     */
    @ViperStrategy(name = "空策略", version = "0.0.1", reason = "初始化")
    public class Example_01_Empty extends BaseStrategy {
    
        @Override
        public void initialize() {
        }
    
        @Override
        public void setBackTestConfig(StrategyBackTestConfig backTestStrategyRunConfig) {
        }
    
        @Override
        public void setRealConfig(StrategyRealConfig realStrategyRunConfig) {
        }
    
        @Override
        public void processTick(ITickQuote tickQuote) {
        }
    
        @Override
        public void processBar(IBarQuote barQuote) {
        }
    
        @Override
        public void processOrderUpdate(OrderEvent orderEvent) {
        }
    
        @Override
        public void processSwitchTradingDay(LocalDate localDate) {
        }
    }
    

一个策略由3个基础部分构成:

  • @ViperStrategy注解:所有策略都需要添加该注解,该注解的作用在于为策略的迭代过程记录版本号和变动原因,方便用户后期进行甄别
  • 类对象:继承BaseStrategy,从而继承了账户、下单、持仓、行情等各类API函数
  • 实现抽象函数:抽象函数的处理由用户进行,从而实现特定的目标

Note

借助于Javadoc的功能,我们只需把鼠标放在函数名上面,将会自动显示我们为函数做的详细注释

logo

回调函数介绍

我们为用户准备的回调函数都尽可能简单而实用,方便用户在快速搭建自己的程序化策略。

initialize


initialize作为初始化函数,在策略的构造函数中进行调用,整个策略生命周期只执行一次,提供给用户做一些准备工作,如时间检查,数据初始化下载,网络连接情况等,方便用户进行初始化处理。使用案例:

/**
    	 * macd指标
    	 */
        private MACD macd = new MACD();
    
        @Override
        public void initialize() {
            this.macd.setFastPeriod(12);
            this.macd.setSlowPeriod(26);
            this.macd.setSignalPeriod(9);
            this.initBarQuote();
            this.recalculate();
        }
    
        /**
    	 * 策略启动:向前查询n个日线的行情
    	 */
        private void initBarQuote() {
            /**
    		 * 计算起始的时间:实盘的起始时间为当前时间,回测的起始时间为设置的回测时间
    		 */
            LocalDateTime starTime = this.getRunMode() == StrategyRunMode.Real ? LocalDateTime.now()
                    : this.getBackTestQuoteConfigs().get(0).getStartTime();
    
            /**
    		 * 计算需要的K线个数
    		 */
            int length = MACD.macdLookback(26, 12, 9) + 1;
            QuantityQuoteQuery query = new QuantityQuoteQuery(this.contract, starTime, -(length + 10),
                    QuoteCycleType.FIVE_MINUTE);
            this.barQuoteSeries.addAll(this.queryBarQuote(query));
        }
    
        /**
    	 * 重新计算指标
    	 */
        private void recalculate() {
            this.macd.setInput(this.barQuoteSeries.getCloseArray());
            this.macd.recalculate();
        }
    

在上述的案例中,我们看到MACD策略作为趋势指标策略,在初始化时需要提前加载一些历史数据计算第一个值,该工作就可以放在initialize函数中进行,从而在策略获取第一个行情时即可进行MACD的穿越计算

setBackTestConfig


setBackTestConfig函数作用非常重要:该函数作为回测的主要配置函数,为策略的回测提供了精细化的支持。使用案例:

/**
    	 * 策略回测设置:设置回测的行情范围和初始资金,该函数只在回测模式下被调用
    	 * 
    	 * @param config 策略运行配置
    	 */
        @Override
        public void setBackTestConfig(StrategyBackTestConfig config) {
            /**
    		 * 设置要回测的行情范围:<br>
    		 * 可以设置多个,回测行情订阅只在该函数内生效,回测开始启动后其他函数订阅的回测行情无效<br>
    		 * 可以同时订阅tick和K线,策略只会收到设置的证券行情<br>
    		 * 可以同时订阅股票和期货,时间可以不一致
    		 */
            LocalDateTime beginTime = LocalDateTime.of(2019, 11, 01, 0, 0);
            LocalDateTime endTime = LocalDateTime.of(2019, 12, 1, 0, 0);
            config.addQuoteRange(Exchange.SSE.getContract("600519"), beginTime, endTime, QuoteCycleType.ONE_MINUTE);
    
            /**
    		 * 设置回测的股票手续费:<br>
    		 * 优先采用用户设置的回测手续费,如果设置了A股的手续费为万2,实盘为万3,如果此时交易A股,下单的时候则采用万3<br>
    		 * 如果此时交易B股,B股没有设置特殊手续费,则采用实盘的手续费
    		 */
            config.addStockCommission(new StockCommissionConfig(this.accountId).setBuyCharge(0.0002));
    
            /**
    		 * 设置基准收益:默认为中证500
    		 */
            config.setBenchMark(Exchange.SSE.getContract("000905"));
    
            /**
    		 * 设置账户回测的初始资金,可以设置多个,资金账号必须是实盘存在的资金账号<br>
    		 * 如果策略要使用某资金账号进行下单,则必须在此设置初始资金资金账号
    		 */
            config.setAccountCapital(this.accountId, 1000000);
            config.setAccountCapital("1101", 1000000);
        }
    


回测配置主要为以下功能

  • 设置回测的行情
  • 设置回测的手续费信息
  • 设置回测的资金信息

setRealConfig


setRealConfig作为实盘运行的配置入口点,最重要的作用为设置该策略每个资金账号的初始资金。该初始资金会在实盘运行时和可分配资金进行比较,最终策略获得的资金为 min(设置的资金,可分配资金)。使用案例:

/**
	 * 策略实盘设置:设置实盘的行情订阅和最大可用资金,该函数只在实盘模式下被调用
	 * 
	 * @param config 策略运行配置
	 */
	@Override
	public void setRealConfig(StrategyRealConfig config) {
		/**
		 * 订阅实时行情,实盘运行模式下生效<br>
		 * 可以在程序运行过程中随意订阅
		 */
		this.subRealQuote(Exchange.SZSE.getContract("000651"), QuoteCycleType.TICK, this.accountId);

		/**
		 * 设置每个账户的的初始资金:每个策略的账户都是独立核算<br>
		 * 设置的资金会先根据实盘账户的可分配资金进行比较,分配完之后实盘资金减少相应的可分配资金
		 */
		config.setAccountCapital(this.accountId, 1000000);
		config.setAccountCapital("1101", 1000000);
	}

processTick


processTick函数:为tick行情的处理函数,不同的合约代码的tick行情都会调用该函数,一般的处理为首先判断合约代码,在获取价格进行运算。使用案例:

	@Override
	public void processTick(ITickQuote mdQuote) {
		if (mdQuote.getContract() == this.contract1) {
			tickQuote1 = mdQuote;
			this.updateSpread();
		} else if (mdQuote.getContract() == this.contract2) {
			this.tickQuote2 = mdQuote;
			this.updateSpread();
		}
	}

	/**
	 * 更新最新价差
	 */
	private void updateSpread() {
		if (this.tickQuote1 != null && this.tickQuote2 != null) {
			if (Math.abs(this.tickQuote1.getTime() - tickQuote2.getTime()) < 1000) {
				System.out.println(String.format("合约1最新行情:%s,合约2最新行情:%s,价差为:%f", tickQuote1, tickQuote2,
						tickQuote1.getLatestPrice() - tickQuote2.getLatestPrice()));
			}
		}
	}

Note

行情处理为一个单独的事件,每个策略有自己的策略线程,用户无需担心一个策略处理行情会影响另一个策略处理行情的时间。

processBar


processBar函数:为K线行情的处理函数,与tick类似,所有的不同的合约代码的K线行情都会调用该函数,相同代码不同周期也会调用该函数,如600519的1分钟K线和5分钟K线,用户可以通过IBarQuote对象获取合约代码和K线周期。


Note

大多数交易接口不支持K线行情订阅,用户获取的K线行情为tick行情本地进行合成,所以策略启动后第一根K线的开盘价、最高价、最低价可能异常。

processOrderUpdate


processOrderUpdate函数:该函数为主要的订单处理函数,函数参数OrderEvent包含了2类信息,OrderUpdateReason表示订单更新的原因:分为成交和状态更新。Iorder为发生变动的订单对象。使用案例:

	/**
	 * 处理策略订单状态变化
	 * 
	 * @param order 订单对象
	 */
	@Override
	public void processOrderUpdate(OrderEvent orderEvent) {
		System.out
				.println(String.format("订单更新原因:%s,订单对象:%s", orderEvent.getOrderUpdateReason(), orderEvent.getOrder()));
	}

Note

实盘的订单回调和回测稍有不同,在回测中,回调函数是同步的。在实盘中,订单回报是异步处理。

processSwitchTradingDay


processSwitchTradingDay函数:切换交易日,该函数主要给用户进行时间切换处理,许多策略在交易日的结束和开始需要做清算和初始化任务,用户可以借助该函数进行。


Note

回测过程的交易日切换在第二天的开盘,实盘的交易日切换在用户设置的结算时间(默认是当天的17点)。

主要API函数介绍

我们为用户提供了精简的API函数,这里主要介绍常用和重要的一些API。详细部分可以查看API手册。

Note

除非文中特定说明,则默认所有的API在回测和实盘都表现一致。

资金获取


策略在运行过程中需要随时获取账户的可用资金、总资金信息。

	/**
	 * 演示策略相关的函数 此处获取的账户信息是本策略的账号,所有策略的资金账号组合成为总资金账号<br>
	 * 例如: 实盘资金账号:1100,可分配资金:500000,可用资金:600000,市值:400000;<br>
	 * 策略1:资金账号:1100,初始分配资金:200000,可用资金:100000,市值:100000;<br>
	 * 策略2:资金账号:1100, 初始分配资金:300000,可用资金:0,市值:300000;<br>
	 */
	public void capitalFunction() {
		/**
		 * 获取本策略配置的资金账号的资金信息<br>
		 * 账号配置在setBackTest和setReal中实现
		 */
		for (IAccountCapital capital : this.getAllAccountCapital()) {
			System.out.println(capital);
		}

		IAccountCapital accountCapital = this.getAccountCapital(accountId);
		System.out.println(accountCapital);
	}

从以上代码可以看到,无论是获取当个账户的资金还是整个策略所有账户的资金,都可以快速获取。

下单/撤单


下单和撤单作为用户最常用的api:我们为了减少用户输入参数风险,大部分参数都使用枚举值,同时设置了调用链,方便用户构建下单对象。

	/**
	 * 下单演示
	 */
	public void insertOrderFunction() {
		/**
		 * 构建订单:构建的参数信息查看API文档
		 */
		OrderParams orderParams = new OrderParams().setAccountID(accountId).setContract(contract).setInputPrice(8)
				.setOrderAction(OrderAction.buytoopen).setOrderType(OrderType.Limit).setOrderDuration(OrderDuration.GFD)
				.setInputVol(100);
		/**
		 * 下单
		 */
		this.insertOrder(orderParams);
	}

	/**
	 * 撤单演示
	 */
	public void cancelOrderFunction() {
		for (IOrder order : this.getAllOrders()) {
			if (order.isUnfinished()) {
				this.cancelOrder(order);
			}
		}
	}

我们对订单提供详细的状态和方向辅助函数,方便用户对订单进行下一步处理


	/**
  	 * 判断报单状态
  	 * 
  	 * @return 报单状态未完成
  	 */
    public boolean isUnfinished();
  
    /**
  	 * 判断报单状态
  	 * 
  	 * @return true代表报单已完成
  	 */
    public boolean isFinished();
  
    /**
  	 * 判断订单方向
  	 * 
  	 * @return true代表订单为开仓
  	 */
    public boolean isOpen();
  
    /**
  	 * 判断订单方向
  	 * 
  	 * @return true代表订单为平仓
  	 */
    public boolean isClose();
  
    /**
  	 * 1代表平今仓,-1代表昨仓,0代表未指定(优先平昨仓,昨仓不足再加今仓)
  	 * 
  	 * @return 是否是平今仓
  	 */
    public int isCloseToday();
  
    /**
  	 * 判断订单方向
  	 * 
  	 * @return true代表是买入操作
  	 */
    public boolean isBuy();
  
    /**
  	 * 判断订单方向
  	 * 
  	 * @return true代表订单为卖出
  	 */
    public boolean isSell();
  

仓位信息


Viper系统支持双向持仓,我们为每笔持仓都提供了独立的核算机制。

	/**
	 * 演示仓位有关的函数 此处获取的仓位是本策略产生的仓位,并非实盘账户持仓<br>
	 * 例如:000651实盘总持仓10000股,策略1持仓3000,策略2持仓4000,策略3持仓3000。每个策略独立核算
	 */
	public void positionFuncition() {
		/**
		 * 获取本策略的所有持仓
		 */
		for (IPosition position : this.getAllPosition()) {
			System.out.println(position);
		}

		/**
		 * 获取指定账号、合约代码、方向的策略仓位信息:可能为空
		 */
		IPosition position = this.getPosition(accountId, contract, PositionDirection.Long);
		System.out.println(position);

		/**
		 * 获取指定账号、合约代码的多头和空头持仓:多头和空头可能都为空
		 */
		PositionGroup positionGroup = this.getPosition(accountId, contract);
		System.out.println(positionGroup.getLongPosition());
		System.out.println(positionGroup.getShortPosition());

		/**
		 * 获取指定资金账号下的所有持仓
		 */
		for (IPosition position1 : this.getPosition(accountId)) {
			System.out.println(position1);
		}

		/**
		 * 获取指定合约代码下的所有持仓
		 */
		for (IPosition position1 : this.getPosition(contract)) {
			System.out.println(position1);
		}
	}

Note

期货持仓的保证金占用和浮动盈亏,与每天的结算价有关,可能计算不准确,但账户的总资产应该一致

订单信息


我们记录了每笔订单的成交明细,方便用户进行后续微观分析。

	/**
	 * 演示策略订单相关的函数 策略默认只关联该策略产生的订单,可以通过实现注册策略监听来获取其他策略的事件
	 */
	public void orderFunction() {
		/**
		 * 获取订单:获取所有订单、指定合约、指定账户
		 */
		for (IOrder order : this.getAllOrders()) {
			System.out.println(order);
		}
		for (IOrder order : this.getOrder(accountId, contract)) {
			System.out.println(order);
		}
		for (IOrder order : this.getOrder(accountId)) {
			System.out.println(order);
		}
		for (IOrder order : this.getOrder(contract)) {
			System.out.println(order);
		}

		/**
		 * 获取订单的每次成交信息:订单成交明细按照成交次序进行排序,最后一个为最新的成交
		 */
		for (IOrder order : this.getOrder(OrderStatus.FILLED)) {
			for (IOrderDeal orderDeal : order.getOrderDeal()) {
				System.out.println(orderDeal);
			}
		}
	}

Note

实盘运行过程中,如果账户登出或断开,则该时段的成交明细无法再现。Viper默认只处理本系统发出的订单,收到其他渠道的订单回报将直接丢弃。

订阅实时行情(实盘生效)

实时行情的订阅和退订在Viper系统中只需一行代码即可,策略启动之后才会开始订阅行情。策略停止将会退订行情。

	/**
	 * 演示行情相关的函数使用
	 */
	public void quoteFunction() {
		/**
		 * 订阅、退订实时行情,此函数只在实盘运行时有效:可以从不同行情源进行订阅
		 */
		this.subRealQuote(contract, QuoteCycleType.TICK, "1100");
		this.subRealQuote(contract, QuoteCycleType.FIVE_MINUTE, "1101");
		this.unSubRealQuote(contract, QuoteCycleType.TICK, "1102");
		this.unSubAllRealQuote();
  }
 

Note

该函数只在实盘运行有效,在模拟阶段,调用该函数不会产生错误,也无任何效果。

查询历史行情

Viper为用户提供简单易用的历史行情API,提供以下主要功能:

  • 查询某个标的指定时间段的:Tick或K线行情
  • 查询某个标的以指定时间为轴:向前或向后n个行情(可以是tick也可以是K线)。
  • 查询某个指数表的所有成分股指定时间段的:Tick或K线行情。返回多个行情
  • 查询某个指数表的所有成分股以指定时间为轴:向前或向后n个行情(可以是tick也可以是K线)。返回多个行情
	/**
	 * 查询K线行情:指定时间范围
	 * 
	 * @param query 行情查询
	 * @return K线集合
	 */
	public List<IBarQuote> queryBarQuote(TimeRangeQuoteQuery query);

	/**
	 * 查询指数、合约组、连续合约行情<br>
	 * 键为成分股的代码,值为该成分股的行情集合
	 * 
	 * @param query 时间范围行情查询
	 * @return K线集合
	 */
	public Map<IContract, List<IBarQuote>> queryItemsBarQuote(TimeRangeQuoteQuery query);

	/**
	 * 查询K线行情:指定时间和偏移量<br>
	 * 偏移量为负代表向前查询,偏移量为正代表向后查询
	 * 
	 * @param query K线个数行情查询
	 * @return K线集合
	 */
	public List<IBarQuote> queryBarQuote(QuantityQuoteQuery query);

	/**
	 * 查询指数、合约组行情,不支持连续合约<br>
	 * 键为成分股的代码,值为该成分股的行情集合
	 * 
	 * @param query 时间范围行情查询
	 * @return K线集合
	 */
	public Map<IContract, List<IBarQuote>> queryItemsBarQuote(QuantityQuoteQuery query);

	/**
	 * 查询tick行情
	 * 
	 * @param query 行情查询
	 * @return K线集合
	 */
	public List<ITickQuote> queryTickQuote(TimeRangeQuoteQuery query);

	/**
	 * 查询标的tick线行情<br>
	 * 查询指定起始时间和结束时间内的行情<br>
	 * 支持指数、合约组、连续合约<br>
	 * 如果需要单独查询指数行情,请使用queryTickQuote
	 * 
	 * @param query 行情查询
	 * @return tick线行情
	 */
	public Map<IContract, List<ITickQuote>> queryItemsTickQuote(TimeRangeQuoteQuery query);

	/**
	 * 查询标的tick行情<br>
	 * 指定时间和偏移量,偏移量为负向前查询,偏移量为正向后查询<br>
	 * 如果输入的指数代码,则返回该指数的行情,如果需要查询指数成分股的行情,请使用queryItemsTickQuote
	 * 
	 * @param query 数量查询对象
	 * @return tick行情集合
	 */
	public List<ITickQuote> queryTickQuote(QuantityQuoteQuery query);

	/**
	 * 
	 * 查询标的tick行情<br>
	 * 指定时间和偏移量,偏移量为负向前查询,偏移量为正向后查询<br>
	 * 支持指数、合约组,不支持连续合约<br>
	 * 如果需要单独查询指数行情,请使用queryTickQuote
	 * 
	 * @param query 数量查询对象
	 * @return tick行情集合
	 */
	public Map<IContract, List<ITickQuote>> queryItemsTickQuote(QuantityQuoteQuery query);

快速平仓

我们为用户提供了快捷的平仓功能,针对账户、针对代码、针对方向等

	/**
	 * 演示平仓的函数使用
	 */
	public void closePosition() {
		/**
		 * 一键平仓
		 */
		this.closeAllPositions();
		
		/**
		 * 平指定合约的所有持仓
		 */
		this.closePosition(this.contract);
		
		/**
		 * 平指定资金账号的所有订单
		 */
		this.closePosition(this.accountId);
		
		/**
		 * 平指定合约和资金账号的双边持仓
		 */
		PositionGroup positionGroup = this.getPosition(this.accountId, this.contract);
		this.closePosition(positionGroup);
		
		this.closePosition(this.accountId, contract, PositionDirection.Long);
	}

策略基本信息

策略基本信息包含策略启动时间、停止时间、标识符等重要基础信息,用户可以使用api函数获取。

	/**
	 * 演示如何获取本策略的一些配置信息
	 */
	public void configFunction() {
		/**
		 * 策略基本信息
		 */
		System.out.println(String.format("策略运行编号:%s", this.getStrategyId()));
		System.out.println(String.format("策略当前时间:%s", new Date(this.getCurrentTime())));
		System.out.println(String.format("策略运行模式:%s", this.getRunMode()));
		System.out.println(String.format("策略启动时间:%s", this.getStartTime()));
		System.out.println(String.format("策略停止时间:%s", this.getStopTime()));
		System.out.println(String.format("策略当前状态:%s", this.getStrategyStatus()));
		System.out.println(String.format("策略基准收益:%s", this.getBenchMark()));

		/**
		 * 策略的回测配置<br>
		 * 资金配置、手续费配置、保证金配置
		 */
		for (IQuoteConfig quoteConfig : this.getBackTestQuoteConfigs()) {
			System.out.println(quoteConfig);
		}
		for (IStockCommission stockCommission : this.getStockCommissions()) {
			System.out.println(stockCommission);
		}
		for (IStockCommission stockCommission : this.getStockCommission(accountId)) {
			System.out.println(stockCommission);
		}
		System.out.println(this.getStockCommission(accountId, StockType.STOCK_A));

		for (IFutureCommissionMargin futureCommissionMargin : this.getFutureCommissionMargins()) {
			System.out.println(futureCommissionMargin);
		}
		for (IFutureCommissionMargin futureCommissionMargin : this.getFutureCommissionMargin(accountId)) {
			System.out.println(futureCommissionMargin);
		}
		System.out.println(this.getFutureCommissionMargin(accountId, contract));
	}

Note

模拟运行手续费和保证金为用户设置或默认的信息,实盘获取的手续费和保证金信息为券商开立账户的实盘信息

常用辅助函数

我们为用户提供了常用的交易类辅助和Java类辅助函数,方便用户快速进行使用。

日志和邮件

用户在开发过程中需要打印计算的中间过程和一些重要信息,可以使用日志记录功能。对于自动化运行的策略,需要在特殊事情触发的时候及时发送邮件进行通知。

	/**
	 * 演示打印日志和发送邮件
	 */
	public void pringLogAndSendMail() {
		/**
		 * 打印日志
		 */
		this.log("这是一条简单日志");

		/**
		 * 发送邮件
		 */
		MailParam mailParam = new MailParam("测试邮件发送", "public@yuliangtec.com", "Hello Viper!");
		this.sendMail(mailParam);
	}

Note

邮件的发送需要管理员已经配置好邮件服务器!

日期函数

对于一些策略而言,例如期权策略,需要经常计算交易日信息,节假日信息,我们为用户提供方便,快捷的日期获取函数。

	/**
	 * 演示获取交易日信息
	 */
	public void getTradingDay() {
		LocalDate currentDate = this.getCurrentLocalDate();

		LocalDate localDate = Exchange.SSE.getNextTradingDay(currentDate);
		System.out.println(String.format("下一交易日:%s", localDate));

		localDate = Exchange.SSE.getNextTradingDay(currentDate, 5);
		System.out.println(String.format("往后5个交易日:%s", localDate));

		localDate = Exchange.SSE.getPreviousTradingDay(currentDate, 5);
		System.out.println(String.format("往前5个交易日:%s", localDate));

		localDate = Exchange.SSE.getNextHoliday(currentDate);
		System.out.println(String.format("下一节假日:%s", localDate));

		localDate = Exchange.SSE.getNextHoliday(currentDate, 5);
		System.out.println(String.format("往后5个节假日:%s", localDate));

		localDate = Exchange.SSE.getPreviousHoliday(currentDate, 5);
		System.out.println(String.format("往前5个节假日:%s", localDate));
	}

Note

示例代码采用上交所日历,也可以获取其他交易所的日历信息

指数信息

我们为利用指数合约和连续合约的策略提供了时点函数,通过获取某时点的成分股和真实合约信息,方便用户进行处理。

	/**
	 * 演示成分股和连续合约
	 */
	public void getIndexItem() {
		/**
		 * 获取指数合约在某一个具体时点的成分股信息
		 */
		IndexContract indexContract = Exchange.VIPER.getIndexContract("000905");
		Map<IContract, IndexItem> itemMap = indexContract.getIndexItems(this.getCurrentLocalDate());
		itemMap.values().forEach(item -> System.out.println(item));

		/**
		 * 获取指数合约在所有时点的换月信息
		 */
		ContinuousContract continuousContract = Exchange.SHFE.getContinuousContract("CU");
		TreeMap<LocalDateTime, ContinuousItem> itemsTreeMap = continuousContract.getItemChange();
		itemsTreeMap.values().forEach(item -> System.out.println(item));
	}

固定长度序列和日期转换

对于一些策略而言,需要累积计算固定数量的历史数据,我们为用户设计了简单易用的数据结构。

在Viper中,主要用到2类事件概念,时点对象:LocalDateTime,事件戳:long类型,我们为用户提供了直接的转换函数。

	/**
	 * 显示固定序列
	 */
	public void fixSeries() {
		/**
		 * 设置一个固定长度的K线序列:不设置长度默认为200
		 */
		BarQuoteSeries barQuoteSeries = new BarQuoteSeries(100);

		/**
		 * 我们提供了负向索引,使用该方式可以直接获取最后一个
		 */
		IBarQuote barQuote = barQuoteSeries.get(-1);

		/**
		 * 行情的时间一般用时间戳表示,java8的localDateTime提供了丰富的时间相关功能
		 */
		long time = barQuote.getTime();
		LocalDateTime localDateTime = TimeUtil.longToLocalDateTime(time);
		System.out.println(localDateTime);
	}

talib

我们对talib进行了二次封装,将所有的指标都变成对象,同时提供了负向索引,方便用户从末尾开始取数据。

	/**
	 * 延时talib指标使用
	 */
	public void talib() {
		MA ma5 = new MA();
		ma5.setMaType(MAType.Ema);
		ma5.setTimePeriod(5);
		ma5.setInput(new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
		ma5.recalculate();
		System.out.println(String.format("获取最新值:%f", ma5.getResult(-1)));
	}

其他技巧

引用其他类对象

用户在策略编写过程中,可以将常用的一些函数和功能提取出来,在多个策略文件中进行调用,从而达到代码复用的效果。


logo

Warning

导入其他类需要在同一个项目中,不能扩项目进行应引用。

引用其他包

Java流行的基础在于其有一个强大的社区和众多的使用者支持,Apache的Hadoop、Spark、Flume、Kafka,Goolge的protobuf、guava等都是非常易用且经过长期检验的包。

用户可以在策略开发中使用Maven引入这些包,从而获取Java开源生态系统中的众多功能。

Tip

对于python的使用者来说,maven是一个包管理器,相当于pip的功能。


Warning

当前对包的自定义引用还不支持,用户如果需要用到某个包,需要我们为其打包一个单独的Viper BackTest和Viper Real运行文件,用户才可以在回测和实盘中使用,后期我们将采用osgi的方式,允许用户自定义进行添加。