HowTo: Working Tournament M Values + Get M Specific Stats

Forum for users that want to write their own custom queries against the PT database either via the Structured Query Language (SQL) or using the PT3 custom stats/reports interface.

Moderator: Moderators

HowTo: Working Tournament M Values + Get M Specific Stats

Postby Mike0550 » Tue May 11, 2010 11:46 pm

MODERATOR EDIT:

This kind of thing is no longer needed as PT3 now has a built-in "M" stat and mechanism for building other "live" HUD stats.


--------------------

Ok, so I made some quick SQL functions to get M working. These will also let you convert simple stats to M specific such as having a separate VPIP / PFR / 3Bet / almost anything.

Like the last one of these I did, you need to open up pgAdmin to run a script.

This script will calculate the M value and work around the caching issue.

Code: Select all
CREATE LANGUAGE plpgsql;

-- Function: tourney_getm(integer, integer, integer)

-- DROP FUNCTION tourney_getm(integer, integer, integer);

CREATE OR REPLACE FUNCTION tourney_getm(ihand integer, iplayer integer, bforce integer)
  RETURNS double precision AS
$BODY$

DECLARE
   idBlinds integer;
   iSB float;
   iBB float;
   iPlayers integer;
   iAnte float;
   iChipsStart float;
   iChipsChange float;
   iMax int;
   iReturn double precision;

BEGIN

   IF (bForce = 1) THEN
      iMax := 0;
   ELSE
      UPDATE tourney_holdem_cache SET val_m = 0 WHERE id_player = iPlayer;
      SELECT max(id_hand) INTO iMax FROM tourney_holdem_hand_player_statistics WHERE id_player = iPlayer;
   END IF;
   
   IF (iHand < iMax) THEN
      iReturn := 0;
   ELSE
      SELECT id_blinds INTO idBlinds FROM tourney_holdem_hand_player_statistics WHERE id_hand = iHand AND id_player = iPlayer;
      SELECT amt_bb INTO iBB FROM tourney_holdem_blinds WHERE id_blinds = idBlinds;
      SELECT amt_sb INTO iSB FROM tourney_holdem_blinds WHERE id_blinds = idBlinds;
      SELECT amt_ante INTO iAnte FROM tourney_holdem_hand_player_detail WHERE id_hand = iHand;
      SELECT amt_before INTO iChipsStart FROM tourney_holdem_hand_player_detail WHERE id_hand = iHand AND id_player = iPlayer;
      SELECT cnt_players INTO iPlayers FROM tourney_holdem_hand_summary WHERE id_hand = iHand;
      IF (bForce = 1) THEN
         iChipsChange := 0;
      ELSE
         SELECT amt_won INTO iChipsChange FROM tourney_holdem_hand_player_statistics WHERE id_hand = iHand AND id_player = iPlayer;
      END IF;
      iReturn := (iChipsStart + iChipsChange) / ((iAnte * iPlayers) + iSB + iBB);
   END IF;
   RETURN iReturn;

END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION tourney_getm(integer, integer, integer) OWNER TO postgres;

-- Function: tourney_modifystat(integer, integer, integer, text, text, character)

-- DROP FUNCTION tourney_modifystat(integer, integer, integer, text, text, character);

CREATE OR REPLACE FUNCTION tourney_modifystat(ihand integer, iplayer integer, izone integer, _table text, stat text, test character)
  RETURNS integer AS
$BODY$

DECLARE
   iM double precision;
   sExec text;
   sValue character(1);
   iVerify integer;

BEGIN
   SELECT Tourney_GetM(iHand, iPlayer, 1) INTO iM;
   SELECT Tourney_VerifyZone(iM, iZone) INTO iVerify;
   IF (iVerify = 1) THEN
      EXECUTE 'SELECT ' || stat || ' FROM ' || _table || ' WHERE id_Hand = ' || iHand || ' AND id_Player = ' || iPlayer INTO sValue;
   END IF;

   IF (sValue = test) THEN
      RETURN 1;
   ELSE
      RETURN 0;
   END IF;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION tourney_modifystat(integer, integer, integer, text, text, character) OWNER TO postgres;

-- Function: tourney_modifystat(integer, integer, integer, text, text, integer)

-- DROP FUNCTION tourney_modifystat(integer, integer, integer, text, text, integer);

CREATE OR REPLACE FUNCTION tourney_modifystat(ihand integer, iplayer integer, izone integer, _table text, stat text, i integer)
  RETURNS integer AS
$BODY$

DECLARE
   iM double precision;
   bReturn boolean;
   sExec text;
   iVerify integer;

BEGIN
   bReturn = FALSE;
   SELECT Tourney_GetM(iHand, iPlayer, 1) INTO iM;
   SELECT Tourney_VerifyZone(iM, iZone) INTO iVerify;
   IF (iVerify = 1) THEN
      EXECUTE 'SELECT ' || stat || ' FROM ' || _table || ' WHERE id_Hand = ' || iHand || ' AND id_Player = ' || iPlayer INTO bReturn;
   END IF;

   IF (bReturn) THEN
      RETURN 1;
   ELSE
      RETURN 0;
   END IF;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION tourney_modifystat(integer, integer, integer, text, text, integer) OWNER TO postgres;

-- Function: tourney_modifystat(integer, integer, integer, text, text)

-- DROP FUNCTION tourney_modifystat(integer, integer, integer, text, text);

CREATE OR REPLACE FUNCTION tourney_modifystat(ihand integer, iplayer integer, izone integer, _table text, stat text)
  RETURNS double precision AS
$BODY$

DECLARE
   iM double precision;
   iReturn double precision;
   sExec text;
   iVerify integer;

BEGIN
   iReturn := 0;
   SELECT Tourney_GetM(iHand, iPlayer, 1) INTO iM;
   SELECT Tourney_VerifyZone(iM, iZone) INTO iVerify;
   IF (iVerify = 1) THEN
      EXECUTE 'SELECT ' || stat || ' FROM ' || _table || ' WHERE id_Hand = ' || iHand || ' AND id_Player = ' || iPlayer INTO iReturn;
   END IF;

   RETURN iReturn;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION tourney_modifystat(integer, integer, integer, text, text) OWNER TO postgres;

-- Function: tourney_verifyzone(double precision, integer)

-- DROP FUNCTION tourney_verifyzone(double precision, integer);

CREATE OR REPLACE FUNCTION tourney_verifyzone(im double precision, izone integer)
  RETURNS integer AS
$BODY$

DECLARE
   iReturn integer;

BEGIN
   iReturn := 0;
   IF (iZone = 0) THEN
      IF (iM <= 1) THEN iReturn := 1; END IF;
   ELSEIF (iZone = 1) THEN
      IF (iM <= 5.5 AND iM >= 1) THEN iReturn := 1; END IF;
   ELSEIF (iZone = 2) THEN
      IF (iM <= 11 AND iM >= 4.75) THEN iReturn := 1; END IF;
   ELSEIF (iZone = 3) THEN
      IF (iM <= 21 AND iM >= 9) THEN iReturn := 1; END IF;
   ELSEIF (iZone = 4) THEN
      IF (iM <= 54 AND iM >= 19) THEN iReturn := 1; END IF;
   ELSEIF (iZone = 5) THEN
      IF (iM >= 48) THEN iReturn := 1; END IF;
   END IF;
   RETURN iReturn;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION tourney_verifyzone(double precision, integer) OWNER TO postgres;


The last function included here called Tourney_VerifyZone is the one that designates the ranges of zones you'd like to use. I like to have a bit of overlap in my zones such as red going from 1 to 5.5 and orange going from 4.75 to 11. This is up to you if you can edit the code above.

Ok, how to use it?

Make a Column in the "Configure Stats" called "val_m"

The expression you use is:
Code: Select all
sum((SELECT Tourney_GetM(tourney_holdem_hand_player_statistics.id_hand, tourney_holdem_hand_player_statistics.id_player, 0)))


Then you can make a Statistic called "M" that has the expression of val_m

Next, if you want to make zone specific stats:

Example is for VPIP in the red zone

Make a Column called cnt_zone_vpip_red, and give it the expression:
Code: Select all
sum((SELECT Tourney_ModifyStat(tourney_holdem_hand_player_statistics.id_hand, tourney_holdem_hand_player_statistics.id_player, 1,  'tourney_holdem_hand_player_statistics', 'flg_vpip', 1)))


The first two variables passed are the hand and player numbers. Don't change these. Next is the zone number - 1 for red, 2 for orange, 3 for yellow, 4 for green and 5 for blue.

Next is the table name of the stat you want to use. Since VPIP is in tourney_holdem_hand_player_statistics, that's what we use (must be in single quotes).

Then you put in the stat you want to use, here it's 'flg_vpip'.

Last is a 1 which is used if you're getting a flg_ variable. If you want to test against a char (to see if the variable holds an 'R' or 'C'), you can pass that on like this for checking on a flop cbet:

Code: Select all
sum((SELECT Tourney_ModifyStat(tourney_holdem_hand_player_statistics.id_hand, tourney_holdem_hand_player_statistics.id_player, 2,  'tourney_holdem_hand_player_statistics', 'enum_f_cbet_action', 'R')))


I haven't perfected the complex stats yet (such as how someone reacts to a steal attempt), but I will get that done eventually.

I hope someone finds this useful.
Mike0550
 
Posts: 24
Joined: Thu May 15, 2008 1:03 pm

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby kraada » Wed May 12, 2010 9:11 am

That's pretty awesome, thanks a bunch for this!
kraada
Moderator
 
Posts: 54431
Joined: Wed Mar 05, 2008 2:32 am
Location: NY

Precision on M zone for current session

Postby liontree » Wed May 19, 2010 3:20 pm

Hello,

I posted this at the wrong place so here it is again.

First, my interest for now is only in getting M for the current session in the HUD static box (not mouse hovering though).
It's good in mouse hovering but it takes away precious thinking time as I cannot think while I do the hover. I often need to know for 4-5 players at a time to decide on possible plays so it can take 10 secs instead of 1 or 2!

Do you think its possible to do it without building M zone data per position which takes considerable resources that I do not need for now?

Also, I tried your solution and had incorrect values but then noticed that my db seems corrupted. Restore was done and db seems fine. So before implementing your solution I thought I should check with you for the above.

Then confirm with you that M for current session should work! :-)

Many thanks!
Claude
liontree
 
Posts: 10
Joined: Wed Apr 21, 2010 3:13 pm

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby liontree » Wed May 19, 2010 5:36 pm

Hello again,

Script questions:
(Using WinXP Home Edition)

1. Can I run this as a regular user; I am unable to connect as admin as I do not know the password nor could I find it by searching all over the world! I would be using the postgress user created by PokerTracker at installation.

2. CREATE LANGUAGE plpgsql; This gives me the error that plpgsql already exists is that a problem?

3. Do you mind if I modify the script for my own purpose? Although you would not know haha.

I really want M!! So I took a glance at the tourney tables in postgress and at your script and here is my understanding. If you have any comment on the following it would be greatly appreciated. (I am still going through so many manuals it would help!)

1. Players stats in HUD static boxes can only come from tourney_holdem_cache

2. The standard PTracker installation does not have session (table number) nor date-time infos in tourney_holdem_cache and this is why M zone for the current session cannot be displayed directly in the HUD static boxes without your script.

3. With the goal of getting M without building positional stats, if I create a script to somehow add session infos in tourney_holdem_cache would you think it might work?

Thank you very much,
Claude
liontree
 
Posts: 10
Joined: Wed Apr 21, 2010 3:13 pm

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby liontree » Wed May 19, 2010 7:03 pm

Hi.
Me too I hope it is my last question!

If I decide to build positional stats, must I first do the steps in the original M zone post (with date related functions)?

Thanks
liontree
 
