Непонятки с MarketQuotingStrategy
Atom
31.01.2012
vfreeman


Может кто подсказать как разобраться с проблемой? Вчера обнаружил что MQS в каких-то случаях выполняет задачу в двойном размере. Я завел топик и выложил там более полное описание, возможно, что название не совсем корректное. Сегодня на другом инструменте столкнулся опять с той же самой проблемой. Судя по журналу MQS пытается переставить заявку в данном случае 42133045, а она к этому моменту уже выполнена. Причем получив ошибку "Вы не можете снять данную заявку" выставляет новую заявку.

13:13:01.880 | | MQS | Перекотирование зарегистрировано для заявки 42133045на Buy с ценой 30295 объемом 1. 13:13:02.145 | Error | MQS | Заявка 42133045 не была принята по причине System.InvalidOperationException: Сервер для транзакции 'ACTION=MOVE_ORDERS; TRANS_ID=42133045; CLASSCODE=SPBFUT; SECCODE=SiH2; MODE=0; FIRST_ORDER_NUMBER=0; FIRST_ORDER_NEW_PRICE=30295; FIRST_ORDER_NEW_QUANTITY=1;' вернул неправильное сообщение 'Вы не можете снять данную заявку' по передвинутым заявкам.. 13:13:02.176 | Error | MQS | Заявка 42133045 не принята биржей по причине 'Сервер для транзакции 'ACTION=MOVE_ORDERS; TRANS_ID=42133045; CLASSCODE=SPBFUT; SECCODE=SiH2; MODE=0; FIRST_ORDER_NUMBER=0; FIRST_ORDER_NEW_PRICE=30295; FIRST_ORDER_NEW_QUANTITY=1;' вернул неправильное сообщение 'Вы не можете снять данную заявку' по передвинутым заявкам.'. 13:13:02.239 | | MQS | Цена текущей NULL и лучшей 30295. 13:13:02.301 | | MQS | Лучший бид 30295 и лучший аск 30297. 13:13:02.411 | | MQS | Регистрация новой заявки на Buy с ценой 30295 и объемом 1.

ps: если можно взглянуть на фрагмент MarketQuotingStrategy, который выполняет действия в приложенном логе, попытаюсь сам найти ответ


Теги:


Спасибо:


< 1 2 3 
Moadip

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


Т.е когда стратегия завершается с ошибкой это нормальная ситуация?

Допустим выставил quotingVolume = 5, Volume = 1. Запускается MQS. После того как скотировано 2 лота, стратегия останавливается.

Т.е. в основной стратегии надо выставить

RemoveChildStrategies = false;

чтобы после остановки дочерняя стратегия не удалялась.

У MQS подписаться на событие Stopped и в нем смотреть LeftVolume, если больше нуля, то повторно запускать с quotingVolume = LeftVolume?

Спасибо:

Mikhail Sukhov

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


Moadip: Т.е когда стратегия завершается с ошибкой это нормальная ситуация?

Допустим выставил quotingVolume = 5, Volume = 1. Запускается MQS. После того как скотировано 2 лота, стратегия останавливается.

Если так ставить условия, то да, это ошибка. Но котирование не прекращает свою работу при возникновении ошибки при снятии или перерегистрации стратегии (см логи того же vfreeman, где у него таких ошибок было несколько). У вас что-то еще.

Спасибо:

Moadip

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


Вот еще один скрин, скотировалось 2 лота из 5, после чего MQS остановилась.

Код, проще некуда, для того чтобы проверить работу MQS. В чем проблема я понять не могу.

Выкладываю полностью весь код.

MainWindow.xaml.cs


using System.Linq;
using System.Windows;

using Ecng.Collections;
using Ecng.Xaml;
using StockSharp.BusinessEntities;
using StockSharp.Quik;

using StockSharp.Xaml;
using StockSharp.Algo.Logging;

using System.Windows.Forms;
using MessageBox = System.Windows.MessageBox;
using System.ComponentModel;


namespace Kotirovanie
{
    public partial class MainWindow : Window
    {
        public QuikTrader trader;

        static Security instr1;
        public static MarketDepth depth1;
        
        const string secCode1 = "SBER";

        myStrategy myStrat;

        readonly LogManager logManager;

        public MainWindow()
        {
            InitializeComponent();

            //Path.Text = QuikTerminal.GetDefaultPath();
            Path.Text = "c:\\Program Files\\QUIK-Junior\\";

            var monitor = new MonitorWindow() { Topmost = true };
            monitor.Show();

            logManager = new LogManager();
            logManager.Listeners.Add(new GuiLogListener(monitor));
        }

        private void FindPath_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new FolderBrowserDialog();

