np74
|
Date: 8/15/2017
|
|
|
|
Hi
I just modified existing sample SampleChartActivOrders as follows to show the pnf chart but i dont see it can you see why? i cant see candle chart though
public partial class MainWindow { public ObservableCollection<Order> Orders { get; }
private ChartArea _area; private ChartCandleElement _candleElement; private ChartCandleElement _pnfCandleElement; private ChartActiveOrdersElement _activeOrdersElement; private TimeFrameCandle _candle;
private readonly DispatcherTimer _chartUpdateTimer = new DispatcherTimer(); private readonly SynchronizedDictionary<DateTimeOffset, TimeFrameCandle> _updatedCandles = new SynchronizedDictionary<DateTimeOffset, TimeFrameCandle>(); private readonly CachedSynchronizedList<TimeFrameCandle> _allCandles = new CachedSynchronizedList<TimeFrameCandle>(); private readonly Dictionary<Order, ChartActiveOrderInfo> _chartOrderInfos = new Dictionary<Order, ChartActiveOrderInfo>();
private const decimal _priceStep = 10m; private const int _timeframe = 1;
private bool NeedToDelay => _chkDelay.IsChecked == true; private bool NeedToFail => _chkFail.IsChecked == true; private bool NeedToConfirm => _chkConfirm.IsChecked == true;
private static readonly TimeSpan _delay = TimeSpan.FromSeconds(2);
private readonly Security _security = new Security { Id = "RIZ2@FORTS", PriceStep = _priceStep, Board = ExchangeBoard.Forts };
private readonly ThreadSafeObservableCollection<Portfolio> _portfolios = new ThreadSafeObservableCollection<Portfolio>(new ObservableCollectionEx<Portfolio> { new Portfolio { Name = "Test portfolio" } });
private PnFArg _pngArg = new PnFArg() { BoxSize = 20, ReversalAmount = 3 }; public MainWindow() { ConfigManager.RegisterService(_portfolios);
Orders = new ObservableCollection<Order>(); InitializeComponent(); Loaded += OnLoaded;
Chart.OrderSettings.Security = _security; Chart.OrderSettings.Portfolio = _portfolios.First(); Chart.OrderSettings.Volume = 5;
_chartUpdateTimer.Interval = TimeSpan.FromMilliseconds(10000); _chartUpdateTimer.Tick += ChartUpdateTimerOnTick; _chartUpdateTimer.Start(); }
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) { InitCharts(); LoadData(@"..\..\..\..\Testing\HistoryData\".ToFullPath()); }
private void InitCharts() { Chart.ClearAreas(); Chart.OrderCreationMode = true;
_area = new ChartArea();
var yAxis = _area.YAxises.First();
yAxis.AutoRange = true; Chart.IsAutoRange = true; Chart.IsAutoScroll = true;
Chart.AddArea(_area);
var series = new CandleSeries( typeof(TimeFrameCandle), _security, TimeSpan.FromMinutes(_timeframe));
var pnfSeries = new CandleSeries( typeof(PnFCandle), _security, _pngArg);
_candleElement = new ChartCandleElement { FullTitle = "Candles" }; Chart.AddElement(_area, _candleElement, series);
_pnfCandleElement = new ChartCandleElement { FullTitle = "PNF" }; Chart.AddElement(_area, _pnfCandleElement, pnfSeries);
_activeOrdersElement = new ChartActiveOrdersElement { FullTitle = "Active orders" }; Chart.AddElement(_area, _activeOrdersElement); }
private void LoadData(string path) { _candle = null; _allCandles.Clear();
Chart.Reset(new IChartElement[] { _candleElement, _activeOrdersElement }); //Chart.Reset(new IChartElement[] { _pnfCandleElement, _activeOrdersElement });
var storage = new StorageRegistry();
var maxDays = 2;
BusyIndicator.IsBusy = true;
Task.Factory.StartNew(() => { var date = DateTime.MinValue;
foreach (var tick in storage.GetTickMessageStorage(_security, new LocalMarketDataDrive(path)).Load()) { AppendTick(_security, tick);
if (date != tick.ServerTime.Date) { date = tick.ServerTime.Date;
this.GuiAsync(() => { BusyIndicator.BusyContent = date.ToString(); });
maxDays--;
if (maxDays == 0) break; } } }) .ContinueWith(t => { if (t.Exception != null) Error(t.Exception.Message);
this.GuiAsync(() => { BusyIndicator.IsBusy = false; Chart.IsAutoRange = false; _area.YAxises.First().AutoRange = false;
Log($"Loaded {_allCandles.Count} candles"); });
}, TaskScheduler.FromCurrentSynchronizationContext()); }
private void ChartUpdateTimerOnTick(object sender, EventArgs eventArgs) { TimeFrameCandle[] candlesToUpdate;
lock (_updatedCandles.SyncRoot) { candlesToUpdate = _updatedCandles.OrderBy(p => p.Key).Select(p => p.Value).ToArray(); _updatedCandles.Clear(); }
var lastCandle = _allCandles.LastOrDefault(); _allCandles.AddRange(candlesToUpdate.Where(c => lastCandle == null || c.OpenTime != lastCandle.OpenTime));
var data = new ChartDrawData(); PnFCandle prevCandle = null; foreach (var candle in candlesToUpdate) { if(prevCandle ==null) { PnFCandle newCandle = new PnFCandle() { Security = candle.Security, CloseTime = candle.CloseTime, HighTime = candle.HighTime, OpenTime = candle.OpenTime, ClosePrice = candle.ClosePrice, OpenPrice = candle.OpenPrice, HighPrice = candle.HighPrice, LowPrice = candle.LowPrice, TotalVolume = candle.TotalVolume,
}; newCandle.PnFArg = _pngArg; newCandle.Type = PnFTypes.X; prevCandle = newCandle; data.Group(candle.OpenTime).Add(_pnfCandleElement, newCandle); } else { if( prevCandle.Type == PnFTypes.X) { if( candle.ClosePrice - prevCandle.ClosePrice >= _pngArg.BoxSize) { PnFCandle newCandle = new PnFCandle() { Security = candle.Security, CloseTime = candle.CloseTime, HighTime = candle.HighTime, OpenTime = candle.OpenTime, ClosePrice = candle.ClosePrice, OpenPrice = candle.OpenPrice, HighPrice = candle.HighPrice, LowPrice = candle.LowPrice, TotalVolume = candle.TotalVolume, PnFArg = _pngArg, Type = PnFTypes.X, }; prevCandle = newCandle; data.Group(candle.OpenTime).Add(_pnfCandleElement, newCandle); } else if(candle.ClosePrice - prevCandle.ClosePrice <= _pngArg.BoxSize * _pngArg.ReversalAmount) { PnFCandle newCandle = new PnFCandle() { Security = candle.Security, CloseTime = candle.CloseTime, HighTime = candle.HighTime, OpenTime = candle.OpenTime, ClosePrice = candle.ClosePrice, OpenPrice = candle.OpenPrice, HighPrice = candle.HighPrice, LowPrice = candle.LowPrice, TotalVolume = candle.TotalVolume, PnFArg = _pngArg, Type = PnFTypes.O, }; prevCandle = newCandle; data.Group(candle.OpenTime).Add(_pnfCandleElement, newCandle); }
} else if (prevCandle.Type == PnFTypes.O) { if (candle.ClosePrice - prevCandle.ClosePrice <= _pngArg.BoxSize) { PnFCandle newCandle = new PnFCandle() { Security = candle.Security, CloseTime = candle.CloseTime, HighTime = candle.HighTime, OpenTime = candle.OpenTime, ClosePrice = candle.ClosePrice, OpenPrice = candle.OpenPrice, HighPrice = candle.HighPrice, LowPrice = candle.LowPrice, TotalVolume = candle.TotalVolume, PnFArg = _pngArg, Type = PnFTypes.O, }; prevCandle = newCandle; data.Group(candle.OpenTime).Add(_pnfCandleElement, newCandle); } else if (candle.ClosePrice - prevCandle.ClosePrice >= _pngArg.BoxSize * _pngArg.ReversalAmount) { PnFCandle newCandle = new PnFCandle() { Security = candle.Security, CloseTime = candle.CloseTime, HighTime = candle.HighTime, OpenTime = candle.OpenTime, ClosePrice = candle.ClosePrice, OpenPrice = candle.OpenPrice, HighPrice = candle.HighPrice, LowPrice = candle.LowPrice, TotalVolume = candle.TotalVolume, PnFArg = _pngArg, Type = PnFTypes.X, }; prevCandle = newCandle; data.Group(candle.OpenTime).Add(_pnfCandleElement, newCandle); }
} } }
Chart.Draw(data); }
private void AppendTick(Security security, ExecutionMessage tick) { var time = tick.ServerTime; var price = tick.TradePrice.Value;
if (_candle == null || time >= _candle.CloseTime) { if (_candle != null) { _candle.State = CandleStates.Finished; lock (_updatedCandles.SyncRoot) _updatedCandles[_candle.OpenTime] = _candle; }
var tf = TimeSpan.FromMinutes(_timeframe); var bounds = tf.GetCandleBounds(time, _security.Board); _candle = new TimeFrameCandle { TimeFrame = tf, OpenTime = bounds.Min, CloseTime = bounds.Max, Security = security, };
_candle.OpenPrice = _candle.HighPrice = _candle.LowPrice = _candle.ClosePrice = price; }
if (time < _candle.OpenTime) throw new InvalidOperationException("invalid time");
if (price > _candle.HighPrice) _candle.HighPrice = price;
if (price < _candle.LowPrice) _candle.LowPrice = price;
_candle.ClosePrice = price;
_candle.TotalVolume += tick.TradeVolume.Value;
lock (_updatedCandles.SyncRoot) _updatedCandles[_candle.OpenTime] = _candle; }
|