i try to put some orders at a specific price.
For example i would like to put 20 dollars to buy some ETHUSDT at 800 usdt but it gives me this error:
binance.exceptions.BinanceAPIException: APIError(code=-1106): Parameter 'quoteOrderQty' sent when not required.
there is my call function:
buy_order = client.create_order(
symbol = "ETHUSDT",
price = 800,
quoteOrderQty = 25,
side = client.SIDE_BUY,
type = client.ORDER_TYPE_LIMIT,
timeInForce = client.TIME_IN_FORCE_GTC)
but i dont have any error when i put this :
buy_order = client.create_test_order(symbol="ETHUSDT", side='BUY', type='MARKET', quoteOrderQty=10)
to be honnest actually i do that:
def putOrderBuy_at_price(self, symbol, amount, price):
monney_price = self.client.get_symbol_ticker(symbol=symbol)
# Calculate how much ETH $200 can buy
print(monney_price['price'])
i = 10
while i != 0:
try:
buy_quantity = round(amount / float(price), i)
print("-----------", buy_quantity)
#ETHUSDT
buy_order = self.client.create_order(
symbol = symbol,
price = price,
quantity = buy_quantity,
side = self.client.SIDE_BUY,
type = self.client.ORDER_TYPE_LIMIT,
timeInForce = self.client.TIME_IN_FORCE_GTC)
break
except Exception:
print(i)
i -= 1
And i think there is a better way for that.
Thanks for yours answers
quoteOrderQty is only for MARKET order.
I am using PuLP to solve a minimization problem for a Loan optimisation problem. The code below is outputting the correct combination of loans with the current constraints (capital requirement and max drawdown amounts).
from pulp import *
class Loan():
def __init__(self, id, interest_rate, drawdown_amount, lender, min_drawdown, max_drawdown):
self.id = id
self.interest_rate = interest_rate
self.drawdown_amount = drawdown_amount
self.lender = lender
self.min_drawdown = min_drawdown
self.max_drawdown = max_drawdown
def __str__(self):
return f"loan(id={self.id}, lender={self.lender}, drawdown_amount={self.drawdown_amount}, interest_rate={self.interest_rate}, min_drawdown={self.min_drawdown}, max_drawdown={self.max_drawdown})"
# PROBLEM DATA:
capital_requirement = 1200000
ids = ["WF_1", "BA_1", "BA_2", "JP_1"]
interest_rates = [0.05, 0.03, 0.02, 0.04]
drawdown_amounts = [1,1,1,1,1]
lenders = ["Wells Fargo", "Bank of America" , "Bank of America", "JPMorgan"]
min_drawdowns = [75000, 100000, 300000, 80000]
max_drawdowns = [500000, 500000, 500000, 500000]
loans = [Loan(id, interest_rate, drawdown_amount, lender, min_drawdown, max_drawdown ) for id, interest_rate, drawdown_amount, lender, min_drawdown, max_drawdown in
zip(ids, interest_rates, drawdown_amounts, lenders, min_drawdowns, max_drawdowns)]
# DECLARE PROBLEM OBJECT
prob = LpProblem("Loan Optimiser", LpMinimize)
# VARIABLES
loanVars = LpVariable.dicts('loans', loans, 0)
# OBJECTIVE
prob += lpSum([loan.interest_rate * loanVars[loan] for loan in loans])
# CONSTRAINTS
# Amount of money to borrow:
prob += lpSum([loan.drawdown_amount * loanVars[loan] for loan in loans]) == capital_requirement
# If a loan is included, it must be below the maximum drawdown amount of that loan:
for loan in loans:
prob += loanVars[loan] <= loan.max_drawdown * loanVars_selected[loan]
Sample output with capital requirement of 1.2m:
---------The optimal loans to use for borrowing € 1200000.0 are----------
$200000.0 of JP_1
$500000.0 of BA_1
$500000.0 of BA_2
Total Interest Cost = $33000.00
Total Interest Rate = 2.75 %
I would like to add a constraint so that a lender can only appear once in the output, in the above example this would remove BA_1 from the output and add in WF_1.
The code that I have written for this constraint is below but is not applying the logic correctly:
unique_lenders = set([loan.lender for loan in loans])
print(unique_lenders)
for lender in unique_lenders:
prob += lpSum([loanVars[loan] for loan in loans if loan.lender == lender]) >= 1
Thanks in advance.
EDIT:
I got the constraint working using a binary variable loanVars_selected and the below code based off Erwins answer:
for lender in unique_lenders:
prob += lpSum(loanVars_selected[loan] for loan in loans if loan.lender == lender) <= 1
I think you want a binary variable for each loan. Then add:
loanVars[loan] <= b[loan]*maxLoan[loan]
and
for each lender L:
sum(for all loans issued by L,b[loan]) <= 1
(I used pseudo code for clarity)
I have a csv file / pandas dataframe which looks like this. It contains various portfolio compositions for a portfolio which is re-balanced everyday according to my own calculations.
date asset percentage
4-Jan-21 AAPL 12.00%
4-Jan-21 TSM 1.00%
4-Jan-21 IBM 31.00%
4-Jan-21 KO 15.00%
4-Jan-21 AMD 41.00%
5-Jan-21 DELL 23.00%
5-Jan-21 TSM 12.20%
5-Jan-21 IBM 15.24%
5-Jan-21 KO 1.50%
5-Jan-21 NKE 7.50%
5-Jan-21 TSLA 9.50%
5-Jan-21 CSCO 3.30%
5-Jan-21 JPM 27.76%
6-Jan-21 AMD 45%
6-Jan-21 BA 0.50%
6-Jan-21 ORCL 54.50%
7-Jan-21 AAPL 50.00%
7-Jan-21 KO 50.00%
...
I want to test a strategy with a 12 asset portfolio.
AAPL,TSM,IBM,KO,AMD,DELL,NKE,TSLA,CSCO,JPM,BA,ORCL
So let's say on 4Jan2021, the portfolio's composition would be 12% in apple, 1% in TSM.. etc. I want to be able to check the prices and know how many I should be holding.
The next day, 5Jan2021, the composition will change to 23% in Dell.. etc, if the stock isn't in this list means its 0% for that day.
I have been looking at backtrader as a backtesting platform, however, the code I have seen in the repo mostly shows how to do stuff with indicators, like SMA cross over, RSI...
My question is: Is it possible to create and test a portfolio based on these compositions I have so I can check the return of this strategy? It would check this frame, and know how many stocks in a ticker to buy or sell on that particular day.
So the universe of stocks I am buying or sell is AAPL,TSM,IBM,KO,AMD,DELL,NKE,TSLA,CSCO,JPM,BA,ORCL
So on 4-Jan-21 it might look like,
dictionary['4Jan2021'] = {'AAPL':0.12,
'TSM':0.01,
'IBM':0.31,
'KO':0.15,
'AMD':0.41,}
On 5-Jan-21 it will look like,
dictionary['5Jan2021'] = {'DELL':0.23,
'TSM':0.122,
'IBM':0.1524,
'KO':0.015,
'NKE':0.075,
'TSLA':0.095,
'CSCO':0.033,
'JPM':0.2776,}
If the ticker isnt there means its 0%.
The portfolio composition needs to change everyday.
The first thing you will want to do it load your targets with your datas. I like
personally to attach the target to the dataline as I add it to backtrader.
tickers = {"FB": 0.25, "MSFT": 0.4, "TSLA": 0.35}
for ticker, target in tickers.items():
data = bt.feeds.YahooFinanceData(
dataname=ticker,
timeframe=bt.TimeFrame.Days,
fromdate=datetime.datetime(2019, 1, 1),
todate=datetime.datetime(2020, 12, 31),
reverse=False,
)
data.target = target
cerebro.adddata(data, name=ticker)
In next you will want to go through each data, and determine the current allocation. If the current allocation is too far from the desired allocation (threshold) you trade all datas.
Notice there is a buffer variable. This will reduce the overall value of the account for calculating units to trade. This helps avoid margin.
You will use a dictionary to track this information.
def next(self):
track_trades = dict()
total_value = self.broker.get_value() * (1 - self.p.buffer)
for d in self.datas:
track_trades[d] = dict()
value = self.broker.get_value(datas=[d])
allocation = value / total_value
units_to_trade = (d.target - allocation) * total_value / d.close[0]
track_trades[d]["units"] = units_to_trade
# Can check to make sure there is enough distance away from ideal to trade.
track_trades[d]["threshold"] = abs(d.target - allocation) > self.p.threshold
Check all the thresholds to determine if trading. If any of datas need trading, then all need trading.
rebalance = False
for values in track_trades.values():
if values['threshold']:
rebalance = True
if not rebalance:
return
Finally, execute your trades. Always sell first to generate cash in the account and avoid margins.
# Sell shares first
for d, value in track_trades.items():
if value["units"] < 0:
self.sell(d, size=value["units"])
# Buy shares second
for d, value in track_trades.items():
if value["units"] > 0:
self.buy(d, size=value["units"])
Here is the all of the code for your reference.
import datetime
import backtrader as bt
class Strategy(bt.Strategy):
params = (
("buffer", 0.05),
("threshold", 0.025),
)
def log(self, txt, dt=None):
""" Logging function fot this strategy"""
dt = dt or self.data.datetime[0]
if isinstance(dt, float):
dt = bt.num2date(dt)
print("%s, %s" % (dt.date(), txt))
def print_signal(self):
self.log(
f"o {self.datas[0].open[0]:7.2f} "
f"h {self.datas[0].high[0]:7.2f} "
f"l {self.datas[0].low[0]:7.2f} "
f"c {self.datas[0].close[0]:7.2f} "
f"v {self.datas[0].volume[0]:7.0f} "
)
def notify_order(self, order):
""" Triggered upon changes to orders. """
# Suppress notification if it is just a submitted order.
if order.status == order.Submitted:
return
# Print out the date, security name, order number and status.
type = "Buy" if order.isbuy() else "Sell"
self.log(
f"{order.data._name:<6} Order: {order.ref:3d} "
f"Type: {type:<5}\tStatus"
f" {order.getstatusname():<8} \t"
f"Size: {order.created.size:9.4f} Price: {order.created.price:9.4f} "
f"Position: {self.getposition(order.data).size:5.2f}"
)
if order.status == order.Margin:
return
# Check if an order has been completed
if order.status in [order.Completed]:
self.log(
f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
# f"EXECUTED for: {dn} "
f"Price: {order.executed.price:6.2f} "
f"Cost: {order.executed.value:6.2f} "
f"Comm: {order.executed.comm:4.2f} "
f"Size: {order.created.size:9.4f} "
)
def notify_trade(self, trade):
"""Provides notification of closed trades."""
if trade.isclosed:
self.log(
"{} Closed: PnL Gross {}, Net {},".format(
trade.data._name,
round(trade.pnl, 2),
round(trade.pnlcomm, 1),
)
)
def next(self):
track_trades = dict()
total_value = self.broker.get_value() * (1 - self.p.buffer)
for d in self.datas:
track_trades[d] = dict()
value = self.broker.get_value(datas=[d])
allocation = value / total_value
units_to_trade = (d.target - allocation) * total_value / d.close[0]
track_trades[d]["units"] = units_to_trade
# Can check to make sure there is enough distance away from ideal to trade.
track_trades[d]["threshold"] = abs(d.target - allocation) > self.p.threshold
rebalance = False
for values in track_trades.values():
if values['threshold']:
rebalance = True
if not rebalance:
return
# Sell shares first
for d, value in track_trades.items():
if value["units"] < 0:
self.sell(d, size=value["units"])
# Buy shares second
for d, value in track_trades.items():
if value["units"] > 0:
self.buy(d, size=value["units"])
if __name__ == "__main__":
cerebro = bt.Cerebro()
tickers = {"FB": 0.25, "MSFT": 0.4, "TSLA": 0.35}
for ticker, target in tickers.items():
data = bt.feeds.YahooFinanceData(
dataname=ticker,
timeframe=bt.TimeFrame.Days,
fromdate=datetime.datetime(2019, 1, 1),
todate=datetime.datetime(2020, 12, 31),
reverse=False,
)
data.target = target
cerebro.adddata(data, name=ticker)
cerebro.addstrategy(Strategy)
# Execute
cerebro.run()
####################################
############# EDIT ###############
####################################
There was an additional requiest for adding in variable allocations per day per security. The following code accomplishes that.
import datetime
import backtrader as bt
class Strategy(bt.Strategy):
params = (
("buffer", 0.05),
("threshold", 0.025),
)
def log(self, txt, dt=None):
""" Logging function fot this strategy"""
dt = dt or self.data.datetime[0]
if isinstance(dt, float):
dt = bt.num2date(dt)
print("%s, %s" % (dt.date(), txt))
def print_signal(self):
self.log(
f"o {self.datas[0].open[0]:7.2f} "
f"h {self.datas[0].high[0]:7.2f} "
f"l {self.datas[0].low[0]:7.2f} "
f"c {self.datas[0].close[0]:7.2f} "
f"v {self.datas[0].volume[0]:7.0f} "
)
def notify_order(self, order):
""" Triggered upon changes to orders. """
# Suppress notification if it is just a submitted order.
if order.status == order.Submitted:
return
# Print out the date, security name, order number and status.
type = "Buy" if order.isbuy() else "Sell"
self.log(
f"{order.data._name:<6} Order: {order.ref:3d} "
f"Type: {type:<5}\tStatus"
f" {order.getstatusname():<8} \t"
f"Size: {order.created.size:9.4f} Price: {order.created.price:9.4f} "
f"Position: {self.getposition(order.data).size:5.2f}"
)
if order.status == order.Margin:
return
# Check if an order has been completed
if order.status in [order.Completed]:
self.log(
f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
# f"EXECUTED for: {dn} "
f"Price: {order.executed.price:6.2f} "
f"Cost: {order.executed.value:6.2f} "
f"Comm: {order.executed.comm:4.2f} "
f"Size: {order.created.size:9.4f} "
)
def notify_trade(self, trade):
"""Provides notification of closed trades."""
if trade.isclosed:
self.log(
"{} Closed: PnL Gross {}, Net {},".format(
trade.data._name,
round(trade.pnl, 2),
round(trade.pnlcomm, 1),
)
)
def __init__(self):
for d in self.datas:
d.target = {
datetime.datetime.strptime(date, "%d-%b-%y").date(): allocation
for date, allocation in d.target.items()
}
def next(self):
date = self.data.datetime.date()
track_trades = dict()
total_value = self.broker.get_value() * (1 - self.p.buffer)
for d in self.datas:
if date not in d.target:
if self.getposition(d):
self.close(d)
continue
target_allocation = d.target[date]
track_trades[d] = dict()
value = self.broker.get_value(datas=[d])
current_allocation = value / total_value
net_allocation = target_allocation - current_allocation
units_to_trade = (
(net_allocation) * total_value / d.close[0]
)
track_trades[d]["units"] = units_to_trade
# Can check to make sure there is enough distance away from ideal to trade.
track_trades[d]["threshold"] = abs(net_allocation) > self.p.threshold
rebalance = False
for values in track_trades.values():
if values["threshold"]:
rebalance = True
if not rebalance:
return
# Sell shares first
for d, value in track_trades.items():
if value["units"] < 0:
self.sell(d, size=value["units"])
# Buy shares second
for d, value in track_trades.items():
if value["units"] > 0:
self.buy(d, size=value["units"])
if __name__ == "__main__":
cerebro = bt.Cerebro()
allocations = [
("AAPL", "4-Jan-21", 0.300),
("TSM", "4-Jan-21", 0.200),
("IBM", "4-Jan-21", 0.300),
("KO", "4-Jan-21", 0.2000),
("AMD", "4-Jan-21", 0.1000),
("DELL", "5-Jan-21", 0.200),
("TSM", "5-Jan-21", 0.20),
("IBM", "5-Jan-21", 0.1),
("KO", "5-Jan-21", 0.1),
("NKE", "5-Jan-21", 0.15),
("TSLA", "5-Jan-21", 0.10),
("CSCO", "5-Jan-21", 0.050),
("JPM", "5-Jan-21", 0.1),
("AMD", "6-Jan-21", 0.25),
("BA", "6-Jan-21", 0.25),
("ORCL", "6-Jan-21", 0.50),
("AAPL", "7-Jan-21", 0.5000),
("KO", "7-Jan-21", 0.5000),
]
ticker_names = list(set([alls[0] for alls in allocations]))
targets = {ticker: {} for ticker in ticker_names}
for all in allocations:
targets[all[0]].update({all[1]: all[2]})
for ticker, target in targets.items():
data = bt.feeds.YahooFinanceData(
dataname=ticker,
timeframe=bt.TimeFrame.Days,
fromdate=datetime.datetime(2020, 12, 21),
todate=datetime.datetime(2021, 1, 8),
reverse=False,
)
data.target = target
cerebro.adddata(data, name=ticker)
cerebro.addstrategy(Strategy)
cerebro.broker.setcash(1000000)
# Execute
cerebro.run()
I was trying to solve the problem But I could not figure it out.
I have product dictionary:
product = {
"shirt" : {
"price" :300 ,
"no_reqired_for_dis" : {"3": ["shirt","pents","tshirt","shorts"],"discount_price" : 250}},
"pents" : {
"price" :200 ,
"no_reqired_for_dis" : {"3": ["shirt","pents","tshirt","shorts"],"discount_price" : 250}}
"tshirt" : {
"price" :150 ,
"no_reqired_for_dis" : {"3": ["shirt","pents","tshirt","shorts"],"discount_price" : 250}}
"shorts" : {
"price" :100 ,
"no_reqired_for_dis" : {"3": ["shirt","pents","tshirt","shorts"],"discount_price" : 250}}
}
What should be best approach to to find the total
discount criteria if anyone who buys a minimum of three products or a multiple of 3 they will get three item for 250?
for example if someone buy total 11 (shirt = 5,pants = 4, tshirt = 1, short = 1) products,then their total should be 250 * 3 + remaining item * lowest price product. Here remaining item should be lowest price of the product(here it should be shorts and tshirt).
I have done this:
total_payment = 0
total_product = {"shirt" : 5,"pents":4,"tshirt":1,"shorts" 1}
total_item = sum(total_product.values())
for key, value in total_product.items():
min_no_required_for_discount = product[key]["no_required_for_dis"].keys()
if total_item < int(min_no_required_for_discount[0]:
total_payment += value * product[key]["price"]
else:
remaining_unit = total_item % 3
total_pair = (total_item - remaining_unit) // 3
total_payment += total_pair * 250
Now i am confuse in remaining_unit. how to calculate price for remaining_unit because remaining_unit must multiply with who has minimum price . in above example remaining_unit will be 2 and it will calculate price of shorts and tshirt
Here is quick template that might help you to start working on this problem:
[Notes: use set() to get the items difference quickly, and use print() statement to confirm each step is expected] Again, this is NOT a complete solution - but just offers a good template for you to start quickly.
from pprint import pprint
lowest_price_items = ['tshirt', 'shorts']
discount_price_items = ['shirt', 'pants']
discount_Set = set(discount_price_items)
cart = ['shirt', 'shirt', 'shirt', 'shirt', 'shirt', 'pants', 'pants', 'pants', 'pants', 'tshirt', 'shorts']
cart_Set = set(cart)
low_price_goods = cart_Set - discount_Set
pprint(product)
print(f' products: {product.keys()} ') # first level of prod. dict.
print(product['shirt'].keys()) # 'price' and 'no_requied_for_dis'
# products key1 key2
print(product['shirt']['no_reqired_for_dis']['discount_price']) # 250
tshirt_price = product['tshirt']['price']
print(tshirt_price)
"""
total should be 250 * 3 + remaining item * lowest_price_products (tshirts, shorts) only
"""
total_items = len(cart)
print(total_items)
# modify this to calculate the final price.
if total_items > 3:
final_price = 250 * total_items %3 + "remaining item * lowest_price_products" # select the lowest price items
I cannot seem to understand how to use if/else in the following question:
You need to design a program for a courier company to calculate the cost of sending a parcel.
Ask the user to enter the price of the package they would like to purchase.
Ask the user to enter the total distance of the delivery in kilometers.
Now, add on the delivery costs to get the final cost of the product. There are four categories to factor in when determining a parcel’s final cost, each with two options based on the customer’s delivery preferences. (Use an if else statement based on the choice they make)
Delivery via air ($0.36 per km) or via freight ($0.25 per km)
Full insurance ($50.00) or limited insurance ($25.00)
Gift option ($15.00) or not ($0.00)
Priority delivery ($100.00) or standard delivery ($20.00)
Write code to work out the total cost of the package based on the options
selected in each category.
#Mohseen Ramjan
I used some of the original code, but simplified it a bit.
I am no expert, and I'm sure even this code can be improved a lot.
===== NOTE: our currency is Rand, thus the use of the 'R' =====
But maybe you'll understand this a bit better:
main_product_price = int(float(input("""Please enter the price of the package you would like to purchase:
(Only use numbers, do not inlcude 'R')\n""")))
total_distance = int(float(input("\nPlease enter the total distance of the delivery in Kilometers:\n")))
print ("\nNow please choose your shipping preferences;")
print ("\nWould you prefere Air at R0.36 per km, or Freight at R0.25 per km?")
freight_choise = input("Enter: 'Air' or 'Freight'\n")
cost_per_distance = 0
if freight_choise in ['Freight']:
cost_per_distance = 0.25
elif freight_choise in ['Air']:
cost_per_distance = 0.36
print ("\nWould you prefere Full insurance (R50.00), or Limited insurance (R25.00)?")
insurance_choise = input("Enter: 'Full' or 'Limited'?\n")
insurance_cost = 0
if insurance_choise in ['Full']:
insurance_cost = 50
elif insurance_choise in ['Limited']:
insurance_cost = 25
print ("\nWould you like to add a Gift for R15.00?")
gift_choise = input("Enter: 'Yes please' or 'No thanks'\n")
gift_cost = 0
if gift_choise in ['Yes please']:
gift_cost = 15
elif gift_choise in ['No thanks']:
gift_cost = 0
print ("\nWould you prefere Priority delivery for R100.00, or Standard delivery for R20.00?")
delivery_choise = input("Enter: 'Priority' or 'Standard'\n")
priority_or_standard_delivery = 0
if delivery_choise in ['Priority']:
priority_or_standard_delivery = 100
elif delivery_choise in ['Standard']:
priority_or_standard_delivery = 20
total_cost = main_product_price + total_distance*cost_per_distance + insurance_cost + gift_cost + priority_or_standard_delivery
print (f"""\nThis is your Total cost:
R{total_cost}""")
# Courier cost of delivering parcel
# You can and should add your own assertions and checks if the user input is valid
# I used a list instead of '==' so that you can expand the response options
# There are many other ways to do it, this is just my quick and dirty method
# But I suppose you could iterate from here
def user_input():
price_of_package = float(input('Input price of package.\n'))
total_distance = float(input('Input total distance in km\n'))
freight_or_air = input('Input freight or air delivery?\n').lower()
full_or_limited_insurance = input('Input full or limited insurance?\n').lower()
gift_or_not = input('Is this a gift?\n').lower()
priority_or_standard = input('Is this priority or standard delivery?\n').lower()
cost_per_distance = 0
if freight_or_air in ['freight']:
cost_per_distance = 0.25
elif freight_or_air in ['air']:
cost_per_distance = 0.36
cost_of_insurance = 0
if full_or_limited_insurance in ['full']:
cost_of_insurance = 50.00
elif full_or_limited_insurance in ['limited']:
cost_of_insurance = 25.00
cost_of_gift = 0
if gift_or_not in ['yes']:
cost_of_gift = 15
cost_of_delivery = 0
if priority_or_standard in ['priority']:
cost_of_delivery = 100
elif priority_or_standard in ['standard']:
cost_of_delivery = 20
print (f'\nThe user has specified that\n\
price of package: {price_of_package}\n\
total distance: {total_distance}\n\
freight or air: {freight_or_air}\n\
cost per distance {cost_per_distance}\n\
type of insurance: {full_or_limited_insurance}\n\
cost of insurance: {cost_per_distance}\n\
if it is a gift: {gift_or_not}\n\
cost of gift: {cost_of_gift}\n\
type of delivery: {priority_or_standard}\n\
cost of delivery: {cost_of_delivery}.')
return price_of_package, total_distance, cost_per_distance,\
cost_of_insurance, cost_of_gift, cost_of_delivery
def total_cost():
price_of_package, total_distance, cost_per_distance,\
cost_of_insurance, cost_of_gift, cost_of_delivery = user_input()
total_cost = price_of_package + total_distance*cost_per_distance +\
cost_of_insurance + cost_of_gift + cost_of_delivery
print (f'\nThe total cost is {total_cost}.')
return total_cost