Клиентский API > AdirConnector

Разработка с использованием клиентского API
mihinator
Сообщения: 1
Зарегистрирован: 14 апр 2020, 14:28

Re: AdirConnector

Непрочитанное сообщение mihinator » 14 июн 2020, 12:59

У меня один вопрос, чтобы не задавать кучу других. Откуда вы знаете, какие именно классы, методы, константы и т.д. из DLL библиотек АД нужно использовать для тех или иных целей? Вы один из их программистов? Или эта информация есть где-то помимо вашей головы?

bead
Сообщения: 2
Зарегистрирован: 17 сен 2020, 00:10
Поблагодарили: 2 раза

Re: AdirConnector

Непрочитанное сообщение bead » 17 сен 2020, 00:21

piyyy писал(а):Вызов OrderSendManager.Instance.Init() не имеет смысла, т.к. он ничего не делает. Единственный результат это создание объекта OrderSendManager (см. паттерн Singleton). Что эквивалентно:

Код: Выделить всё

var _orderSendManager = OrderSendManager.Instance;


Однако, до вызова OrderSendManager.CreateClientOrderEntity() он и так создается в рантайме.

Не знаю где он создается, но если не инициализировать OrderSendManager.ClientOrderNum, то заявка успешно будет отклонена по причине нулевого значения этого параметра.
В процессе создания OrderSendManager() происходит как раз получение этого актуального номера заявки, который затем приклеивается через дефис к ConnectionManager.Instance.UserCredentials.OrderPrefix, и составляет полный номер заявки.

Код: Выделить всё

ConnectionManager.Instance.OnLoginLastExtNum += Instance_OnLoginLastExtNum;

private static void Instance_OnLoginLastExtNum(uint loginLastExtNumEntity)
{
   ClientOrderNum = loginLastExtNumEntity;
}


Если не хочется вызывать Init(), можно тупо повесить обработчик после получения Authorized

Код: Выделить всё

ConnectionManager.Instance.OnLoginLastExtNum += Instance_OnLoginLastExtNum;

        private void Instance_OnLoginLastExtNum(uint num)
        {
            OrderSendManager.ClientOrderNum = num;
        }


И уже для создания заявки заполнять этот номер. Причем в get для ClientOrderNum стоит автоинкремент, поэтому его только один раз надо читать для заявки.

Код: Выделить всё

 
                clientOrder.ClientOrderNum = OrderSendManager.ClientOrderNum;


Для округления цен к делителю нашел шикарный метод в интернете:

Код: Выделить всё

        double RoundToNearest(double n, double x)
        {
            return Math.Round(n / x) * x;
        }]


Но этого все равно недостаточно, поэтому уже при генерации заявки делаю так:

Код: Выделить всё

int roundNums = step_val.Length - 2; // step_val содержит шаг цены в текстовом виде
            if (roundNums < 1)
                roundNums = 0;
clientOrder.LimitPrice = Math.Round(limitPrice, roundNums);

:thumbs_up:

Для тестирования создания ордеров можно пользоваться следующим методом, затем визуально сравнить текст заявки и внести исправления. Может пригодится кому.
Нужно добавить в проект ADir.Templates.dll, и using Templates;

Код: Выделить всё

        private String MakeOrderText(ClientOrderEntity clientOrder)
        {
            UserCredentialsEntity credentials = ConnectionManager.Instance.UserCredentials;
            clientOrder.SignTime = ConnectionManager.Instance.GetServerTime();
            TemplateAdditionalParams additionalParams = default(TemplateAdditionalParams);
            additionalParams.ClientNumEDocument = TextOrder.CreateClientNumEDocument(credentials.OrderPrefix, clientOrder.ClientOrderNum);
            DateTime serverTime = ConnectionManager.Instance.GetServerTime(FrontEndType.OperServer);
            additionalParams.SystemTime = serverTime;
            additionalParams.SysName = credentials.Login;
            additionalParams.ManagerName = credentials.FullName;
            TextOrder.CreateTextDocument(TextOrder.DataStorage, clientOrder, additionalParams, out string textOrder, out string errorMessage);
            return textOrder;
           
        }


mihinator писал(а):У меня один вопрос, чтобы не задавать кучу других. Откуда вы знаете, какие именно классы, методы, константы и т.д. из DLL библиотек АД нужно использовать для тех или иных целей? Вы один из их программистов? Или эта информация есть где-то помимо вашей головы?

Информация есть в ILSpy и бесцельно проведенных часах)

slowboy
Сообщения: 1
Зарегистрирован: 11 окт 2020, 00:25
Благодарил (а): 1 раз

Re: AdirConnector

Непрочитанное сообщение slowboy » 11 окт 2020, 00:32

Добрый вечер!
При выставлении заявки столкнулся с ошибкой
"Невозможно найти строку в справочнике SubAccountRazdels для портфеля 0"

Её возвращает как TextOrder.CreateTextDocument, так и Core.OrderSendManager.SendOrder
Перекрутил уже много вариантов, но победить не могу, кто может сталкивался?

Разобрался, была проблема в получении GetIdFI по тикеру, были ошибочные номера бумаг в заявке.

Но осталась другая. Перед отправкой заявки вылезает "Не получен номер последней заявки с сервера. Подача заявок невозможна"
У меня это лечится выполнением disconnect и опять подключением. Может кто сталкивался?

bead
Сообщения: 2
Зарегистрирован: 17 сен 2020, 00:10
Поблагодарили: 2 раза

Re: AdirConnector

Непрочитанное сообщение bead » 13 окт 2020, 08:48

slowboy писал(а):Не получен номер последней заявки с сервера. Подача заявок невозможна

Так предыдущее мое сообщение как раз об этом)

Обрабатываем событие при подключении

Код: Выделить всё

ConnectionManager.Instance.OnLoginLastExtNum += Instance_OnLoginLastExtNum;

        private void Instance_OnLoginLastExtNum(uint num)
        {
            OrderSendManager.ClientOrderNum = num;
        }

Этот номер присылается только один раз. Далее в программе для каждой заявки только один раз читаем номер, после чего он сам автоматически увеличивается на 1 (даже если в отладчике будешь мышкой возить по нему, он тоже будет увеличиваться во всплывающей подсказке).

Полный метод для стоп-лосса например:

Код: Выделить всё

 
        public string SetStopLoss(OrderType ordType, StopLossRow row, bool debug = false)
        {
            string message;

            int roundNums = row.StrStep.Length;
            if (roundNums < 1)
                roundNums = 0;

            double stoploss;
            if (new OrderType[] { OrderType.TSL, OrderType.TRS }.Contains(ordType))
                stoploss = row.SlNow; // трейлинг-стоп для текущей цены, LastPrice +/- Distance
            else
                stoploss = row.StopLoss; // стоп уровень заданный вручную

            ClientOrderEntity clientOrder;
            Core.OrderSendManager.CreateClientOrderEntity(row.IdFI, ordType, QuantityType.QTY, accountnumber, out message, out clientOrder, LifeTime.GTD);
            clientOrder.Quantity = Math.Abs(row.Quantity);
            if (row.Quantity > 0)
            {
                clientOrder.LimitPrice = Math.Round(RoundToNearest(row.Price - row.Slippage, row.Step), roundNums); // Slippage это "проскальзывание" цены для лимитных заявок
                clientOrder.StopPrice = Math.Round(stoploss, roundNums);
                clientOrder.LimitLevelAlternative = Math.Round(RoundToNearest(stoploss - row.Slippage, row.Step), roundNums);
                clientOrder.BuySell = OrderDirection.Sell;
            }
            else
            {
                clientOrder.LimitPrice = Math.Round(RoundToNearest(row.Price + row.Slippage, row.Step), roundNums);
                clientOrder.StopPrice = Math.Round(stoploss, roundNums);
                clientOrder.LimitLevelAlternative = Math.Round(RoundToNearest(stoploss + row.Slippage, row.Step), roundNums);
                clientOrder.BuySell = OrderDirection.Buy;
            }
            clientOrder.IdPriceControlType = PriceControlType.LAST;
            clientOrder.ClientOrderNum = OrderSendManager.ClientOrderNum;

            var wdTime = "31.12.2020"; // время окончания
            clientOrder.WithDrawTime = DateTime.ParseExact(wdTime, "dd.MM.yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo);
            string str;
            if (debug)
            {
                str = MakeOrderText(clientOrder);
            }
            else
            {
                str = Core.OrderSendManager.SendOrder(clientOrder, true);
            }
            return str;
        }


Еще я "дефолтную обработку пакетов" не выключал, иначе ключ не грузится.

ifinch
Сообщения: 14
Зарегистрирован: 14 янв 2021, 14:47
Благодарил (а): 1 раз
Поблагодарили: 1 раз

Re: AdirConnector

Непрочитанное сообщение ifinch » 20 авг 2021, 11:35

Есть коннектор при попытке подключиться через который выдается следующая ошибка. Естьли мысли в чем дело? (NetProtocol.dll на месте)

System.TypeInitializationException: The type initializer for '#=zNSJwfNMcvXHlIMoaOLnUnyd_bnZbb4le_Q==' threw an exception.
---> System.TypeInitializationException: The type initializer for 'AD.Common.Helpers.Packer' threw an exception.
---> System.IO.FileNotFoundException: Could not load file or assembly 'NetProtocol, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'NetProtocol, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null'
at AD.Common.Helpers.Packer..cctor()
--- End of inner exception stack trace ---
at AD.Common.Helpers.Packer.Initialize()
at #=zNSJwfNMcvXHlIMoaOLnUnyd_bnZbb4le_Q==..cctor()
--- End of inner exception stack trace ---
at #=zNSJwfNMcvXHlIMoaOLnUnyd_bnZbb4le_Q==..ctor(AlfaDirectMessageAdapter #=zG6JT1Uo=)
at StockSharp.AlfaDirect.AlfaDirectMessageAdapter.OnSendInMessage(Message message)
at StockSharp.Messages.MessageAdapter.SendInMessage(Message message)

ensh
Сообщения: 220
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 40 раз

Re: AdirConnector

Непрочитанное сообщение ensh » 20 авг 2021, 11:54

Нужно правильно определить ссылку на NetProtocol, бывшую dll-ку NetProtocol.dll переименовали в ADir.NetProtocol.dll

ifinch
Сообщения: 14
Зарегистрирован: 14 янв 2021, 14:47
Благодарил (а): 1 раз
Поблагодарили: 1 раз

Re: AdirConnector

Непрочитанное сообщение ifinch » 21 авг 2021, 16:45

Если разобрать длл коннектора, то там ссылки только на

// ADClientSDK, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null
// BaseStructures, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null
// ClientStructures, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null

из стека в первом посте видно вызов

at AD.Common.Helpers.Packer..cctor()
--- End of inner exception stack trace ---
at AD.Common.Helpers.Packer.Initialize()

который определен в BaseStructures.dll где уже и есть ссылка на
// DataCollections, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null
// mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// NetProtocol, Version=4.0.1900.1900, Culture=neutral, PublicKeyToken=null

может ссылка в base неправильно определена?

ensh
Сообщения: 220
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 40 раз

Re: AdirConnector

Непрочитанное сообщение ensh » 21 авг 2021, 21:42

Да, эти ссылки надо обновить, на ADir* а там внутри этих dll поднимается уже NetProtocol

ensh
Сообщения: 220
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 40 раз

Re: AdirConnector

Непрочитанное сообщение ensh » 21 авг 2021, 21:46

Вобще, никто не мешает пользоваться старой версией терминала и взять dll-ки из нее

или актуализировать проект ====>

sol.PNG
sol.PNG (10.98 КБ) 22448 просмотров

ifinch
Сообщения: 14
Зарегистрирован: 14 янв 2021, 14:47
Благодарил (а): 1 раз
Поблагодарили: 1 раз

Re: AdirConnector

Непрочитанное сообщение ifinch » 22 авг 2021, 00:40

Проект не мой, мало что там могу сделать. Эта дллка идет как есть и ссылается на 4.0.1900.1900 версии Альфы. И вот все падает на Netprotocol, которой не было изначально в дистр бутиве, но добавление в папку с проектом ее ничего не решает. :? вот пытаюсь понять как это можно решить каким-либо способом.


Вернуться в «Клиентский API»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 7 гостей