суббота, 20 октября 2012 г.

О пользе просмотра трансляций

Некоторые мои знакомые с гордостью сообщают всему миру, что они "они ваще не смотрят зомбо-ящик". Причем делают это очень многие, это даже стало каким-то модным трендом. Я же считаю, что фактически получается, что эти люди сознаются в том, что они имеют неустойчивую психику или того хуже, психически неполноценные. Поскольку, можно сделать вывод о том, что они боятся смотреть телевизор из-за того, что "зомбо-ящик" их может в чем-то убедить и спровоцировать на какие-то действия. 

Я же на такие "признания", обычно, никак не реагирую и мысленно кручу пальцем у виска. Если человек не умеет фильтровать информацию и отличить черное от белого, то таких людей надо не только от телевизора оттаскивать, но и отселять в какие-то отдаленные районы чтоб не натворили чего-нибудь :-))

Поэтому я телевизор смотрю. Иногда даже с интересом. Сегодня, например, смотрел трансляцию Динамо-Металлист. До матча щитал ставку на Betfair ПРОТИВ Динамо с 1.7 за дармовое, поэтому после гола Металлиста закрылся и смотрел одним глазом трансляцию без всякой торговли. После матча я глянул на график и увидел, что матч был интересный. При счете 1:0 в пользу Металлиста кто-то изловчился, сделать ставку на Металлист с коэффициентами 4.0 и 4.4 при истинном 2.1. Похоже, что эти ставки были сделаны в то время, когда Динамо забивало голы которые были сразу отменены. Мне вот только интересно узнать у тех кто сидел на торговле на этом матче - саспендился ли матч во время незасчитанных голов Динамо?

понедельник, 1 октября 2012 г.

Betfair Free API. Ч.4. Продолжаем создавать бот.


Продолжаем создавать бот для автоматического доступа к бирже Betfair. В конце концов, в последней части, у нас получится полностью законченный бот. Что же он будет делать? Ну, допустим, пусть он будет расставлять минимальную  ставку LAY с коэффициентом 1.01 на все вновь появившиеся теннисные рынки.

Итак, в это части добавим в бот, который уже умеет логиниться к бирже, способность получать новые рынки. Внизу измененный код, из предыдущего примера, который умеет это делать. Изменить следует основной фал исходного кода программы JavaApplication1.java (не забудьте подставить свой логин и пароль к бирже в строках 27 и 28)


package javaapplication1;

import com.betfair.publicapi.types.exchange.v5.ArrayOfInt;
import com.betfair.publicapi.types.exchange.v5.GetAllMarketsReq;
import com.betfair.publicapi.types.exchange.v5.GetAllMarketsResp;
import com.betfair.publicapi.types.global.v3.LoginReq;
import com.betfair.publicapi.types.global.v3.LoginResp;
import com.betfair.publicapi.v3.bfglobalservice.BFGlobalService;
import com.betfair.publicapi.v3.bfglobalservice.BFGlobalService_Service;
import com.betfair.publicapi.v5.bfexchangeservice.BFExchangeService;
import com.betfair.publicapi.v5.bfexchangeservice.BFExchangeService_Service;
import java.util.ArrayList;

public class JavaApplication1 {

    public static void main(String[] args) {
            String sessionToken = "";
            com.betfair.publicapi.types.exchange.v5.APIRequestHeader exchangeHeader = new com.betfair.publicapi.types.exchange.v5.APIRequestHeader();
            
            BFGlobalService_Service WSDLService_Global = new BFGlobalService_Service();
            BFGlobalService WSDLPort_Global = WSDLService_Global.getBFGlobalService();

            BFExchangeService_Service WSDLService_Exchange = new BFExchangeService_Service();
            BFExchangeService WSDLPort_Exchange = WSDLService_Exchange.getBFExchangeService();
            
            LoginReq loginRequest = new LoginReq();
            loginRequest.setUsername("mylogToBetfair");
            loginRequest.setPassword("mypassword");
            loginRequest.setProductId(82);
            loginRequest.setVendorSoftwareId(0);
            loginRequest.setIpAddress("0");
            loginRequest.setLocationId(0);
            
            LoginResp result = WSDLPort_Global.login(loginRequest);
            
            System.out.println("Логин на Betfair - " + result.getErrorCode().toString());
            if (result.getErrorCode().toString().equals("OK")) {
                sessionToken = result.getHeader().getSessionToken();
                System.out.println("Текущий session Token - " + result.getHeader().getSessionToken());
            } else {
                // По какой-то причине логин не получился. Выход из программы
                System.exit(0);
            }
            
            /*********** Готовим запрос и запрашиваем все теннисные рынки **************/
            
            // Готовим заголовок для запроса
            exchangeHeader.setSessionToken(sessionToken);
            exchangeHeader.setClientStamp(0);
            
            // Готовим запрос всех теннисных рынков
            GetAllMarketsReq allMarketsRequest = new GetAllMarketsReq();
            // Добавляем в запрос заголовок запроса
            allMarketsRequest.setHeader(exchangeHeader);
            allMarketsRequest.setLocale("en");
            // Создаем массив интересущих нас видов спорта
            ArrayOfInt array = new ArrayOfInt();
            // Добавляем в этот массив число 2 соответствующее теннису
            // Например, для футбола это 1.
            // Соответствие чисел видам спорта смотрим здесь http://data.betfair.com/sportids.htm?rfr=15929
            array.getInt().add(2);
            // Подставляем в массив видов спорта в запрос
            allMarketsRequest.setEventTypeIds(array);
            
            // Запрос готов! Отправляем его на сайт Betfair
            GetAllMarketsResp resp = WSDLPort_Exchange.getAllMarkets(allMarketsRequest);

            System.out.println("Ответ на запрос рынков - " + resp.getErrorCode().toString());
            // Проверяем ответ. Сравниваем его со строкой ОК
            if (!resp.getErrorCode().toString().equals("OK")) {
                // Запрос завершился неудачно. Выходим из программы
                System.out.println("Ответ на запрос рынков - " + resp.getErrorCode().toString());
                System.exit(0);
            }
            // Разбираем весь запрос.
            ArrayList<MyMarketInfo>> markets = MarketsParser.parseMarkets(resp.getMarketData());
            if (markets.isEmpty()) {
                System.out.println("Не получено ни одного рынка в ответе на запрос рынков");
                System.exit(0);
            } else {
                System.out.println("Получено всего " + markets.size() + " рынков в ответе на запрос рынков");
            }
            
            // Из всего множества теннисных рынков формируем массив
            // который будет содержать только рынки Match Odds (ставки на победителя в матче)
            ArrayLis<MyMarketInfo> matchOddsMarkets = new ArrayList<MyMarketInfo>();
            for (int i = 0; i < markets.size(); i++) {
                if (markets.get(i).getMarketName().equals("Match Odds")) {
                    matchOddsMarkets.add(markets.get(i));
                }
            }
            // Печатаем количество Match Odds рынков или выходим из программы если таких рынков не обнаружено
            if (matchOddsMarkets.isEmpty()) {
                System.out.println("Не найдено ни одного Match Odds рынка");
                System.exit(0);
            } else {
                System.out.println("Получено всего " + matchOddsMarkets.size() + " Macth Odds рынков в ответе на запрос теннисных рынков");
            }
            
            // Печатаем все полученные рынки на экран
            for (int i = 0; i < matchOddsMarkets.size(); i++) {
                System.out.println((i+1) + ". " + matchOddsMarkets.get(i).getEventName() + ", " + matchOddsMarkets.get(i).getMarketMenuPath());
            }
    }
}

class MarketsParser {
}

class MyMarketInfo {
}

Пробежимся по коду.

Строки 48, 49. Готовим заголовок для запроса рынков. Подставляем в заголовок сессионный ключ полученный в ответе на логин. Это делается для того что бы не надо было в каждом запросе вставлять свой логин и пароль.

Строки 52-63. Готовим запрос к бирже для получения всех возможных теннисных рынков. То, что нас интересуют только теннисные рынки указано в строке 61. Об этом говорит число 2. Если б нас интересовал еще и футбол, то надо было бы написать в следующей строке  array.getInt().add(2). У каждого вида спорта есть свое число которое надо подставлять в запрос. Список всех возможных чисел смотрим здесь.

Строка 66. Отправляем, только что сформированный запрос на биржу.

Строки 68-74. Проверяем код ошибки и завершаем программу если код ошибки отличается от строки "ОК".

Строки 76-82. Разбираем ответ биржи. Внимание! Ответ от биржи будет получен в виде одной строки следующего уродливого вида -
106955486~Match Odds~O~ACTIVE~1349238600000~\Tennis\Group A\China Open 2012\Womens Tournament\Second Round Matches\Bartoli v Morita~/2/26900942/26901463/26901449/26901677/106955486~0~1~CHN~1349038369954~2~1~0.0~N~Y:106955487~Set Betting~O~ACTIVE~1349238600000~\Tennis\Group A\China Open 2012\Womens Tournament\Second Round Matches\Bartoli v Morita~/2/26900942/26901463/26901449/26901677/106955487~0~1~CHN~1349038369954~4~1~0.0~N~Y
Новичку в программировании поначалу сложно будет извлечь полезную информацию из этой информационной свалки. Поэтому я облегчу ваши страдания. Я написал специальный класс который будет за мгновение ока разбирать эту строку и создавать отдельный объект типа MyMarketInfo для каждого найденного рынка. Что бы не загромождать страницу я не привел описания этих классов здесь. Однако, я приложу весь исходный текст программы целиком в конце этой заметки. Вам надо будет только скопипасить его на место кода написанного в предыдущем посте.

Строки 86-91. Фильтруем все найденные рынки и отбираем рынки которые называются Match Odds. Что соответствует обычным ставкам на победителя в теннисном матче. Собираем отфильтрованные рынки в переменной массиве matchOddsMarkets.

Строки 92-103. Распечатываем количество полученных теннисных рынков, а также все Match Odds рынки  с названиями рынков.

Весь исходный текст программы в одном файле JavaApplication1.java