Параметры текущей свечи

Параметры текущей свечи
Atom
2/27/2013
Shaly


Каким методом получить параметры текущей свечи? High, Low предыдущей (сформировавшейся) свечи получаем через ProcessCandle(Candle candle), текущей (формирующейся) через ProcessValues(Candle candle), но последнее не работает.

Tags:


Thanks:


1 2  >
Moadip

Avatar
Date: 2/27/2013
Reply


Свечки

Code

private CandleSeries _candleSeries;
private Security _security;

...

_candleSeries = new CandleSeries(typeof(TimeFrameCandle), _security, TimeSpan.FromMinutes(1));


Текущая свечка:
Code

var candle = _candleSeries.GetCandle<TimeFrameCandle>(0);


Предыдущая свечка:
Code

var candle = _candleSeries.GetCandle<TimeFrameCandle>(1);


High/Low:
Code


var highPrice = candle.HighPrice;
var lowPrice = candle.LowPrice;

Thanks: Shaly

Shaly

Avatar
Date: 2/27/2013
Reply


В этом случае все равно текущую формирующуюся свечу на видит, показывает последнюю полностью сформировавшуюся.
Может проблема в другом месте например эдесь
protected override void OnStarted()
{
//LINQ-запрос - когда свеча сформирована, то запустить метод обработки свечи ProcessCandle
_candleSeries
.WhenCandlesFinished()//

.Do(ProcessValues)
.Apply(this);

base.OnStarted();
}
Thanks:

Moadip

Avatar
Date: 2/27/2013
Reply


Проверил.
Code

QuikTrader      | 27.02.2013 16:18:57.001 |            | processCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152870
QuikTrader      | 27.02.2013 16:18:57.001 |            | currentCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152870
QuikTrader      | 27.02.2013 16:18:57.885 |            | processCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152860
QuikTrader      | 27.02.2013 16:18:57.885 |            | currentCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152860
QuikTrader      | 27.02.2013 16:18:58.199 |            | processCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152880
QuikTrader      | 27.02.2013 16:18:58.199 |            | currentCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152880
QuikTrader      | 27.02.2013 16:19:00.123 |            | processCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152860
QuikTrader      | 27.02.2013 16:19:00.123 |            | currentCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152860
QuikTrader      | 27.02.2013 16:19:00.866 |            | processCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152860
QuikTrader      | 27.02.2013 16:19:00.866 |            | currentCandle OpenTime:27.02.2013 16:18:00 O:152880 H:152910 L:152860 C:152860
QuikTrader      | 27.02.2013 16:19:00.866 |            | processCandle OpenTime:27.02.2013 16:19:00 O:152860 H:152860 L:152860 C:152860
QuikTrader      | 27.02.2013 16:19:00.866 |            | currentCandle OpenTime:27.02.2013 16:19:00 O:152860 H:152860 L:152860 C:152860


Все значения совпадают. Что в пришедшей по событию Processing, что взятой через GetCandle;

Code

		_candleManager.Processing += Process;

		...

		void Process(CandleSeries series, Candle candle)
		{
			_quikTrader.AddInfoLog("processCandle OpenTime:{OpenTime} O:{OpenPrice} H:{HighPrice} L:{LowPrice} C:{ClosePrice}".PutEx(candle));

			var currCandle = _candleSeries.GetCandle<TimeFrameCandle>(0);
			_quikTrader.AddInfoLog("currentCandle OpenTime:{OpenTime} O:{OpenPrice} H:{HighPrice} L:{LowPrice} C:{ClosePrice}".PutEx(currCandle));
		}
Thanks:

Moadip

Avatar
Date: 2/28/2013
Reply


Code
        
protected override void OnStarted()
        {
            //LINQ-запрос - когда свеча сформирована, то запустить метод обработки свечи ProcessCandle
        _candleSeries
                .WhenCandlesFinished()//
            
                .Do(ProcessValues)
                .Apply(this);

            base.OnStarted();
        }


Вы используете правило WhenCandlesFinished - правило на событие окончания свечки.

Соответственно метод ProcessValues буде выполняться только тогда, когда Сandle.State == CandleStates.Finished.
И в метод ProcessValues будет передаваться только целая свечка.

Почитайте про правила и желательно весь раздел событийная модель.
Thanks:

Shaly

Avatar
Date: 2/28/2013
Reply


Единственный метод по описанию подходящий под эти цели - WhenChanged(), но он выдает ошибки
Ошибка 1 Аргумент экземпляра: невозможно преобразовать из "StockSharp.Algo.Candles.CandleSeries" в "StockSharp.BusinessEntities.Order"
Ошибка 2 "StockSharp.Algo.Candles.CandleSeries" не содержит определения для "WhenChanged" и наиболее подходящий перегруженный метод расширения "StockSharp.Algo.MarketRuleHelper.WhenChanged(StockSharp.BusinessEntities.Order)" содержит несколько недопустимых аргументов
Thanks:

Moadip

Avatar
Date: 3/1/2013
Reply


Вы опишите конкретно что пытаетесь/надо сделать, а не абстрактные куски кода.

И желательно показать код, что и как делаете. Может и найдется решение.[smile]
Thanks:

kahuna

Avatar
Date: 3/2/2013
Reply


Shaly
Каким методом получить параметры текущей свечи? High, Low предыдущей (сформировавшейся) свечи получаем через ProcessCandle(Candle candle), текущей (формирующейся) через ProcessValues(Candle candle), но последнее не работает.


Вызывая индикатор в ProcessCandle
подписываясь в стратегии вот так
_series.WhenCandlesFinished().Do(this.ProcessCandle).Apply(this);
получаю в качестве результата законченные значения индикатора по завершенным свечам.

Чтобы получать значения в процессе формирования свечи вызываю в стратегии другую функцию
Security.WhenChanged().Do(TryMakeTrade).Apply(this);
и там беру значение индикатора. Тогда получаю значения и по не сформировавшейся свече.

Если внутри OnProcess индикатора, то вот это у меня работает именно выдавая текущую формирующуся свечу.
protected override decimal OnProcess(IIndicatorValue input)
{
var candle = input.GetValue<Candle>()
var High=candle.HighPrice;
...
}
а если поставлю проверку типа
if (candle.State == CandleStates.Finished)
{ var High=candle.HighPrice; }
то получу в High только завершенную
Thanks:

Shaly

Avatar
Date: 3/2/2013
Reply


Для расчета индикатора требуются минимальные и максимальные цены текущего и предыдущего баров, независимо, сформировался последний бар или нет. Вот этот код взят за основу, который я пытаюсь изменить, чтобы рассчитать индикатор.
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Ecng.Collections;
using Ecng.Xaml;

using StockSharp.Algo;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Candles;
using StockSharp.Quik;
using StockSharp.BusinessEntities;

/*
 * Стратегия на основе пробоя N внутридневных свечей для Si
*/

namespace Robot
{
    class RobotStrategy: Strategy
    {

        private CandleManager _candleManager;     //Менеджер свечей
        private CandleSeries _candleSeries;     //Свечи
        private TimeSpan _timeFrame;            //ТаймФрейм

        decimal stopLossPersent = 0.1m;     //Стоп-лосс в процентах

        bool isSendOrder = false;

        decimal _slippage;


        private MarketQuotingStrategy _quoteStrategy;    //стратегия котирование


        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="candleSeries"></param>
        /// <param name="timeFrame"></param>
        public RobotStrategy(CandleManager candleManager, CandleSeries candleSeries, TimeSpan timeFrame, decimal slippage)
        {
            _candleManager = candleManager;
            _candleSeries = candleSeries;
            _timeFrame = timeFrame;
            _slippage = slippage;
        }



        /// <summary>
        /// Событие старта стратегии
        /// </summary>
        protected override void OnStarted()
        {
            //LINQ-запрос - когда свеча сформирована, то запустить метод обработки свечи ProcessCandle
            _candleSeries
                .WhenCandlesFinished()
                .Do(ProcessCandle)
                .Apply(this);

            base.OnStarted();
        }



