Блог им. turbo_pascal

Судак-Тудак (робот)

Алгоритм данной торговли был описан уважаемым Гном  (https://smart-lab.ru/blog/499606.php) и, поскольку я являюсь любителем различных теорий Мартингейла и усреднения, написал робота по этой стратегии.

Подробно на алгоритме останавливаться не буду — читайте по ссылке у Гнома, там очень хорошо всё расписано.

Здесь — немного измененная реализация. Отличие в том, что позиции открываются не через равные промежутки цены, а чуть шире: еще должно прийти хотя бы минимальное подтверждение, что дальше не полетит (в данном случае использован вход обратно в канал Боллинджера, но это несложно поменять на что угодно).

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

Итак, представляю: «Судак-Тудак» Универсальный (одновременно для акций и фьючерсов).

Судак-Тудак (робот)

Если хотите добавить инструменты (а они добавляются в массив aTickerList), не забудьте вписать их данные в массивы:

* aLotSize — кол-во лотов на сделку. Обычно 1 (помните, что в акциях — кол-во акций в лоте у каждого свой. Так что лучше просто оставьте 1).
* aProskalzivanie — для сделки. Примерно пол-процента от цены.
* aAccountCode — могут отличаться для фьючерсов и акций.
* aClassCode — TQBR для фьючерсов, SPBFUT — для акций.

ВНИМАНИЕ! Для каждого инструмента должен быть открытый график с ценой и болосой Боллиинджера.

Идентификатор цены: имя тикера + "_Price_Sudak".
Идентификатор Боллинджера: имя тикера + "_BB_Sudak".
Без прописывания идентификаторов работать не будет (CreateDataSource я не использую и не хочу, пусть данные цены и индикаторов считаются на графике, а я оттуда заберу готовое).

Алгоритм (работает по каждому инструменту из перечисленных в aTickerList).

Если Цена снизилась от предыдущей покупки на покупку более чем на StepSize,
и при этом мы вошли снизу внутрь Боллинджера, то Докупка aLotSize.
Наоборот — сброс aLotSize.
aStepSize не играет роли в сильном боковике — мы продаем и покупаем при каждом касании краев Боллинджера (но не менее чем aFlatSize).
aStepSize нужен только для растягивания усреднения докупки и растягивании усреднения сдачи.
Параметры последней следки: направление, цена последней сделки, и объем позиции — хранятся в файликах.
Имя Тикера + "_LastPrice" — цена последней сделки.
Имя Тикера + "_LastDirection" — направление последней сделки.
Имя Тикера + "_Volume" — текущий объем позиции.
Робот выставляет сделки по рынку и НЕ проверяет OnOrder и OnTrade, поэтому в файлик "_LastPrice" может быть записана чуть неточная цена (с учетом проскальзывания).
Файлики можно править вручную (хотя нужно ли).
Только в лонг. Если условия выполняются, но продавать нечего (_Volume = 0) — не продаем.

Судак-Тудак (робот)

Более подробно об остальных параметрах — в самом скрипте. Комментариев там более чем достаточно.

Как сделать так, чтобы данный робот не сливал от слова совсем? Правильно: не суйте туда много с самого начала. Это инвестиционный робот, он не предназначен для ежедневной прибыли. Он предназначен для пощипывания рынка при практически любом движении, в расчете на то, что если случится вселенский песец, мы уже отработали бы и вывели все что надо.

Если все таки ожидаете роста актива, купите стартовый лот сами, сколько хотите. Пропишите только вручную в файлы _LastPrice и _Volume цену покупки и объем (в лотах, а не в штуках), и ждите роста, подсекая колебания в свою пользу.

Стопов тут нет, используется усреднение (и это основной механизм). Перед тем, как запускать его по отдельному инструменту, необходимо расчитать, на сколько данный инструмент может упасть вниз и что мы при этом будем делать.

Например, сейчас Газпром торгуется по 160 рублей. Выставляем StepSize = 2 рубля и начинаем с одного лота. Итого, мы можем открыть 80 лотов со средней ценой 80 рублей, даже если цена упадет до нуля. У нас уйдет на это меньше 70 тысяч рублей (в реальности намного меньше, т.к. открываем мы сделки не через 2 рубля, а шире).
Теперь остается посчитать, каковы шансы Газпрому стоить ноль, и шансы, что он опять будет 10 лет болтаться в боковике, наращивая нам прибыль, а мы будем стричь дивиденды на всю открытую позицию, и покупать-продавать на каждом чихе.

Скрипт ниже.

Всем кто будет пользоваться: будут лезть ошибки — пишите.

Уважаемым алготрейдерам: если предложите оптимизацию кода и логики, буду благодарен (по программированию на qlua я пока не большой спец), поправлю и выложу новую версию.

p.s.
Ничего не продаю, семинаров не веду, каналов нет, в ДУ не беру.

-- Судак-Тудак Универсальный (для акций и фьючерсов). Версия 0.17
-- "Turbo Pascal" © 2019. Это ник такой. Текст на Луа.

-- Если хотите добавить инструменты (а они добавляются в массив aTickerList), не забудьте вписать их данные в массивы
-- * aLotSize - кол-во лотов на сделку. Обычно 1 (помните, что в акциях - кол-во акций в лоте у каждого свой. Так что лучше просто оставьте 1).
-- * aProskalzivanie - для сделки. Примерно пол-процента от цены.
-- * aAccountCode - могут отличаться для фьючерсов и акций.
-- * aClassCode - TQBR для фьючерсов, SPBFUT - для акций.
-- ВНИМАНИЕ! Для каждого инструмента должен быть открытый график с ценой и болосой Боллиинджера.
-- Идентификатор цены: имя тикера + "_Price_Sudak".
-- Идентификатор Боллинджера: имя тикера + "_BB_Sudak".
-- Без прописывания идентификаторов работать не будет.

-- Алгоритм (работает по каждому инструменту из перечисленных в aTickerList).
-- Если Цена снизилась от предыдущей покупки на покупку более чем на StepSize,
-- и при этом мы вошли снизу внутрь Боллинджера, то Докупка aLotSize.
-- Наоборот - сброс aLotSize.
-- aStepSize не играет роли в сильном боковике - мы продаем и покупаем при каждом касании краев Боллинджера.
-- Минимальный диапазон "купи-продай" - aFlatSize.
-- aStepSize нужен только для растягивания усреднения докупки и растягивании усреднения сдачи.
-- Параметры последней следки: направление, цена последней сделки, и объем позиции - хранятся в файликах.
-- Имя Тикера + "_LastPrice" - цена последней сделки.
-- Имя Тикера + "_LastDirection" - направление последней сделки.
-- Имя Тикера + "_Volume" - текущий объем позиции.
-- Робот выставляет сделки по рынку, поэтому в файлик "_LastPrice" может быть записана
-- чуть неточная цена (с учетом проскальзывания).
-- Файлики можно править вручную (хотя нужно ли).
-- Только в лонг. Если условия выполняются, но продавать нечего - не продаем.

-- По расчетам: Если докупать Сбер(ао) с цены 250, то чтобы набрать позу 50 лотов, упав до 150, достаточно капитала в 100т.р.
-- Газпром упадет с 160 до 60 - для удержания достаточно 50т.р.
-- На "рехеджах" (каждая пара бай-селл) еще и заработать можно. Дивы - тоже в нашу пользу.

-- ************************ СЕКЦИЯ ОБЩИХ ПАРАМЕТРОВ ****************************
CLIENT_CODE = "сюдой пиши своё" -- общий код для акций и фьючерсов.
LogFileName = "c:\\Log\\sudaktudak_log.txt" -- Технический лог.
ParamPath = "c:\\SudakTudak\\" -- здесь хранятся файлики с параметрами. Три файла на каждый инструкмент.
SdelkaLog = "c:\\Log\\sudaktudak_sdelki.txt" -- Лог сделок. Сюда пишутся ТОЛЬКО сделки.
SleepDuration = 10; -- отдыхаем 10 секунд. Слишком часто не надо молотить.
DemoMode = false -- Включите, чтобы начать "боевые" сделки. Если = false, сделок не будет, просто запишет в лог.

-- ************************ СЕКЦИЯ МАССИВОВ ДЛЯ ИНСТРУМЕНТОВ ************************
aTickerList = {"SBER", "GZM9"}; -- сюда массив инструментов. Не забывайте перекладывать фьючерсы!!!
-- А при перекладывании фьючерсов не забывайте менять код как здесь, так и в следующих массивах.

-- Следующие массивы должны иметь значения для каждого инструмента из aTickerList
aClassCode = {SBER="TQBR", GZM9="SPBFUT"} -- TQBR для акций, SPBFUT для фьючерсов.
aAccountCode = {SBER="сюды своё", GAZP="сюды своё", GZM9="сюды своё"} -- может отличаться для акций и фьючерсов.
aLotSize = {SBER=1, GAZP=1, GZM9=1}; -- Массив лотов для покупки.
aStepSize = {SBER=2, GAZP=2, GZM9=200}; -- Шаг Цены.
aFlatSize = {SBER=0.5, GAZP=0.5, GZM9=50}; -- Шаг Цены.
aProskalzivanie = {SBER=1,GAZP=1, GZM9=100}; -- Проскальзывание при сделке.

is_run=true

function main()
	while is_run do
		for k,v in pairs(aTickerList) do
			Obrabotka(v,k);
		end;
		sleep(SleepDuration*1000) -- Отдыхаем SleepDuration секунд.
	end
end

function GetLastPrice(TickerName, CandleType)
	-- Берем цену из графика. CreateDataSource пока не используем, т.к. при необходимости модификации
	-- алгоритма, хотим легко добавлять индикаторы.
	-- Плюс меньше зависим от коннекта - графики всегда с нами.
	local NL=getNumCandles(TickerName.."_Price_Sudak")
	tL, nL, lL = getCandlesByIndex (TickerName.."_Price_Sudak", 0, NL-1, 1) -- last свеча
	local aCurrentPrice=tL[0].close -- получили текущую цену (ЦПС)
	if CandleType=="OPEN" then aCurrentPrice=tL[0].open end;
	if CandleType=="HIGH" then aCurrentPrice=tL[0].high end;
	if CandleType=="LOW" then aCurrentPrice=tL[0].low end;
	return aCurrentPrice
end

function GetBollinger(TickerName, LineCode)
	-- получаем текущие значения Боллинлжера.
	-- LineCode может иметь значения: "High", "Middle", "Low"
	local NbbL=getNumCandles(TickerName.."_BB_Sudak")
	tbbL, nbbL, lbbL = getCandlesByIndex (TickerName.."_BB_Sudak", 0, NbbL-1, 1)  -- last свеча, средняя линия Боллинджера
	iBB_Local_Middle = tbbL[0].close -- тек значение средней BB Local
	tbbL, nbbL, lbbL = getCandlesByIndex (TickerName.."_BB_Sudak", 1, NbbL-1, 1)  -- last свеча, верхняя линия Боллинджера
	iBB_Local_High = tbbL[0].close -- тек значение верхней BB Local
	tbbL, nbbL, lbbL = getCandlesByIndex (TickerName.."_BB_Sudak", 2, NbbL-1, 1)  -- last свеча, нижняя линия Боллинджера
	iBB_Local_Low = tbbL[0].close -- тек значение нижней BB Local
	if LineCode == "High" then return iBB_Local_High end
	if LineCode == "Middle" then return iBB_Local_Middle end
	if LineCode == "Low" then return iBB_Local_Low end
end

function PriceCrossMAToUp(TickerName)
	-- Функция возвращает TRUE, если пересекли среднюю линию Боллинджера снизу вверх
	if GetLastPrice(TickerName, "OPEN")<GetBollinger(TickerName, "Middle")
		and GetLastPrice(TickerName, "LAST")>GetBollinger(TickerName, "Middle")
	then return true
	else return false
	end;
end

function PriceCrossMAToDown(TickerName)
	-- Функция возвращает TRUE, если пересекли среднюю линию Боллинджера снизу вверх
	if GetLastPrice(TickerName, "OPEN")>GetBollinger(TickerName, "Middle")
		and GetLastPrice(TickerName, "LAST")<GetBollinger(TickerName, "Middle")
	then return true
	else return false
	end;
end

function PriceEnterToBollingerFromDown(TickerName)
	-- Функция возвращает TRUE, если пересекли нижнюю линию Боллинджера снизу вверх
	-- (то есть вошли внутрь канала Боллинджера снизу).
	if GetLastPrice(TickerName, "LOW")<GetBollinger(TickerName, "Low")
		and GetLastPrice(TickerName, "LAST")>GetBollinger(TickerName, "Low")
	then return true
	else return false
	end;
end

function PriceEnterToBollingerFromUp(TickerName)
	-- Функция возвращает TRUE, если пересекли верхнюю линию Боллинджера сверху вниз
	-- (то есть вошли внутрь канала Боллинджера сверху).
	if GetLastPrice(TickerName, "HIGH")>GetBollinger(TickerName, "High")
		and GetLastPrice(TickerName, "LAST")<GetBollinger(TickerName, "High")
	then return true
	else return false
	end;
end

--Функция Обработки отдельного тикера
function Obrabotka(sTickerName, sNum)
	-- Теперь откываем файлы с нашим тикетом, и читаем оттуда значения: LastPrice, LastDirection, Объем Позы.
	LastPrice = tonumber(GetValueFromFile(ParamPath..sTickerName.."_LastPrice.txt"));
	LastDirection = GetValueFromFile(ParamPath..sTickerName.."_LastDirection.txt");
	iVolume = tonumber(GetValueFromFile(ParamPath..sTickerName.."_Volume.txt"));
	local CurrentPrice=GetLastPrice(sTickerName) -- вытаскиваем из графика текущую цену.
	-- Логируем текущую и последнюю цены и разницу между ними.
	WLOG(sTickerName.. " Current="..CurrentPrice.. " Last="..LastPrice.." Razn = "..(CurrentPrice-LastPrice).. " StepSize = "..aStepSize[sTickerName].." Vol="..iVolume.." LastDir="..LastDirection);
	
	-- Теперь проверяем, не надо ли докупиться?
	if (((CurrentPrice<LastPrice-aStepSize[sTickerName]) or (CurrentPrice<LastPrice-aFlatSize[sTickerName] and LastDirection=="S")) or (iVolume==0)) and PriceEnterToBollingerFromDown(sTickerName) then
		-- Подсекаем или Начинаем
		WLOG("Podsekaem or Nachinaem");
		if (DoFire(sTickerName, "B", CurrentPrice) == "") then
			iVolume = tonumber(iVolume)+aLotSize[sTickerName];
			SetValueToFile(ParamPath..sTickerName.."_LastPrice.txt", CurrentPrice)
			SetValueToFile(ParamPath..sTickerName.."_LastDirection.txt", "B")
			SetValueToFile(ParamPath..sTickerName.."_Volume.txt", tostring(iVolume))
			LastPrice = CurrentPrice; -- чтобы не продать сразу на следующем условии.
		end
	end
	
	-- Теперь проверяем, не надо ли немного сбросить?
	if ((CurrentPrice>LastPrice+aStepSize[sTickerName]) or (CurrentPrice>LastPrice+aFlatSize[sTickerName] and LastDirection=="B")) and PriceEnterToBollingerFromUp(sTickerName) and (iVolume>0) then
		-- Сдаем
		WLOG("Sdaem");
		if (DoFire(sTickerName, "S", CurrentPrice) == "") then
			iVolume = tonumber(iVolume)-aLotSize[sTickerName];
			SetValueToFile(ParamPath..sTickerName.."_LastPrice.txt", CurrentPrice)
			SetValueToFile(ParamPath..sTickerName.."_LastDirection.txt", "S")
			SetValueToFile(ParamPath..sTickerName.."_Volume.txt", tostring(iVolume))
		end
	end
end;

function DoFire(SEC_CODE, p_dir, p_price) -- Функция - СДЕЛКА ПО РЫНКУ!
	if p_dir == "B" then AAA = 1 else AAA = -1 end
	t = {
			["CLASSCODE"]=aClassCode[SEC_CODE],
			["SECCODE"]=SEC_CODE,
			["ACTION"]="NEW_ORDER", -- новая сделка.
			["ACCOUNT"]=aAccountCode[SEC_CODE],
			["CLIENT_CODE"]=CLIENT_CODE,
			["TYPE"]="L", -- "M" "L". По M давал ошибку на TQBR.
			["OPERATION"]=p_dir, -- направление сделки, "B" или "S"
			["QUANTITY"]=tostring(aLotSize[SEC_CODE]), -- объем, (акции - в лотах, а не штуках).
			["PRICE"]=tostring(p_price+(aProskalzivanie[SEC_CODE]*AAA)), -- цену лимитки ставим для мгновенного исполнения.
			["TRANS_ID"]="1"
		}
	
	if DemoMode==false then -- Если всё по серьезному, то ...
		res1 = sendTransaction(t) -- ... передаем сделку по рынку.
	end
	
	if (res1~="") then -- Ошибочка вышла. Логируем ошибку.
		WLOG("SendTransaction Error = "..res1);
	end
	
	local l_file1=io.open(SdelkaLog, "a")
	l_file1:write(os.date()..";SECCODE="..SEC_CODE..";PRICE="..p_price..";DIR="..p_dir.."\n")
	l_file1:close()
		
	return res1
end

function GetValueFromFile(FileName) -- Читаем параметр из файла.
	local f = io.open(FileName, "r");
	if f == nil then -- если файла нет, но создаем пустой.
		f = io.open(FileName,"w");
		DefaultValueForFile = "0" -- по умолчанию пишем нуль.
		-- Для LastDirection надо бы писать не нуль, а "B", но пусть будет нуль, т.к.
		-- этого условия достаточно для открытия начальной сделки.
		f:write(DefaultValueForFile)
		f:close();
		-- Открывает уже гарантированно существующий файл в режиме "чтения/записи"
		f = io.open(FileName, "r");
	end;
	aValue = f:read("*l")
	f:close()
	return aValue
end

function SetValueToFile(FileName, aValue) -- Пишем параметр в файл.
	local ff=io.open(FileName, "w") -- используем "w", а не "a", чтобы перезаписать существующий.
	ff:write(aValue)
	ff:close()
end

function OnStop(stop_flag)
	is_run=false
end

function WLOG(st) -- Универсальная функция записи в лог.
	local l_file=io.open(LogFileName, "a") -- используем "a", чтобы добавить новую строку.
	l_file:write(os.date().." "..st.."\n")
	l_file:close()
end

Не сливайте!
★86 | ₽ 165
avatar

2153sved

Ого! Автор заманивает свежее мясо на крипту… тьфу, то есть на фонду))
function Obrabotka(

Чувак, это что такое? Как ты мог? Какая ещё нах Obrabotka?
Vodka
Balalaika
Kalash
Putin
и внимание...

Obrabotka!
avatar

Kapeks

Kapeks, не ну а чо, зато всем понятно :)
Скрипт то для русскоязычной аудитории.
avatar

Turbo Pascal

Turbo Pascal, на каком языке написало?
avatar

Евгений

Евгений, qlua.
avatar

Turbo Pascal

Turbo Pascal, C:\SUDAK-TUDAK\SudakTudak1.lua:204: attempt to index local 'f' (a nil value) У меня вот такая ошибка. 
Что не так?
Геннадий Петров, 1) проверяйте идентификаторы на графике, у цены, и индикаторов.
2) Проверяйте, чтобы папки, указанные для логов и настроек, существовали. Файлы робот создаст сам, а папки должны быть.
avatar

Turbo Pascal

Да, идея правильная. Если есть «уровни», например, то на них мартингейлить — почти неубиваемо в плюс будет. Даже 0,6 вместо 0,5 за тебя вероятности на них — на порядок увеличивает запас глубины. Соответственно увеличивает размер первоначального входа, делая его уже не мизерным.
avatar

MS

Плюсик даже только за название Судак-Тудак можно поставить. 
avatar

Laukar

Laukar, а особенно — за это:
Ничего не продаю, семинаров не веду, каналов нет, в ДУ не беру.
avatar

Vlаdimi®



avatar

Astrolog

Turbo Pascal, красава — хоть кто-то по делу пишет!
И хотя я пока занят немного другим, без сожаления отдал весь остаток тимофейчиков, пусть и крохотный, зато от души — ибо бальзам на сердце :) 

avatar

Носорог

Turbo Pascal, при нескольких подряд докупках внизу — алгоритм высчитывает общую среднюю цену покупки и далее на расстоянии  + aStepSize и заходом цены внутрь верхнего боллинджера закрывает все накопившиеся позиции в плюс? Или закрывает по одной позиции?
avatar

YuryDok

YuryDok, нет, общая цена покупки не интересует. После того как наоткрывали «колен» вниз и пошли вверх, робот сдает не всё сразу, а по одному лоту по тем же правилам (только обратным), что и набирал. Если зависли в боковике, то просто идёт цикл «купи-продай» в рамках горизонтального канала Боллинджера.

Набор позиции и сдача оптом — хочу отдельный скрипт накидать. Но это будет уже классический безжалостный (для депозита ) усреднятор.
avatar

Turbo Pascal

Turbo Pascal, Но это будет уже классический безжалостный (для депозита ) усреднятор.< поменьше жалости, побольше цинизма… Люди это любят. О.Бендер
avatar

YuryDok

YuryDok, ну а что, идея вполне живая и вечная.
На одном форексном форуме годами всем миром пилят «иланы» и «2-side-стохастики». Народу не надоедает :)
Они, конечно, сольют, но в процессе брейншторма идей там очень много полезных генерится.
avatar

Turbo Pascal

Turbo Pascal, ну и плюс погоня за мечтой, это всегда интересно ;)
Винету Карабасович Монетка, да, я и сам там помнится пару тем делал, лет 7-8 назад, создавая алгоритмы под MT4. Сколько энтузиазма было — жуть.
avatar

Turbo Pascal

Прикольно. Надо для тслаб создать как циклы выкатят. Давно хотел. То есть я считаю сам потенциал до куда упадёт, задаю ширину уровня и лот? Он далее с этой шириной и лотом покупает пр возврате в ББ и продаёт по уровням по лоту?
avatar

Александр Элс

Можешь ещё в текстовом файле выложить бот и инструкцию ещё как тестить? А то тут редактор может символы по портить.
Александр Элс, Ничего не портит, нормально копируется.
Попозже, наверно, на гитхабе буду выкладывать.
avatar

Turbo Pascal

Александр Элс, да, циклов на тслабе сам жду. А то набор позиции в кучу цепочек рисовать — глупо.
Продает он не по уровням, а по входу в ББ сверху, но чтобы было шире чем aStepSize.
avatar

Turbo Pascal

Turbo Pascal, понял. Тестил на реале? Какой ТФ юзать не принципиально?
Александр Элс, у меня он на реале стоит. ТФ не принципиален, подбирайте под себя. У меня стоит сейчас на Сбере и Газике на 5-минутке.
avatar

Turbo Pascal

А на меня ругаются
Syntax error while compiling C:\SudakTudak\sudak.lua: C:\SudakTudak\sudak.lua:1: unexpected symbol near 'п'
avatar

Александр Элс

Александр Элс, копируйте 1-в-1 то, что выше, от первого символа до последнего. Возможно, первую строчку не всю схватили. В первой строке буквы «п» нет.
К тому же, откуда «Compiling»? Вы в чем его запускаете? К квике или в обычном Lua?

Сам скопировал, проверил, работает.
avatar

Turbo Pascal

Turbo Pascal, в квике загружаю через запуск алго файлик с расширением lua. Проверил тоже, комментарии все в порядке
monosnap.com/file/oRG1CDh2UnCEw9sVM5BuaWWpxaRceT
Александр Элс, пока не могу сказать навскидку. Ну вот файлом.
www.filedropper.com/sudaktudak1

avatar

Turbo Pascal

Turbo Pascal, всё понял, в кодировке была загвоздка. Сейчас цену не понимает. В графике прописал тикер и префикс monosnap.com/file/rQvQ2akNuradjeO29RxZPQUF3lwK4u
Александр Элс, да, в 71-й строке у меня тоже вылезало. Перепроверяйте имя в цене (НЕ в боллинджере, а именно в цене). префикс + "_Price_Sudak".
avatar

Turbo Pascal

Turbo Pascal, разобрался. Я балда не тем идентификатор в графике прописывал :) А работу только через лог файлик отслеживать можно?
Turbo Pascal, для акции Сбербанк ао тикер SBER будет? Всё проверил, не получается.
Александр Элс, какой тикер в aTickerList пропишете, такой и будет. Прописали «SBER», значит на цене должно быть «SBER_Price_Sudak».
у меня вот как раз по Сберу так и стоИт.
avatar

Turbo Pascal

Turbo Pascal, спасибо. Запустил 3 тикера. Сбер торгутся 2 дня. Почему то он после закрытия 2 лонгов встал в шорт. Это нормально? Я бы не хотел шортить ))

04/23/19 14:28:02 SBER Current=236.22 Last=236.28 Razn = -0.060000000000002 StepSize = 2 Vol=-1 LastDir=S
04/23/19 14:28:02 GAZP Current=163.19 Last=163.1 Razn = 0.090000000000003 StepSize = 1 Vol=3 LastDir=B
04/23/19 14:28:02 MTSS Current=260.75 Last=0 Razn = 260.75 StepSize = 3 Vol=0 LastDir=0

Александр Элс, теоретически он не мог встать в шорт, потому что при Vol=0 продажа не работает.
Проверяйте: был шорт (и вообще открытая позиция) до запуска?
avatar

