Open iflash5 opened 5 years ago
я понимаю что все очень заняты и стараюсь вообще вопросов не задавать. , но через тест на луа я выяснил что ошибка получается из-за присутствия дробной части, если ее убрать то ошибка уходит. Вопрос как сделать это с помощью данной библиотеки?
п.с. прочитал все закрытые задачи.
пробовал расширить не сильно помогло.
public async Task<long> CreateStopOrder(StopOrder stopOrder)
{
Transaction newStopOrderTransaction = new Transaction
{
........
STOPPRICE2 = stopOrder.ConditionPrice2,
};
private StopOrderKind ConvertStopOrderType(StopOrderType stopOrderType)
{
switch (stopOrderType)
{
case StopOrderType.StopLimit:
return StopOrderKind.SIMPLE_STOP_ORDER;
case StopOrderType.TakeProfit:
return StopOrderKind.TAKE_PROFIT_STOP_ORDER;
case StopOrderType.StopLimitAndTakeProfit:
return StopOrderKind.TAKE_PROFIT_AND_STOP_LIMIT_ORDER;
default:
throw new Exception("Not implemented stop order type: " + stopOrderType);
}
}
вы только скажите что этого нет или это баг и я попробую сделать коммит....
В крайнем случае ПОЖАЛУЙСТА напишите, что просто игнорите чтобы понимать что вас не ждать.
Начнем с того, что сюда вообще редко кто заглядывает, если не возникает проблем. Я хоть и подписан на оповещения, но тоже не всегда могу оперативно отреагировать.
Базовой функцией, для отправки заявок, в QLua является SendTransaction. В библиотеке также. От этого и отталкивайтесь. Все дополнительные функции типа "CreateStopOrder" или "CreateOrder" - это все надстройки над базовой функцией, созданные для упрощения процесса в СТАНДАРТНЫХ ситуациях. Когда появляются специфические запросы, то решать их нужно через базовый функционал самостоятельно.
Теперь по порядку Ваших вопросов:
Когда-то давно я начинал использовать StopLoss и TakeProfit заявки. Были написаны отдельные функции для выставления этих заявок, и они работали. Функции были основаны на SendTransaction. Позже я отказался от использования таких заявок в пользу обычных лимитированных. Думал найду эти функции, но оказалось, что я их полностью вырезал из кода, и выглядит это теперь так:
public async Task SetNewStopOrder()
{
await Task.Delay(1);
}
:) так что поделиться не получится. Единственное, что могу посоветовать, это внимательно изучить код функций в свободно распространяемой библиотеке QL.lua. В свое время я оттуда много полезного почерпнул.
Рискну предположить (хотя могу и ошибаться), что ошибка появляется из-за региональных настроек на Вашем компе. Чаще всего это связано с используемым в системе символом разделения дробной части ("." или ","). Заметьте, что Вы единственный, у кого возникает данная проблема. Это должно было натолкнуть Вас на соответствующие мысли. Обратите внимание на строчку:
readonly Char separator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
В демо-приложении, а также где и как используется эта переменная. Возможно, это натолкнет Вас на какие-то мысли.
З.Ы.: Т.к. разработчики квика весьма странные товарищи в некоторых вопросах, то при изучении функционала какой-либо функции, не забывайте обращать внимание на то в каком формате происходит обмен данными. Например, нередко, там, где мы передаем число, разработчики квика организовали этот процесс через передачу данных в текстовом формате, ну и т.п.
@Pr0phet1c
огромнейшее спасибо что ответили!
Насчет моей ошибки: Дело оказалось не системных настройках. есть графики у которых нет дробной части и шаг целый в этом проблема для библиотеки. решил, но в библиотеке она осталась. (может кину коммит чуть позже. не уверен что примут т.к. по сути это обработка ошибок qLua и данных с quik) decimal "123.000" или "123,000" вызовет ошибку, нужно кидать "123"
"QLua ,SendTransaction, QL.lua" спасибо за детальный ответ и направления! думаю мне это очень поможет.
То, что Вы называете проблемой библиотеки, на самом деле таковой не является. Еще раз повторюсь: Изначальная задача библиотеки - повторить функционал QLua. Я почти уверен, что если вы попытаетесь подсунуть дробную часть цены, там где ее не должно быть, при формировании заявки непосредственно в QLua, то столкнетесь с той же проблемой. Но Вы же не станете писать разработчикам Квика о том, что у них ошибка...
Я призываю Вас внимательно изучить код демонстрационных приложений. Думаете следующее сочетание строчек:
decimal priceInOrder = Math.Round(tool.LastPrice + tool.Step * 5, tool.PriceAccuracy);
long transactionID = (await _quik.Orders.SendLimitOrder(tool.ClassCode, tool.SecurityCode, tool.AccountID, Operation.Buy, priceInOrder, 1).ConfigureAwait(false)).TransID;
просто так написано? Обнаруживая, что-то, что Вам кажется проблемой или ошибкой, в первую очередь задайтесь вопросом: Если это повсеместно используемая функция, то почему уже достаточно длительное время, никто не шлет коммиты на эту тему? Может быть это и не проблема вовсе, а давно решенная кем-то задачка?
Я специально написал демонстрационные приложения, в том числе рабочего робота, чтобы новые пользователи библиотеки в первую очередь осознали, что полноценный робот на этой библиотеке УЖЕ построен и полностью работоспособен. И если у Вас не получается сделать своего робота, то скорее всего Вы сами делаете что-то не так.
@Pr0phet1c
То, что Вы называете проблемой библиотеки, на самом деле таковой не является. Еще раз повторюсь: Изначальная задача библиотеки - повторить функционал QLua.
да я все больше это осознаю в т.ч. благодаря вам! за это спасибо.
Я почти уверен, что если вы попытаетесь подсунуть дробную часть цены, там где ее не должно быть, при формировании заявки непосредственно в QLua, то столкнетесь с той же проблемой. Но Вы же не станете писать разработчикам Квика о том, что у них ошибка...
Попробуйте посмотреть на ситуацию с точки зрения человека который первый раз видит библиотеку и хочет ее использовать. впервые сталкиваюсь с ситуацией когда decimal 123.000 != decimal 123 что делать если не могу найти ответ на свой вопрос? может faq поможет? там нет такой проблемы может были такие проблемы у кого-то и посмотреть в список закрытых багов - там тоже не нашел. (кстати только там приходит осознание что основная функция sendTransaction, а не набор вспомогательных) отладка - да, но упираемся в exception со стороны qlua => проблема там и копаем в qlua изучить демки(классно что они есть кстати!) - тоже хорошая идея и я это сделал тремя проходами. но во-первых найти 1 строчку в 1000 строк кода не всегда очевидно особенно когда не понимаешь что искать и вместо стопов и профитов используются обычные заявки (как я это увидел + еще куча вопросов вида как решается проскальзование и т.д.), а во-вторых робот бывает просто вылетает т.к. конфликтуют потоки да конечно же первая мысль попробовать поправить хоть как-то и пишется
void AddLog(TextBox _tb, string _text)
{
try
{
_tb.Text = _text + _tb.Text;
//_tb.SelectionStart = _tb.TextLength;
//_tb.SelectionLength = 0;
//_tb.Select(_tb.Text.Length-3,2);
}
catch (Exception ex)
{
var t = ex;
}
return;
if (_tb.InvokeRequired)
{
var d = new TextBoxTextDelegate(AddLog);
_tb.Invoke(d, _tb, _text);
//_tb.BeginInvoke(new Action(() => { _tb.Text = _text; }));
}
else _tb.Text = _text;
}
}
но и тогда не все так гладко ему не хватает данных и мы видим (картинку)
для любых других библиотек можно загуглить, а тут как?
и по-моему задавать вопросы это норм.. было бы здорово если был может какой-то форум..
Я призываю Вас внимательно изучить код демонстрационных приложений. Думаете следующее сочетание строчек:
decimal priceInOrder = Math.Round(tool.LastPrice + tool.Step * 5, tool.PriceAccuracy); long transactionID = (await _quik.Orders.SendLimitOrder(tool.ClassCode, tool.SecurityCode, tool.AccountID, Operation.Buy, priceInOrder, 1).ConfigureAwait(false)).TransID;
просто так написано?
это замечательное решение в пределах обозначенной задачи и спасиб за него! найти его не так очевидно, я видел эти строки, но они воспринимаются скорее как вы используете их для каких-то своих целей (возможно так требует алгоритм) делаете округление... без пояснения не совсем очевидно что они решают проблему.
И если у Вас не получается сделать своего робота, то скорее всего Вы сами делаете что-то не так.
моя задача была тривиальнее: помимо осуществления сделки по рыночной заявке выставить стоп и тейк настоящие со всеми параметрами. Может быть я не увидел где-то в комментариях или в коде или в faq
если это место есть и вы укажите на него был бы благодарен.
void ClosePosition(decimal price)
{
if (settings.RobotMode == "Боевой")
{
if (position.toolQty > 0) position.closingOrderID = NewOrder(_quik, tool, Operation.Sell, price, Math.Abs(position.toolQty / tool.Lot));
else if (position.toolQty < 0) position.closingOrderID = NewOrder(_quik, tool, Operation.Buy, price, Math.Abs(position.toolQty / tool.Lot));
long NewOrder(Quik _quik, Tool _tool, Operation operation, decimal price, int qty)
{
long res = 0;
if (settings.RobotMode == "Боевой")
{
Order order_new = new Order();
order_new.ClassCode = _tool.ClassCode;
order_new.SecCode = _tool.SecurityCode;
order_new.Operation = operation;
order_new.Price = price;
order_new.Quantity = qty;
order_new.Account = _tool.AccountID;
try
{
res = _quik.Orders.CreateOrder(order_new).Result;
}
catch
{
Console.WriteLine("Неудачная попытка отправки заявки");
}
}
else
с одной стороны new Order который из Order.cs с другой стороны Operation которая из StopOrder что очень сильно смущает, а если поискать по слову Profit то вообще ничего нет с этой операцией. Хотя скорее всего profit получается здесь обычной операцией
void ClosePosition(decimal price)
{
if (settings.RobotMode == "Боевой")
{
if (position.toolQty > 0) position.closingOrderID = NewOrder(_quik, tool, Operation.Sell, price, Math.Abs(position.toolQty / tool.Lot));
else if (position.toolQty < 0) position.closingOrderID = NewOrder(_quik, tool, Operation.Buy, price, Math.Abs(position.toolQty / tool.Lot));
AddLog(textBoxLogs, "ID заявки - " + position.closingOrderID + Environment.NewLine);
}
else
{
decimal profit;
if (position.toolQty > 0) // для логовых позиций
{
profit = Math.Round((price * Math.Abs(position.toolQty / tool.Lot) * tool.Lot - position.priceEntrance * Math.Abs(position.toolQty / tool.Lot) * tool.Lot) / tool.Step * tool.PriceStep, tool.PriceAccuracy);
}
else // для шортовых позиций
{
profit = Math.Round((position.priceEntrance * Math.Abs(position.toolQty / tool.Lot) * tool.Lot - price * Math.Abs(position.toolQty / tool.Lot) * tool.Lot) / tool.Step * tool.PriceStep, tool.PriceAccuracy);
}
summProfit = summProfit + profit;
position.toolQty = 0;
position.priceEntrance = 0;
position.stopLoss = 0;
directionPosition = "-";
textBoxPositionDirection.Text = "-";
textBoxPositionPE.Text = "";
textBoxPositionQty.Text = "";
ClosePos2Table(DateTime.Now, price, profit, summProfit);
closePause = false;
}
}
вполне возможно я как-то не так воспринимаю сами сделки. для меня это операция с параметрами. И в зависимости от параметров имеется разное поведение, например:
Как итог хотелось бы по возможности большей документированности в любом виде чтобы всем было проще использовать.
Меня радует что вы не послали меня в код - "сам дурак, копай там все есть"
спасибо вам за пояснения и пример кода. Однозначно буду использовать.
Не ждите бОльшей документированности. Это не платный проект, где Вы за свои деньги получаете техническую поддержку. Еще раз: Задача библиотеки - повторить функционал QLua. Эта задача выполнена (где-то на 99% наверное). На этом все. Хотите получить понимание - напишите полноценного робота на QLua. После того как справитесь с этой задачей, к тому как написать робота на C#, с использованием библиотеки, вопросов скорее всего уже не останется.
З.Ы.: Некоторые из функций и классов, которые Вы можете наблюдать в демо-приложениях, я выдирал из своих личных библиотек и роботов (в ряде случаев, упрощая их). Моя задача была продемонстрировать наглядное доказательство работоспособности библиотеки, и на мой взгляд, с этой задачей я справился. Объяснять и/или доказывать почему и для чего я выполнил ту или иную реализацию отдельных частей кода я не планировал и не планирую.
З.З.Ы: Ну и для справки - я вообще ни разу не программист. Однако, получилось и собственноручно роботов написать и даже помочь в развитии данной библиотеки. Было бы желание...
Может это поможет. На срочном рынке, есть только лимитные ордера. Других алгоритм сведения сделок на бирже не понимает. Все SL и ТП реализованы на базе этого ордера программным обеспечением. Ударить по рынку, это тоже лимитный ордер с ценой исполнения на планке дня. Надо как то реализовать функцию OCO (один ордер отменяет другой для ТП и CЛ). Биржа за нас это делать не будет, нужно самим это программировать. Надеюсь помог
@iflash5 не уверен, что актуально: стоп-заявки с StopOrderType.TakeProfit сейчас в библиотеке не реализовано, т.к. нет соответствующих полей в StopOrder и использования в CreateStopOrder параметров OFFSET, OFFSET_UNITS, SPREAD, SPREAD_UNITS, MARKET_STOP_LIMIT, MARKET_TAKE_PROFIT и т.д. в Transaction. Сейчас пытаюсь это все реализовать на локальной копии.
@iflash5 добавлена поддержка стоп-заявок с типом "Тейк-профит стоп-лимит".
Доброго времени суток.
на луа можно так
Подскажите как это сделать с использованием данной библиотеки?
Ребят, если у кого-то есть рабочий пример хотя бы последовательного выставления таких заявок поделитесь пожалуйста.
при этом как бы не выставлял цены ниже, выше....