我正在尝试制作我的第一个algo-bot,并决定使用IB和他们的API。我已经跟随Jacob Aramral的youtube系列关于制作一个bot,并几乎沿着和添加调整沿途使逻辑执行我想要的。在尝试运行代码后,我不断得到错误,无法连接。所以,我只是复制了他的代码试着运行(https://github.com/Jake0303/InteractiveBrokersPythonBot/blob/main/InteractiveBrokersPythonBot.py),连接交易平台(我假设是IB服务器),我可以输入股票代码并获得真实的数据,但它不能进行交易。然后我调整了Jacob的代码,基本上可以在每根蜡烛上进行交易(只是因为它正在阅读我的纸面账户,我想看到任何交易),但当达到标准时(最后一个收盘价高于之前蜡烛的收盘价)没有交易。我开始有点泄气了,所以希望有人能帮我。我也试着复制这里的介绍指南,试图让交易平台进行交易,但仍然没有运气。如果有人能看到我做错了什么,并能帮助我得到修复,我将不胜感激。
我有我的IBpro帐户资金与游戏钱,并已订阅“美国股票和期权附加流捆绑”和“美国证券快照和期货价值捆绑”订阅。对于纸帐户,我使用7497作为套接字端口,检查了活动X和套接字客户端,我禁用了只读API,我相信这就是我需要启用的所有API,以允许我进行交易(除了有一个功能代码,哈哈)。这里是应该工作的代码。我会很好奇,如果它工作的其他和地方贸易。此外,我已经包括了一个剪下的监视器一旦代码运行。任何帮助都很感激!
#Imports
import ibapi
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.order import *
import ta
import numpy as np
import pandas as pd
import pytz
import math
from datetime import datetime, timedelta
import threading
import time
#Vars
orderId = 1
#Class for Interactive Brokers Connection
class IBApi(EWrapper,EClient):
def __init__(self):
EClient.__init__(self, self)
# Historical Backtest Data
def historicalData(self, reqId, bar):
try:
bot.on_bar_update(reqId,bar,False)
except Exception as e:
print(e)
# On Realtime Bar after historical data finishes
def historicalDataUpdate(self, reqId, bar):
try:
bot.on_bar_update(reqId,bar,True)
except Exception as e:
print(e)
# On Historical Data End
def historicalDataEnd(self, reqId, start, end):
print(reqId)
# Get next order id we can use
def nextValidId(self, nextorderId):
global orderId
orderId = nextorderId
# Listen for realtime bars
def realtimeBar(self, reqId, time, open_, high, low, close,volume, wap, count):
super().realtimeBar(reqId, time, open_, high, low, close, volume, wap, count)
try:
bot.on_bar_update(reqId, time, open_, high, low, close, volume, wap, count)
except Exception as e:
print(e)
def error(self, id, errorCode, errorMsg):
print(errorCode)
print(errorMsg)
#Bar Object
class Bar:
open = 0
low = 0
high = 0
close = 0
volume = 0
date = datetime.now()
def __init__(self):
self.open = 0
self.low = 0
self.high = 0
self.close = 0
self.volume = 0
self.date = datetime.now()
#Bot Logic
class Bot:
ib = None
barsize = 1
currentBar = Bar()
bars = []
reqId = 1
global orderId
smaPeriod = 50
symbol = ""
initialbartime = datetime.now().astimezone(pytz.timezone("America/New_York"))
def __init__(self):
#Connect to IB on init
self.ib = IBApi()
self.ib.connect("127.0.0.1", 7497,221)
ib_thread = threading.Thread(target=self.run_loop, daemon=True)
ib_thread.start()
time.sleep(1)
currentBar = Bar()
#Get symbol info
self.symbol = input("Enter the symbol you want to trade : ")
#Get bar size
self.barsize = int(input("Enter the barsize you want to trade in minutes : "))
mintext = " min"
if (int(self.barsize) > 1):
mintext = " mins"
queryTime = (datetime.now().astimezone(pytz.timezone("America/New_York"))-timedelta(days=1)).replace(hour=16,minute=0,second=0,microsecond=0).strftime("%Y%m%d %H:%M:%S")
#Create our IB Contract Object
contract = Contract()
contract.symbol = self.symbol.upper()
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
self.ib.reqIds(-1)
# Request Market Data
#self.ib.reqRealTimeBars(0, contract, 5, "TRADES", 1, [])
self.ib.reqHistoricalData(self.reqId,contract,"","2 D",str(self.barsize)+mintext,"TRADES",1,1,True,[])
#Listen to socket in seperate thread
def run_loop(self):
self.ib.run()
#Bracet Order Setup
def bracketOrder(self, parentOrderId, action, quantity, profitTarget, stopLoss):
#Initial Entry
#Create our IB Contract Object
contract = Contract()
contract.symbol = self.symbol.upper()
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
# Create Parent Order / Initial Entry
parent = Order()
parent.orderId = parentOrderId
parent.orderType = "MKT"
parent.action = action
parent.totalQuantity = quantity
parent.transmit = False
# Profit Target
profitTargetOrder = Order()
profitTargetOrder.orderId = parent.orderId+1
profitTargetOrder.orderType = "LMT"
profitTargetOrder.action = "SELL"
profitTargetOrder.totalQuantity = quantity
profitTargetOrder.lmtPrice = round(profitTarget,2)
profitTargetOrder.parentId = parentOrderId
profitTargetOrder.transmit = False
# Stop Loss
stopLossOrder = Order()
stopLossOrder.orderId = parent.orderId+2
stopLossOrder.orderType = "STP"
stopLossOrder.action = "SELL"
stopLossOrder.totalQuantity = quantity
stopLossOrder.parentId = parentOrderId
stopLossOrder.auxPrice = round(stopLoss,2)
stopLossOrder.transmit = True
bracketOrders = [parent, profitTargetOrder, stopLossOrder]
return bracketOrders
#Pass realtime bar data back to our bot object
def on_bar_update(self, reqId, bar,realtime):
global orderId
#Historical Data to catch up
if (realtime == False):
self.bars.append(bar)
else:
bartime = datetime.strptime(bar.date,"%Y%m%d %H:%M:%S").astimezone(pytz.timezone("America/New_York"))
minutes_diff = (bartime-self.initialbartime).total_seconds() / 60.0
self.currentBar.date = bartime
lastBar = self.bars[len(self.bars)-1]
#On Bar Close
if (minutes_diff > 0 and math.floor(minutes_diff) % self.barsize == 0):
self.initialbartime = bartime
#Entry - If we have a higher high, a higher low and we cross the 50 SMA Buy
#1.) SMA
closes = []
for bar in self.bars:
closes.append(bar.close)
self.close_array = pd.Series(np.asarray(closes))
self.sma = ta.trend.sma(self.close_array,self.smaPeriod,True)
print("SMA : " + str(self.sma[len(self.sma)-1]))
#2.) Calculate Higher Highs and Lows
lastLow = self.bars[len(self.bars)-1].low
lastHigh = self.bars[len(self.bars)-1].high
lastClose = self.bars[len(self.bars)-1].close
# Check Criteria
if (bar.close > lastHigh
and self.currentBar.low > lastLow
and bar.close > str(self.sma[len(self.sma)-1])
and lastClose < str(self.sma[len(self.sma)-2])):
#Bracket Order 2% Profit Target 1% Stop Loss
profitTarget = bar.close*1.02
stopLoss = bar.close*0.99
quantity = 1
bracket = self.bracketOrder(orderId,"BUY",quantity, profitTarget, stopLoss)
contract = Contract()
contract.symbol = self.symbol.upper()
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
#Place Bracket Order
for o in bracket:
o.ocaGroup = "OCA_"+str(orderId)
self.ib.placeOrder(o.orderId,contract,o)
orderId += 3
#Bar closed append
self.currentBar.close = bar.close
print("New bar!")
self.bars.append(self.currentBar)
self.currentBar = Bar()
self.currentBar.open = bar.open
#Build realtime bar
if (self.currentBar.open == 0):
self.currentBar.open = bar.open
if (self.currentBar.high == 0 or bar.high > self.currentBar.high):
self.currentBar.high = bar.high
if (self.currentBar.low == 0 or bar.low < self.currentBar.low):
self.currentBar.low = bar.low
#Start Bot
bot = Bot()
1条答案
按热度按时间qyuhtwio1#
做了一些调整,包括不符合条件时的消息。应该可以开始了