Параметры текущей свечи
Atom Ответить
27.02.2013


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

Теги:


Спасибо:




18 Ответов
Moadip

Фотография
Автор статей Программист
Дата: 27.02.2013
Ответить


Свечки

Код

private CandleSeries _candleSeries;
private Security _security;

...

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


Текущая свечка:
Код

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


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

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


High/Low:
Код


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

Спасибо: Shaly

Shaly

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


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

.Do(ProcessValues)
.Apply(this);

base.OnStarted();
}
Автор топика
Спасибо:

Moadip

Фотография
Автор статей Программист
Дата: 27.02.2013
Ответить


Проверил.
Код

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;

Код

		_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));
		}
Спасибо:

Moadip

Фотография
Автор статей Программист
Дата: 27.02.2013
Ответить


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

            base.OnStarted();
        }


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

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

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

Shaly

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


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

Moadip

Фотография
Автор статей Программист
Дата: 01.03.2013
Ответить


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

И желательно показать код, что и как делаете. Может и найдется решение.Smile
Спасибо:

kahuna

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


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 только завершенную
Спасибо:

Shaly

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


Для расчета индикатора требуются минимальные и максимальные цены текущего и предыдущего баров, независимо, сформировался последний бар или нет. Вот этот код взят за основу, который я пытаюсь изменить, чтобы рассчитать индикатор.
Код
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();
        }



    }
}
Автор топика
Спасибо:

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 02.03.2013
Ответить


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

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

            base.OnStarted();
        }

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

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

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

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


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


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

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

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

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

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

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







Спасибо: alexan3010

Shaly

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


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

VassilSanych

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


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

Каким образом VS express может накладывать ограничения на .net?
В VS express отсутствуют только некоторые средства разработки, которые есть в платных версиях. Сама же .net и её API доступны вне зависимости от инструментов. Можно в notepad писать и из командной строки компилировать.
Спасибо:

VassilSanych

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


IPersistable наследуют, кстати, ещё и Strategy и ITrader до кучи к другим классам.
Спасибо:

VassilSanych

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


Если отсутствуют какие-то библиотеки, попробуйте установить триальную версию VS и скопировать нужные библиотеки из её папок (врядли это нарушает лицензию)
Можно ещё, наверное, установить SDK. Но я не знаю в какой именно SDK входят "Testing Tools", если входят вообще куда-то.
upd
попробуйте
Visual Studio SDK
или ещё (что врядли)
Windows SDK
(не обращайте внимание на "windows 8" сейчас весь SDK называется именно так)
Только осторожно: в последний раз, когда я качал Platform SDK (давно это было), он у меня занял около 7Гб.
Спасибо:

Moadip

Фотография
Автор статей Программист
Дата: 05.03.2013
Ответить


VassilSanych не пугайте девушку обилием терминологии.Smile

Классы S# которые реализуют интерфейс IPersistable это не тот интерфейс который находится в Microsoft.VisualStudio.QualityTools.Common.dll.
Это интерфейс S#, находится в Ecng.Serialization.dll, поэтому ничего доп. скачивать и устанавливать не надо.

Shaly, добавьте в References проекта данную dll, должно все заработать.
Спасибо: Shaly

Shaly

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


Данная dll уже давно добавлена в проект и есть ссылка на StockSharp.Algo.Indicators(прописана), но ошибка, что не хватает ссылки, не исчезает никак.
Автор топика
Спасибо:

Moadip

Фотография
Автор статей Программист
Дата: 05.03.2013
Ответить


Выложите скрин с ошибкой. Возможно прояснит ситуацию. Плюс скрин, что добавлено в рефы.
Спасибо:

Shaly

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



С предыдущей проблемой всё разрешилось) спасибо! Не хватало ссылки Ecng.Serialization. Но вот появилась другая проблема. Подскажите, как устранить?
Ошибка.jpg 176,2KB (0)
Автор топика
Спасибо:

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 05.03.2013
Ответить


вместо
Код
public override decimal OnProcess(IIndicatorValue input)


напишите
Код
protected override decimal OnProcess(IIndicatorValue input)


Спасибо: Shaly


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

loading
clippy