Помогите составить алгоритм на python для подбора значений
при этом 1
n = 3 a = 5, 4, 6 b = 1, 2, 3 результат = 24 n = 5 a = 2 3 4 4 5 b = 5 4 4 3 1 результат = 28
Заранее спасибо за внимание!!
Отслеживать
задан 21 окт 2020 в 7:56
55 1 1 серебряный знак 8 8 бронзовых знаков
Ну, самое простое — двойной (вложенный) цикл, и вперед.
21 окт 2020 в 7:58
@EOF это значит что j может быть или больше или равна n, то есть использовать последний или любой другой элемент массива, который больше i.
21 окт 2020 в 8:25
Правильно ли я понимаю, что у нас два массива a и b ?
Сравнение экземпляров объектов в Python по атрибутам
Для сравнения объектов на равенство, исходя из их атрибутов, необходимо переопределить метод __eq__ . Это хороший способ, особенно когда требуется сравнивать все атрибуты объекта:
Скопировать код
class MyClass: def __init__(self, *args): self.attributes = args def __eq__(self, other): return isinstance(other, MyClass) and all(getattr(self, attr) == getattr(other, attr) for attr in vars(self)) obj1 = MyClass(1, 'a') obj2 = MyClass(1, 'а') print(obj1 == obj2) # Вернёт "True", если объекты равны
Данный подход эффективен, масштабируем и легко поддерживается, особенно при наличии большого количества атрибутов у класса.
Подробнее о __eq__
Перед сравнением атрибутов убедитесь, что типы сравниваемых объектов совпадают:
Программирование в «Эврике»
В цикле с условием while цикл выполняется, пока истинно задающее его условие. Поэтому этот цикл также иногда называют циклом «пока». Часто цикл while используется, когда невозможно заранее предсказать, сколько раз необходимо выполнить тело цикла. В повседневной жизни цикл while можно встретить в алгоритмах, вроде «Пока в пределах видимости есть машины, стоять на месте» или «Пока в ящике есть детали, достать деталь из ящика».
В следующей программе цикл while используется подобно циклу for для вывода на экран всех чисел от 1 до 10:
i=1 while iВ этой программе переменной i присваивается значение 1. Затем начинается цикл (ключевое слово while ) с проверяемым условием i
Как только проверяемое условие станет ложно (это произойдет, когда переменная i станет равна 11), цикл завершит работу и управление будет передано следующей инструкции после блока цикла. Поэтому после завершения цикла переменная i будет иметь значение 11.
В общем виде синтаксис цикла с условием в языке Питон такой:
while условие: инструкция 1 инструкция 2 . инструкция n
- Условие, определяющее, будет ли выполняться тело цикла. Это условие записывается после слова while и может быть произвольным арифметическим выражением, в котором должен быть хотя бы один из операторов == , != , < , >, = и могут использоваться логические операторы and , or , not . После условия ставится двоеточие.
- Тело цикла, состоящее из одной или нескольких инструкций, записанных с отступом одинаковой величины.
- Инструкции, изменяющие значения переменных, входящих в проверяемое условие. В рассмотренном примере это инструкция i=i+1 . Если бы этой инструкции не было, то значение переменной i не менялось бы и проверяемое условие всегда было бы истинным, что привело бы к бесконечному циклу. Для прерывания работы программы, попавшей в бесконечный цикл, используется комбинация клавиш Ctrl+C .
n=input("Введите натуральное число") i=0 while 2**iВ этом примере переменная i внутри цикла увеличивается на 1, пока значение 2**i не превосходит n . После окончания цикла величина 2**i будет больше n , и соответствующее значение i будет напечатано на экране. Внутри цикла могут быть различные другие инструкции, в том числе инструкции if , while и for . В этом случае говорят о вложенных циклах, или об условной инструкции, вложенной в цикл. Тело вложенного цикла выделяется от цикла, в который оно вложено, большей величиной отступа. Рассмотрим два примера. В первом примере программа печатает на экран все натуральные делители данного натурального числа n . Для этого используется цикл, в котором переменная i меняется от 1 до n , а внутри цикла проверяется условие, и если остаток от деления n на i равен 0, то печатается значение i :
n=input("Введите число, для которого необходимо вывести делители") i=1 while iВ следующем примере на экран печатается таблица умножения всех однозначных чисел. Для этого организовано два цикла: в одном переменная i меняется от 1 до 9, внутри этого цикла (то есть при каждом новом значении i ) переменная j также меняется от 1 до 9. В блоке вложенного цикла на экран печатаются значения переменных i , j и их произведение:
i=1 while i for i in range(1,10): for j in range(1,10): print i, "*", j, " heading">Инструкции управления цикломВ циклах
whileиforможно использовать две инструкции, управляющие циклом.Инструкция
breakпрерывает выполнение цикла. Управление передается на следующую инструкцию после тела цикла.Инструкция
continueпрерывает текущую итерацию цикла. Все инструкции после инструкцииcontinueдо конца блока цикла пропускаются. В циклеforпеременной, которая меняется в цикле, присваивается следующее значение из списка и цикл продолжает выполняться с новым значением переменной. В циклеwhileпроверяется условие, заданное в цикле и если оно истинно, то цикл продолжает выполняться с начала блока цикла.Например, допустим, что нам необходимо перебрать в цикле все натуральные числа, меньшие
nи не делящиеся на 3. Для этого можно перебрать все числа, проверить их остаток от деления на 3, и если число делится на 3, выполнить инструкциюcontinue, которая пропустит оставшиеся до конца цикла инструкции и перейдет к следующему числу:for in range(n): if i%3==0: continue print i # а далее выполняем прочие необходимые действияИнструкции break и continue следует использовать только внутри условных инструкций. Безусловные инструкции break и continue , как правило, бессмысленны. Также в циклах while и for можно указать else -блок после основного блока цикла. else -блок в циклах выполняется один раз после завершения работы цикла, но только в случае, если цикл не был прерван инструкцией break . Поясним это на программе, которая по введенному целому числу n>1 определяет, является ли оно простым или составным.
n=input("Введите целое число, больше 1 ") # 1 Считали число n for d in range(2, n): # 2 d меняется от 2 до n-1 if n % d == 0: # 3 Проверка: n делится на d? print n, "имеет делитель", d # 4 break # 5 Завершаем цикл for else: # 6 Это else-блок цикла print n, "простое число" # 7Поясним эту программу. После ввода с клавиатуры числа n в программе организовывается цикл по переменной d , принимающей значения от 2 до n-1 (строка 2). Далее в теле цикла проверяется, является ли d делителем n (строка 3). Если является делителем, то на экран выводится соответствующее сообщение (строка 4) и при помощи инструкции break завершается выполнение цикла (строка 5). После тела цикла for идет else -блок. То, что инструкция else (строка 6) относится к циклу for (строка 2), а не к инструкции if (строка 3), определяется по величине отступа перед инструкцией else : отступ перед ней такой же, как и перед инструкцией for . Поэтому если цикл не был прерван инструкцией break , то есть для числа n не будет найден нетривиальный делитель, то будет выполнен else -блок, то есть на экран будет напечатано сообщение о том, что n — простое число (строка 7).
Метод подбора параметров функции за ограниченное время. Торговый симулятор + улучшение стратегии
Представлюсь, я Алексей Волков, руководитель нескольких IT проектов. И сейчас в данной коротенькой статье будет вам представлена проблематика тестирования торговых стратегий с приближением к реальности и мои пути решения. Также поделюсь личным опытом в выявлении перспективности какой-либо торговой стратегии. (это не машинное обучение, не нейросети, не гадание и не астрология).
Главным нашим инструментом будет Python и Jupiter Notebook. Этого достаточно. Все по простому.
В первую очередь эта статья будет полезна, тем кто пишет торговых роботов, или разрабатывает стратегию для сигнальных ботов, и даже тем, кто в поисках чего-то интересного и нового.
Описываю проблематику
Сегодня, как всем известно, популярность алготрейдинга очень высока. Возможно кто-то уже нашел свой "золотой грааль". Но мы здесь будем в поисках.
Как это происходит: смотрите обзор общих стратегий, модифицируете ее, проводите риск-менеджмент, выходите на рынок с новым алгоритмом и . сливаете депо. Затем алгоритм "пожертвований" повторяется.
Почему делается идет упор на важность изучения ваших торговых стратегий? А все потому что из-за изменчивости конъюнктуры рынка ваша стратегия может просто перестать работать как прежде. Поэтому с изменением рынка, нужно подстраиваться подстраиваться под него = менять свое поведение на нем.
Составим некий перечень ошибок, возможно что не учитывается, по крайней мере с чем столкнулся сам. (не исключаю, что возможно для вас очевидно, или вы сталкивались с чем-то большим и проблематичным)
Перечисляю ошибки с которыми столкнулся автор
0. Быть полностью уверенным что ваша стратегия точно работает.
Излишний оптимизм не дает холоднокровному разуму
применить хотя бы методы статистического анализа.1. Самый наглядный, это малый интервал тестирования стратегии.
Изучите стратегию на ее устойчивость при разных рыночных условиях. Часто добавление тестирования на инвертированных графиках дает дополнительную гарантию устойчивости стратегии в несуществующих еще рыночных условиях. В данной статье будет использоваться именно малый интервал времени котировок.2. Подстраивание "точных" настроек стратегии.
Попытки поймать каждое движение на рынке терпит фиаско при частом не срабатывании ключевых для вашей стратегии паттернов, условий. Попробуем достичь "грубой" гибкости.3. Отход от модели предполагаемой перспективной стратегии.
Как правило в момент уже тестирования появляются мысли как можно "улучшить" стратегию, добавить что-то новое, поэксперементировать с дополнительными паттернами, желая забрать все движения с рынка.4. Незнание слабых сторон стратегии.
Например, применение болленджера в условиях, когда очень сильная волательность, резкие изменения цены.
Или падение ликвидности инструмента вынуждает перебираться на более старшие таймфреймы.Для начала подгрузим данные об одном из финансовых инструментов с Binance биржи через api за последние 3 года. Рынок криптовалют очень волатильный, и это замечательно.
Соберем базовый симулятор, с заранее обозначенными условиями.
Учтем следующие условия:
1. Возьмем за гипотезу, что рынок это случайность (где все игроки с равноценными кошельками)
2. Используем минутный таймфрейм, чтобы его преобразовать в другой тайм для торговой стратегии, а симмулятор будет двигаться с шагом в 1 минуту.
3. Введем понятие максимального и минимального наблюдаемого профита. Пригодится для измерения потенциала стратегии. (оценка глубины роста и просадки)
4. Добавим значение стоплосса (либо процент либо конкретная цена)
5. Вводим фактор проскальзывания цены в 0.1%
6. Учитываем комиссию на бирже с умножительным коэффициентом (я использую запас 100% комиссии)
7. Нам понадобится также записывать все сделанные сделки симулятором в отдельный журнал. Очень пригодится, для того чтобы отдельные сделки можно было построить и вручную проверить работу симулятора, а также изучить статистические величины.
8. Введем генератор стратегий на основе регулируемого количества полос боллинджера с генерацией случайных параметров.
9. Добавим случайный перебор take profit и stop lossЗатем построим симулятор с генератором случайной стратегии на основе линий боллинджера. Кстати, вы можете использовать свою стратегию, или/и добавить другие составляющие индикаторов, добавить дополнительные иные аспекты поведения алгоритма на рынке (час торгов, звезды, число упоминаний в новостях какого то слова, и т.д.). Но суть хочу показать, что можно легко строить очень сложные математические модели поведения и тут же тестировать их с перебором огромного количества параметров. Абсурдность в этом вся в том, сложность системы требует больше времени и исторического контента.
Итак, начнем. Мы сделали простой симулятор, и прогнали на нем множество итераций. Каждая итерация генерировала случайные значения параметров.
Первые две серии итераций будут по коротким дистанциям. По одной неделе исторических данных. Затем эти интервалы будут увеличены с ростом фиксированных параметров.
Код симулятора с генератором стратегий
# Импорты import warnings warnings.filterwarnings('ignore') import pandas as pd import os import numpy as np import matplotlib.pyplot as plt import random# Загружаем датасет предварительно подгруженный с биржи symbols_data_close = <> path = 'history4/' for symbol in os.listdir(path)[0:1]: data = pd.read_csv(f'') symbols_data_close.update()# Берем фрагмет датасета и выведем что он представляет из себя symbols = list(symbols_data_close.keys()) closdata = symbols_data_close[symbols[0]][:10000] plt.figure(figsize=(20,10)) plt.plot(closdata)
# Функция генерации слчайных параметров def get_generate_params(count=None): params = params['ma_window'] = np.asarray(np.random.random(count) * 1000 + 1, 'int32') params['std_window'] = np.asarray(np.random.random(count) * 1000 + 1, 'int32') params['std_rate_up'] = np.random.random(count) * 8 - 4 params['std_rate_dw'] = np.random.random(count) * 8 - 4 params['take_profit'] = np.random.random(count) * 10 params['stop_profit'] = -np.random.random(count) * 10 return params# Функция случайной стратегии по сгенерированным случайным параметрам def get_my_strategy(p=None, cdata=None, count=None): # p -> params bb_up = [] bb_dw = [] for i in np.arange(count): ma = pd.Series(cdata).rolling(window=p['ma_window'][i]).mean().values std = pd.Series(cdata).rolling(window=p['std_window'][i]).std().values bb_up.append((ma + std * p['std_rate_up'][i])[1000:]) bb_dw.append((ma - std * p['std_rate_dw'][i])[1000:]) return# Функция поведения симулятора def get_rules_result(p=None, strategy=None, operation=None, profit=None, max_profit=None, min_profit=None, y_index=None, y_index_last=None, x_index=None): signal = if operation is None: for y_line in strategy['bb_up']: if y_index_last < y_line[x_index] < y_index: signal['in_long'] = True return signal if operation == 'long': for ind, (y_line_up, y_line_dw) in enumerate(zip(strategy['bb_up'], strategy['bb_dw'])): rule_1 = y_index >y_line_up[x_index] and profit > p['take_profit'][ind] and profit > 0 rule_2 = y_index > y_line_up[x_index] and max_profit - profit > p['take_profit'][ind] and profit > 0 rule_3 = y_index > y_line_up[x_index] and max_profit < -p['take_profit'][ind] and profit >0 rule_4 = y_index < y_line_dw[x_index] and profit < p['stop_profit'][ind] if rule_1 or rule_2 or rule_3 or rule_4: signal['end_long'] = True return signal return signalВыведем как выглядит наша одна случайная стратегия (график цены и линии боллинджера)
countData = 15 # количество линий боллинджера, которые к учиту в стратегии my_strategy = get_my_strategy( p=get_generate_params(count=countData), cdata=closdata, count=countData) plt.figure(figsize=(20,10)) plt.plot(my_strategy['closdata'], color='black') for n in np.arange(countData): plt.plot(my_strategy['bb_up'][n]) plt.plot(my_strategy['bb_dw'][n])
Основной движок симулятора. Здесь используем только сделки в лонг.
countData = 10 leverage = 10 # плечо params_history = [] for cnt in np.arange(9999999): # генерируем случайные параметры generate_params = get_generate_params(count=countData) # генерируем стратерию my_strategy = get_my_strategy(p=generate_params, cdata=closdata, count=countData) depo = [1000] operation=None profit=0 max_profit=0 min_profit=0 # по шагам идем по ценовому графику for x, (closedata_last, closedata) in enumerate(zip(my_strategy['closdata'][:-1], my_strategy['closdata'][1:])): x_index = x + 1 # вход в сделку лонг if rules_result['in_long']: rules_result['in_long'] = False operation = 'long' size_buy = depo[-1] price_buy = closedata # оценка профита, максимальной просадки и роста if operation is not None: profit = (closedata / price_buy - 1) * 100 - 0.3 if profit > max_profit: max_profit = profit if profit < min_profit: min_profit = profit # выясняем наше поведение на каждом шаге rules_result = get_rules_result(p=generate_params, strategy=my_strategy, operation=operation, profit=profit, max_profit=max_profit, min_profit=min_profit, y_index=closedata, y_index_last=closedata_last, x_index=x_index) depo.append(depo[-1]) # выход из сделки по сигналу if rules_result['end_long']: rules_result['end_long'] = False depo[-1] = depo[-1] + size_buy * profit / 100 * leverage operation=None profit=0 max_profit=0 min_profit=0 depo[-1] = depo[-1] + size_buy * profit / 100 * leverage # сохраняем результаты на каждой итерации случайной генерации параметров params_history.append() if depo[-1] > 1000: print(round(depo[-1], 1), end=' ')1276.3 1681.9 1072.2 1185.5 1013.5 1419.1 1206.4 1842.5 1260.9 1222.8 1016.5 1084.9 1478.2 1384.9 1022.9 1016.2 1490.1 2235.1 1100.1 1164.0 1076.1 1079.4 1070.4 1245.3 1007.7 1291.8 1101.4 1003.6 1002.8 1125.8 1010.9 1115.4 1197.5 1353.4 1037.5 1179.6 1204.8 1070.2 1334.8 1138.2 1301.0 1490.7 1036.8 1030.5 1400.4 1150.7 1146.6 1218.0 1362.6 1098.4 1695.6 1006.0 1149.5 1126.4 1048.8 1086.0 1137.5 1577.9 1266.4 1246.5 1005.0 1015.9 1031.1 1087.9 1311.0 1389.6 1019.0 1049.1 1210.9 1146.3 1127.8 1366.6 1360.8 1465.9 1101.6 1076.6 1060.4 1044.1 1281.3 1073.3 1047.7 1041.7 1322.0 1012.2 1301.1 1568.1 1056.8 1024.1 1485.3 1106.6 1008.8 1186.8 1007.3 1007.9 1100.6 1834.9 1142.1 1806.9 1352.7 1052.4 1284.5 1045.4 1017.0 1083.4 1229.2 1214.1 1012.2 1398.4 1000.3 1152.4 1003.1 2073.1 1301.3 2235.9 1223.4 1091.3 1011.6 1163.9 1006.3 1084.5 1514.4 1125.3 1334.6 1038.8 1375.3 1136.9 1211.9 1194.3 1746.2 1131.6 1029.2 1132.5 1311.5 1018.0 1355.9 1264.4 1069.1 .Генерируем как можно больше результатов. Оставляем генерацию на 96 часов.
# Наконец, выводим результаты result = pd.DataFrame(params_history).sort_values(by='profit') print('количество итераций', result.shape[0]) result = result[result['profit'] > 2500] resultколичество итераций 4326132


