Assignment: Using Simulated Annealing and
Genetic Evolution to optimize a strategy for buying and selling cryptocurrencies
Barry Denby
October 7, 2022
1 Introduction
NOTE: read the whole assignment brief first before implementing it contains very important information
In this assignment you will be tasked with doing four things: • Create a simulation of a sample cryptocurrency market based on multiple years of 5 cryptocurrencies. The portfolio will assume you will only hold one batch of any currency at any given time. You will simulate the buying and selling of currencies with the aim of producing the largest return at the end of trading (last day in the data). Your simulation will also take into account capital gains tax
• A mapping onto the simanneal library that will use Simulated Annealing algorithm to determine the best strategy
• A mapping onto the deap library that will use genetic evolution to determine the best strategy
• Determining which of the strategies produced is the best strategy overall.
In terms of effort the vast majority of your time will be spent on the first part in creating the simulation. The mappings to both libraries will not take long, and the experimentation to find the best strategy will take about 3 to 5 minutes per run using either annealing or evolution. In terms of effort, the majority of your time will be spent on the initial phase of simulation creation. The mappings to both libraries will not require much time, and the experimentation to determine the optimal strategy will take between three and five minutes per run, using either annealing or evolution.
It is advised that you test the simulation as you progress. This test case is provided with a default set of values and a log of the actions it should perform on any given day. Try to get day 128 to function, then days 129, 130, etc. If you generate the same log at the end, your simulation is functioning properly. Remember that if you create an inaccurate simulation, the results of numerical optimisation cannot be relied upon.
It is recommended that you should test the simulation as you go. There is a default set of values given for this test case along with a log for what actions it should take on any given day. Try to get day 128 working, then 129, 130 etc. If you produce the same log at the end then your simulation is working correctly. Remember if you produce a bad simulation your results from numerical optimisation cannot be trusted.
Read the details of the simulation carefully and if you have any questions do not hesitate to ask. You will need to have full clarity on the simulation in order for implementation to be correct and by consequence your numerical optimisation to be correct
2 Simulation Details
The reason why simulations of this nature are needed is that strategies for trading cryptocurrencies can be trialled with virtual money without risk of losing money. With the crypto market there are two things that we are trying to predict at all times.
1. When is the best time to purchase a currency
2. When is the best time to sell a currency
In the ideal case you should purchase a currency when it’s value is lowest and sell it when its value is highest. The difference in price between when the currency was purchased and when it was sold is the profit or loss that was made on that currency.
Thus a lot of people are highly interested in modelling the crypto market to see if there is a clear cut strategy that can determine in advance when the right time to buy and sell will occur in order to maximise profit.
Here technical analysis is the approach that is used where we look at the historical crypto price and try to use that alone to predict how the currency will change. We will ignore external events such as news, comments about currencies etc from our analysis to simplify thing.
In this particular case we will have a portfolio of 5 slots one for each of our chosen currencies (Bitcoin, Dogecoin, Ethereum, Litecoin, XRP). For each slot on day one you will start with an amount of $2,000. meaning you will have a maximum of $10,000 to invest in this version of the crypto market. On each day you will look at the buy signals and sell signals for each of the currencies and use this to determine if you should purchase or sell that currency.
Once you apply optimisation to this problem using either approach you should be aiming to get a final portfolio value between $200,000,000 and above after the dataset is completed. My initial tests suggest that anything up to $1,000,000,000 is possible. Anything between those two values will indicate that your annealing and evolution is working properly.
3 Classes
Discussion of the classes that you will need in order to write the simulation
3.1 Portfolio
A class to represent a full cryptocurrency portfolio that will track what currencies have been purchased and sold and how much they were worth at the time
• init : constructor for the class that takes in a funds for each slot in the portfolio and the full set of closing values for all currencies (provided in base script)
– self.funds: a list that holds the funds available for each cryptocurrency
– self.bitcoin buy weights: as list of 8 floating point numbers detailing what the profit loss between now and selected historial prices should be in order to indicate a buy signal. The weights are for 1,2,4,8,16,32,64, and 128 days respectively.
– self.bitcoin sell weights: similar list to bitcoin buy weights but these are sell signals
– self.{dogecoin,ethereum,litecoin,xrp} buy weights: similar buy weights for the other currencies
– self.{dogecoin,ethereum,litecoin,xrp} sell weights: similar sell weights for the other currencies
– self.coins: list containing the amount of coins this portfolio has for each of the 5 currencies
– self.price per coin: The price of each coin as it stood at time of purchase.
– self.closing values: a reference to the closing values that are passed in
– self.funds per slot: a copy of the funds allocated to each slot in the portfolio. will be needed for resetting later.
– self.capital gains: A variable for holding the amount of capital gains tax that must be paid on this portfolio.
– self.{bitcoin,dogecoin,ethereum,litecoin,xrp} profit loss: The profit and loss values for each day of all cryptocurrencies. This will be precalculated before simulation in order to reduce running time.
• determineBuySignals(self, bitcoin, dogecoin, ethereum, litecoin, xrp): determines the buy signals for all 5 currencies. this counts the number of profit and loss values on the current day that are above the buy weights for the relevant currency. a currency can have anywhere between 0 to 8 buy signals on any given day.
• determineSellSignals(self, bitcoin, dogecoin, ethereum, litecoin, xrp): determines the sell signals for all 5 currencies. this counts the number of profit and loss values on the current day that are below the sell weights for the relevant currency. a currency can have anywhere between 0 to 8 sell signals on any given day.
• displayValueGraph(self): displays a graph using matplotlib that shows the value of the portfolio on every day of the simulation. In order to use this you will need to record the value of the portfolio on every day of the simulation. I would suggest you have a boolean to control this and only activate it when you have generated your best strategies.
• precalculateProfitLoss(self, currency closing): calculates the profit and loss values for all currencies on every day of the data. needs profitLoss() implemented before this will work. By precalculating the profit and loss values before simulations you will cut simulation time in half. The profit loss values will not change from simulation to simulation so it does not make sense to recalculate them repeatedly.
• profitLoss(self, currency closing, day): calculates the profit and loss values for the given currency on the given day. this should return a list of 8 values representing profit and loss for 1,2,4,8,16,32,64, and 128 days respectively. The formula for calculating a profit or loss is the following

• purchaseCurrency(self, currency, buy signals, sell signals): will purchase as much of the given currency as is possible provided the following conditions have been met
– the currency has a closing value of 0.01 or more
– there are more buy signals than sell signals (same number of signals we will not purchase)
– we haven’t purchased this currency already
Only full coins can be purchased. no partial coins allowed
• reset(self): resets the simulation and portfolio to the original created state and day 128.
• sellCurrency(self, currency, buy signals, sell signals): will sell the entire set of this currency provided the following conditions have been met:
– We have coins to sell
– There are more sell signals than buy signals
The coins are then sold off at whatever the current day’s closing value is for that currency. if a profit has been made on the coins then take 33% of the profit and add that to the capital gains tax amount
• simulate(self): simulates the strategy represented by this portfolio. starts on day 128 and stops on the last day of the data. On each day it will calculate the buy and sell signals and buy and sell currency as appropriate. • totalNetValue(self): the total value of the portfolio with capital gains tax removed.
• totalValue(self): The total value of the portfolio which is the value of all held coins on the current day plus any funds left over in the slots for each currency.
3.2 General Additional Functions
• printPortfolioStrategy(): prints out the buy and sell weights for each currency along with the total value and total net value for this portfolio. • rouletteWheel(a, b): useful for the genetic evolution part. this generates a random number between 0 and 1 and returns a if less than 0.5, b otherwise.
4 Suggestion for how you should proceed and other relevant information
The recommendation here would be to make sure the portfolio works first before attempting to do any optimisation. You’ve been provided with a log, a copy of the data for all 5 currencies and a base python script that will read in the currency data and assemble it as required for you.
In the log there is a test case. Each day in the log will give the buy and sell weights for each of the 5 currencies are displayed along with each trade made and the corresponding profit loss associated with it. The test case sets all buy weights to 0.01 and all sell weights to -0.01.
Try to recreate day 128 first then day 129, and day 130. If you get this much working then when you run the simulation for the full length of time every other day should work correctly. You should end up with a portfolio that is worth approx $59 million but only worth approx $17 million once capital gains tax is removed.
Once you have the simulation matching the test case you can then apply simulated annealing and genetic evolution to this. It is recommended for both cases you use a list of 80 floating point values representing the buy and sell weights for all 5 currencies. The weights should be mapped to a portfolio and simulated. Again this is for performance reasons. If you copy a full portfolio to the annealer or to a member of the evolution population two things will happen: your memory usage will go through the roof due to deep copies, and also due to deep copies you will waste a lot of computations for no gain.
If you use this strategy you should be able to run simulated annealing in approx 6 minutes for 10,000 steps and 4 minutes for 30 generations of genetic evolution. For reference the times given are for a 2017 Dell Inspiron 15 5000 laptop with a dual core 7th generation Intel Core i7 processor i7-7500U CPU and 16GB of RAM.
5 Notes
You are required to submit this assignment by 2022-12-18 (Sunday 18th of December) by 23:55. You are required to submit two separate components to the Moodle
• A single python file containing all of your code.
• A PDF containing documentation of your experiments along with graphs If you do not provide documentation your code will not be marked.
There are also a few penalties you should be aware of
• Code that fails to compile will incur a 30% penalty before grading. At this stage you have zero excuse to produce non compiling code. I should be able to open your project and be able to compile and run without having to fix syntax errors.
• The use of libraries outside the python SDK and permitted libraries (simanneal, deap, sklearn, matplotlib) will incur a 20% penalty before grading. You have all you need in the standard SDK. I shouldn’t have to figure out how to install and use an external library to get your app to work
• The standard late penalties will also apply
You should be aware that I will remove marks for the presence of bugs anywhere in the code and this will incur a deduction of between 1% and 15% depending on the severity. If you have enough of these bugs it is entirely possible that you may not score very many marks overall. I want robust bug free code for this that closely matches the graphs above
Also note that the percentage listed after each task is the maximum mark you can obtain if you complete that many brackets without error.
6 Tasks
1. Write the simulation using the detail above and test it works by correlatingyour simulation with the output given in the provided log file (50%)
2. Map the simulation so it can run using simulated annealing to computethe ideal strategy (65%)
3. Map the simulation so it can run using genetic algorithms to compute theideal strategy (80%)
4. Generate strategies using both simulated annealing and genetic algorithmsfor the following situations. You must detail what the best strategy is used (buy weights and thresholds ) for all, write a small discussion of the strategy (time taken, any interesting effects, total discussion should be no more than 1,000 words). Using matplotlib provide a graph of the value of the portfolio after each day (100%)
• Strategies produced by three seperate runs of simulated annealing
• Strategies produced by three seperate runs of genetic algorithms

Published by
Essays
View all posts