diff --git a/data/futures/roll_calendars_csv/BTC*SPREAD.csv b/data/futures/roll_calendars_csv/BTC*SPREAD.csv new file mode 100644 index 0000000000..a1a4190d35 --- /dev/null +++ b/data/futures/roll_calendars_csv/BTC*SPREAD.csv @@ -0,0 +1,51 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2019-09-20 00:00:00,20190900,20191000,20190800 +2019-09-27 00:00:00,20191000,20191100,20190900 +2019-11-21 00:00:00,20191100,20191200,20191000 +2019-12-20 00:00:00,20191200,20200100,20191100 +2019-12-27 02:00:00,20200100,20200200,20191200 +2020-01-31 00:00:00,20200200,20200300,20200100 +2020-02-27 12:00:00,20200300,20200400,20200200 +2020-03-27 00:00:00,20200400,20200500,20200300 +2020-04-24 00:00:00,20200500,20200600,20200400 +2020-05-29 00:00:00,20200600,20200700,20200500 +2020-06-26 00:00:00,20200700,20200800,20200600 +2020-07-31 00:00:00,20200800,20200900,20200700 +2020-08-28 00:00:00,20200900,20201000,20200800 +2020-09-25 00:00:00,20201000,20201100,20200900 +2020-10-30 00:00:00,20201100,20201200,20201000 +2020-11-27 00:00:00,20201200,20210100,20201100 +2020-12-24 00:00:00,20210100,20210200,20201200 +2021-01-29 00:00:00,20210200,20210300,20210100 +2021-02-26 00:00:00,20210300,20210400,20210200 +2021-03-26 00:00:00,20210400,20210500,20210300 +2021-04-30 00:00:00,20210500,20210600,20210400 +2021-05-28 00:00:00,20210600,20210700,20210500 +2021-06-25 00:00:00,20210700,20210800,20210600 +2021-07-30 00:00:00,20210800,20210900,20210700 +2021-08-27 00:00:00,20210900,20211000,20210800 +2021-09-24 00:00:00,20211000,20211100,20210900 +2021-10-29 00:00:00,20211100,20211200,20211000 +2021-11-26 00:00:00,20211200,20220100,20211100 +2021-12-31 00:00:00,20220100,20220200,20211200 +2022-01-28 00:00:00,20220200,20220300,20220100 +2022-02-25 00:00:00,20220300,20220400,20220200 +2022-03-25 00:00:00,20220400,20220500,20220300 +2022-04-29 00:00:00,20220500,20220600,20220400 +2022-05-27 00:00:00,20220600,20220700,20220500 +2022-06-24 00:00:00,20220700,20220800,20220600 +2022-07-29 00:00:00,20220800,20220900,20220700 +2022-08-26 00:00:00,20220900,20221000,20220800 +2022-09-30 00:00:00,20221000,20221100,20220900 +2022-10-28 00:00:00,20221100,20221200,20221000 +2022-11-25 00:00:00,20221200,20230100,20221100 +2022-12-30 00:00:00,20230100,20230200,20221200 +2023-01-27 00:00:00,20230200,20230300,20230100 +2023-02-24 00:00:00,20230300,20230400,20230200 +2023-03-31 00:00:00,20230400,20230500,20230300 +2023-04-28 00:00:00,20230500,20230600,20230400 +2023-05-26 06:00:00,20230600,20230700,20230500 +2023-06-30 02:00:00,20230700,20230800,20230600 +2023-07-28 01:00:00,20230800,20230900,20230700 +2023-08-25 00:00:00,20230900,20231000,20230800 +2023-09-29 00:00:00,20231000,20231100,20230900 diff --git a/data/futures/roll_calendars_csv/BTC*SPREAD2.csv b/data/futures/roll_calendars_csv/BTC*SPREAD2.csv new file mode 100644 index 0000000000..081fe7face --- /dev/null +++ b/data/futures/roll_calendars_csv/BTC*SPREAD2.csv @@ -0,0 +1,51 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2019-09-02,20190900,20191000,20190800 +2019-09-20,20191000,20191100,20190900 +2019-10-25,20191100,20191200,20191000 +2019-11-29,20191200,20200100,20191100 +2019-12-23,20200100,20200200,20191200 +2020-01-22,20200200,20200300,20200100 +2020-02-20,20200300,20200400,20200200 +2020-03-23,20200400,20200500,20200300 +2020-04-21,20200500,20200600,20200400 +2020-05-22,20200600,20200700,20200500 +2020-06-22,20200700,20200800,20200600 +2020-07-22,20200800,20200900,20200700 +2020-08-21,20200900,20201000,20200800 +2020-09-21,20201000,20201100,20200900 +2020-10-22,20201100,20201200,20201000 +2020-11-20,20201200,20210100,20201100 +2020-12-22,20210100,20210200,20201200 +2021-01-22,20210200,20210300,20210100 +2021-02-19,20210300,20210400,20210200 +2021-03-22,20210400,20210500,20210300 +2021-04-21,20210500,20210600,20210400 +2021-05-21,20210600,20210700,20210500 +2021-06-21,20210700,20210800,20210600 +2021-07-22,20210800,20210900,20210700 +2021-08-23,20210900,20211000,20210800 +2021-09-21,20211000,20211100,20210900 +2021-10-22,20211100,20211200,20211000 +2021-11-22,20211200,20220100,20211100 +2021-12-22,20220100,20220200,20211200 +2022-01-21,20220200,20220300,20220100 +2022-02-18,20220300,20220400,20220200 +2022-03-22,20220400,20220500,20220300 +2022-04-21,20220500,20220600,20220400 +2022-05-23,20220600,20220700,20220500 +2022-06-21,20220700,20220800,20220600 +2022-07-22,20220800,20220900,20220700 +2022-08-22,20220900,20221000,20220800 +2022-09-21,20221000,20221100,20220900 +2022-10-21,20221100,20221200,20221000 +2022-11-21,20221200,20230100,20221100 +2022-12-22,20230100,20230200,20221200 +2023-01-23,20230200,20230300,20230100 +2023-02-20,20230300,20230400,20230200 +2023-03-22,20230400,20230500,20230300 +2023-04-21,20230500,20230600,20230400 +2023-05-22,20230600,20230700,20230500 +2023-06-21,20230700,20230800,20230600 +2023-07-21,20230800,20230900,20230700 +2023-08-22,20230900,20231000,20230800 +2023-09-21,20231000,20231100,20230900 diff --git a/data/futures/roll_calendars_csv/BTC*SPREAD2_BIDOFFER.csv b/data/futures/roll_calendars_csv/BTC*SPREAD2_BIDOFFER.csv new file mode 100644 index 0000000000..081fe7face --- /dev/null +++ b/data/futures/roll_calendars_csv/BTC*SPREAD2_BIDOFFER.csv @@ -0,0 +1,51 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2019-09-02,20190900,20191000,20190800 +2019-09-20,20191000,20191100,20190900 +2019-10-25,20191100,20191200,20191000 +2019-11-29,20191200,20200100,20191100 +2019-12-23,20200100,20200200,20191200 +2020-01-22,20200200,20200300,20200100 +2020-02-20,20200300,20200400,20200200 +2020-03-23,20200400,20200500,20200300 +2020-04-21,20200500,20200600,20200400 +2020-05-22,20200600,20200700,20200500 +2020-06-22,20200700,20200800,20200600 +2020-07-22,20200800,20200900,20200700 +2020-08-21,20200900,20201000,20200800 +2020-09-21,20201000,20201100,20200900 +2020-10-22,20201100,20201200,20201000 +2020-11-20,20201200,20210100,20201100 +2020-12-22,20210100,20210200,20201200 +2021-01-22,20210200,20210300,20210100 +2021-02-19,20210300,20210400,20210200 +2021-03-22,20210400,20210500,20210300 +2021-04-21,20210500,20210600,20210400 +2021-05-21,20210600,20210700,20210500 +2021-06-21,20210700,20210800,20210600 +2021-07-22,20210800,20210900,20210700 +2021-08-23,20210900,20211000,20210800 +2021-09-21,20211000,20211100,20210900 +2021-10-22,20211100,20211200,20211000 +2021-11-22,20211200,20220100,20211100 +2021-12-22,20220100,20220200,20211200 +2022-01-21,20220200,20220300,20220100 +2022-02-18,20220300,20220400,20220200 +2022-03-22,20220400,20220500,20220300 +2022-04-21,20220500,20220600,20220400 +2022-05-23,20220600,20220700,20220500 +2022-06-21,20220700,20220800,20220600 +2022-07-22,20220800,20220900,20220700 +2022-08-22,20220900,20221000,20220800 +2022-09-21,20221000,20221100,20220900 +2022-10-21,20221100,20221200,20221000 +2022-11-21,20221200,20230100,20221100 +2022-12-22,20230100,20230200,20221200 +2023-01-23,20230200,20230300,20230100 +2023-02-20,20230300,20230400,20230200 +2023-03-22,20230400,20230500,20230300 +2023-04-21,20230500,20230600,20230400 +2023-05-22,20230600,20230700,20230500 +2023-06-21,20230700,20230800,20230600 +2023-07-21,20230800,20230900,20230700 +2023-08-22,20230900,20231000,20230800 +2023-09-21,20231000,20231100,20230900 diff --git a/data/futures/roll_calendars_csv/BTC*SPREADBIDOFFER.csv b/data/futures/roll_calendars_csv/BTC*SPREADBIDOFFER.csv new file mode 100644 index 0000000000..a1a4190d35 --- /dev/null +++ b/data/futures/roll_calendars_csv/BTC*SPREADBIDOFFER.csv @@ -0,0 +1,51 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2019-09-20 00:00:00,20190900,20191000,20190800 +2019-09-27 00:00:00,20191000,20191100,20190900 +2019-11-21 00:00:00,20191100,20191200,20191000 +2019-12-20 00:00:00,20191200,20200100,20191100 +2019-12-27 02:00:00,20200100,20200200,20191200 +2020-01-31 00:00:00,20200200,20200300,20200100 +2020-02-27 12:00:00,20200300,20200400,20200200 +2020-03-27 00:00:00,20200400,20200500,20200300 +2020-04-24 00:00:00,20200500,20200600,20200400 +2020-05-29 00:00:00,20200600,20200700,20200500 +2020-06-26 00:00:00,20200700,20200800,20200600 +2020-07-31 00:00:00,20200800,20200900,20200700 +2020-08-28 00:00:00,20200900,20201000,20200800 +2020-09-25 00:00:00,20201000,20201100,20200900 +2020-10-30 00:00:00,20201100,20201200,20201000 +2020-11-27 00:00:00,20201200,20210100,20201100 +2020-12-24 00:00:00,20210100,20210200,20201200 +2021-01-29 00:00:00,20210200,20210300,20210100 +2021-02-26 00:00:00,20210300,20210400,20210200 +2021-03-26 00:00:00,20210400,20210500,20210300 +2021-04-30 00:00:00,20210500,20210600,20210400 +2021-05-28 00:00:00,20210600,20210700,20210500 +2021-06-25 00:00:00,20210700,20210800,20210600 +2021-07-30 00:00:00,20210800,20210900,20210700 +2021-08-27 00:00:00,20210900,20211000,20210800 +2021-09-24 00:00:00,20211000,20211100,20210900 +2021-10-29 00:00:00,20211100,20211200,20211000 +2021-11-26 00:00:00,20211200,20220100,20211100 +2021-12-31 00:00:00,20220100,20220200,20211200 +2022-01-28 00:00:00,20220200,20220300,20220100 +2022-02-25 00:00:00,20220300,20220400,20220200 +2022-03-25 00:00:00,20220400,20220500,20220300 +2022-04-29 00:00:00,20220500,20220600,20220400 +2022-05-27 00:00:00,20220600,20220700,20220500 +2022-06-24 00:00:00,20220700,20220800,20220600 +2022-07-29 00:00:00,20220800,20220900,20220700 +2022-08-26 00:00:00,20220900,20221000,20220800 +2022-09-30 00:00:00,20221000,20221100,20220900 +2022-10-28 00:00:00,20221100,20221200,20221000 +2022-11-25 00:00:00,20221200,20230100,20221100 +2022-12-30 00:00:00,20230100,20230200,20221200 +2023-01-27 00:00:00,20230200,20230300,20230100 +2023-02-24 00:00:00,20230300,20230400,20230200 +2023-03-31 00:00:00,20230400,20230500,20230300 +2023-04-28 00:00:00,20230500,20230600,20230400 +2023-05-26 06:00:00,20230600,20230700,20230500 +2023-06-30 02:00:00,20230700,20230800,20230600 +2023-07-28 01:00:00,20230800,20230900,20230700 +2023-08-25 00:00:00,20230900,20231000,20230800 +2023-09-29 00:00:00,20231000,20231100,20230900 diff --git a/data/futures/roll_calendars_csv/ETH*SPREAD*BIDOFFER.csv b/data/futures/roll_calendars_csv/ETH*SPREAD*BIDOFFER.csv new file mode 100644 index 0000000000..d530772daf --- /dev/null +++ b/data/futures/roll_calendars_csv/ETH*SPREAD*BIDOFFER.csv @@ -0,0 +1,28 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2021-03-21 19:00:00,20210300,20210400,20210200 +2021-03-26 08:00:00,20210400,20210500,20210300 +2021-04-30 05:00:00,20210500,20210600,20210400 +2021-05-28 00:00:00,20210600,20210700,20210500 +2021-06-25 01:00:00,20210700,20210800,20210600 +2021-07-30 00:00:00,20210800,20210900,20210700 +2021-08-27 00:00:00,20210900,20211000,20210800 +2021-09-24 00:00:00,20211000,20211100,20210900 +2021-10-29 00:00:00,20211100,20211200,20211000 +2021-11-26 01:00:00,20211200,20220100,20211100 +2021-12-31 00:00:00,20220100,20220200,20211200 +2022-01-28 00:00:00,20220200,20220300,20220100 +2022-02-25 00:00:00,20220300,20220400,20220200 +2022-03-25 00:00:00,20220400,20220500,20220300 +2022-04-29 02:00:00,20220500,20220600,20220400 +2022-05-27 00:00:00,20220600,20220700,20220500 +2022-06-24 14:00:00,20220700,20220800,20220600 +2022-07-29 00:00:00,20220800,20220900,20220700 +2022-08-26 00:00:00,20220900,20221000,20220800 +2022-09-30 00:00:00,20221000,20221100,20220900 +2022-10-28 00:00:00,20221100,20221200,20221000 +2022-11-25 13:00:00,20221200,20230100,20221100 +2022-12-30 00:00:00,20230100,20230200,20221200 +2023-01-27 14:00:00,20230200,20230300,20230100 +2023-02-24 00:00:00,20230300,20230400,20230200 +2023-03-31 12:00:00,20230400,20230500,20230300 +2023-04-28 12:00:00,20230500,20230600,20230400 diff --git a/data/futures/roll_calendars_csv/ETH*SPREAD.csv b/data/futures/roll_calendars_csv/ETH*SPREAD.csv new file mode 100644 index 0000000000..d530772daf --- /dev/null +++ b/data/futures/roll_calendars_csv/ETH*SPREAD.csv @@ -0,0 +1,28 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2021-03-21 19:00:00,20210300,20210400,20210200 +2021-03-26 08:00:00,20210400,20210500,20210300 +2021-04-30 05:00:00,20210500,20210600,20210400 +2021-05-28 00:00:00,20210600,20210700,20210500 +2021-06-25 01:00:00,20210700,20210800,20210600 +2021-07-30 00:00:00,20210800,20210900,20210700 +2021-08-27 00:00:00,20210900,20211000,20210800 +2021-09-24 00:00:00,20211000,20211100,20210900 +2021-10-29 00:00:00,20211100,20211200,20211000 +2021-11-26 01:00:00,20211200,20220100,20211100 +2021-12-31 00:00:00,20220100,20220200,20211200 +2022-01-28 00:00:00,20220200,20220300,20220100 +2022-02-25 00:00:00,20220300,20220400,20220200 +2022-03-25 00:00:00,20220400,20220500,20220300 +2022-04-29 02:00:00,20220500,20220600,20220400 +2022-05-27 00:00:00,20220600,20220700,20220500 +2022-06-24 14:00:00,20220700,20220800,20220600 +2022-07-29 00:00:00,20220800,20220900,20220700 +2022-08-26 00:00:00,20220900,20221000,20220800 +2022-09-30 00:00:00,20221000,20221100,20220900 +2022-10-28 00:00:00,20221100,20221200,20221000 +2022-11-25 13:00:00,20221200,20230100,20221100 +2022-12-30 00:00:00,20230100,20230200,20221200 +2023-01-27 14:00:00,20230200,20230300,20230100 +2023-02-24 00:00:00,20230300,20230400,20230200 +2023-03-31 12:00:00,20230400,20230500,20230300 +2023-04-28 12:00:00,20230500,20230600,20230400 diff --git a/data/futures/roll_calendars_csv/ETH*SPREAD2.csv b/data/futures/roll_calendars_csv/ETH*SPREAD2.csv new file mode 100644 index 0000000000..987c510be8 --- /dev/null +++ b/data/futures/roll_calendars_csv/ETH*SPREAD2.csv @@ -0,0 +1,28 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2021-03-01,20210300,20210400,20210200 +2021-03-22,20210400,20210500,20210300 +2021-04-21,20210500,20210600,20210400 +2021-05-21,20210600,20210700,20210500 +2021-06-21,20210700,20210800,20210600 +2021-07-22,20210800,20210900,20210700 +2021-08-23,20210900,20211000,20210800 +2021-09-21,20211000,20211100,20210900 +2021-10-22,20211100,20211200,20211000 +2021-11-22,20211200,20220100,20211100 +2021-12-22,20220100,20220200,20211200 +2022-01-21,20220200,20220300,20220100 +2022-02-18,20220300,20220400,20220200 +2022-03-22,20220400,20220500,20220300 +2022-04-21,20220500,20220600,20220400 +2022-05-23,20220600,20220700,20220500 +2022-06-21,20220700,20220800,20220600 +2022-07-22,20220800,20220900,20220700 +2022-08-22,20220900,20221000,20220800 +2022-09-21,20221000,20221100,20220900 +2022-10-21,20221100,20221200,20221000 +2022-11-21,20221200,20230100,20221100 +2022-12-22,20230100,20230200,20221200 +2023-01-23,20230200,20230300,20230100 +2023-02-20,20230300,20230400,20230200 +2023-03-22,20230400,20230500,20230300 +2023-04-21,20230500,20230600,20230400 diff --git a/data/futures/roll_calendars_csv/ETH*SPREAD2BIDOFFER.csv b/data/futures/roll_calendars_csv/ETH*SPREAD2BIDOFFER.csv new file mode 100644 index 0000000000..987c510be8 --- /dev/null +++ b/data/futures/roll_calendars_csv/ETH*SPREAD2BIDOFFER.csv @@ -0,0 +1,28 @@ +DATE_TIME,current_contract,next_contract,carry_contract +2021-03-01,20210300,20210400,20210200 +2021-03-22,20210400,20210500,20210300 +2021-04-21,20210500,20210600,20210400 +2021-05-21,20210600,20210700,20210500 +2021-06-21,20210700,20210800,20210600 +2021-07-22,20210800,20210900,20210700 +2021-08-23,20210900,20211000,20210800 +2021-09-21,20211000,20211100,20210900 +2021-10-22,20211100,20211200,20211000 +2021-11-22,20211200,20220100,20211100 +2021-12-22,20220100,20220200,20211200 +2022-01-21,20220200,20220300,20220100 +2022-02-18,20220300,20220400,20220200 +2022-03-22,20220400,20220500,20220300 +2022-04-21,20220500,20220600,20220400 +2022-05-23,20220600,20220700,20220500 +2022-06-21,20220700,20220800,20220600 +2022-07-22,20220800,20220900,20220700 +2022-08-22,20220900,20221000,20220800 +2022-09-21,20221000,20221100,20220900 +2022-10-21,20221100,20221200,20221000 +2022-11-21,20221200,20230100,20221100 +2022-12-22,20230100,20230200,20221200 +2023-01-23,20230200,20230300,20230100 +2023-02-20,20230300,20230400,20230200 +2023-03-22,20230400,20230500,20230300 +2023-04-21,20230500,20230600,20230400 diff --git a/sysbrokers/IB/client/ib_contracts_client.py b/sysbrokers/IB/client/ib_contracts_client.py index ba37df0c7f..c1d5020a18 100644 --- a/sysbrokers/IB/client/ib_contracts_client.py +++ b/sysbrokers/IB/client/ib_contracts_client.py @@ -37,6 +37,7 @@ class ibContractsClient(ibClient): + def broker_get_futures_contract_list( self, futures_instrument_with_ib_data: futuresInstrumentWithIBConfigData, diff --git a/sysbrokers/IB/client/ib_orders_client.py b/sysbrokers/IB/client/ib_orders_client.py index 0a4c8cd12f..52ea136894 100644 --- a/sysbrokers/IB/client/ib_orders_client.py +++ b/sysbrokers/IB/client/ib_orders_client.py @@ -91,6 +91,7 @@ def broker_submit_order( account_id: str = arg_not_supplied, order_type: brokerOrderType = market_order_type, limit_price: float = None, + what_if: bool = False ) -> tradeWithContract: """ @@ -121,7 +122,10 @@ def broker_submit_order( limit_price=limit_price, ) - order_object = self.ib.placeOrder(ibcontract, ib_order) + if what_if: + order_object = self.ib.whatIfOrder(ibcontract, ib_order) + else: + order_object = self.ib.placeOrder(ibcontract, ib_order) trade_with_contract = tradeWithContract(ibcontract_with_legs, order_object) diff --git a/sysbrokers/IB/ib_broker_commissions.py b/sysbrokers/IB/ib_broker_commissions.py new file mode 100644 index 0000000000..a187343cdd --- /dev/null +++ b/sysbrokers/IB/ib_broker_commissions.py @@ -0,0 +1,64 @@ +from sysbrokers.IB.client.ib_contracts_client import ibContractsClient +from sysbrokers.IB.client.ib_orders_client import ibOrdersClient +from sysbrokers.IB.ib_futures_contracts_data import ibFuturesContractData +from sysbrokers.IB.ib_instruments_data import ( + ibFuturesInstrumentData +) +from sysbrokers.IB.ib_connection import connectionIB +from sysbrokers.IB.ib_orders import ibExecutionStackData +from sysdata.data_blob import dataBlob +from sysexecution.orders.broker_orders import brokerOrder +from sysobjects.contracts import futuresContract + +from syslogging.logger import * +from sysbrokers.broker_commissions import brokerFuturesContractCommissionData + +class ibFuturesContractCommissionData(brokerFuturesContractCommissionData): + """ + Extends the baseData object to a data source that reads in and writes prices for specific futures contracts + + This gets HISTORIC data from interactive brokers. It is blocking code + In a live production system it is suitable for running on a daily basis to get end of day prices + + """ + + def __init__( + self, + ibconnection: connectionIB, + data: dataBlob, + log=get_logger("ibFuturesContractCommissionData"), + ): + super().__init__(log=log, data=data) + self._ibconnection = ibconnection + + def __repr__(self): + return "IB Futures commissions data %s" % str(self.ib_client) + + @property + def ibconnection(self) -> connectionIB: + return self._ibconnection + + @property + def execution_stack(self) -> ibExecutionStackData: + return self.data.broker_execution_stack + + def get_commission_for_contract(self, futures_contract: futuresContract) -> float: + ## FOR NOW DO NOT RUN IF ANYTHING ELSE IS RUNNING + ## NEEDS CODE TO TAKE THE TEST STRATEGY OFF THE STACK WHEN RETURNING ORDERS + size_of_test_trade = 10 + instrument_code = futures_contract.instrument_code + contract_date = futures_contract.contract_date.list_of_date_str[0] + + broker_order =brokerOrder(test_commission_strategy, instrument_code, contract_date, + size_of_test_trade) + + order = self.execution_stack.put_what_if_order_on_stack(broker_order) + + while not self.execution_stack.is_completed(order.order.order_id): + ## could last forever! + continue + + order_from_stack = self.execution_stack.get_order_with_id_from_stack(order_id=order.order.order_id) + return order_from_stack.commission / 10.0 + +test_commission_strategy = "testCommmission" diff --git a/sysbrokers/IB/ib_futures_contracts_data.py b/sysbrokers/IB/ib_futures_contracts_data.py index e34e3fbbd2..7a3b8d62ee 100644 --- a/sysbrokers/IB/ib_futures_contracts_data.py +++ b/sysbrokers/IB/ib_futures_contracts_data.py @@ -54,6 +54,10 @@ def ib_client(self) -> ibContractsClient: def ib_futures_instrument_data(self) -> ibFuturesInstrumentData: return self.data.broker_futures_instrument + def get_commission_for_contract(self, futures_contract: futuresContract) -> float: + ib_contract = self.get_contract_object_with_IB_data(futures_contract) + return self.ib_client.get_commission_for_contract(ib_contract) + def get_list_of_contract_dates_for_instrument_code( self, instrument_code: str, allow_expired: bool = False ) -> listOfContractDateStr: diff --git a/sysbrokers/IB/ib_orders.py b/sysbrokers/IB/ib_orders.py index f7bbdb20b8..b1ca0c2aee 100644 --- a/sysbrokers/IB/ib_orders.py +++ b/sysbrokers/IB/ib_orders.py @@ -266,12 +266,33 @@ def put_order_on_stack(self, broker_order: brokerOrder) -> ibOrderWithControls: :param broker_order: key properties are instrument_code, contract_id, quantity :return: ibOrderWithControls or missing_order """ - trade_with_contract_from_ib = self._send_broker_order_to_IB(broker_order) - order_time = datetime.datetime.now() + trade_with_contract_from_ib = self._send_broker_order_to_IB(broker_order, what_if=False) + + placed_broker_order_with_controls = self._return_place_order_given_ib_trade_with_contract(trade_with_contract_from_ib=trade_with_contract_from_ib, + broker_order=broker_order) + + return placed_broker_order_with_controls + def put_what_if_order_on_stack(self, broker_order: brokerOrder) -> ibOrderWithControls: + """ + + :param broker_order: key properties are instrument_code, contract_id, quantity + :return: ibOrderWithControls or missing_order + """ + trade_with_contract_from_ib = self._send_broker_order_to_IB(broker_order, what_if=True) + + placed_broker_order_with_controls = self._return_place_order_given_ib_trade_with_contract( + trade_with_contract_from_ib=trade_with_contract_from_ib, + broker_order=broker_order) + + return placed_broker_order_with_controls + + def _return_place_order_given_ib_trade_with_contract(self, trade_with_contract_from_ib: tradeWithContract, broker_order: brokerOrder) -> ibOrderWithControls: if trade_with_contract_from_ib is missing_order: return missing_order + order_time = datetime.datetime.now() + placed_broker_order_with_controls = ibOrderWithControls( trade_with_contract_from_ib, ibclient=self.ib_client, @@ -288,7 +309,7 @@ def put_order_on_stack(self, broker_order: brokerOrder) -> ibOrderWithControls: return placed_broker_order_with_controls - def _send_broker_order_to_IB(self, broker_order: brokerOrder) -> tradeWithContract: + def _send_broker_order_to_IB(self, broker_order: brokerOrder, what_if: bool = False) -> tradeWithContract: """ :param broker_order: key properties are instrument_code, contract_id, quantity @@ -317,6 +338,7 @@ def _send_broker_order_to_IB(self, broker_order: brokerOrder) -> tradeWithContra account_id=account_id, order_type=order_type, limit_price=limit_price, + what_if=what_if ) if placed_broker_trade_object is missing_order: self.log.warning("Couldn't submit order", **log_attrs) diff --git a/sysbrokers/broker_commissions.py b/sysbrokers/broker_commissions.py new file mode 100644 index 0000000000..e211695120 --- /dev/null +++ b/sysbrokers/broker_commissions.py @@ -0,0 +1,18 @@ +from sysdata.futures.contracts import futuresContractData +from sysdata.data_blob import dataBlob +from sysobjects.contracts import futuresContract + +from syslogging.logger import * + + +class brokerFuturesContractCommissionData(futuresContractData): + def __init__(self, data: dataBlob, log=get_logger("brokerFuturesContractCommissionData")): + super().__init__(log=log) + self._data = data + + def get_commission_for_contract(self, contract: futuresContract) -> float: + raise NotImplementedError + + @property + def data(self): + return self._data diff --git a/sysbrokers/broker_factory.py b/sysbrokers/broker_factory.py index be4eaabe44..6cfe4e3bbb 100644 --- a/sysbrokers/broker_factory.py +++ b/sysbrokers/broker_factory.py @@ -7,6 +7,7 @@ from sysbrokers.IB.ib_orders import ibExecutionStackData from sysbrokers.IB.ib_static_data import ibStaticData from sysbrokers.IB.ib_fx_handling import ibFxHandlingData +from sysbrokers.IB.ib_broker_commissions import ibFuturesContractCommissionData from syscore.objects import resolve_function from sysdata.data_blob import dataBlob @@ -43,4 +44,5 @@ def get_ib_class_list(): ibCapitalData, ibFuturesInstrumentData, ibFxHandlingData, + ibFuturesContractCommissionData ] diff --git a/sysbrokers/broker_futures_contract_data.py b/sysbrokers/broker_futures_contract_data.py index 69bff1653a..47124937d8 100644 --- a/sysbrokers/broker_futures_contract_data.py +++ b/sysbrokers/broker_futures_contract_data.py @@ -13,6 +13,9 @@ def __init__(self, data: dataBlob, log=get_logger("brokerFuturesContractData")): super().__init__(log=log) self._data = data + def get_commission_for_contract(self, contract: futuresContract) -> float: + raise NotImplementedError + def get_actual_expiry_date_for_single_contract( self, futures_contract: futuresContract ) -> expiryDate: diff --git a/syscore/interactive/progress_bar.py b/syscore/interactive/progress_bar.py index 887529a21c..1f82f79bfc 100644 --- a/syscore/interactive/progress_bar.py +++ b/syscore/interactive/progress_bar.py @@ -26,6 +26,9 @@ def __init__( show_timings=True, toolbar_width: int = 80, ): + if range_to_iterate_over==0: + range_to_iterate_over=1 + self._start_time = time.time() self._current_iteration = 0 self._suffix = suffix diff --git a/sysexecution/order_stacks/order_stack.py b/sysexecution/order_stacks/order_stack.py index e2c95987fe..e913e75941 100644 --- a/sysexecution/order_stacks/order_stack.py +++ b/sysexecution/order_stacks/order_stack.py @@ -138,6 +138,8 @@ def put_order_on_stack(self, new_order: Order): """ Put an order on the stack + ARgs and Kwargs in case of overwriting + :param new_order: Order :return: order_id or failure condition: duplicate_order, failure """ @@ -145,6 +147,7 @@ def put_order_on_stack(self, new_order: Order): return order_id + # FIND AND LIST ORDERS def get_list_of_orders(self, exclude_inactive_orders: bool = True) -> list: diff --git a/sysinit/futures/build_roll_calendars.py b/sysinit/futures/build_roll_calendars.py index 8ee559983d..4f0cc19dfb 100644 --- a/sysinit/futures/build_roll_calendars.py +++ b/sysinit/futures/build_roll_calendars.py @@ -469,7 +469,7 @@ def _valid_dates_from_paired_prices(paired_prices: pd.DataFrame, avoid_date): def _matching_prices_from_paired_prices(paired_prices): paired_prices_check_match = paired_prices.apply( - lambda xlist: not any(np.isnan(xlist)), axis=1 + lambda xlist: not any(pd.isnull(xlist)), axis=1 ) paired_prices_matching = paired_prices_check_match[paired_prices_check_match] diff --git a/sysproduction/data/broker.py b/sysproduction/data/broker.py index c6b1607111..646bedcc5d 100644 --- a/sysproduction/data/broker.py +++ b/sysproduction/data/broker.py @@ -1,4 +1,3 @@ -from copy import copy from sysbrokers.broker_factory import get_broker_class_list from sysbrokers.broker_fx_handling import brokerFxHandlingData @@ -10,10 +9,10 @@ from sysbrokers.broker_contract_position_data import brokerContractPositionData from sysbrokers.broker_fx_prices_data import brokerFxPricesData from sysbrokers.broker_instrument_data import brokerFuturesInstrumentData +from sysbrokers.broker_commissions import brokerFuturesContractCommissionData from syscore.exceptions import missingData from syscore.constants import arg_not_supplied -from syscore.exceptions import orderCannotBeModified from sysexecution.orders.named_order_objects import missing_order from syscore.dateutils import Frequency, DAILY_PRICE_FREQ from sysobjects.production.trading_hours.trading_hours import listOfTradingHours @@ -35,7 +34,7 @@ from sysobjects.contract_dates_and_expiries import expiryDate from sysobjects.contracts import futuresContract from sysobjects.instruments import futuresInstrumentWithMetaData -from sysobjects.production.positions import contractPosition, listOfContractPositions +from sysobjects.production.positions import listOfContractPositions from sysobjects.spot_fx_prices import fxPrices from sysobjects.futures_per_contract_prices import futuresContractPrices from sysproduction.data.positions import diagPositions @@ -57,6 +56,10 @@ def _add_required_classes_to_data(self, data) -> dataBlob: data.add_class_list(broker_class_list) return data + @property + def broker_futures_contract_commission(self) -> brokerFuturesContractCommissionData: + return self.data.broker_futures_contract_commission + @property def broker_fx_price_data(self) -> brokerFxPricesData: return self.data.broker_fx_prices @@ -98,6 +101,8 @@ def diag_controls(self) -> diagControlProcess: return self._diag_controls ## Methods + def get_commission_for_contract(self, contract: futuresContract) -> float: + return self.broker_futures_contract_commission.get_commission_for_contract(contract) def get_list_of_contract_dates_for_instrument_code( self, instrument_code: str, allow_expired: bool = False @@ -335,19 +340,6 @@ def get_market_conditions_for_contract_order_by_leg( def check_market_conditions_for_single_legged_contract_and_qty( self, contract: futuresContract, qty: int ) -> analysisTick: - """ - Get current prices - - :param contract_order: - :return: tuple: side_price, mid_price OR missing_data - """ - - """ - Get current prices - - :param contract_order: - :return: tuple: side_price, mid_price OR missing_data - """ tick_data = self.get_recent_bid_ask_tick_data_for_contract_object(contract) @@ -357,7 +349,7 @@ def check_market_conditions_for_single_legged_contract_and_qty( return analysis_of_tick_data - def submit_broker_order(self, broker_order: brokerOrder) -> orderWithControls: + def submit_broker_order(self, broker_order: brokerOrder, *args, **kwargs) -> orderWithControls: """ :param broker_order: a broker_order diff --git a/sysquant/fitting_dates.py b/sysquant/fitting_dates.py index 3764f909e3..844b87fd82 100644 --- a/sysquant/fitting_dates.py +++ b/sysquant/fitting_dates.py @@ -209,7 +209,7 @@ def _add_dummy_period_if_required( start_date: datetime.datetime, list_of_starting_dates_per_period: list, ): - if date_method in ["rolling", "expanding"]: + if date_method in ["rolling", "expanding"] and len(list_of_starting_dates_per_period)>1: # add on a dummy date for the first year, when we have no data periods = [ fitDates( diff --git a/systems/accounts/pandl_calculators/pandl_calculation.py b/systems/accounts/pandl_calculators/pandl_calculation.py index ebf1ced812..6380f86c95 100644 --- a/systems/accounts/pandl_calculators/pandl_calculation.py +++ b/systems/accounts/pandl_calculators/pandl_calculation.py @@ -1,5 +1,4 @@ import pandas as pd -import numpy as np from syscore.constants import arg_not_supplied from syscore.dateutils import from_config_frequency_pandas_resample diff --git a/systems/portfolio.py b/systems/portfolio.py index cc4d11f7f5..1931a6f6d1 100644 --- a/systems/portfolio.py +++ b/systems/portfolio.py @@ -459,7 +459,6 @@ def get_unsmoothed_instrument_weights_fitted_to_position_lengths( ) ## this should remove when have NAN's - ## FIXME CHECK instrument_weights = fix_weights_vs_position_or_forecast( raw_instrument_weights, subsystem_positions @@ -730,7 +729,7 @@ def _add_zero_weights_to_instrument_weights_df( weight_index = instrument_weights.index new_pd_as_dict = dict( [ - (instrument_code, pd.Series([0.0] * len(weight_index))) + (instrument_code, pd.Series([0.0] * len(weight_index), index=weight_index)) for instrument_code in instrument_list_to_add ] )