            if (!Path.Text.IsEmpty()) dlg.SelectedPath = Path.Text;
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) Path.Text = dlg.SelectedPath;
        }

        bool isConnected;

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            if (!isConnected)
            {
                if (Path.Text.IsEmpty())
                    MessageBox.Show(this, "Путь к Quik не выбран");
                else
                {
                    if (trader == null)
                    {
                        trader = new QuikTrader(Path.Text) { IsAsyncMode = false };
                        logManager.Sources.Add(trader);

                        trader.ReConnectionSettings.Interval = TimeSpan.FromSeconds(10);
                        trader.ReConnectionSettings.WorkingTime = Exchange.Rts.WorkingTime;
                        trader.ReConnectionSettings.ConnectionRestored += () => this.GuiAsync(() => MessageBox.Show(this, "Соединение восстановлено"));
                        trader.ConnectionError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString()));
                        trader.Connected += () => this.GuiAsync(() => btnExportDde.IsEnabled = true);

                        trader.NewPortfolios += portfolios => this.GuiAsync(() => Portfolio.Portfolios.AddRange(portfolios));

                        trader.NewSecurities += securities =>
                        {
                            if (instr1 == null)
                            {
                                instr1 = securities.FirstOrDefault(sec => sec.Code == secCode1);
                                instr1.Exchange.IsSupportAtomicReRegister = false;
                            }
                        };

                        trader.QuotesChanged += depths =>
                        {
                            if (depth1 == null && instr1 != null)
                            {
                                depth1 = depths.FirstOrDefault(d => d.Security == instr1);
                            }
                        };
                    }

                    trader.Connect();

                    isConnected = true;
                    btnConnect.Content = "Отключиться";
                }
            }
            else
            {
                trader.Disconnect();

                isConnected = false;
                btnConnect.Content = "Подключиться";
            }
        }

        private void btnExportDde_Click(object sender, RoutedEventArgs e)
        {
            if (isDdeStarted) StopDde();
            else StartDde();
        }

        bool isDdeStarted;

        private void StartDde()
        {
            trader.StartExport();
            isDdeStarted = true;
        }

        private void StopDde()
        {
            trader.StopExport();
            isDdeStarted = false; 
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            if (trader != null)
            {
                if (isDdeStarted) StopDde();
                trader.Dispose();
            }
        }

        private void btnExportStakan_Click(object sender, RoutedEventArgs e)
        {
            trader.RegisterQuotes(instr1);
        }

        private void btnParent_Click(object sender, RoutedEventArgs e)
        {
            //Создаем и запускаем основную стратегию
            myStrat = new myStrategy() { Trader = trader, Portfolio = Portfolio.SelectedPortfolio, Security = instr1};
            logManager.Sources.Add(myStrat);
            myStrat.Start();
        }

        private void btnChild_Click(object sender, RoutedEventArgs e)
        {
            //Добавляем дочернюю
            myStrat.addChildStrategy(OrderDirections.Buy, 5, 1);
        }
    }
}

myStrategy.cs


using System;
using System.Collections.Generic;

using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;


namespace Kotirovanie
{
    class myStrategy : Strategy
    {
        protected override void OnStarting()
        {
            RemoveChildStrategies = false;
            base.OnStarting();
        }

        public void addChildStrategy(OrderDirections direct, decimal quotingVol, decimal vol)
        {
            var strt = new MarketQuotingStrategy(direct, quotingVol) { PriceOffset = Security.MinStepSize, Volume = vol };

            ChildStrategies.Add(strt);
        }
    }
}

MainWindow.xaml


<Window x:Class="Kotirovanie.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:EcngTradingXaml="clr-namespace:StockSharp.Xaml;assembly=StockSharp.Xaml"
        Title="" Height="173" Width="478" Closing="Window_Closing" Topmost="True" WindowStartupLocation="CenterScreen">
    <Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="Path" VerticalAlignment="Top" Width="277" />
        <Button Content="..." Height="23" HorizontalAlignment="Left" Margin="295,12,0,0" Name="FindPath" VerticalAlignment="Top" Width="23" Click="FindPath_Click" />
        <Button Content="Подключиться" Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" Name="btnConnect" VerticalAlignment="Top" Width="98" Click="btnConnect_Click" />
        <Button Content="Экспорт DDE" Height="23" HorizontalAlignment="Left" Margin="116,41,0,0" Name="btnExportDde" VerticalAlignment="Top" Width="98" Click="btnExportDde_Click" IsEnabled="False" />
        <EcngTradingXaml:PortfolioComboBox x:Name="Portfolio" Height="23" HorizontalAlignment="Left" Margin="324,41,0,0" VerticalAlignment="Top" Width="120" />
        <Button Content="Экспорт Стаканы" Height="23" HorizontalAlignment="Left" Margin="220,41,0,0" Name="btnExportStakan" VerticalAlignment="Top" Width="98" Click="btnExportStakan_Click" />
        <Button Content="Основная" Height="23" HorizontalAlignment="Left" Margin="12,99,0,0" Name="btnParent" VerticalAlignment="Top" Width="98" Click="btnParent_Click" />
        <Button Content="Дочерняя" Height="23" HorizontalAlignment="Left" Margin="116,99,0,0" Name="btnChild" VerticalAlignment="Top" Width="98" Click="btnChild_Click" />
    </Grid>
</Window>

Михаил, посмотрите пожалуйста что я не так делаю?

Спасибо:

Mikhail Sukhov

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


Moadip: Михаил, посмотрите пожалуйста что я не так делаю?

Асинхронный режим включите.

Спасибо: Moadip

Moadip

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


Мда. Решение как всегда лежит на поверхности, но почему то его не видишь.

Я думал что чтобы наверняка заявки выставлялись/снимались лучше делать это в синхронном режиме. Оказалось нет.

Михаил, спасибо за ответ. А то я уже какой день мучаюсь с MQS.

Спасибо:
< 1 2 3 

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

loading
clippy