Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]: DP Reinvest strategy #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions simulation/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ class Calculator(metaclass=abc.ABCMeta):
def __init__(self, configuration):
self.configuration = configuration

@property
def rate(self):
return self.configuration.rate

def cost_per_hour(self, h):
return h.watt * (self.configuration.kwh / 1000)

Expand Down
6 changes: 3 additions & 3 deletions simulation/egalitarianism.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import matplotlib.pyplot as plt
from matplotlib import rc
from matplotlib.backends.backend_pdf import PdfPages
from simulator import Simulator, GreedyTechnologyFirst, GreedyElectricityFirst, DP, Reinvested
from simulator import Simulator, GreedyTechnologyFirst, GreedyElectricityFirst, DP, Reinvested, DPReinvested
from helpers import slugify, MultiArgument, Plot
from mining_hardware import Hardware
from configuration import Configuration
Expand Down Expand Up @@ -65,7 +65,7 @@ def create_differencies(args, diff_args, hardware):
def main():
parser = argparse.ArgumentParser(description='Cryptocurrency egalitarianism: A quantitative approach')
parser.add_argument('-c', '--currency', default='btc', choices=['btc', 'eth', 'xmr', 'ltc', 'dcr'], help='Currency (default: %(default)s)')
parser.add_argument('-s', '--strategy', default='dp', choices=['tech', 'electricity', 'dp', 'reinvest'], help='Strategy of invenstment (default: %(default)s)')
parser.add_argument('-s', '--strategy', default='dp', choices=['tech', 'electricity', 'dp', 'reinvest', 'dp-reinvest'], help='Strategy of invenstment (default: %(default)s)')
parser.add_argument('-d', '--difficulty', required=True, type=float, nargs='+', help='Block difficulty (required)')
parser.add_argument('-b', '--coinbase', required=True, type=float, help='Coinbase (required)')
parser.add_argument('-k', '--kwh', required=True, type=float, nargs='+', help='Price per kilowatt per hour (required)')
Expand All @@ -79,7 +79,7 @@ def main():
args = parser.parse_args()

calculators = {'btc': BTCCalculator, 'eth': ETHCalculator, 'xmr': XMRCalculator, 'ltc': BTCCalculator, 'dcr': BTCCalculator}
strategies = {'tech': GreedyTechnologyFirst, 'electricity': GreedyElectricityFirst, 'dp': DP, 'reinvest': Reinvested}
strategies = {'tech': GreedyTechnologyFirst, 'electricity': GreedyElectricityFirst, 'dp': DP, 'reinvest': Reinvested, 'dp-reinvest': DPReinvested}
currencies = {'btc': ['Bitcoin'], 'eth': ['Ethereum'], 'xmr': ['Monero'], 'ltc': ['Litecoin'], 'dcr': ['Decred']}

hardware = []
Expand Down
50 changes: 43 additions & 7 deletions simulation/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,10 @@ def simulate(self, capital, hardware, calculator):
class DP(Strategy):
def construct_solution(self, capital, gain_velocity, items):
solution = []
initial_capital = capital

for i in range(capital, 0, -1):
if gain_velocity[i - 1] < gain_velocity[i]:
initial_capital -= int(items[i].price)

if items[i] and initial_capital >= 0:
solution.append(items[i])
while items[capital] and items[capital].price <= capital:
solution.append(items[capital])
capital -= int(items[capital].price)

return solution

Expand Down Expand Up @@ -167,3 +163,43 @@ def simulate(self, initial_capital, hardware, calculator):
r[x] = gain_velocity[x] * self._hours_of_operation

return (r)


class DPReinvested(DP):
def simulate(self, initial_capital, hardware, calculator):
r = [0 for _ in range(initial_capital + 1)]
sorted_hardware = [h for h in sorted(hardware, key=lambda h: calculator.net(h), reverse=True) if calculator.net(h) > 0]
g = self.gain_velocity(initial_capital, sorted_hardware, calculator)
solution = []
revenue_velocity = []
cost_velocity = []
price = []

total_gain_velocity = g[0]
total_items = g[1]

for capital in range(initial_capital + 1):
solution.append(self.construct_solution(capital, total_gain_velocity, total_items))
revenue_velocity.append(sum(calculator.expected_income(h) * calculator.rate for h in solution[capital]))
cost_velocity.append(sum(calculator.cost_per_hour(h) for h in solution[capital]))
price.append(int(sum(h.price for h in solution[capital])))

for capital in range(initial_capital + 1):
optimal_income = 0

for v_tech in range(capital + 1):

if not solution[v_tech]:
continue

v_pocket = capital - price[v_tech]
gain_velocity = total_gain_velocity[v_tech]
available_hours = v_pocket / cost_velocity[v_tech]
available_hours = min(self._hours_of_operation, available_hours)

income = available_hours * revenue_velocity[v_tech] + (self._hours_of_operation - available_hours) * gain_velocity
optimal_income = max(optimal_income, income)

r[capital] = optimal_income

return (r)