Построение баров из trades
Создание собственных баров дает вам возможность применять настраиваемую фильтрацию.
Функция как альтернатива втроенной (BuildBarsFromTrades).
using System;
using System.Drawing;
using OpenQuant.API;
using OpenQuant.API.Indicators;
public class MyStrategy : Strategy
{
public override void OnTrade(Trade trade)
{
if(trade.Price > 0 && trade.Size > 0) {
BuildBarsFromTrades(BarType.Time,60,Trades,Bars);
//BuildBarsFromTrades(BarType.Tick,100,Trades,Bars);
//BuildBarsFromTrades(BarType.Volume,100,Trades,Bars);
}
}
public void BuildBarsFromTrades(BarType barType, long barSize, TradeSeries trades, BarSeries bars)
{
switch(barType)
{
case BarType.Time:
BuildTimeBarsFromTrades(barSize,trades.Last,bars);
break;
case BarType.Tick:
BuildTickBarsFromTrades(barSize,trades,bars);
break;
case BarType.Volume:
BuildVolumeBarsFromTrades(barSize,trades.Last,bars);
break;
}
}
public void BuildTimeBarsFromTrades(long barSize, Trade trade, BarSeries bars)
{
if(barSize < 1){
throw(new Exception("barSize must be > 0"));
}
DateTime nextBarEndTime = new DateTime();
if(bars.Count > 0){ //calculate the end time of the last bar
long lastBarEndInSeconds = bars.Last.EndTime.Ticks / 10000000;
long nextBarEndInSeconds = ((lastBarEndInSeconds + barSize)/barSize)*barSize;
nextBarEndTime = nextBarEndTime.AddSeconds(nextBarEndInSeconds);
}
if(trade.DateTime < nextBarEndTime)
{ //merge bar into previous bar
bars.Add(BarType.Time,barSize,bars.Last.BeginTime, trade.DateTime,
bars.Last.Open,
Math.Max(bars.Last.High,trade.Price),
Math.Min(bars.Last.Low,trade.Price),
Trade.Price,
bars.Last.Volume + trade.Size,
0); //Replaces the last bar
}else{
//Add new bar
bars.Add(BarType.Time,barSize,
trade.DateTime,trade.DateTime,
trade.Price,trade.Price,trade.Price,trade.Price,
trade.Size,0);
}
}
public void BuildTickBarsFromTrades(long barSize, TradeSeries trades, BarSeries bars)
{
Trade trade = trades.Last;
if(barSize < 1){
throw(new Exception("barSize must be > 0"));
}
//check if the last bar is full
if(bars.Count > 0 && (((trades.Count / barSize)*barSize)< trades.Count))
{ //merge bar into previous bar
bars.Add(BarType.Tick,barSize,bars.Last.BeginTime, trade.DateTime,
bars.Last.Open,
Math.Max(bars.Last.High,trade.Price),
Math.Min(bars.Last.Low,trade.Price),
trade.Price,
bars.Last.Volume + trade.Size,
0); //Replaces the last bar
}else{
//Add a small amount of time to the new bar
//new bar must be later than last bar or it will replace the last bar.
DateTime newTradeTime = trade.DateTime;
if(bars.Count > 0 && bars.Last.BeginTime >= trade.DateTime){
newTradeTime = bars.Last.BeginTime.AddTicks(1);
}else{
newTradeTime = trade.DateTime;
}
//Add new bar
bars.Add(BarType.Tick,barSize,
newTradeTime,newTradeTime,
trade.Price,trade.Price,trade.Price,trade.Price,
trade.Size,0);
}
}
public void BuildVolumeBarsFromTrades(long barSize, Trade trade, BarSeries bars)
{
if(barSize < 1){
throw(new Exception("barSize must be > 0"));
}
//make sure not to access bars.Last if there are no bars
//volumeRemaining is the unfilled portion of the last bar
DateTime newTradeTime = trade.DateTime;
long volumeRemaining = 0;
if(bars.Count > 0) {
//new trade must be later than previous bar or it won't add.
if(bars.Last.BeginTime >= trade.DateTime){
newTradeTime = bars.Last.BeginTime.AddTicks(1);
}
volumeRemaining = barSize - bars.Last.Volume;
}
//merge with last volume bar
long volumeAdd = 0;
if(volumeRemaining > 0){
volumeAdd = Math.Min(volumeRemaining,trade.Size);
bars.Add(BarType.Volume,barSize,bars.Last.BeginTime, trade.DateTime,
bars.Last.Open,
Math.Max(bars.Last.High,trade.Price),
Math.Min(bars.Last.Low,trade.Price),
trade.Price,
bars.Last.Volume + volumeAdd,
0); //Replaces the last bar
}
//deduct the volume that was just added from volumeRemaining
volumeRemaining = trade.Size - volumeAdd;
//add new volume bars until there is no more volumeRemaining
while(volumeRemaining > 0){
volumeAdd = Math.Min(volumeRemaining,barSize);
bars.Add(BarType.Volume,barSize,
newTradeTime,newTradeTime,
trade.Price,trade.Price,trade.Price,trade.Price,
volumeAdd,0);
volumeRemaining = volumeRemaining - volumeAdd;
//new trade must be later than previous bar or it won't add.
newTradeTime = bars.Last.BeginTime.AddTicks(1);
}
}
} //MyStrategy()