Investment/betting simulation

I am creating an investment/betting simulation; since is the first I create , I am sure it can be done better, both from a coding and a simulation point of view.

I would like to ask you what you think and if you can share your experience.

There are 5 main variables that the user has to input:

• z --> it is my average winning percentage. As discuss later, a random number between 0 and 100 will be generate. If the generated number (x) is greater than (z), then the trade is loss; if x < z, is a win.

• invest --> how much money invested per trade, es. 10$. In case of a win, the return is always the 70%. i.e. bet 10$, win 7\$ (plus the bet)

• days --> how many days I trade. there is fixed amount of trade per day, which is between 9 and 33

• simulazioni --> the number of simulations

• varianza --> is the shifting probability. If varianza is 5% and my percentage (z) is 50%, my actual variance could be either 45% or 55%. This is calculated randomly for each trade.

As you can see from the code at the bottom, the simulation is based on "for loops". The main one is the simulations, second one are the days and the last one calculates if the trading is positive or negative.

There are also dictionaries that I use to collect data from daily profit and total profit (i.e. "datatot"; these dictionaries are used to plot data later on (this bit is not included in the code).

import random
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import numpy as np

data=[]
data2=[]
datatot = []
portafoliotot = 0
portafolio = 0
pos= 0
neg= 0

#input variables
z= input("Percentuale: ")
invest = input("Investimento:")
days = input ("Giorni:")
simulazioni = input("Simulazioni:")
varianza = input("Varianza:")

for simulazione in range(0,int(simulazioni)):

for giorno in range(0,int(days)):

portafoliotot = 0 #simulation portfolio
portafolio = 0 #daily portfolio
pos = 0 #n of positive trades
neg = 0 #n of negative trades

x=random.randint(0,100) #random number to see if the trade is pos or neg

calcvarianza = 2 * np.random.rand() - 1 # calculation of (varianza). if positive, is going to be added to (z), otherwise subtracted. this is done for each trade.

if calcvarianza > 0:
varianza = - int(varianza)

if x<(int(z)+int(varianza)): #checking if the trade is pos or neg

portafolio += (int(invest)/100)*70
pos +=1
else:
portafolio += -int(invest)
neg +=1

portafoliotot += portafolio
data.append(portafoliotot)
data2.append(portafoliotot)

datatot.append(sum(data2))
data2 = []
• portafolio += -int(invest) why not just -=? Maybe that's just me, but I think that using your native language in code (English isn't native language for me too by the way) is kind a bad decision. For example you may have to show it on a site like this and everybody would understand your code easier if it would be in English. May 19 '17 at 20:09
• Also try to use PyCharm to fix your code formatting. May 19 '17 at 20:10
• If you want to randomly choose True or False instead of if 2 * np.random.rand() - 1 you can just do if random.randbits(1) May 19 '17 at 20:20

Idiomatic Python suggestions:

• Use argparse rather than input to set the configuration. It is easy to use, and very powerful.

General suggestions:

• data and data2 are literally considered the world's worst variable names. Naming is well known to be a hard problem, but it's also a great skill to learn. Naming a thing well gives much needed information to anyone reading the script, including yourself.
• Comments like "checking if the trade is pos or neg" are code smells which point to an opportunity to extract a class or function.
• Your program contains many magic values, like 33. Use constants or set them as defaults for arguments to make it clear what these numbers mean.
• Your program neither prints nor returns anything. In other words it can be replaced by the single line pass.
• This may sound chauvinist, but use English names for things in your program. The world's developers have avoided localising programming languages for a long time, and in a programming job you are very likely going to be expected to write everything except user interfaces in English. As long as practically every function, class, package and module in the world is named in English, you are going to improve maintainability by using a single language in your programs. Disclaimer: I'm not a native English speaker.

I don't understand what you're trying to do (for example you counting negative and positive investments but this information isn't used in code), but you can do this more declarative.

return rnd.randint(0, 100) < (z + (-varianza if rnd.randbits(1) else varianza))

When you summing current investment into temp variable that has value of previous sum and then store this variable into array what you're doing is accumulative sum. This is what itertools.accumulate from stdlib is for.

Hence you can do something like that.

investments = (
tuple(itertools.accumulate(
(invest / 100) * 70 if is_trade_negative() else -invest
for day in range(days)
))
for sim in range(simulations)
)

results = ((sum(inv), inv) for inv in investments)
• This site is Code Review, not Alternate Solutions.
– Nic
May 20 '17 at 0:23
• @QPaysTaxes I know that and I think that declarative style is this case is better than imperative. Hence my code. The author asked how to make his code better. Here's the answer. Use itertools.accumulate and comprehension. May 20 '17 at 0:30
• Except, again, this is Code Review, not Alternate Solutions. You've done nothing but say "here's how I would do it". You didn't review the code.
– Nic
May 20 '17 at 0:31
• @QPaysTaxes How is review different from here's how I would do that? I think the only essential difference is that in review you also say why you would do things your way. Which I've said. It's more declarative and hence easy to understand. May 20 '17 at 0:37