The values at the top of your script are constants so, per the style guide, should be
BINS = [40, 50, 60]
DAYS = 25
GAUSS = True # distribution can be gaussian or lognormal
ITERATIONS = 1000
START_PRICE = 50
STD_DEV = 2
Note that I've also made some of the names a little more meaningful, and added more Pythonic whitespace to the list. I've also ordered them alphabetically, although there may be a more sensible grouping.
It would be nice to add a comment explaining
BINS - the rest are fairly obvious, but it took me a few reads to figure out that they're the top of each bin, and an additional higher bin will be automatically added. Consider adding a module docstring covering this.
Currently, all of the code is just in the body of the script. Instead (as it makes it easier to
import and reuse this functionality elsewhere), it is conventional to define an "entry point" function (conventionally named
main) and call that when the script is invoked directly:
# imports, constants, etc.
# do your thing
if __name__ == '__main__':
Rather than specify two distributions within the body of the code, I would extract the distribution function as a parameter to the simulation. In this case the functions would be:
"""Apply the Gaussian distribution."""
return random.gauss(0, std_dev)
"""Apply the log-normal distribution."""
return random.choice((1, -1)) * random.lognormvariate(0, std_dev)
Now if you wrote a function to do one iteration, it would be very simple:
def simulate(days, start_price, std_dev, distribution):
"""Simulate the asset for the specified number of days."""
price = start_price
for _ in range(days):
price = max(0, price + distribution(std_dev))
You can then create more distribution functions in the future, and pass whichever you want to
simulate; all it requires is a function that takes a single argument and returns a number.
Note that I have made the constants explicit parameters to these functions - this, again, makes reuse of the code easier.
main would now look like:
results =  * (len(BINS) + 1)
dist = gaussian if GAUSS else lognormal
for _ in range(ITERATIONS):
final_price = simulate(DAYS, START_PRICE, STD_DEV, dist)
print(final_results) # you could return final_results instead
You could also abstract the binning of results into a function. I would avoid using the identifier
bin, as this shadows a built-in function