Добро пожаловать на подписку«Python Combat — построение системы количественной торговли на основе акций»Буклет, в буклете будут последовательно публиковаться статьи в колонках, связанные с содержанием буклета, которые обеспечат более полное и расширенное введение в соответствующие точки знаний и будут выборочно включены в буклет, облегчая читателям проверку знаний. точки.Эта колонка является продолжением содержания буклета! ! !
предисловие
Исследование количественной торговой стратегии в основном охватывает микро- и макроаспекты, микроаспект в большей степени основан на базовой информации, такой как рыночные цены и позиции транзакций, в качестве объекта исследования модель транзакций. Макроаспект заключается в разработке моделей транзакций на основе большего количества рыночной информации, например, построение моделей транзакций на основе макроэкономических показателей, таких как ИПЦ, ИЦП и эмиссия валюты, в качестве объектов исследования, или использование технологии интеллектуального анализа данных для анализа новостных событий, которые могут вызвать рыночные аномалии. Нестабильные события, чтобы получить возможность торговать.
Мы знаем, что у известных фондовых форумов есть небольшой дом для инвестиций в золото, акции в мире, интернет-фондовый бар Oriental Fortune, фондовый бар Hexun, форум создания, фондовый рынок MACD и т. д. Автор больше использует интернет-фондовый бар Oriental Fortune. В буклете мы рассмотрим случай сканирования рыночных данных отраслевого сектора Dongfang Fortune Net за день и представим принцип и метод веб-краулера.В этом разделе мы расскажем, как сканировать содержимое Dongfang Фортуна Чистый Бар.
Разобрать URL поста
Сначала посетите общие ресурсы Weixing New Materials через браузер и проверьте URL-адрес веб-страницы:http://guba.eastmoney.com/list,002372.html
, содержимое веб-страницы показано на следующем рисунке:
Когда мы нажимаем на страницу 2 и страницу 3, текущие URL-адреса выглядят следующим образом:http://guba.eastmoney.com/list,002372_2.html
,http://guba.eastmoney.com/list,002372_3.html
, поэтому правило URL отдельных акций получается какhttp://guba.eastmoney.com/list, 002372_%d.html
Форма выражена, правила относительно просты, %d — это номер страницы форума, но эта форма — это URL-адрес, упорядоченный по времени комментария, если URL-адрес упорядочен по времени публикации,http://guba.eastmoney.com/list,002372,f_%d.html
.
Пост биржевого бара состоит из двух частей: одна часть представляет собой объявление или официальную новость, опубликованную «Финансовым обозрением» или «Oriental Fortune Network», а другая часть представляет собой сообщение для обсуждения, опубликованное розничными инвесторами, как показано ниже. фигура:
URL сообщения для первогоhttp://guba.eastmoney.com/news,cjpl,902659513.html
, URL последнего постаhttp://guba.eastmoney.com/news,002372,902629178.html
, оба URL-адреса можно искать в текущем содержимом HTML-файла панели акций, как показано ниже:
Таким образом, основной особенностью сообщений, опубликованных «финансовым комментарием», «Oriental Fortune Network» или розничными инвесторами, является /news.Что касается реализации, мы можем сначала просканировать HTML-содержимое биржевой панели, а затем отфильтровать URL-адрес опубликовать через регулярные выражения.
Ключевой код для чтения HTML-содержимого веб-страниц подробно описан в разделе брошюры «Способ получения данных по отраслевому сектору с помощью сканера». Следует отметить, что urllib, urllib2 и urlparse Python 2 были интегрированы в urllib Python 3. Содержимое urllib и urllib2 Python 2 интегрировано в модуль urllib.request, а urlparse интегрировано в модуль urllib.parse. Содержимое полученного HTML-кода следующее:
Регулярное выражение фильтрует URL-адрес сообщения, используя re.compile и re.findall, код реализации выглядит следующим образом:
pattern = re.compile('/news\S+html',re.S)
news_comment_urls = re.findall(pattern, html_cont.decode('utf-8')) # 非空白字符N次
"""
['/news,cjpl,902659513.html', '/news,cjpl,902684967.html',
'/news,cjpl,902602349.html', '/news,cjpl,902529812.html',
'/news,cjpl,857016161.html', '/news,002372,902629178.html',
'/news,002372,902557935.html', '/news,002372,902533930.html',
'/news,002372,902519348.html', '/news,002372,902468635.html',
'/news,002372,902466626.html', '/news,002372,902464127.html',
......
'/news,002372,901168702.html', '/news,002372,901153848.html']
"""
\S+ в регулярном выражении означает соответствие нескольким непробельным символам, а затем использование функции findall для поиска всех совпадающих строк и возврата их в виде списка.
Затем используйте метод urljoin для объединения всего URL-адреса для сканирования содержимого заголовка одного сообщения.Код ключа выглядит следующим образом:
for comment_url in news_comment_urls :
whole_url = parse.urljoin(page_url, comment_url)
post_urls.add(whole_url)
return post_urls
Создайте очередь URL-адресов сканера
Затем мы управляем всеми страницами панели акций, которые необходимо просканировать, и URL-адресами сообщений на каждой странице в очереди. Типы последовательностей, хранящихся в Python, это list, tuple, dict и set, различия и характеристики между ними просты: tuple не может изменять элементы в нем, set — это неупорядоченный набор, который автоматически удаляет повторяющиеся элементы, список упорядочен. ; dict — это набор комбинаций ключей и значений. На этот раз мы выбираем list в качестве типа хранения очереди.
Создайте класс target_url_manager, который содержит следующие методы:
-
add_page_urls: проанализируйте HTML-код одной страницы панели акций, чтобы получить URL-адрес публикации страницы.
-
add_pages_urls: создайте очередь и создайте формат двумерного списка для URL-адресов постов всех страниц.
-
has_page_url: определить, пуста ли очередь
-
get_new_url: Публиковать URL для одной страницы за раз
Форма создания очереди следующая:
"""
[['http://guba.eastmoney.com/news,002372,899860502.html',
'http://guba.eastmoney.com/news,002372,899832598.html',
......
'http://guba.eastmoney.com/news,002372,899947046.html',
'http://guba.eastmoney.com/news,002372,899897958.html'],
['http://guba.eastmoney.com/news,cjpl,903685653.html',
'http://guba.eastmoney.com/news,cjpl,903679057.html',
......
'http://guba.eastmoney.com/news,002372,901739862.html',
'http://guba.eastmoney.com/news,002372,901727241.html']]
['http://guba.eastmoney.com/news,cjpl,903685653.html',
'http://guba.eastmoney.com/news,cjpl,903679057.html',
......
'http://guba.eastmoney.com/news,002372,901739862.html',
'http://guba.eastmoney.com/news,002372,901727241.html']
"""
Полный код можно найти в буклете «Plus Push! Сканер просматривает посты сетевого бара Oriental Fortune».
Проанализируйте содержание поста.
Просканированное содержимое отдельного поста включает три части: время публикации поста, автора и заголовок поста, а именно:
Мы можем извлечь через регулярные выражения, в которых при объединении регулярных выражений нам нужно учитывать, есть ли в HTML-коде повторяющиеся совпадающие ключевые слова. Обычные коды автора и заголовка сообщения следующие: ключевые слова mainbody и zwcontentmain встречаются в тексте только один раз, и степень совпадения высокая. Из-за изменений в HTML-коде веб-сайта выражения необходимо часто корректировать.
Код ключа следующий:
com_cont = re.compile(r'<div id="mainbody">.*?zwconttbn.*?<a.*?<font>(.*?)</font>.*?<div.*?class="zwcontentmain.*?">.*?"zwconttbt">(.*?)</div>.*?social clearfix',re.DOTALL)
Обычный код времени выпуска выглядит следующим образом, и время постепенно и четко извлекается в два этапа.Поскольку поиск заключается в сканировании строки, чтобы найти позицию, в которой совпадает RE, добавьте group(), чтобы вернуть совпадающую строку.
pub_elems = re.search('<div class="zwfbtime">.*?</div>',html_cont2).group()
#<div class="zwfbtime">发表于 2020-02-11 09:54:48 东方财富Android版</div>
pub_time = re.search('\d\d\d\d-\d\d-\d\d',pub_elems).group()
#2020-02-06
Кроме того, сообщения на форуме связаны с текущим трендом цен на акции во времени, а слишком ранние сообщения не имеют справочного эффекта, поэтому необходимо удалять последние сообщения. Мы можем судить о времени, сканируются и сохраняются только посты, опубликованные в течение месяца. Чтобы получить сегодняшнюю дату, используйте datetime.now().date(), а затем сравните ее со временем и датой просканированного сообщения. время во временной форме.
Ключевой код для реализации некоторых ключей выглядит следующим образом:
time_start=datetime.now().date() # 获取日期信息
dt = datetime.strptime(pub_time,"%Y-%m-%d") # 字符串转时间格式
datetime.date(dt)+timedelta(days=30)
После завершения сканирования содержимого одного сообщения мы используем итеративный метод для сканирования всех сообщений. Мы используем двухуровневый итеративный метод, первый слой — это количество страниц, второй слой — это количество сообщений на странице, URL-адрес каждого сообщения хранится в списке, а содержимое сообщений сканируется один раз. по одному через итерацию.
Вот некоторые ключевые коды для достижения:
while self.target_page.has_page_url():
new_urls = self.target_page.get_new_url() # 获取每个帖子的URL地址队列
for url in new_urls:
……
Когда мы обнаруживаем, что сообщение не существует во время сканирования, а информация о сканировании является ненормальной, мы можем использовать try...except... для обработки исключений.
Содержание окончательного просканированного поста показано на следующем рисунке:
Полный код можно найти в буклете «Plus Push! Сканер просматривает посты сетевого бара Oriental Fortune».
Содержимое поста сохраняется в виде txt
Мы можем записать информацию о сканировании в txt-файл. Реализация кода метода open выглядит следующим образом. a+ добавляет запись в конец текста, а не перезаписывает его. Метод codecs.open может указать кодировку для открытия файл и использовать Python. Встроенный открытый открытый файл может записывать только в тип str.
f=codecs.open(name,'a+','utf-8')
Здесь мы создаем класс output_txt, в котором будем реализовывать методы открытия файла, записи файла и закрытия файла соответственно. Код выглядит следующим образом:
class output_txt(object):
def open_txt(self):
name = "stock_cont.txt"
try:
f = codecs.open(name, 'a+', 'utf-8')
except Exception as e:
print("NO TXT")
return f
def out_txt(self, f_handle, conts):
try:
print("cont",conts)
f_handle.write(conts)
except Exception as e:
print("NO FILE")
def close_txt(self, f_handle):
f_handle.close()
Затем вы можете просканировать содержимое поста и записать его в текстовый файл. Код ключа реализации выглядит следующим образом:
file_txt = self.outputer.open_txt()
while self.target_page.has_page_url():
new_urls = self.target_page.get_new_url() # 获取每个帖子的URL地址队列
for url in new_urls:
if time_start <= (self.downloader.find_time(url)+timedelta(days=30)):
self.outputer.out_txt(file_txt, self.downloader.download(url))
true_time = true_time + 1
else:
error_time = error_time + 1
self.outputer.close_txt(file_txt)
Эффект записи в файл txt следующий:
Суммировать
В этом разделе мы используем методы краулера для получения различного содержимого в сообщениях стоковой панели, так что же для нас значит это содержимое? Мы обнаружили, что некоторые люди поют шорты и вызывают панику, но мы можем проанализировать, имеют ли эти короткие комментарии какое-либо отношение к росту и падению цен на акции, с помощью классификационного анализа. Заинтересованные друзья могут попробовать!
Чтобы узнать больше о количественном трейдинге, подпишитесьбуклетчитать! ! В то же время вы также можете обратить внимание на мой общедоступный аккаунт WeChat [Master Lantern предлагает вам использовать количественную торговлю Python], чтобы узнать больше о количественной торговле Python.