Перепрыгнеть в содержание


- - - - -

Написание бота Betfair на php


18 ответов в эту тему

#1 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 03 April 2016 - 21:00

Решил попробовать написать бот для Betfair. Результатом выполнения данного кода:

<?php
$argv[1] = "";
$argv[2] = "";

$APP_KEY = $argv[1];
$SESSION_TOKEN = $argv[2];

$DEBUG = False; // Setting DEBUG to true will output all request / responses to api-ng

echo "1. Get all Event Types....<br>";
$allEventTypes = getAllEventTypes($APP_KEY, $SESSION_TOKEN);

echo "<br>2. Extract Event Type Id for Horse Racing....<br>";
$horseRacingEventTypeId = extractHorseRacingEventTypeId($allEventTypes);

echo "<br>3. EventTypeId for Horse Racing is: $horseRacingEventTypeId <br>";

echo "<br>4. Get next horse racing market in the UK....<br>";
$nextHorseRacingMarket = getNextUkHorseRacingMarket($APP_KEY, $SESSION_TOKEN, $horseRacingEventTypeId);

echo "<br>5. Print static marketId, name and runners....<br>";
printMarketIdAndRunners($nextHorseRacingMarket);

function getAllEventTypes($appKey, $sessionToken)
{
	$jsonResponse = sportsApingRequest($appKey, $sessionToken, 'listEventTypes', '{"filter":{}}');
	return $jsonResponse[0]->result;
}

function extractHorseRacingEventTypeId($allEventTypes)
{
	foreach ($allEventTypes as $eventType) {
		if ($eventType->eventType->name == 'Soccer') {
			return $eventType->eventType->id;
		}
	}
}

function getNextUkHorseRacingMarket($appKey, $sessionToken, $horseRacingEventTypeId)
{

	$params = '{"filter": {
			"eventTypeIds": ["' . $horseRacingEventTypeId . '"],
			"marketStartTime":{"from":"' . date('c') . '"}},
			"maxResults": "200",
			"marketProjection": ["RUNNER_DESCRIPTION"]
		}';

	$jsonResponse = sportsApingRequest($appKey, $sessionToken, 'listMarketCatalogue', $params);
	return $jsonResponse[0]->result[0];
}
?>

... явился следующий результат:

Цитата

1. Get all Event Types....

2. Extract Event Type Id for Horse Racing....

3. EventTypeId for Horse Racing is: 1

4. Get next horse racing market in the UK....

5. Print static marketId, name and runners....
MarketId: 1.124002994
MarketName: Half Time Score

SelectionId: 1 RunnerName: 0 - 0
SelectionId: 3 RunnerName: 1 - 1
SelectionId: 7 RunnerName: 2 - 2
SelectionId: 2 RunnerName: 1 - 0
SelectionId: 5 RunnerName: 2 - 0
SelectionId: 6 RunnerName: 2 - 1
SelectionId: 4 RunnerName: 0 - 1
SelectionId: 9 RunnerName: 0 - 2
SelectionId: 8 RunnerName: 1 - 2
SelectionId: 4506345 RunnerName: Any Unquoted

Возникает вопрос: почему отображается только один рынок, а не все существующие?

#2 OFFLINE   VBman

    Специалист


  • Участник II
  • ПипПипПип
  • 203 сообщения
44

Добавлено 03 April 2016 - 22:22

У вас здесь перепутан футбол и скачки. $horseRacingEventTypeId значение 1 это для футбола, для скачек должно быть 7. Скорее всего бот был заточен под скачки, а вам нужен футбол?

Выводит один рынок, потому-то $nextHorseRacingMarket содержит самый первый рынок для текущего $horseRacingEventTypeId..

Отредактировано VBman, 03 April 2016 - 22:23.


#3 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 04 April 2016 - 19:42

Цитата

У вас здесь перепутан футбол и скачки. $horseRacingEventTypeId значение 1 это для футбола, для скачек должно быть 7. Скорее всего бот был заточен под скачки, а вам нужен футбол?

VBman, я начал переделывать код примера для скачек (https://github.com/b...php/jsonrpc.php) под футбол. Чтобы не допустить ошибок, решил на начальном этапе переменные с фрагментом "horseRacing" не переименовывать на "soccer". EventType->id как и положено для футбола равно 1.

Цитата

Выводит один рынок, потому-то $nextHorseRacingMarket содержит самый первый рынок для текущего $horseRacingEventTypeId..

Почему только первый рынок? Я же запросил 200: "maxResults": "200".

Отредактировано Джефф, 04 April 2016 - 19:44.


#4 OFFLINE   triggers

    Триггер Мастер


  • Участник II
  • ПипПипПипПип
  • 989 сообщения
184

Добавлено 04 April 2016 - 20:01

СообщенияДжефф, on 04 April 2016 - 19:42, сказал:

Почему только первый рынок? Я же запросил 200: "maxResults": "200".
return $jsonResponse[0]->result[0];

#5 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 04 April 2016 - 20:29

triggers, спасибо. Надо разбираться по работе с json.

#6 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 04 April 2016 - 21:08

Заменил
return $jsonResponse[0] -> result[0];
на
return $jsonResponse[0] -> result;
и преодолел очередное препятствие. Разбираюсь дальше.

#7 OFFLINE   mr.Freeman

    Специалист


  • Участник II
  • ПипПипПип
  • 498 сообщения
177

Добавлено 05 April 2016 - 18:30

Почему тут ещё нету шуточки про то, что Месье знает толк в извращениях писать бота на php? <_<

#8 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 05 April 2016 - 19:08

mr.Freeman, почему написание бот на php приравнивается к извращению?

#9 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 05 April 2016 - 20:31

Переписал функции getNextUkHorseRacingMarket и printMarketIdAndRunners:

function getNextUkHorseRacingMarket ($appKey, $sessionToken, $horseRacingEventTypeId) {

   $params = '{"filter": {
						  "eventTypeIds": ["' . $horseRacingEventTypeId . '"],
						  "marketStartTime":{"from":"' . date('c') . '"}},
					   "maxResults": "5",
					   "marketProjection": ["RUNNER_DESCRIPTION"]
					  }';
   $jsonResponse = sportsApingRequest($appKey, $sessionToken, 'listMarketCatalogue', $params);
   return $jsonResponse[0] -> result;
}

function printMarketIdAndRunners ($nextHorseRacingMarket) {

   foreach ($nextHorseRacingMarket as $market) {

	  if ($market -> marketName = 'Over/Under 2.5 Goals') {

		 echo 'MarketId: ' . $market -> marketId . '<br>';
		 echo 'MarketName: ' . $market -> marketName . '<br><br>';
	  }
   }
}

Теперь выводит 2 рынка:

Цитата

1. Get all Event Types....

2. Extract Event Type Id for Horse Racing....

3. EventTypeId for Horse Racing is: 1

4. Get next horse racing market in the UK....

5. Print static marketId, name and runners....
MarketId: 1.124023722
MarketName: Over/Under 2.5 Goals

MarketId: 1.124023724
MarketName: Over/Under 2.5 Goals

Вопрос: что за рынки-то, для каких они матчей?

Отредактировано Джефф, 05 April 2016 - 20:35.


#10 OFFLINE   mr.Freeman

    Специалист


  • Участник II
  • ПипПипПип
  • 498 сообщения
177

Добавлено 06 April 2016 - 15:39

СообщенияДжефф, on 05 April 2016 - 19:08, сказал:

mr.Freeman, почему написание бот на php приравнивается к извращению?

Не приравнивается. Просто шуток про php огромное количество в силу некоторых особенностей языка и его распространенности. Так, что не обращайте на меня внимания ;)

#11 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 06 April 2016 - 19:34

mr.Freeman, мне не понятно, почему именно такая последовательность: получение списка рынков -> получение прочих данных (матчи, команды, цены...)? Может было бы лучше обратная последовательность: получение списка матчей -> получение прочих данных (рынки, команды, цены)?

Отредактировано Джефф, 06 April 2016 - 19:34.


#12 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 25 June 2016 - 08:11

Рабочий код, отображающий данные следующего матча для скачек. Слепил фрагменты кода примера со страницы docs.developer.betfair.com/docs/display/1smk3cen4v3lu3yomq5qye0ni/PHP#PHP-Prerequisites. Исправил несколько опечаток. Может, кому-нибудь пригодится.

$appKey = ''; // ключ приложения
$sessionToken = ''; // токен сессии

// ЧАСТЬ 0

function sportsApingRequest ($appKey, $sessionToken, $operation, $params) {

$ch = curl_init();
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_URL, "https://api.betfair.com/exchange/betting/json-rpc/v1");
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Expect:',
  'X-Application: ' . $appKey,
  'X-Authentication: ' . $sessionToken,
  'Accept: application/json',
  'Content-Type: application/json'
));

$postData = '[{ "jsonrpc": "2.0", "method": "SportsAPING/v1.0/' . $operation . '", "params" :' . $params . ', "id": 1}]';
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

$response = json_decode (curl_exec($ch));
curl_close ($ch);

if (isset($response[0] -> error)) {
  echo 'Call to api-ng failed: ' . "<br>";
  echo  'Response: ' . json_encode($response);
  exit (-1);
} else return $response;
}

// ЧАСТЬ 1

$eventTypeId = extractEventTypeId(getAllEventTypes($appKey, $sessionToken)); // получить идентификатор для вида спорта
// получение всех видов спорта
function getAllEventTypes ($appKey, $sessionToken) {

$jsonResponse = sportsApingRequest ($appKey, $sessionToken, 'listEventTypes', '{"filter":{}}');
return $jsonResponse[0] -> result;
}
// получить идентификатор для вида спорта
function extractEventTypeId ($allEventTypes) {

foreach ($allEventTypes as $eventType)
  if ($eventType -> eventType -> name == 'Horse Racing')
   return $eventType -> eventType -> id;
}

// ЧАСТЬ 2

//printMarketIdAndRunners (getNextMarket ($appKey, $sessionToken, $eventTypeId));
// получить следующий рынок
function getNextMarket ($appKey, $sessionToken, $eventTypeId) {

$params = '{"filter":{"eventTypeIds":["' . $eventTypeId . '"],
   "marketCountries":["GB"],
   "marketTypeCodes":["WIN"],
   "marketStartTime":{"from":"' . date('c') . '"}},
   "sort":"FIRST_TO_START",
   "maxResults":"1",
   "marketProjection":["RUNNER_DESCRIPTION"]}';

$jsonResponse = sportsApingRequest ($appKey, $sessionToken, 'listMarketCatalogue', $params);

return $jsonResponse[0] -> result[0];
}
function printMarketIdAndRunners ($nextMarket) {

echo 'MarketId: ' . $nextMarket -> marketId . '<br>';
echo 'MarketName: ' . $nextMarket -> marketName . '<br>';

foreach ($nextMarket -> runners as $runner) {
  echo 'SelectionId: ' . $runner -> selectionId . ' RunnerName: ' . $runner -> runnerName . '<br>';
}
}

// ЧАСТЬ 3

$nextMarket = getNextMarket ($appKey, $sessionToken, $eventTypeId);
$marketId = $nextMarket -> marketId;
printMarketIdAndRunnersAndPrices ($nextMarket, getMarketBook ($appKey, $sessionToken, $marketId));
function getMarketBook ($appKey, $sessionToken, $marketId) {

$params = '{"marketIds":["' . $marketId . '"], "priceProjection":{"priceData":["EX_BEST_OFFERS"]}}';

$jsonResponse = sportsApingRequest ($appKey, $sessionToken, 'listMarketBook', $params);

return $jsonResponse[0] -> result[0];
}
function printMarketIdAndRunnersAndPrices ($nextMarket, $marketBook) {

function printAvailablePrices ($selectionId, $marketBook) {

  // Get selection
  foreach ($marketBook -> runners as $runner)
   if ($runner -> selectionId == $selectionId) break;

  echo '<br>Available to Back: <br>';
  foreach ($runner -> ex -> availableToBack as $availableToBack)
   echo $availableToBack -> size . '@' . $availableToBack -> price . ' | ';

  echo '<br><br>Available to Lay: <br>';
  foreach ($runner -> ex -> availableToLay as $availableToLay)
   echo $availableToLay -> size . '@' . $availableToLay -> price . ' | ';
}

echo 'MarketId: ' . $nextMarket -> marketId . '<br>';
echo 'MarketName: ' . $nextMarket -> marketName;

foreach ($nextMarket -> runners as $runner) {
  echo '<br><br><br>===============================================================================<br>';

  echo 'SelectionId: ' . $runner -> selectionId . ' RunnerName: ' . $runner -> runnerName . '<br>';
  echo printAvailablePrices ($runner -> selectionId, $marketBook);
}
}

Отредактировано Джефф, 25 June 2016 - 08:13.


#13 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 25 June 2016 - 09:00

Ребят, почему реальные данные расходятся с данными АPI?

[img]s019.radikal.ru/i615/1606/1e/77cbd5cd0cb4.png[/img]

Отредактировано Джефф, 25 June 2016 - 09:02.


#14 OFFLINE   Cindra

    Новичок


  • Участник
  • Пип
  • 6 сообщения
1
  • МестоположениеTheМля

Добавлено 28 June 2016 - 04:58

СообщенияДжефф, on 25 June 2016 - 09:00, сказал:

Ребят, почему реальные данные расходятся с данными АPI?
Ключик бесплатный, небось? У него задержка установлена, и за время задержки кэф поменяться успел.

#15 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 30 June 2016 - 16:36

СообщенияCindra, on 28 June 2016 - 04:58, сказал:

Ключик бесплатный, небось? У него задержка установлена, и за время задержки кэф поменяться успел.

Я так понимаю, что вновь создаваемые ключи без задержки платные, а созданные раннее - бесплатные.

#16 OFFLINE   Джефф

    Пунтер


  • Участник
  • ПипПип
  • 48 сообщения
-1

Добавлено 02 July 2016 - 06:44

Проблема решена - по совету Triggers в параметрах listMarketBook добавил строку "virtualise": "true"

#17 OFFLINE   triggers

    Триггер Мастер


  • Участник II
  • ПипПипПипПип
  • 989 сообщения
184

Добавлено 02 July 2016 - 07:06

:rolleyes:

#18 OFFLINE   Ozzy2017

    Новичок


  • Участник
  • Пип
  • 5 сообщения
0

Добавлено 23 January 2017 - 07:13

СообщенияДжефф, on 02 July 2016 - 06:44, сказал:

Проблема решена - по совету Triggers в параметрах listMarketBook добавил строку "virtualise": "true"

Как в коде добавляешь??

#19 OFFLINE   enot

    Новичок


  • Участник
  • Пип
  • 1 сообщения
0

Добавлено 02 February 2017 - 22:36

СообщенияOzzy2017, on 23 January 2017 - 07:13, сказал:

Как в коде добавляешь??

$params = '{"marketIds":["' . $marketId . '"], "priceProjection":{"priceData":["EX_BEST_OFFERS"],"virtualise":"true"}}';