Posts: 10
Joined: Wed Apr 21, 2010 3:13 pm

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby kraada » Thu May 20, 2010 9:29 am

(1) The default password to log into PostgreSQL as the postgres user is 'dbpass' (without the quotes). If you installed it from other places though, it might be 'postgrespass'.

(2) That error shouldn't be a problem.

----

(1) Actually any stat in the HUD stat box can come from any statistic created in the Player Statistics section. All data built in a normal fashion in that way uses the cache, but this setup, I've been told, will circumvent it.

(2) I'm not sure what you mean here.

(3) Your M won't change by position so I'm not sure what this would accomplish . . .

----

The post in my How To is no longer accurate and will be removed soon.
kraada
Moderator
 
Posts: 54431
Joined: Wed Mar 05, 2008 2:32 am
Location: NY

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby liontree » Thu May 20, 2010 9:55 am

Hi.

Thank you for your answers.
When I stated no positional stats I meant in the popup stats.

I finally got everything to work! Phew!
Most of my issues we're related to a corrupted db. The housekeeping took 50 hours (no mistake) when I first did it and it got me a bit... :shock:

You most probably know but in case it could save time to other users:
- the postgress language creation issue stated in my previous post was not adding the functions to the db
- I removed the create language statement and it solved the problem
- If interested, you can see in the following link how to get around this error problem:
http://wiki.postgresql.org/wiki/CREATE_OR_REPLACE_LANGUAGE

I am really happy about PT3; amazingly powerful. Thanks for your support!

Claude
Last edited by liontree on Thu May 20, 2010 10:05 am, edited 2 times in total.
liontree
 
Posts: 10
Joined: Wed Apr 21, 2010 3:13 pm

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby kraada » Thu May 20, 2010 10:02 am

My popup for actions based on how you acted when you had a given M will still work fine, the only reason we need this complex setup for current M is that current M is based on what happened in just the last hand. Prior details like Red Zone VP$IP can be done as any other normal stat.
kraada
Moderator
 
Posts: 54431
Joined: Wed Mar 05, 2008 2:32 am
Location: NY

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby Mike0550 » Fri May 21, 2010 12:38 am

liontree wrote:If interested, you can see in the following link how to get around this error problem:
http://wiki.postgresql.org/wiki/CREATE_OR_REPLACE_LANGUAGE


Thanks for figuring this out, I had thought you would get an error but that it would still process the rest of the SQL.

I'm glad this is useful.
Mike0550
 
Posts: 24
Joined: Thu May 15, 2008 1:03 pm

Re: HowTo: Working Tournament M Values + Get M Specific Stats

Postby silvia » Fri May 21, 2010 5:29 am

Hi guys,

This looks extremely useful! (but I can't get it to work :( )
I did step 1 (run the script in pgAdmin, seemed fine) and step 2 (create the stat column and variable) (I avoided the zone specific stats). Now I tried to insert a column on my hands tab. And that went all wrong. It says: 'Unable to execute query: SELECT (tourney...etc.etc.etc), very very long. Then I thought may be it is supposed to be used only with the HUD? Originally I thought the you were adding a column to some of the tables, and then have the M for that hand, and the stat was coming from what was stored in there, but looking around the different tables in my ptdatabase I can't seem to find it. Looking at your code and what I can gather from it is that there is no new column being created, there are just new functions? Do these go added into the function definitions of the language? (I am sorry if I am getting it all wrong, just yesterday I started with SQL, and being so impatient as I am I usually learn a language by trying to work out what I am doing after I did it.) So actually when I do that column I am just using that function and passing parameters that come from the rows? :shock: :?

If it is not only for HUD use, and it is expected to work as a normal column in the tournament hands worksheet of PT too, any ideas of what I am doing wrong?

Thanks a lot,

S.
silvia
 
Posts: 41
Joined: Thu May 29, 2008 4:12 am

Next

Return to Custom Stats, Reports, and SQL [Read Only]

Who is online

Users browsing this forum: No registered users and 7 guests

cron