
[{"content":"","date":"3 December 2025","externalUrl":null,"permalink":"/","section":"Bug or Feature","summary":"","title":"Bug or Feature","type":"page"},{"content":"","date":"3 December 2025","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"List summary of blog posts for Bug or Feature","title":"Posts","type":"posts"},{"content":"","date":"26 November 2025","externalUrl":null,"permalink":"/tags/claude/","section":"tags","summary":"","title":"claude","type":"tags"},{"content":"","date":"26 November 2025","externalUrl":null,"permalink":"/tags/ig/","section":"tags","summary":"","title":"IG","type":"tags"},{"content":"IG Markets added a new set of endpoints to their API sometime in late 2023 or early 2024. I\u0026rsquo;m going to have a crack at adding support for those new endpoints to trading-ig.\nThe new endpoints are documented here, down at the bottom under Indicative costs and charges:\nhttps://labs.ig.com/rest-trading-api-reference.html\nAs far as I know, there was no announcement anywhere about the changes. The IG Community pages were abruptly removed some time ago. The IG Labs page has links to a LinkedIn profile, and a Twitter account, but no activity there. So it\u0026rsquo;s hard to know what the driver is for this new functionality. And who knows what this means?\nwebsite IDs: atm, atf, dem, def, det, esm, esf, est, frm, frf, frt, itm, itf, itt, nlm, nlf, nlt, nom, nof, not, sem, sef, set, eng, enf, ent, iei, iem, ief, iet, igi, igm, por, pof.\nNevertheless, the docs are there, so let\u0026rsquo;s see what this new stuff does.\nThe first step is to enlist the help of my trusty code wrangler Claude - after a brief chat, he made very short work of implementing the four new methods:\nhttps://github.com/bug-or-feature/trading-ig/commit/0ebe47f90e0d1f8bdcf08aa26b416a6fce5456e3\nTop job Claude! That would have taken me hours a few years ago. I usually run the code to see what the responses look like. Then we\u0026rsquo;ll know whether we need to create unit or integration tests, or both. For these endpoints, we don\u0026rsquo;t really know what they\u0026rsquo;re even for yet, so let\u0026rsquo;s see what comes back. The history one looks like the easiest one to try, as it doesn\u0026rsquo;t need any setup. Presumably, it gives a summary of costs and charges for the given dates. Let\u0026rsquo;s see:\nimport logging from trading_ig.config import config from trading_ig.rest import IGService ig_service = IGService( config.username, config.password, config.api_key, acc_number=config.acc_number, acc_type=config.acc_type, ) ig_service.create_session(version=\u0026#34;2\u0026#34;) response = ig_service.fetch_indicative_costs_history( # User-specified from date (yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss. SSSXXX) \u0026#34;2025-01-01T00:00:00. 000+01:00\u0026#34;, \u0026#34;2025-10-31T00:00:00. 000+01:00\u0026#34; ) print(f\u0026#34;fetch_indicative_costs_history: {response}\u0026#34;) Hmm, the date format is a little odd - not an ISO 8601 standard with that space after the dot. Maybe a typo? And it\u0026rsquo;s a bit strange that we need to specify the microseconds and timezone anyway. Plus, that means there are now four different datetime formats to deal with in the IG API \u0026lt;sigh\u0026gt;. Anyway, the response is an error:\nException: {\u0026#34;errorMessage\u0026#34;:\u0026#34;Required request parameter \u0026#39;pageSize\u0026#39; for method parameter type int is not present\u0026#34;} That implies that the pageSize parameter is missing. Even though the docs say it\u0026rsquo;s optional. Not a great start. OK, let\u0026rsquo;s add it to the rest.py function, and try again\n1def fetch_indicative_costs_history( 2 self, 3 from_date, 4 to_date, 5 session=None, 6): 7 8 self.non_trading_rate_limit_pause_or_pass() 9 version = \u0026#34;1\u0026#34; 10 params = {} 11 params[\u0026#34;pageSize\u0026#34;] = 20 12 url_params = {\u0026#34;from\u0026#34;: from_date, \u0026#34;to\u0026#34;: to_date} 13 endpoint = \u0026#34;/indicativecostsandcharges/history/from/{from}/to/{to}\u0026#34;.format( 14 **url_params 15 ) 16 action = \u0026#34;read\u0026#34; 17 response = self._req(action, endpoint, params, session, version) 18 data = self.parse_response(response.text) 19 20 return data and the response\nException: {\u0026#34;errorMessage\u0026#34;:\u0026#34;Required request parameter \u0026#39;pageNumber\u0026#39; for method parameter type int is not present\u0026#34;} Oh dear. Why am I not surprised? OK, let\u0026rsquo;s add params[\u0026quot;pageNumber\u0026quot;] = 1 too.\ntrading_ig.rest.IGException: Server problem: status code: 500, reason: Internal Server Error OK, that is not good. Life is too short to deal with this sort of nonsense so late in the day. Time for a beer and Champions League footy.\nTo be continued at a later date\u0026hellip;\n","date":"26 November 2025","externalUrl":null,"permalink":"/posts/ig-costs-endpoints/","section":"Posts","summary":"IG Markets added a new set of endpoints to their API sometime in late 2023 or early 2024. I\u0026rsquo;m going to have a crack at adding support for those new endpoints to trading-ig","title":"New costs endpoints in IG API","type":"posts"},{"content":"","date":"26 November 2025","externalUrl":null,"permalink":"/tags/python/","section":"tags","summary":"","title":"python","type":"tags"},{"content":"","date":"26 November 2025","externalUrl":null,"permalink":"/tags/","section":"tags","summary":"","title":"tags","type":"tags"},{"content":"","date":"26 November 2025","externalUrl":null,"permalink":"/tags/trading-ig/","section":"tags","summary":"","title":"trading-ig","type":"tags"},{"content":"The default pysystemtrade setup includes a Python script that renames old echo files with the date and an .arch extension, and deletes them after 30 days:\nsysproduction/clean_truncate_echo_files.py This script is executed by the scheduled job run_cleaners, usually just after daily orders are created. This is fine. The script works. But there are a few issues:\nthe behaviour is not configurable the old logs are not compressed there\u0026rsquo;s a lot of Python code for doing not much really But the bigger problem is that there is already a standard unix tool that does this stuff. Unsurprisingly, the act of cleaning up old logs is a common task. logrotate is your friend here; it does its one job very well, is highly configurable, and has been battle tested on countless systems for decades. You can read the man pages here, and a decent howto article here.\nsetup with pysystemtrade # To replicate the existing pysystemtrade behaviour, you\u0026rsquo;ll want a config, something like\n/home/user/echos/*.txt { daily rotate 30 maxage 30 missingok dateext notifempty } You could put the config in a file named logrotate.conf, perhaps alongside the private config files, so /home/user/private_config/logrotate.conf. And then run it daily from cron with a command like\n$ logrotate /home/user/private_config/logrotate.conf -v --state /home/user/.logrotate.state The default echo cleaning script would need to be turned off too. Edit private_control_config.yaml so it looks like:\nprocess_configuration_methods: run_cleaners: clean_backtest_states: max_executions: 1 clean_echo_files: max_executions: 0 However, for my own system I want different behaviour:\nmy log files are named *.log not *.txt I only want to keep logs for a couple of weeks I want to compress old files I want to wait one day before compressing, as usually when I\u0026rsquo;m looking at logs, it\u0026rsquo;s from the day before I don\u0026rsquo;t want the date part at the end of the filename, I want it before the extension To do this with the existing Python scripts would be fiddly and painful. But with logrotate, I can adjust the config like:\n/home/user/pysystemtrade/*.log { daily rotate 10 maxage 14 missingok dateext compress notifempty delaycompress extension .log } My logs are rotated exactly as I want. And I have not had to change any Python files\n","date":"10 November 2025","externalUrl":null,"permalink":"/posts/better-log-rotation/","section":"Posts","summary":"How to use a standard unix tool to manage rotation of pysystemtrade logs better than the supplied Python script","title":"Better log rotation in pysystemtrade","type":"posts"},{"content":"","date":"10 November 2025","externalUrl":null,"permalink":"/tags/logging/","section":"tags","summary":"","title":"logging","type":"tags"},{"content":"","date":"10 November 2025","externalUrl":null,"permalink":"/tags/pysystemtrade/","section":"tags","summary":"","title":"pysystemtrade","type":"tags"},{"content":"Hi - I\u0026rsquo;m Andy Geach, a software engineer with over 25 years\u0026rsquo; experience building enterprise systems. I have a great passion for technology and take great satisfaction in making things work. I have previously worked with Deutsche Bank, J.P. Morgan, Sony Music, Barclays, and the Reserve Bank of Australia.\nI became interested in systematic trading in 2020 and shifted my technology focus from the JDK world to Python and data science. What began as exploring quantitative trading strategies evolved into maintaining several popular open-source systematic trading frameworks, running my own strategies, and providing consultancy for other traders. I have applied decades of software engineering discipline to create maintainable, production-quality code and data pipelines.\nNeed a software developer? Let\u0026rsquo;s talk about how I can help solve your technical challenges. I\u0026rsquo;m available for contract, fractional, or project-based software development work, particularly in fintech, trading systems and data processing.\n","externalUrl":null,"permalink":"/about/","section":"Bug or Feature","summary":"About Bug or Feature","title":"About","type":"page"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"authors","summary":"","title":"authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"categories","summary":"","title":"categories","type":"categories"},{"content":"Bug or Feature Ltd provides software consultancy services in the UK.\nThe purposes of this privacy notice/policy are:\nTo outline what personal information is collected To outline how personal information is collected To outline how personal information is stored What personal information will be collected? The only information collected is:\nname email How will the information be collected? The data and information will be collected directly from our contact form\nHow will the information be used, including shared/disclosed? We collect this data so that we can respond to contact form queries. No data is shared or disclosed\nWhat are the legal grounds for collecting data? The legal grounds for us collecting this data are the laws of England and Wales, specifically UK-GDPR, and the Data Protection Act of 2018. No information is shared with any other organisation or individual\nHow will the data be stored and secured (including security practices)? This information is stored in the server log files and client email applications. The information is retained only as long as is necessary to respond to queries. Once communication between parties is established or finished, the information will be deleted\nChanges to and retention of the data. You are able to make changes to your data by contacting privacy@bugorfeature.net. Your data will be retained for 2 weeks. At the end of that period, your data will be deleted\nUser’s rights including the right to object or withdrawal of consent. Your consent to our usage of your data can be withdrawn at any time. To do this, please contact privacy@bugorfeature.net\nUnder UK data protection laws, users have the following rights:\nThe right to be informed about the processing of personal information The right to have personal information corrected if it is inaccurate and to have incomplete personal information completed The right to object to processing of personal information The right to restrict processing of personal information The right to have personal information erased The right to request access to personal information and how it’s processed The right to move, copy or transfer personal information Rights in relation to automated decision-making which has a legal effect or otherwise significantly affects the user The above rights cannot be exercised in all circumstances, and therefore, not all requests will be approved by us. Any responses received will outline which rights apply (or don’t) and whether we will comply with the request or not and the reasons why\nOpting out of communications. You have the right to opt-out of marketing and other non-essential communications. To do this, please contact privacy@bugorfeature.net\nRight of complaint. In case of any problem or complaint, please contact privacy@bugorfeature.net in the first instance. You have the right to complain to the Information Commissioner’s Office which enforces data protection laws: www.ico.org.uk\nInformation regarding international data transfer. No information is shared with any other organisation or individual\nCookie policy. Cookies are small pieces of text sent to your browser by our site. They help us remember information about your visit, which can help and improve your experience of our website. We use them for\nidentifying bots reducing spam enabling features remembering preferences The data collected by our cookies does not include:\npersonal data Disabling cookies and changing preferences. Cookies can be accepted or rejected, and preferences changed at any time by using the \u0026lsquo;Cookie Settings\u0026rsquo; button, see below\nChanges to the notice/policy. We reserve the right to make changes to this policy at any time to reflect updates to the law or changes to our data collection and security practices. We recommend that you review it regularly for your own knowledge and benefit\n","externalUrl":null,"permalink":"/policy/","section":"Bug or Feature","summary":"Privacy Policy for Bug or Feature","title":"Privacy Policy","type":"page"},{"content":"","externalUrl":null,"permalink":"/series/","section":"series","summary":"","title":"series","type":"series"}]