        /// <summary>
        /// Событие обработки свечей (как новых свечей так и пришедших с начала торгового дня) 
        /// Свечи поступают согласно заданному таймфрейму
        /// </summary>
        /// <param name="candle">последняя сформированная полностью свеча</param>
        private void ProcessCandle(Candle candle)
        {
            // если наша стратегия в процессе остановки
            if (ProcessState == ProcessStates.Stopping)
            {
                CancelActiveOrders();   //отменяем активные заявки
                return;
            }


            //Если время 23,30 - то закрываем все сделки, останавливаем стратегию, выключаем робота
            if (candle.CloseTime.Hour == 23 && candle.CloseTime.Minute >= 30)
            {
                if (GetCurrentPosition() != 0) closeAllPosition();
                stopRobot();
                return;
            }


            //Разрешаем открывать позиции только в определенное время
            if ( canTradeByTime(candle.CloseTime.Hour, candle.CloseTime.Minute) )
            {

                //Проверяем, есть ли открытые позиции по нашему инструменту
                if (GetCurrentPosition() != 0)
                {
                    Console.WriteLine("Has open pos - " + GetCurrentPosition());
                    //isSendOrder = false;
                }
                else
                {
                    //Console.WriteLine("No pos " + candle.CloseTime.Hour + ":" + candle.CloseTime.Minute);

                    //Определяем время последней сформированной свечи
                    DateTime currentCandleTime = (candle.OpenTime + _timeFrame);

                    //Если пришедшая свеча - последняя полностью сформированная (актуальная к текущему времени)
                    if (currentCandleTime.Hour == _candleManager.CurrentTime.Hour && currentCandleTime.Minute == _candleManager.CurrentTime.Minute / (int)_timeFrame.TotalMinutes * (int)_timeFrame.TotalMinutes)
                    {

                        int candlesCount = _candleSeries.GetCandleCount();

                        //Находим High/Low среди всех предыдущих свечей в текущем дне
                        decimal _high = decimal.MinValue;
                        decimal _low = decimal.MaxValue;

                        for (int i = 1; i < candlesCount; i++)
                        {
                            var prevCandle = _candleSeries.GetCandle<TimeFrameCandle>(i);
                            _high = Math.Max(_high, Math.Max(prevCandle.ClosePrice, prevCandle.OpenPrice));
                            _low = Math.Min(_low, Math.Min(prevCandle.ClosePrice, prevCandle.OpenPrice));
                        }

                        Console.WriteLine("High = " + _high + "; Low = " + _low);

                        //Создаем дочернюю стратегию - котирование
                        _quoteStrategy = null;


                        if (candle.ClosePrice > _high)  //Покупаем по рыночной цене 
                        {
                            Console.WriteLine(" >>>> BUY");

                            //Формируем заявку на покупку через котирование
                            var direction = OrderDirections.Buy;
                            _quoteStrategy = new MarketQuotingStrategy(direction, Volume);
                            _quoteStrategy.PriceOffset = _slippage;  //Учитываем проскальзывание
                        }
                        else if (candle.ClosePrice < _low)  //Продаем
                        {
                            Console.WriteLine(" >>>> SHORT");

                            //Формируем заявку на продажу через котирование
                            var direction = OrderDirections.Sell;
                            _quoteStrategy = new MarketQuotingStrategy(direction, Volume);
                            _quoteStrategy.PriceOffset = _slippage;  //Учитываем проскальзывание
                        }


                        //Если сделка произведена
                        if (_quoteStrategy != null)
                        {
                            _quoteStrategy.WaitAllTrades = true;

                            // регистрируем правило, отслеживающее появление новых сделок по заявке
                            _quoteStrategy
                                .WhenNewMyTrades()
                                .Do(OnNewOrderTrades)
                                .Apply(this);

                            ChildStrategies.Add(_quoteStrategy);

                            Console.WriteLine("Make deal");
                        }


                    }

                }   //End else getPos

            }
        }




        /// <summary>
        /// Разрешено ли торговать
        /// </summary>
        /// <param name="hour"></param>
        /// <param name="minute"></param>
        /// <returns></returns>
        private bool canTradeByTime(int hour, int minute)
        {
            //return true;    //!!!Del this

            if (hour >= 11 && hour <= 18)
                return true;
            else
                return false;
        }




        /// <summary>
        /// Событие прихода новой свечи
        /// </summary>
        /// <param name="trades"></param>
        private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
        {
            Console.WriteLine("new trade");

            // для каждой сделки добавляем защитную стратегию
            var protectiveStrategy = trades.Select(trade =>
            {
                //Если позиция открыта
                var stopDelta = (int) (trade.Order.Price * stopLossPersent/100);

                // выставляет стоп-лосс
                var stopLoss = new StopLossStrategy(trade, stopDelta);

                Console.WriteLine("make stop " + stopDelta);

                //Подписываемся на событие срабатывания стоп-лоса
                stopLoss.
                    WhenPositionChanged().
                    Do(closePositionByStopLoss).
                    Apply(this);

                return stopLoss;
            });

            //Добавляем дочернюю стратегию
            ChildStrategies.AddRange(protectiveStrategy);
        }



        /// <summary>
        /// Определение текущей позициИ по инструменту
        /// </summary>
        /// <returns></returns>
        private int GetCurrentPosition()
        {
            if ( Trader.GetPosition(Portfolio, Security) != null )
            {
                return (int) Trader.GetPosition(Portfolio, Security).CurrentValue;
            }
            else
            {
                return 0;
            }
        }






