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


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


Каким методом получить параметры текущей свечи? 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 Go to
Каким методом получить параметры текущей свечи? 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