To solve this problem, we first need to convert the natural language description into a symbolic representation of the optimization problem. Let's denote the number of pens to be bought and sold as $x_1$ and the number of pencils to be bought and sold as $x_2$. 

The objective function is to maximize profit, which can be represented algebraically as $3x_1 + x_2$, since each pen is sold for a profit of $3 and each pencil is sold for a profit of $1.

Now, let's consider the constraints:
1. The store owner can spend at most $500 on inventory: $2x_1 + x_2 \leq 500$.
2. At least 100 pens are sold each month: $x_1 \geq 100$.
3. At most 150 pens are sold each month: $x_1 \leq 150$.
4. The number of pencils sold is at most twice the amount of pens sold: $x_2 \leq 2x_1$.

Given these constraints and the objective function, we have successfully translated the problem into a symbolic representation.

Here is the symbolic representation in JSON format:
```json
{
    'sym_variables': [('x1', 'number of pens'), ('x2', 'number of pencils')],
    'objective_function': '3*x1 + x2',
    'constraints': ['2*x1 + x2 <= 500', 'x1 >= 100', 'x1 <= 150', 'x2 <= 2*x1']
}
```

Now, let's implement this optimization problem using Gurobi in Python:
```python
from gurobipy import *

# Create a new model
m = Model("Stationary Store Optimization")

# Define the variables
x1 = m.addVar(name='pens', lb=0)
x2 = m.addVar(name='pencils', lb=0)

# Set the objective function
m.setObjective(3*x1 + x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(2*x1 + x2 <= 500, name='inventory_limit')
m.addConstr(x1 >= 100, name='min_pens_sold')
m.addConstr(x1 <= 150, name='max_pens_sold')
m.addConstr(x2 <= 2*x1, name='pencils_vs_pens')

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution: {x1.varName} = {x1.x}, {x2.varName} = {x2.x}")
    print(f"Maximum profit: {m.objVal}")
else:
    print("No optimal solution found")
```