        /// <summary>
        /// Закрытие позиции по Стоп-лосу
        /// </summary>
        private void closePositionByStopLoss()
        {
            Console.WriteLine("Close By Stop");
        }



        /// <summary>
        /// Закрытие всех открытых позиций
        /// </summary>
        private void closeAllPosition()
        {
            
        }





        /// <summary>
        /// Остановка робота
        /// </summary>
        private void stopRobot()
        {
            CancelActiveOrders();
            //Закрытие всех активных позиций
            if (GetCurrentPosition() != 0)
            {
                _quoteStrategy.ClosePositionByQuoting();
            }

            this.Stop();
        }



    }
}
Thanks:

Иван З.

Avatar
Date: 3/2/2013
Reply


Здравствуйте! По всей видимости у вас нет понимания как это все работает.

Code
        protected override void OnStarted()
        {
            //LINQ-запрос - когда свеча сформирована, то запустить метод обработки свечи ProcessCandle
            _candleSeries
                .WhenCandlesFinished()
                .Do(ProcessCandle)
                .Apply(this);

            base.OnStarted();
        }

Здесь вы воспользовались правилом "MarketRuleHelper.WhenFinished - правило на событие окончания свечки." То есть в ProcessCandle будут приходить только оконченные свечи. На ряду с этим правилом, есть еще следующие,

MarketRuleHelper.WhenCandlesStarted - правило на событие появления новых свечек.
MarketRuleHelper.WhenCandlesChanged - правило на событие изменения свечек.
MarketRuleHelper.WhenChanged - правило на событие изменения свечки.
и другие, их можно посмотреть здесь http://www.stocksharp.co...1-9306-275d55d4cf36.htm во вкладке Событийная модель=>Правило.
Попробуйте другие правила, прочитайте как ими пользоваться.

можно попробовать еще следующий способ, от сюда http://www.stocksharp.co...9-a573-abf0245b3f5d.htm

Code
_candleManager.Processing += ProcessCandle;// я бы воспользовался этим способом


Когда разберетесь со способом передачи свечей в ProcessCandle. Так как ProcessCandle принимает только свечи, создайте буфер для хранения оконченных свечек
Code
List<Candle> _buffer = new List<Candle>();


, добавляйте в буфер в методе ProcessCandle каждую оконченную свечку
Code
 if (candle.State == CandleStates.Finished)// проверка окончена свеча или нет
              _buffer.Insert(0, candle);

если таким образом добавлять свечи то _buffer[0] это будет последняя свеча, _buffer[1] предпоследняя и т.д.
Когда буфер станет большим, допустим вам больше 10 свечей не надо. то удаляем последнюю.
Code
if (_buffer.Count > 10) _buffer.RemoveAt(10);

Вообще это стандартная система для индикаторов, достаточно посмотреть здесь http://stocksharp.codepl...eset/view/23281#166110, да по другим индикаторам.
Теперь у вас в ProcessCandle есть текущая свеча candle, и список предыдущих свечей _buffer для обработки. Делайте с ними что душе угодно.

candle.LowPrice; // минимальная цена текущей свечи
_buffer[0].HighPrice; // максимальная цена предыдущей свечи и т.д.
Все свойства свечи можно посмотреть здесь http://www.stocksharp.co...Algo_Candles_Candle.htm

Надеюсь немного прояснил для вас ситуацию. Советую вам не пропускать ссылки которые я вам дал. Документация достаточно хорошо сделана и сильно помогает. Есть еще поиск по форуму тоже хорошо помогает. Даже годичной давности сообщения могут помочь или показать как можно сделать, например http://www.stocksharp.co...zatsiia-intierfieisov/. Есть еще обучение, мне лично помогло.(я не агитирую, сугубо личное мнение)

p.s. Здесь скорее сообщество трейдеров чем программистов, и помогать вам особо ни кто не будет, особенно писать за вас робота. По этому надеюсь когда вы станете получать стабильную прибыль с торговли поделитесь со мной доходом![lol]







Thanks: alexan3010

Shaly

Avatar
Date: 3/5/2013
Reply


Просмотрев форум,и изучив индикаторы с codeplex я обнаружила что доступ к индикаторам StockSharp не доступен обладателям VS express по причине не доступности интерфейса IPersistable или я ошибаюсь?
Thanks:
1 2  >

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy