Closed ben1628 closed 1 year ago
There are part of the module that requires Django to run to work. To test for instance, you cannot do unittest ... , you need to do python manage.py test. Django running means that the DB is running and so on. That's also the reason why I have such a distinction between strat, stratL, stratP... the first two don't need Django to run, they are there for backtesting. The "P" works however only in production and need Django to run.
Here in your case, ib import from orders.models, which is a clear Django "thing". Python alone cannot interpret what is in this model.
To do what you want to do. Start Django, (python manage.py runserver), and put the script you want to run in (let's say reporting/)view.py in the test function. You can then trigger it with localhost:8000/test.
There are two files with the IBData changes:
1/ opt_packages.py
Add
ib_insync=dict(name="ib_insync", link="https://github.com/erdewit/ib_insync"),
after riskfolio
2/ Custom.py
Add
"IBData"
after "TVData"
and then append ( the branch vectorbt.pro-IB_support, with version 1.8.2)
ib_global={"connected":False, "client":None}
class IBData(RemoteData):
...
at the end of the file after
TVData.override_column_config_doc(__pdoc__)
I hope that's all the changes in vectrobtpro
You can look at https://github.com/polakowo/vectorbt.pro/tree/IB_support_2/contrib/IB_support (a bit sad, that it is not merged yet).
You can put it in vectorbt or in the bot, it is exactly the same (and thx again for the push, to put it in vbt!)
Unfortunately, I don't have access to Vectorbtpro after version 1.90, I don't need those new features. I hope IB_Support you have previously is all the changes you have made.
The changes I made was noted previously in this comment.
Here is the IBData that I have in data/custom.py
__all__ = [
"AlpacaData",
"PolygonData",
"AVData",
"NDLData",
"TVData",
"IBData"
]
and the class IBData
ib_global={"connected":False, "client":None}
class IBData(RemoteData):
_setting_keys: tp.SettingsKeys = dict(custom="data.custom.ib")
@classmethod
def connect(cls):
ib_cfg = cls.get_settings(key_id="custom")
if not cls.client.isConnected():
clientID=1
while clientID<=100:
try:
cls.client.connect(host=ib_cfg['localhost'], port=ib_cfg['port'], clientId=clientID)
break
except:
clientID+=1
pass
if cls.client.isConnected():
ib_global["connected"]=True
else:
warnings.warn("connection to IB failed, check that IB is started")
@classmethod
def resolve_client(cls, client: tp.Optional[tp.Any] = None, **client_config) -> tp.Any:
from vectorbtpro.utils.opt_packages import assert_can_import
assert_can_import("ib_insync")
from ib_insync import IB
import asyncio
if client is None and "cls.client" not in locals(): #create a new connection
if ib_global["client"] is None:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
cls.client=IB()
cls.connect()
ib_global["client"]=cls.client
else:
cls.client=ib_global["client"]
elif client is not None:
cls.client=client
return cls.client
@classmethod
def get_contract_ib(cls, symbol,exchange,index):
#resolve client???
from ib_insync import Stock, Index
if index:
return Index(exchange=exchange,symbol=symbol)
elif exchange=="NASDAQ":
return Stock(symbol,"SMART", primaryExchange='NASDAQ')
else:
return Stock(symbol,exchange)
return None
@classmethod
def fetch_symbol(
cls,
symbol: str,
client: tp.Optional[tp.Any] = None,
client_config: tp.KwargsLike = None,
period: tp.Optional[str] = None,
start: tp.Optional[tp.DatetimeLike] = None,
end: tp.Optional[tp.DatetimeLike] = None,
timeframe: tp.Optional[str] = None,
indexes: tp.Optional[dict] = None,
exchanges: tp.Optional[dict] = None,
) -> tp.Any:
from vectorbtpro.utils.opt_packages import assert_can_import
assert_can_import("ib_insync")
from ib_insync import util
exchange="SMART" #default
if exchanges is not None:
if symbol in exchanges:
exchange=exchanges[symbol]
index=False
if indexes is not None:
if symbol in indexes:
index=indexes[symbol]
if client_config is None:
client_config = {}
cls.resolve_client(client=client, **client_config)
if ib_global["connected"]:
contract=cls.get_contract_ib(symbol,exchange,index)
#check period and timeframe
bars = cls.client.reqHistoricalData(
contract,
endDateTime='',
durationStr=period, #"10 D","1 M"
barSizeSetting=timeframe, #"1 day", "1 min"
whatToShow='TRADES',
useRTH=True,
formatDate=1)
df=util.df(bars)
if df is not None:
df.rename(
columns={
"date":"Date",
"open": "Open",
"high": "High",
"low": "Low",
"close": "Close",
"volume": "Volume",
"average":"Average",
"barCount": 'BarCount',
},
inplace=True,
)
df=df.set_index('Date')
return df
@classmethod
def get_last_price(cls,contract):
timeout=2
t=0
cls.resolve_client(client=None)
m_data = cls.client.reqMktData(contract)
while m_data.last != m_data.last and t<timeout: #Wait until data is in.
t+=0.01
cls.client.sleep(0.01)
if t==timeout:
m_data.last=0
cls.client.cancelMktData(contract)
return m_data.last
In _settings.py you also need to add in data
ib=FrozenConfig(
localhost='127.0.0.1',
port=7496,
),
Okay, it is now talking to IB, which is great. I tried the half a month report and it's calling IB without problem.
Now, I just have to figure out when it's not calling IB when I click Start_Bot. I ctrl-click AAPL and TSLA on normal strategy. However, telegram is working, but not seeing the program calling IB to get the real time market data.
However, it's a good start, I'm slowly getting there and in the process understanding what's going on, which is essential.
Again, thanks for your help!
P.S. My IB gateway is running on a windows 10, so I have a good GUI there. While trading-bot is on linux
I'm trying to make sure my IB api is working, so I just do the following in my notebook, and may try to do a simple test on IB.
and I get this error
any ideas?
I am using vectorbtpro 1.9.0 and merge the IBData you have, at the time, IBData wasn't updated with 1.9.0, I hope it's complete