Recent Question/Assignment

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.
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
• 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
– self.funds per slot: a copy of the funds allocated to each slot in the
portfolio. will be needed for resetting later.
– 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
P L =
(currency closing today-currency closing previous)
currency closing previous
• 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
• 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
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
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
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 correlating
your simulation with the output given in the provided log file (50%)
2. Map the simulation so it can run using simulated annealing to compute
the ideal strategy (65%)
3. Map the simulation so it can run using genetic algorithms to compute the
ideal strategy (80%)
4. Generate strategies using both simulated annealing and genetic algorithms
for 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