Charting to build custom chart
Atom
08.08.2017
np74


Hi

I looked at your charting sample and i am interested in building point and figure charts, can you please guide how can i do it , is it possible to override chart.draw to do custom drawing?



Спасибо:


Mikhail Sukhov

Фотография
Дата: 09.08.2017
Ответить


Hello,

Please see our documentation http://doc.stocksharp.co...1d-af29-cf80b633db3c.htm
Спасибо:

np74

Фотография
Дата: 09.08.2017
Ответить


Hi

Thanks for response. I did looked at it but really didnt understood how do i customize it ? The DrawStyle got few possible values but what i am trying is not available as DrawStyle.

It will be very helpful if you could give some pointers - what method or which area i need to look

thanks
Спасибо:

Mikhail Sukhov

Фотография
Дата: 14.08.2017
Ответить


Hello,

Please see the section http://doc.stocksharp.co...d-af29-cf80b633db3c.htm There is description how to work with Chart component.
Спасибо:

np74

Фотография
Дата: 15.08.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;
}
Спасибо:

np74

Фотография
Дата: 21.08.2017
Ответить


Hi

can you please tell if stocksharp chart are capable to draw point and figure chart?


Also if possible can you please share some pseudo code or something to draw pnf chart?

Thanks
Спасибо:


Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy