Клиентский 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;
        }


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


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

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

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