-
Notifications
You must be signed in to change notification settings - Fork 272
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
market_order_target #224
Comments
Could definitely be an upgrade. I would recommend writing this utility though on your own because it's just one extra API call to size that portfolio. If you're interested in contributing, I would be happy to accept a contribution to the spot base class to have this functionality. |
I tried to monkey patch the code using: import blankly
from blankly.data.data_reader import PriceReader
from blankly import Strategy, StrategyState
from blankly.enums import Side
from blankly.exchanges.orders.market_order import MarketOrder
def init(symbol, state: StrategyState):
print(symbol, state)
state.variables["run_once"] = True
def market_order_target(interface,
symbol: str,
target: float) -> MarketOrder:
"""
Used for buying or selling market orders
Args:
symbol: asset to buy or sell
target: relative size of the position after the trade
"""
pos_weight = interface.get_positions(symbol) / interface.cash
buy_pos = (target - pos_weight) * interface.cash
if buy_pos > 0:
return interface.market_order(symbol, Side.BUY, buy_pos)
elif buy_pos < 0:
return interface.market_order(symbol, Side.SELL, -buy_pos)
return None
def price_event(price, symbol, state: StrategyState):
#print(price, symbol, state)
if state.variables["run_once"]:
# state.interface.market_order(symbol, side='buy', size=1.0)
type(state.interface).market_order_target = market_order_target
#market_order_target(state.interface, symbol, 1)
state.interface.market_order_target(symbol, 1)
if state.variables["run_once"]:
state.variables["run_once"] = False
if __name__ == "__main__":
# Run on the keyless exchange, starting at 100k
exchange = blankly.KeylessExchange(price_reader=PriceReader('./XBTUSDT_1Min.csv', 'BTC-USD'))
# Use our strategy helper
strategy = Strategy(exchange)
# Make the price event function above run every minute (60s)
strategy.add_price_event(price_event, symbol='BTC-USD', resolution=60, init=init)
# Backtest the strategy
results = strategy.backtest(start_date=1576778778, end_date=1656633557, initial_values={'USD': 10000})
print(results) but I'm getting the following error:
Any idea what is wrong with my code ? Kind regards |
it doesn't fix the
should be changed to
where def portfolio_value(interface, quote_asset):
portfolio_value = 0.0
for base_asset, values in interface.account.items():
if values["available"] != 0:
if base_asset == quote_asset:
portfolio_value += values["available"]
else:
price = interface.get_price(f"{base_asset}-{quote_asset}")
portfolio_value += price * values["available"]
return portfolio_value maybe such a function which returns portfolio value should also be defined. |
This looks correct, however the |
I wonder if a buildin Here is WIP import requests
import pandas as pd
import blankly
from blankly.data.data_reader import PriceReader
from blankly import Strategy, StrategyState
from blankly.enums import Side
from blankly.exchanges.orders.market_order import MarketOrder
from blankly import utils
def portfolio_value(interface, quote_asset):
portfolio_value = 0.0
for base_asset, account_values in interface.account.items():
if account_values["available"] != 0:
if base_asset == quote_asset:
values = account_values["available"]
portfolio_value += values
else:
symbol = f"{base_asset}-{quote_asset}"
price = interface.get_price(symbol)
print(f"price: {price}")
values = price * account_values["available"]
portfolio_value += values
return portfolio_value
def market_order_target(interface,
symbol: str,
target: float) -> MarketOrder:
quote_asset = utils.get_quote_asset(symbol)
base_asset = utils.get_base_asset(symbol)
pv = portfolio_value(interface, quote_asset)
pos_weight = (interface.get_account(base_asset)["available"]* interface.get_price(symbol)) / pv
buy_pos = (target - pos_weight) * pv
price = interface.get_price(symbol)
filter = interface.get_order_filter(symbol)
increment = filter["market_order"]["base_increment"]
precision = utils.increment_to_precision(increment)
size = blankly.trunc(abs(buy_pos) / price, precision)
if buy_pos > 0:
if size >= filter["market_order"]["base_min_size"]:
return interface.market_order(symbol, Side.BUY, size)
elif buy_pos < 0:
if size >= filter["market_order"]["base_min_size"]:
return interface.market_order(symbol, Side.SELL, size)
return None
def init(symbol, state: StrategyState):
print(symbol, state)
state.variables["run_once"] = True
state.variables["runs"] = 0
def price_event(price, symbol, state: StrategyState):
state.variables["runs"] += 1
#print(price, symbol, state)
if state.variables["run_once"]:
print(state.base_asset)
print(state.quote_asset)
print(symbol)
#state.interface.market_order(symbol, side='buy', size=1.0)
type(state.interface).market_order_target = market_order_target
##market_order_target(state.interface, symbol, 1.0)
state.variables["run_once"] = False
if state.variables["runs"] == 100_000:
target = 0.25
print(f"target: {target}")
state.interface.market_order_target(symbol, target)
elif state.variables["runs"] == 200_000:
target = 0.5
print(f"target: {target}")
state.interface.market_order_target(symbol, target)
elif state.variables["runs"] == 300_000:
target = 0.75
print(f"target: {target}")
state.interface.market_order_target(symbol, target)
elif state.variables["runs"] == 400_000:
target = 1.0
print(f"target: {target}")
state.interface.market_order_target(symbol, target)
if __name__ == "__main__":
# This downloads an example CSV
#data = requests.get(
# 'https://firebasestorage.googleapis.com/v0/b/blankly-6ada5.appspot.com/o/demo_data.csv?alt=media&token=acfa5c39-8f08-45dc-8be3-2033dc2b7b28').text
#with open('./price_examples.csv', 'w') as file:
# file.write(data)
# Run on the keyless exchange, starting at 100k
#exchange = blankly.KeylessExchange(price_reader=PriceReader('./price_examples.csv', 'BTC-USD'))
"""
df = pd.read_csv("XBTUSDT.csv", names=["time", "price", "volume"])
df["time"] = pd.to_datetime(df["time"], unit="s")
df = df.set_index("time")
prices = df.resample("1Min")["price"].ohlc().fillna(method="ffill")
volume = df.resample("1Min")["volume"].sum().fillna(value=0)
volume.name = "volume"
df_1Min = pd.concat([prices, volume], axis=1)
df_1Min = df_1Min.reset_index()
df_1Min["time"] = df_1Min["time"].map(pd.Timestamp.timestamp)
df_1Min.to_csv("XBTUSDT_1Min.csv")
"""
exchange = blankly.KeylessExchange(price_reader=PriceReader('./XBTUSDT_1Min.csv', 'BTC-USD'))
# Use our strategy helper
strategy = Strategy(exchange)
# Make the price event function above run every minute (60s)
strategy.add_price_event(price_event, symbol='BTC-USD', resolution=60, init=init)
# Backtest the strategy
#results = strategy.backtest(start_date=1588377600, end_date=1650067200, initial_values={'USD': 10000})
results = strategy.backtest(start_date=1576778778, end_date=1656633557, initial_values={'USD': 10000})
print(results) |
Hello,
According to doc https://docs.blankly.finance/orders/order/ a
market_order
method exists but it could be a nice improvement to addmarket_order_target
withtarget
parameter (relative size of the position after the trade) being a float between -1 and 1.target = 1 means buy with 100% of portfolio value
target = -1 means sell with 100% of portfolio value (ie sell shorting)
Kind regards
The text was updated successfully, but these errors were encountered: