Блог им. 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

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

2153sved

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

Бабёр-Енот

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