Turbo Pascal
Turbo Pascal личный блог
18 апреля 2019, 15:32

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

Алгоритм данной торговли был описан уважаемым Гном  (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

Не сливайте!
63 Комментария
  • Niktesla (бывш. Бабёр-Енот)
    18 апреля 2019, 16:30
    Ого! Автор заманивает свежее мясо на крипту… тьфу, то есть на фонду))
  • Kapeks
    18 апреля 2019, 17:13
    function Obrabotka(

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

    Obrabotka!
      • Евгений
        19 апреля 2019, 08:04
        Turbo Pascal, на каком языке написало?
      • Геннадий
        29 апреля 2019, 22:27
        Turbo Pascal, C:\SUDAK-TUDAK\SudakTudak1.lua:204: attempt to index local 'f' (a nil value) У меня вот такая ошибка. 
        Что не так?
  • MS
    18 апреля 2019, 17:18
    Да, идея правильная. Если есть «уровни», например, то на них мартингейлить — почти неубиваемо в плюс будет. Даже 0,6 вместо 0,5 за тебя вероятности на них — на порядок увеличивает запас глубины. Соответственно увеличивает размер первоначального входа, делая его уже не мизерным.
  • Laukar
    18 апреля 2019, 17:42
    Плюсик даже только за название Судак-Тудак можно поставить. 
    • Vlаdimi®
      19 апреля 2019, 14:30
      Laukar, а особенно — за это:
      Ничего не продаю, семинаров не веду, каналов нет, в ДУ не беру.
  • Astrolog
    18 апреля 2019, 17:52


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

  • YuryDok
    18 апреля 2019, 22:50
    Turbo Pascal, при нескольких подряд докупках внизу — алгоритм высчитывает общую среднюю цену покупки и далее на расстоянии  + aStepSize и заходом цены внутрь верхнего боллинджера закрывает все накопившиеся позиции в плюс? Или закрывает по одной позиции?
  • YuryDok
    19 апреля 2019, 08:29
    Turbo Pascal, Но это будет уже классический безжалостный (для депозита ) усреднятор.< поменьше жалости, побольше цинизма… Люди это любят. О.Бендер
      • Turbo Pascal, ну и плюс погоня за мечтой, это всегда интересно ;)
  • Александр Элс
    19 апреля 2019, 13:06
    Прикольно. Надо для тслаб создать как циклы выкатят. Давно хотел. То есть я считаю сам потенциал до куда упадёт, задаю ширину уровня и лот? Он далее с этой шириной и лотом покупает пр возврате в ББ и продаёт по уровням по лоту?
    • Александр Элс
      19 апреля 2019, 13:06
      Можешь ещё в текстовом файле выложить бот и инструкцию ещё как тестить? А то тут редактор может символы по портить.
      • Александр Элс
        19 апреля 2019, 18:26
        Turbo Pascal, понял. Тестил на реале? Какой ТФ юзать не принципиально?
  • Александр Элс
    19 апреля 2019, 18:49
    А на меня ругаются
    Syntax error while compiling C:\SudakTudak\sudak.lua: C:\SudakTudak\sudak.lua:1: unexpected symbol near 'п'
      • Александр Элс
        19 апреля 2019, 21:33
        Turbo Pascal, в квике загружаю через запуск алго файлик с расширением lua. Проверил тоже, комментарии все в порядке
        monosnap.com/file/oRG1CDh2UnCEw9sVM5BuaWWpxaRceT
          • Александр Элс
            19 апреля 2019, 21:46
            Turbo Pascal, всё понял, в кодировке была загвоздка. Сейчас цену не понимает. В графике прописал тикер и префикс monosnap.com/file/rQvQ2akNuradjeO29RxZPQUF3lwK4u
              • Александр Элс
                21 апреля 2019, 13:31
                Turbo Pascal, разобрался. Я балда не тем идентификатор в графике прописывал :) А работу только через лог файлик отслеживать можно?
              • Александр Элс
                22 апреля 2019, 10:23
                Turbo Pascal, для акции Сбербанк ао тикер SBER будет? Всё проверил, не получается.
                  • Александр Элс
                    23 апреля 2019, 14:28
                    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

                      • Александр Элс
                        23 апреля 2019, 14:37
                        Turbo Pascal, по инструменту поз не было. Даже лог вон кажет же -1 сейчас, значит отображает. Я кажется допёр. Подозреваю что дело в том, что открывался я +1 изначально, потом лот увеличил до 2, и он, видимо просто закрыл +1 на -2. Надо лог стереть и позы и перезапустить щас, видимо.
                          • Александр Элс
                            24 апреля 2019, 10:41
                            Turbo Pascal, а ты не мог бы дописать чтобы доход по инструменту еще считался суммарный и объем входов-выходов (для подсчёта комиссии)?
                              • Александр Элс
                                24 апреля 2019, 13:21
                                Turbo Pascal, ок, буду дальше тестировать. Пиши как будет новая версия :)
                                  • Александр Элс
                                    25 апреля 2019, 11:37
                                    Turbo Pascal, не замечал с утра что не может цену получить и не стартует? 
                                      • Александр Элс
                                        25 апреля 2019, 11:51
                                        Turbo Pascal, странно, у меня за 5 мин до старта подключается и не получает, видать, данных. На срочке бот работает постоянно без проблем. Может ему сделать отсрочку запуска до 10 01 00?
                                          • Александр Элс
                                            25 апреля 2019, 12:14
                                            Turbo Pascal, я сейчас перезапустил уже, он пишет что значение "?" или как то так, в цене. Я просто жму запуск и все работает.
                                              • Александр Элс
                                                03 мая 2019, 10:14
                                                Turbo Pascal, не накодил задержку? Другой бот не может зависать если этот не запустился?

                                                И что можно с логом на 35 МБ делать? :)
              • Алексей Гурышев
                09 февраля 2024, 19:38

                Turbo Pascal, привет! Перепроверил, график подписан SBER_Price_Sudak, боллинджер SBER_BB_Sudak. 

                Настраиваю, соответсвенно Сбер, пока один

                И тоже на 71 строке выдает «attempt to index a nil value (field 'integer index')»

                Может что-то в коде обновили за 5 лет?

                И еще вопрос сразу - aAccountCode — это вообще что? Что писать? 

                • Алексей Гурышев
                  09 февраля 2024, 19:46

                  ВСЕХ благодарю!

                  2 дня тыкался — как сюда вопрос написал — так сразу все запустилось

                  Видимо аура сайта сработала 

  • Петрович
    21 апреля 2019, 10:27

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

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

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

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

    • П М
      21 апреля 2019, 13:16
      podbelski, ты раскрыл заговор :)
      • Петрович
        21 апреля 2019, 19:16
        Turbo Pascal, так и догадался. Просто решил не гадать, а уточнить, т.к. lua вижу первый раз. Не думал, что это может вызвать эмоции. Прошу прощения.
  • MegaFan
    01 мая 2019, 12:59
    Я правильно понял идею, что первая позиция открывается / закрывается по маленькому отступу, а когда открыли 2-ю и более, то и закрывать её будем по большому? Т.е. нет такого, чтобы набрали, например, по 220, 218, 216, и начали колбаситься в боковике 217, 216, 217, 216, 215, 216.
  • Геннадий
    06 мая 2019, 19:27
    C:\SudakTudak\SudakTudak1.lua:71: attempt to index field '?' (a nil value)

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

    Что нужно править?
  • Александр Элс
    24 июня 2019, 07:22
    Обновлений не было?
    Можно ли сделать бота на шорт ещё? Неплохая штука для хэджа портфеля акций через мини индекс.
  • Френк френков
    17 мая 2020, 14:24
    Проверить надо скачать или в библиотеку.

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн