Musing #61: Adapting apps for Gear Fit2 (Pro)

While the original post was about the 2048 app, I feel it would be best to have a single post for all my adapted Gear Fit2 (Pro) apps. The original article is still present below for any guidance it may provide in installing the apps on the device. I will be listing the apps along with a screenshot and the link to download the *.wgt files. A short description has been included along with references to the original source/app.

1. 2048: Based on the latest source (Oct 2017) for 2048 posted on Github with suitable interface/colour modifications for Gear Fit2 Pro. Uploaded on Sep 11, 2018.

2. SciCal: Based on an app called 'Kalkulator' or 'Calculator Net 6' for the Gear S, I have renamed it to SciCal as it is a scientific calculator while adding a catchy icon from Wikimedia. The dimensions of all the "pages" of the calculator have been modified so that no scrolling is present. Unfortunately, the interface stays as it is due to the large amount of information involved. Uploaded on Sep 23, 2018.

Original Article (Sep 11, 2018):

It is no surprise that Samsung has artificially stifled the Gear Fit series for it to not steal the limelight from their flagship "S" series. Consequently, Galaxy Apps store submissions for the Gear Fit2 and Pro are only limited to watch faces with partners like Spotify being the only ones allowed to publish apps for the device.

This doesn't imply that the device itself is incapable of running third-party apps. Samsung provides the necessary tools to create, install and run applications for the Tizen platform as a whole and this benefits the Gear Fit2 devices as well. However, without a centralised distributor, it takes a lot more effort to get an app distributed and installed on the device.

The Gear Fit2 is capable of running web apps which are essentially websites stored on the device. Hence, for my first Tizen app, I decided to go with the sliding-block puzzle game 2048 which is freely available on GitHub under MIT license and presents an everlasting challenge, even on the wrist.

Apart from scaling the game to fit the 216x432 screen, I have made a couple of tweaks to the interface so as to optimise the experience for the device. The first is switching the colour scheme to darker colours to preserve battery life on the SAMOLED screen as against the default lighter colour scheme. The second tweak, apart from adjusting the font size and spacing, is to switch the 'New Game' option higher up and to the left to prevent accidental resetting of the game when swiping up, as has happened to me on more than a few occasions.

I have uploaded the 2048.wgt file, as installed on my Gear Fit2 Pro. This implies that the file is self-signed and hence will not install on any other device. Thus, you will have to sign it specifically for your device prior to installation. Detailed instructions on the same can be found on XDA. After self-signing, the app can be installed using the Tizen Studio SDK by connecting to the device using "sdb connect <ipaddress>" and then issuing the command "sdb install 2048.wgt". Details on that command can be found here.

So, test it out and let me know how you feel about it in the comments. You may also share the details of any other web applications that you would like to adapted for the Gear Fit2 devices.

Review #53: Samsung Gear Fit2 Pro (with iOS) ★★★⯪☆

Update #2 (Sep 21, 2018): The GF2 Pro isn't detected on the iOS 12.1 beta either. However, it works normally after downgrading to 11.4.1. Surprisingly, it seems that the original GF2 has no compatibility issues with iOS 12 which makes this situation even more curious. Samsung hasn't yet responded to any of my communications through the App Store, Twitter and e-mail, so one can only hope that a fix is in the works.

Update #1 (Sep 13, 2018): With a new iPhone launch comes a new OS. While iOS 12 is a welcome relief for iOS 11 users, it spells danger for Gear Fit2 Pro owners.

I updated to the iOS 12 GM release (16A366) yesterday which is what will be released to the general public on September 17th and it breaks compatibility with the Gear Fit2 Pro to the extent that it is not even detected as a Bluetooth device. All other Bluetooth devices are detected fine on iOS 12 and the Gear Fit2 itself is detected by other Bluetooth devices.

To top it all, there was no forewarning that this would happen as even the last iOS 12 Beta release worked fine with the Gear Fit2 Pro. Hence, it can only be construed that Apple made a change that hampers competing wearable devices, or at least this one from Samsung.

I have already shared the incompatibility details with Samsung and hope that they would release an update soon to address this issue since it seems Apple has already drawn the sword. Prospective owners should wait it out till the GF2 Pro becomes compatible with iOS 12.

P.S.: To follow-up on my previous post-script on Unicode 11.0, I have included the 'Star with left half black' as the fourth character in my star rating. You would be seeing a hollow block until your browser supports Unicode 11.0 which might not happen until the end of 2018 at the earliest, but that's the price you pay for writing in to the future.

Musing #60: PC Overclocking



Having grown up through the megahertz and subsequently the gigahertz war, I can only say that speed matters. Over the years, I fought to get the last ounce of performance out of the system that was "machinely" possible. This was the case until Sandy Bridge arrived. On one hand, it offered the most value for money in an eternity and on the other, set a trend where overclocking meant buying in to the most expensive processors and motherboards.

Hence, it was a practical decision at the time to go with the i5-3470, a processor with locked multiplier, along with a H77 chipset motherboard that was not meant to assist overclocking. It still offered the option to run all the cores at the turbo frequency of 3.6 GHz instead of the base frequency of 3.2 GHz and that is how it ran for nearly 6 years. It met every requirement I had of the system and a bit more so as to not be concerned about upgrading.

However, as is always the case, my hand was forced, like it was in the past when I upgraded to the GTX 1060. Only this time, I had no intention of upgrading the trio of processor, motherboard and RAM considering the inflated memory prices as well as with AMD's Zen 2 and Intel's 10nm processors around the corner. For the first time, I was left in a rather peculiar situation where I needed to change a component for a platform that has been discontinued for years.

Luckily, there is always the web that one can turn to. Scourging the tech forums for a desired motherboard is akin to hitting the lottery and sure enough I didn't luck out. Then, I decided to go with one of the B75 chipset motherboards that were still mysteriously available on Amazon, only to discover that they were OEM boards with a locked BIOS and lacking compatibility with my RAM. So, after I made the most of Amazon's gracious return policy, I decided to uptake the final resort and go ahead with the purchase of a used motherboard, admittedly with my fingers crossed, on AliExpress.

The shipment had its fair bit of drama over a period of 3 weeks but finally made its way through and was surprisingly well packaged. The absence of dust was a welcome sight, though the rusted socket screws immediately gave way to the fact that the board was used. All things considered, the motherboard was in good condition and thankfully the mounting bracket was included.


The board, an Asus P8Z77-V LX, opened up CPU overclocking opportunities in ages, albeit limited ones on account of my existing hardware. Overclocking can't be thought of in isolation as due consideration is needed to be given toheat. Intel's stock cooler is anything but the perfect foil for overclocking and hence I had to first stock up (pun intended) on an after-market cooler. For this, I again first turned to the used market and amazingly found an open box Deepcool Gammaxx 300 for INR 1200 ($17) as opposed to a new unit price of INR 2000 ($29). It isn't something on any ardent overclocker's wishlist but it gets the job done with its 3 heat pipes and a ginormous 120 mm fan.


To capture the difference that even a budget after-market cooler can make, I ran the stock cooler back-to-back with the Gammaxx 300 on the exposed motherboard. To check the stress temperatures, I simply bumped up the CPU multiplier over the default settings. Even in this setup, the Gammaxx 300 lowered the temperatures by over 20 degrees when under load while also ensuring a much lower idle temperature.


The bigger test however is ensuring lower temperatures in a constrained environment. In that sense, my cabinet (a generic old one at that) is not located in the most optimum position due to cabling constraints. Hence, I was expecting the temperatures to be much worst than they actually turned out to be. It also indicates that using the stock cooler was not even an option, unless you are looking for fried eggs and expensive paperweights.


Being out of the overclocking game for so long, I read up on the motherboard's features while the board was still in transit to fathom some of the newer terms and pretty much decided on a list of settings I would go around changing in my pursuit of performance with the lowest power consumption and heat generation. Thankfully, up until Ivy Bridge, Intel provided limited unlocked multipliers 4 bins above the maximum turbo frequency. This meant that my i5-3470 with a base multiplier of 32 and turbo multiplier of 36 was capable of being run at 40 multiplier. This doesn't imply that all 4 cores can simultaneously hit the 4 GHz mark as it is limited to 3.8 GHz by design. However, what it means is that it can certainly hit the magical 4G mark when one or two of the cores are loaded. I suppose there is some satisfaction in finally getting an old horse to learn new tricks.


Setting the multiplier at its maximum is easy and can even be done using the Auto or XMP overclock option. The difficult part is controlling the temperatures while also finding the limits of the RAM. To that end, I found the Load-Line Calibration to be an indispensable tool in tightening up the voltages and thereby lowering the offset. After much trial and error, I was able to set a stable CPU offset of -0.045V with the high (50%) LLC option which lowered the temperatures by a few more degrees and ensured next to no vDroop.

Running quad-channel RAM from different manufacturers is always a tricky proposition, even when the timings are the same. I had my initial CAS 9, DDR3-1600, 2 x 4 GB Corsair Vengeance teamed up with a similar GSkill RipjawsX set from 4 years later. This meant the job of overclocking the RAM was anything but easy and involved numerous failed boots. Eventually, I was able to get them to run stably at 1800 MHZ, CAS 10 with only a minor bump up in voltage to 1.53V. However, the impact on memory performance was not insignificant.

I suppose it makes sense to go all-in when you have entered the game. Hence, I decided to overclock my GPU as well. For over 2 years, I never overclocked the Zotac GTX 1060 Mini, being as it is, a single fan device. Size can be misleading though and the added CPU cooler certainly aids the overall air flow. It didn't take me long to figure out the memory isn't going to be up to the task, which is understandable considering it is not protected by a heat sink. In the end, I conservatively increased the memory clock by 100 MHz and the core clock by 200 MHz without touching the voltage.

A final tool available in pushing the clock even further is the base clock. Unfortunately, after setting up the overclock for all the other components, I found that the base clock increment to even 101 caused significant instability. Increasing the CPU and RAM voltage brought some modicum of stability but inexplicably reduced the performance across all benchmarks while simultaneously raising the temperature. Thus, there was no use pursuing this path any further.

The performance comparison presents of the overclocked system with the default one certainly provides some satisfaction. The XMP overclock is set to use the maximum CPU multiplier of 40 but it was unable to run the RAM at 1800 MHz at the same time. Going by the incredibly higher temperatures, it is obvious that the XMP overclock pushes the voltages a lot higher. The only upside here is that it is capable of running all the cores simultaneously at 4 GHz which produces a minuscule performance advantage. However, the manual settings are more than a match and come with a significant upshot in memory performance with much better thermals.


While the upshot in CPU and RAM performance is quite evident looking at the table, the GPU performance is not. As it happens, PCMark doesn't stress the GPU much whereas Hitman seems to be constrained by the CPU. Thus, the need of the hour was a GPU intensive benchmark which came in the form of Heaven. As can be seen in the results, the overclock results in an FPS improvement of over 8% compared to the stock speeds. At the same time, it makes sense to set a custom fan curve as it can keep the temperatures down under full load.


To round up the post, no overclock is worth its salt without a stress and torture test. The idle CPU temperature of 27 is pushed up to 63 by AIDA64's stress test and then stratospherically to 77 by Prime95's torture test. However, this is well within the processor's specifications and represents the worst possible scenario that normally doesn't manifest itself in the most taxing of daily use cases.


To conclude, this entire episode was brought about by an unforeseen failure in ageing hardware and hence the overclock exercise is strictly incidental, but the thrill of it as much as anyone would get when setting up a new system.

P.S.: If you followed my earlier post on Meltdown and Spectre, then you'd know it is something I thought of when buying the motherboard. Like with the ASRock boards, there was a helpful soul patching the unsupported Asus boards as well. However, when I went about flashing the BIOS, I found it to be incompatible due to the way it was packaged. Thankfully, Microsoft has fully patched Windows to support the latest microcodes from Intel (1F in the case of the i5-3470). It wasn't auto installed over Windows update and I had to manually install the KB4100347 patch for Spectre.

Tutorial #20: Home (Network) Improvement using a Pi


Update #1 (Aug 19, 2018):

With the passage of time, things change and in this case it is mostly for the better. I was setting up the Pi once again and was pleasantly surprised that some of the workarounds mentioned previously are no longer needed. Thus, I have edited the original tutorial to accommodate these changes while striking out the old text.

Also, after comparison, I found AB-Solution to be a better solution for network-wide ad blocking, if you happen to have a Merlin supported Asus router like I do. Since the router is on 24x7, having an old ext2 formatted pen drive plugged in to the router itself and running ab-solution is a better alternative as against running the Pi 24x7. It also has various preset ad blocking files that suit different needs while pixelserv-tls does a great job with HTTPS ads.

Lastly, I failed to mention the option of having a Samba server running on the Pi itself in order to access the files directly from the pen drive over the network. This can be accomplished by simply following the official tutorial on the Raspberry Pi website.

Original Article (May 3, 2018):

I had previously shared some tutorials in setting up the Pi and putting it to good use. However, the use cases I mentioned then have ceased to exist. The Fire TV has taken care of most of my multimedia needs and I have come to realise that I really don't have much time to go back in time for nostalgia. For the retro needs that remain, the lesser-used Core M 5Y10 equipped Windows tablet of mine does a much better job plugged in to the TV.

Hence, it is time to put the Pi to good use in a different sense. Thankfully, the versatility of the Pi means that it is not difficult to identify its next project. Ads can become a nuisance, especially for the more aged members of the family and hence my first intent was to set up an ad blocker across my home network. However, putting the Pi to such limited use and keeping it on 24/7 would be quite a waste, so I decided to also repurpose it as a download box with centralised storage.

Setting up the tools necessary to accomplish these tasks seemed straightforward. However, the relevancy of publicly available tutorials diminish over time due to changes in technology. In fact, I had to put quite some effort beyond the listed tutorials and hence I have decided to put the same to words for posterity.

Before starting out:

PINN is a great utility when multi-booting across different distributions on the same SD card. However, Raspbian alone fits the bill for the current use case. Hence, writing the raw Raspbian image directly on the card is preferable as it provides more usable space. As far as writing on the card goes, Etcher is the way to go.

1. Pi-hole®

As the website so prominently displays, all you need is a single command.

curl -sSL https://install.pi-hole.net | bash
However, I made a couple of settings that are worth mentioning:

a. The predefined list of upstream DNS providers does not yet include Cloudflare which I found to be the fastest of the lot. Hence, it would be worthwhile to use the custom option and enter the Cloudflare DNS Server IP addresses of 1.1.1.1 and 1.0.0.1.

b. The other part of the equation is setting up the home equipment to use the local DNS server. In case of Asus routers, this implies changing the DNS Server IP address to the Pi-hole one, not only on the WAN page (under WAN DNS Settings) but also under LAN > DHCP Server > DNS and WINS Server Setting. Make sure that there are no other IP addresses present in either of the pages. You could also run the DHCP server on Pi-hole, in which case the latter setting is not needed. However, since I use the router-assigned IP addresses for other functions (eg. VPN), I prefer to have the DHCP server running on the router itself.

2. qBittorrent

qBittorrent has been my preferred Bittorrent client for quite some time with it being open-source and having proper support for proxies as against Transmission. It can be installed easily using APT, though I prefer the headless route.

sudo apt-get install qbittorrent-nox
My primary endeavour was to have the downloaded files ready on the USB 3.0 hard disk connected to my router (and thus acting like a NAS) while minimising the read-write operations. Since it is not a great idea to write to the SD card running the client, I decided to plug in an old 32 GB pen drive to act as the "working folder" by adding it under Downloads > Hard Disk > Keep incomplete torrents in:

The next part was to add the network drive as the final resting place by entering its address under  Downloads > Hard Disk >  Save files to location: and also under the Copy .torrent files for finished downloads to field. The latter is sometimes necessary due to some quirks in different versions of qBittorrent. The external network drive needs to be mounted within Raspbian on boot which can be accomplished by editing /etc/fstab with these details:

mount -t cifs //xx.xx.xx.xx/folder /media/NAS -o rw,vers=2.0,username=abc,password=xyz
//xx.xx.xx.xx/folder /media/NAS cifs vers=1.0,username=abc,password=xyz,x-systemd.automount

where,
xx.xx.xx.xx -> LAN IP address as configured on the router running the Samba server
folder -> Path to the folder on the network drive that needs to be mounted
/media/NAS -> Path on the Pi where the network drive is to be mounted

In my case, I had to specifically mention the SMB version (2.0), without which the mounting would fail as well as the rw argument to be able to write to the device. Also. it is a good idea to update the cifs-util package from APT prior to editing the fstab file, as mentioned above.

Note: The earlier entry no longer worked with the June 2018 version of Raspbian due to which I had to use the alternative entry in /etc/fstab mentioned above. Also, I was only able to get v1.0 working this time despite the server supporting v2.0 as well.

Finally, to cover for unexpected reboots, it is preferable to have qBittorrent autostart which can be accomplished using systemd. First, create the startup script using:

sudo nano /etc/systemd/system/qbittorrent.service
Next, enter its contents as follows:

[Unit]
Description=qBittorrent Daemon Service
After=network.target
[Service]
User=pi
ExecStart=/usr/bin/qbittorrent-nox
ExecStop=/usr/bin/killall -w qbittorrent-nox
[Install]
WantedBy=multi-user.target 
Lastly, enable the script.

sudo systemctl enable qbittorrent
3. pyLoad

The final part of the exercise was to set up a download manager. I had briefly given thought to JDownloader but decided against running JRE just for it. Hence, I opted for pyLoad instead. The tutorial listed over here works fine for the most part but needed quite some tweaks along the way. For the sake of completion, I will list all the steps in brief.

1. Create system user for pyload

sudo adduser --system pyload
2. Edit /etc/apt/sources.list to be able to install the dependencies. For Raspbian Stretch, the source URLs are as follows:

deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi
deb-src http://archive.raspbian.org/raspbian/ stretch main contrib non-free rpi
3. Update package list and install dependencies.

sudo apt-get update
sudo apt-get -y install git liblept4 python python-crypto python-pycurl python-imaging tesseract-ocr zip unzip python-openssl libmozjs-24-bin
sudo apt-get -y build-dep rar unrar-nonfree
sudo apt-get source -b unrar-nonfree
sudo dpkg -i unrar_*_armhf.deb
sudo rm -rf unrar-*
4.  Create symlink to get "spidermonkey" working.
cd /usr/bin
sudo ln -s js24 js
5. Unlike in the linked tutorial, I had to first switch to the stable branch before I could initiate the pyLoad setup. This is done as follows:

cd /opt
sudo git clone https://github.com/pyload/pyload.git
cd pyload
git branch -r
git checkout stable 
 6. The next step, as per the linked tutorial, should have been the initiation of the pyLoad setup using:


sudo -u pyload python pyLoadCore.py
However, doing so produced the following error: "ImportError: No module named pycurl". Hence the next logical step was to install pycurl:


sudo pip -v install pycurl --upgrade
This in turn resulted in the error: "InstallationError: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-IsWfyN/pycurl/". This was resolved by:


sudo apt-get install libcurl4-gnutls-devpip
 As you can now guess, this in turn resulted in yet another error: "Failed building wheel for pycurl" which was remedied as follows:


sudo apt-get install libgnutls28-dev

After all this effort, I was finally able to install pycurl using the command mentioned previously...


sudo pip -v install pycurl --upgrade 
...and execute the pyLoad setup using a slightly shorter command:


 python pyLoadCore.py
On the June 2018 release, I was able to get pyload wizard started by executing
sudo -u pyload python pyLoadCore.py 

The final tweak was to get pyLoad running on boot with the commands executed in a manner similar to what has been already covered for qBittorrent.

sudo nano /etc/systemd/system/pyload.service 
[Unit]
Description=Python Downloader
After=network.target
[Service]
User=pyload
ExecStart=/usr/bin/python /opt/pyload/pyLoadCore.py
[Install]
WantedBy=multi-user.target
 sudo systemctl enable pyload.service
Beyond Home

The benefits of this setup can be extended beyond the home network, though a lot depends on the vagaries of the network setup.

Pi-hole can be put to use on external networks by accessing the home network over OpenVPN, though speed and latency might be factors to consider. It can also be setup as a Public DNS but it is extremely risky and not at all recommended.

qBittorrent and pyLoad can be simply accessed using the IP address and port, provided they have been setup to be accessible from outside the LAN. For dynamic IP addresses, the Dynamic DNS (DDNS) option available on most routers can be put to use and my suggestion would be to pick up a cheap $1 domain from NameCheap for this purpose. However, if you happen to be under a multi-layered NAT network under ISP control like me, then there is no option other than to pay for a static IP for public access.

Thankfully, there is a last resort to access the Pi over a public network. The licensed copy of RealVNC that comes with Raspbian offers Cloud Connect that enables one to remotely control the OS and thereby all applications on it. It is quite cumbersome to use if your intent is to only load some links on qBittorrent or pyLoad, but it is better than nothing.

Thus, the Pi can be extremely useful even when used in a rather sedentary capacity and you grow to appreciate the efforts that everyone has put in to make this possible.