Turbo Pascal

Turbo Pascal, по инструменту поз не было. Даже лог вон кажет же -1 сейчас, значит отображает. Я кажется допёр. Подозреваю что дело в том, что открывался я +1 изначально, потом лот увеличил до 2, и он, видимо просто закрыл +1 на -2. Надо лог стереть и позы и перезапустить щас, видимо.
Александр Элс, да, если открываетесь, а позиция уже есть, надо размер позичии и последнюю цену прописать в файлики параметров. Он сам позу не считает пока еще.
avatar

Turbo Pascal

Turbo Pascal, а ты не мог бы дописать чтобы доход по инструменту еще считался суммарный и объем входов-выходов (для подсчёта комиссии)?
Александр Элс, да, планирую дальше развивать.
avatar

Turbo Pascal

Turbo Pascal, ок, буду дальше тестировать. Пиши как будет новая версия :)
Александр Элс, тут и выложу.
avatar

Turbo Pascal

Turbo Pascal, не замечал с утра что не может цену получить и не стартует? 
Александр Элс, нет. Он же берет из графика, а не заказывает через CreateDataSource.
У меня обычно робот включается минут за 15 до начала рынка, и в первую минуту уже иногда делает сделку.
avatar

Turbo Pascal

Turbo Pascal, странно, у меня за 5 мин до старта подключается и не получает, видать, данных. На срочке бот работает постоянно без проблем. Может ему сделать отсрочку запуска до 10 01 00?
Александр Элс, нет, у меня и по срочке, и по бумагам работает одинаково и не валится. Я посмотрю, конечно. Киньте текст ошибки, плиз.
avatar

Turbo Pascal

Turbo Pascal, я сейчас перезапустил уже, он пишет что значение "?" или как то так, в цене. Я просто жму запуск и все работает.
Александр Элс, возможно, из-за медленного компа не успевает прочитать график. У меня такое встречается тоже иногда (а у меня на работе очень-очень слабый комп — планшет). Ошибка не очень стабильная, специально повторить не могу.
Но потом сутками молотит и не отваливается.
avatar

Turbo Pascal

Turbo Pascal, не накодил задержку? Другой бот не может зависать если этот не запустился?

И что можно с логом на 35 МБ делать? :)

Turbo Pascal, в комментах к коду написано:
«DemoMode = false — Включите, чтобы начать „боевые“ сделки. Если = false, сделок не будет, просто запишет в лог.»

Смотрю по коду:

if DemoMode==false then — Если всё по серьезному, то ...
res1 = sendTransaction(t) — … передаем сделку по рынку.
end

Наверное, наоборот: демо-режим — это если DemoMode= true?

avatar

podbelski

podbelski, ты раскрыл заговор :)
avatar

ПBМ

podbelski, ну да, опечатка. Можно было бы и догадаться.
avatar

Turbo Pascal

Turbo Pascal, так и догадался. Просто решил не гадать, а уточнить, т.к. lua вижу первый раз. Не думал, что это может вызвать эмоции. Прошу прощения.
avatar

podbelski

Я правильно понял идею, что первая позиция открывается / закрывается по маленькому отступу, а когда открыли 2-ю и более, то и закрывать её будем по большому? Т.е. нет такого, чтобы набрали, например, по 220, 218, 216, и начали колбаситься в боковике 217, 216, 217, 216, 215, 216.
avatar

MegaFan

C:\SudakTudak\SudakTudak1.lua:71: attempt to index field '?' (a nil value)

71 строка у меня так 
local aCurrentPrice=tL[0].close — получили текущую цену (ЦПС)

Что нужно править?
Обновлений не было?
Можно ли сделать бота на шорт ещё? Неплохая штука для хэджа портфеля акций через мини индекс.

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.

Залогиниться

Зарегистрироваться
....все тэги
UPDONW