Musing #59: Waterproof Socks!


Soggy socks can be an arduous affair. It is a memento of the monsoon's dreariness that you are compelled to carry with you and there is certainly no escaping it in a sinking city with crumbling infrastructure. The fault of this plight lies in no way at nature's doorstep but rather on the nefariousness of human nature, but that musing is left for another day.

How ought then one waddle through the inland pools of blight resembling water without the fear of being infected? Bare foot spares the sogginess but at the risk of ending up on a hospital bed. Luckily, homo sapiens causeth and homo sapiens giveth, at a price of course.

The marvel of keeping water at bay while slaloming between potholes lies in getting oneself a pair of waterproof socks. Oh yes, they do exist! They have been lying in the burrows of e-commerce for years and it is for the needy one to dig it up, especially if you happen to be in a country where the product has no retail existence. Accordingly, yours truly got a pair, and a trekking one at that.

The proof lies in the pudding and I can only describe it as a miraculously feeling when squeaking boots are not in cohort with shrivelled skin. Of course, prior to testing them on the roads, I had my feet immersed in a tub full of water, only to be oblivious of the existence of the second state of matter. It is like being dissociated from reality, though not in the sense of nirvana.

Of course, all is not hunky-dory since there is no ignoring the weight of the additional layers and the heat build-up in the dry. This one is certainly best saved for a rainy day. Then, there is the small matter of the price and my fingers are not enough to count the number of ordinary pairs that I could have purchased in lieu of this.

On the whole, I can't state how much I appreciate the dryness brought forth by this item, as much as I abhor the same in a human being. Sometimes, it just the little experiences that make a high price seem totally worth it.

Musing #58: Mutual Fund (SIP) Portfolio Overlap Analyser



Being from a finance background, I made it a point to invest in SIPs early on. Over the years, while the investment amount has increased steadily, the number of funds being invested in has remained more or less constant. Hence, I need not emphasis how important it is to know where exactly the money is going.

Too often, the choice of a fund is made simply on returns and diversification is achieved by selecting a different fund class. However, it provides no indication of the extent of value creation. I prefer to keep an eye out on what's happening with my portfolio and it is not only when selecting a new fund but also for keeping tabs on what's going on with the existing investments.


My search for websites/files providing this information yielded a few options that were quite limited in nature, dispensing basic overlap information between two or three funds. Unable to find the requisite information, I decided to go on my own and create an Excel workbook that provides overlap analysis for up to six funds. The other target I had set for myself was to do so without the use of VBA, so the only permission required is to access the external data source - moneycontrol.com.

The workbook is structured in to distinct sheets for input and detailed analysis. The 'Input' sheet is pretty straightforward and is essentially a two-step process requiring the funds and investment amount to be entered along with the selection of the fund that would form the basis of checking the overlap. It would be a good idea to read through the notes prior to using the workbook. The sheet has some safeguards built in to alert the user about inconsistent inputs, like missing investment values/funds and failure to refresh the 'base fund' selection. At the same time, it is robust enough to still function immaculately when any of the selected funds are deleted.


Note that although the sheet includes funds with equity holdings from various classes, some of them do not have their holdings listed on moneycontrol.com which may cause an error illustrated above. As such, there is nothing that can be done about it. Also, to state the obvious, the default funds selected in the sheet are for illustration and are not suggestive.


The 'Analysis' sheet provides the primary analysis of the portfolio. Besides listing the fund class and the equity holdings of each fund, it provides the percentage overlap of the base fund with all the other funds in the portfolio, both, in terms of the number of stocks and the value invested. The charts in turn provide 'Top 10' visualisations for individual stocks as well as the different sectors.


The 'Detail' sheet provides the tabular information that form the basis of the analysis and lists all the values as against only the Top 10 in the charts.


The 'MFx' sheets list the holdings of each fund, as retrieved from moneycontrol.com and is subsequently used for the overlap calculations.


Finally, the 'List' sheet is a list of the funds retrieved from moneycontrol.com and covers the various equity fund classes. It is easy to add any new funds to the list in the specified format and the information can be scraped en masse from the MoneyControl site.

As is often the case, I have created something to primarily fulfil my needs but with the intention of sharing it with other netizens. Consequently, I am open to any suggestions for improvement which you may leave in the comments section.

Link: Download from Google Drive