Example #1
0
def main():
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(threadName)s - %(message)s')

    trader_1 = Trader()
    trader_2 = Trader()
    trader_3 = Trader()
    trader_4 = Trader()
    
    thread_update_exchange = threading.Thread(target=Trader.update_exchange_info, name="Exchange Updater")
    thread_update_exchange.daemon = True

    thread_analyze_market = threading.Thread(target=Trader.analyze_market_data, name="Market Analyzer")
    thread_analyze_market.daemon = True

    thread_check_order = threading.Thread(target=Trader.check_order, name="Order Checker")
    thread_check_order.daemon = True

    thread_trader_1 = threading.Thread(target=trader_1.trade, name="trader_1")
    thread_trader_2 = threading.Thread(target=trader_2.trade, name="trader_2")
    thread_trader_3 = threading.Thread(target=trader_3.trade, name="trader_3")
    thread_trader_4 = threading.Thread(target=trader_4.trade, name="trader_4")

    thread_update_exchange.start()
    thread_analyze_market.start()
    thread_check_order.start()

    thread_trader_1.start()
    thread_trader_2.start()
#    thread_trader_3.start()
#    thread_trader_4.start()

    while True:
        logging.debug('Sleep 60 sec...')
        time.sleep(60)
Example #2
0
class Environment:
    def __init__(self):
        self.trader = Trader()
        self.action_space = [0, 1]
        self.steps_till_done = 0
        self.steps_todo_done = 20

    def random_action(self):
        return self.action_space[np.random.randint(2)]

    def get_state(self):
        return self.trader.get_history_data(STATE_DIM)

    def step(self, action):
        self.steps_till_done += 1
        current_price = self.trader.get_history_data(1)[0]
        done = 0
        if self.steps_till_done % self.steps_todo_done == 0:
            done = 1
            self.steps_till_done = 0
        if action == 0:
            reward = self.trader.buy_bracket_and_return_sold(cfg.quantity, current_price)
        else:
            reward = self.trader.sell_bracket_and_return_sold(cfg.quantity, current_price)

        next_state = self.trader.get_history_data(STATE_DIM)
        return next_state, reward, done
Example #3
0
 def arrivedRemote(self):
     print(self,"arrived.")
     self.market=self.destination
     self.destination=None
     for business,quantity in self.businesses:
         Trader.transact(self,business,quantity)
         time.sleep(2)
     self.goHome()
Example #4
0
def main():
    print("******************* \n --Program start--- \n ******************* ")

    bithumb = Bithumb()  #bithumb 객체를 선언하고
    coinone = Coinone()
    bithumb.renew_info()  #renew_info()함수를 돌리면 쓰레드가 시작되어 api의 값을 받아오는데,
    coinone.renew_info()

    trader = Trader()
    trader.trade(bithumb, coinone)
    print("lowest_ask_price Bithumb:%s Coinone:%s" %
          (bithumb.lowest_ask_price, coinone.lowest_ask_price))
Example #5
0
    def __init__(self, param, instrument, environment='demo', mode='test'):
        self.instrument = instrument
        self.environment = environment
        self.param = param
        self.trader = Trader(instrument, environment, mode)
        #self.predictors = {k: Predictor(k) for k in param.timelist}
        #self.fetters = {k: Fetter(k) for k in param.timelist}
        self.evaluator = Evaluator(self.param.timelist, instrument,
                                   environment)

        self.checking_freq = 0
        self.count = 0
Example #6
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--update", help="Update all stock values.", action="store_true")
    parser.add_argument("-r", "--run", help="Run the trader.", action="store_true")
    parser.add_argument("-s", "--show", help="Show the trader's current status.", action="store_true")
    parser.add_argument("--reset", help="Reset the trader's data.", action="store_true")
    parser.add_argument("-t", "--trader", help="The trader to work with.  All if not specified.")
    args = parser.parse_args()
    
    # Do all traders or just one?
    traders = sorted(rulesets.keys())
    if args.trader:
        traders = [args.trader]
    
    logger.info("Starting up")
    for trader in traders:
        logger.info("Handling trader %s", trader)
        t = Trader(rules=rulesets[trader], name=trader)
        if args.reset:
            logger.info("Resetting data")
            t.reset()
        if args.update:
            logger.info("Updating all stocks")
            t.update_all_stocks()
        if args.run:
            logger.info("Running trader")
            t.run()
        if args.show:
            print "===============================\n\n%s" % t
 def encounter(self):
     encounterChance = random.randint(0, 1)
     if encounterChance == 1:
         if self.difficulty == "Easy":
             chance = random.randint(1, 6)
             if chance == 1:
                 randAttacker = random.randint(0, 1)
                 if randAttacker == 0:
                     if len(self.player.ship.inventory) > 0:
                         self.npc = Police()
                     else:
                         self.npc = Bandit(self.difficulty)
                 else:
                     self.npc = Bandit(self.difficulty)
             else:
                 self.npc = Trader(self.curr_region)
         if self.difficulty == "Medium":
             chance = random.randint(1, 6)
             if chance > 1 and chance < 4:
                 randAttacker = random.randint(0, 1)
                 if randAttacker == 0:
                     if len(self.player.ship.inventory) > 0:
                         self.npc = Police()
                     else:
                         self.npc = Bandit(self.difficulty)
                 else:
                     self.npc = Bandit(self.difficulty)
             else:
                 self.npc = Trader(self.curr_region)
         if self.difficulty == "Hard":
             chance = random.randint(3, 6)
             if chance > 3:
                 randAttacker = 0
                 if randAttacker == 0:
                     if len(self.player.ship.inventory) > 0:
                         self.npc = Police()
                     else:
                         self.npc = Bandit(self.difficulty)
                 else:
                     self.npc = Bandit(self.difficulty)
             else:
                 self.npc = Trader(self.curr_region)
     else:
         self.npc = None
Example #8
0
	def __init__(self, param: list, instrument: str, environment: str='demo', mode: str='test'):
		"""

		トレードの対象となる通貨ペアと時間足(種類と本数)を定義

		Parameter
		---------
		param : list
			取り扱う時間足のリスト
		instrument : str
			取り扱う通貨ペア
		environment : str
			トレード環境(本番or仮想)を指定
		mode : str
			デバッグ用の出力を行うかどうかを指定

		Self
		----
		param : list
			取り扱う時間足のリスト
		instrument : str
			取り扱う通貨ペア
		environment : str
			トレード環境(本番or仮想)を指定
		trader : Trader (User defined)
		evaluator : Evaluator (User defined)
		checking_freq : int (const)
			画面出力の頻度を決定するための定数
		count : int
			画面出力のための内部カウンタ
		

		"""

		self.instrument = instrument
		self.environment = environment
		self.param = param
		self.trader = Trader(instrument, environment, mode)
		#self.predictors = {k: Predictor(k) for k in param.timelist}
		#self.fetters = {k: Fetter(k) for k in param.timelist}
		self.evaluator = Evaluator(self.param.timelist, instrument, environment)

		self.checking_freq = 10
		self.count = 0
Example #9
0
 def __init__(self, models, accountId, trader=None, logger=None):
   self.models = models
   self.accountId = accountId
   if trader is None:
     trader = Trader(logger=logger)
   self.trader = trader
   if logger is None:
     logger = logging.getLogger()
   self.logger = logger
   self.minPrecision = 2
Example #10
0
    def setup_class(self):
        self.town1 = Town('Los Mantos', (-2, 0), 500, [10, 10], 'Coastal', [])
        self.town2 = Town('Kallac', (1, 1), 500, [10, 10], 'Karst', [])
        self.town3 = Town('Vinas', (2, -2), 500, [10, 10], 'Hilly', [])
        self.towns = [self.town1, self.town2, self.town3]

        self.player = Trader("The player", [1, 1], [0, 0], 15000, [], [])
        self.traders = [self.player]

        self.world = World(0, self.towns, self.traders)
Example #11
0
 def create_trader(self, dict_arguments):
     # 不允许重复创建交易员实例
     if len(self.__list_trader) > 0:
         for i in self.__list_trader:
             if i.get_trader_id() == dict_arguments['trader_id']:
                 print("MultiUserTraderSys.create_trader()已经存在trader_id为", dict_arguments['trader_id'], "的实例")
                 return False
     self.__list_trader.append(Trader(dict_arguments))
     print('===========================')
     print("CTPManager.create_trader()创建交易员实例", dict_arguments)
Example #12
0
def main():
    stock_names = []
    with open("PyBroker/sp500.txt", "r") as stocks:
        for stock in stocks:
            stock_names.append(stock[:-1])

    market = Market(stock_names)
    trader = Trader(capital=1000000.0, day=252)

    strategy = SimpleStrategy(trader, market)
    strategy.trade_for_days(252)
Example #13
0
    def __init__(self):

        cwd = os.getcwd()
        print("Running Astibot in: %s" % cwd)

        self.isInitializing = True
        self.iterationCounter = 0
        self.historicPriceIterationCounter = 0

        self.app = pg.QtGui.QApplication(['Astibot'])

        # Show Splash Screen
        splash_pix = QtGui.QPixmap('AstibotSplash.png')
        splash = QtGui.QSplashScreen(splash_pix,
                                     QtCore.Qt.WindowStaysOnTopHint)
        splash.show()

        # Instanciate objects
        self.theSettings = Settings()
        self.theUIGraph = UIGraph(self.app, self.theSettings)
        self.theGDAXControler = GDAXControler(self.theUIGraph,
                                              self.theSettings)
        self.theMarketData = MarketData(self.theGDAXControler, self.theUIGraph)
        self.theTransactionManager = TransactionManager(
            self.theGDAXControler, self.theUIGraph, self.theMarketData,
            self.theSettings)
        self.theUIGraph.UIGR_SetTransactionManager(self.theTransactionManager)
        self.theTrader = Trader(self.theTransactionManager, self.theMarketData,
                                self.theUIGraph, self.theSettings)
        self.theInputDataHandler = InputDataHandler(self.theGDAXControler,
                                                    self.theUIGraph,
                                                    self.theMarketData,
                                                    self.theTrader,
                                                    self.theSettings)
        self.theApp = AppState(self.theUIGraph, self.theTrader,
                               self.theGDAXControler, self.theInputDataHandler,
                               self.theMarketData, self.theSettings)

        # Setup Main Tick Timer
        self.mainTimer = pg.QtCore.QTimer()
        self.mainTimer.timeout.connect(self.MainTimerHandler)
        self.mainTimer.start(100)

        # Hide splash screen
        splash.close()

        # Endless call
        self.app.exec_()

        # App closing
        self.theGDAXControler.GDAX_closeBackgroundOperations()
        self.theInputDataHandler.INDH_closeBackgroundOperations()
        self.theUIGraph.UIGR_closeBackgroundOperations()
Example #14
0
 def create_trader(trader_type, trader_id, min_price, max_price):
     if trader_type == TType.GVWY:
         trader = Giveaway(trader_type, trader_id, min_price, max_price)
     elif trader_type == TType.ZIU:
         trader = ZIU(trader_type, trader_id, min_price, max_price)
     elif trader_type == TType.ZIC:
         trader = ZIC(trader_type, trader_id, min_price, max_price)
     elif trader_type == TType.ZIP:
         trader = ZIP(trader_type, trader_id, min_price, max_price)
     else:
         trader = Trader(trader_type, trader_id, min_price, max_price)
     return trader
Example #15
0
def trader():
    global trade
    global player
    trade = Trader(player)
    market_list = {}
    for item in trade.market.items.keys():
        market_list[item] = trade.market.items[item].buy_value
    region_info = {
        'market': market_list,
        'inventory': player.inventory,
        'fuel': player.ship.fuel,
        'health': player.ship.health
    }
    return render_template("NPCs/Trader.html", region_info=region_info)
from Trader import Trader
import json
import time
t = Trader('PIMBEX', 'PBB41539586')
stock = 'TLL'


r = t.get_quote(stock)
askSize = 0
bidSize = 0
ask = 0
bid = 0
if 'askSize' in r:
    askSize = r['askSize']
    ask = r['ask']
if 'bidSize' in r:
    bidSize = r['bidSize']
    bid = r['bid']
r1 = 0
if askSize > 10 * bidSize and askSize > 5000:
    r1 = t.order(stock, ask - 10, 1000, 'sell', 'limit')

if bidSize > 10 * askSize and bidSize > 5000:
    r1 = t.order(stock, bid + 10, 1000, 'buy', 'limit')

json.dump(r1)
time.sleep(0.5)
Example #17
0
    'vol_th': 10,
    'rate_growth': 0.01,
    'vol_growth': 0.05
}]

params_out = [{
    'period_sma': 14,
    'period_ema': 9,
    'tick_time': 5,
    'period_time': 60,
    'take_profit': None,
    'stop_loss': None
}]

if __name__ == '__main__':
    trader = Trader(API_KEY, API_SECRET, SLACK_TOKEN)
    in_analyzers = [
        InAnalyzer(trader, params=params_in[i]) for i in range(len(params_in))
    ]
    out_analyzers = [
        OutAnalyzer(trader, params=params_out[i])
        for i in range(len(params_out))
    ]
    trader.hire(in_analyzers, out_analyzers)

    follow_dict = csv_to_dict(FOLLOWED_USERS_FILE)
    listener = Listener(follow_dict, trader)
    auth = OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

    try:
Example #18
0
from Trader import Trader
from Types import Price
from Types import PreOrder
from Constants import env
from Constants import trd
from Stategy.DefaultScalp import get_trade
from _rabbit import _rabbit
from _redis import _redis
from _time import _time

module_name = "TradeMaker"
rabbit = _rabbit()
redis = _redis()

# trader = Trader(*Trader.get_dependencies())
trader = Trader(*Trader.get_dependencies_bt())
price_list = []


def callback(ch, method, properties, body):
    # start timer.
    t0 = _time.time()

    # trading configurables.
    position_size, take_profit_pips, stop_loss_pips, time_in_force = 50, 0.0001, 0.0005, "GTC"

    price = Price.from_json(body)
    print(module_name, price.time, price.instrument, price.ask, price.bid)
    price_list.append(price.to_simple_dict())
    price_list_len = len(price_list)
Example #19
0
 def create_trader(self, dict_arguments):
     self.__trader = Trader(dict_arguments)
     self.__trader_id = self.__trader.get_trader_id()
Example #20
0
        if i < len(timestamp) - 1:

            list_gain = []
            list_mean = []

            for iteration in range(0, iterations_per_day):

                dif = (int(timestamp[i + 1]) -
                       int(timestamp[i])) / (iterations_per_day)

                start = str(int(timestamp[i]) + (dif * iteration))
                end = str(int(timestamp[i]) + (dif * (iteration + 1)))

                marketExchange = Poloniex(currencyPair, start, end, period)

                trader = Trader(indicators, marketExchange, BotConfig())
                trader.startTrading(btc, currencyPair, objective_gain,
                                    limit_loss, gain, loss)

                if BotConfig.print_chart:
                    trader.printChart(trader.df)

                if BotConfig.printPlot:
                    for indicator in indicators:
                        indicator.plot(trader.df, plt)

                if i == 0:
                    first_open = trader.df.iloc[0]["open"]
                last_close = trader.df.iloc[len(trader.df) - 1]["close"]

                open_quote = trader.df['open'][0]
Example #21
0
class Manager:

	"""

	売買のタイミングを管理するクラス
	"""
	
	def __init__(self, param: list, instrument: str, environment: str='demo', mode: str='test'):
		"""

		トレードの対象となる通貨ペアと時間足(種類と本数)を定義

		Parameter
		---------
		param : list
			取り扱う時間足のリスト
		instrument : str
			取り扱う通貨ペア
		environment : str
			トレード環境(本番or仮想)を指定
		mode : str
			デバッグ用の出力を行うかどうかを指定

		Self
		----
		param : list
			取り扱う時間足のリスト
		instrument : str
			取り扱う通貨ペア
		environment : str
			トレード環境(本番or仮想)を指定
		trader : Trader (User defined)
		evaluator : Evaluator (User defined)
		checking_freq : int (const)
			画面出力の頻度を決定するための定数
		count : int
			画面出力のための内部カウンタ
		

		"""

		self.instrument = instrument
		self.environment = environment
		self.param = param
		self.trader = Trader(instrument, environment, mode)
		#self.predictors = {k: Predictor(k) for k in param.timelist}
		#self.fetters = {k: Fetter(k) for k in param.timelist}
		self.evaluator = Evaluator(self.param.timelist, instrument, environment)

		self.checking_freq = 10
		self.count = 0

	def __del__(self):
		self.trader.clean()

	def has_price(self, msg):
		if msg:
			msg = from_byte_to_dict(msg)
			if msg["type"] == "PRICE":
				return True
			else:
				return False
		else:
			return False

	def has_heartbeat(self, msg):
		if msg:
			msg = from_byte_to_dict(msg)
			if msg["type"] == "HEARTBEAT":
				return True
			else:
				return False
		else:
			return False

	def driver(self, candlesticks):

		"""

		ローソク足データの収集、解析、取引を取り扱う

		Parameters
		----------
		candlesticks: dict
			ローソク足データを任意の時間足分格納したdict
		environment: str
			取引を行う環境。バーチャル口座(demo)orリアル口座(live)
		instrument: str
			取引を行う通貨	

		"""

		#現在保有しているポジションをすべて決済
		self.trader.clean()
		print('<Manager> Close all positions')

		while True:
			#指定した通貨のtickをストリーミングで取得する
			pricing_handler = Pricing(self.environment)
			resp = pricing_handler.connect_to_stream(self.instrument)
			try:
				resp.raise_for_status()
			except ConnectionError as e:
				print(f'connect_to_stream : Catch {e}')
				print(f'connect_to_stream : Retry to Connect')
				time.sleep(1)
				continue

			try:
				self.run(resp, candlesticks)
			except requests.exceptions.ChunkedEncodingError as e:
				print(f'run : Catch {e}')
				print(f'run : Retry to Connect')
				time.sleep(1)
				continue

	def run(self, resp, candlesticks):

		"""

		戦略を元に売買を実行する

		Parameter
		---------
		resp : requests.response
			ストリーミングでの接続を行うためのレスポンスデータ
		candlesticks : dict
			取り扱うローソク足の種類と本数を格納した辞書型

		Exception
		---------
		ValueError
		urllib3.exceptions.ProtocolError
		requests.exceptions.Chunked EncodingError

		"""

		for line in resp.iter_lines(1):
			if self.has_price(line):
				recv = from_byte_to_dict(line)
				self.execute_strategy(recv, candlesticks)

			#一定時間ごとに注文or決済が反映されたかを確認する
			if self.checking_freq == self.count:
				print(f'heart beat(span): {self.count}')
				#注文が反映されたか
				if self.trader.test_is_reflected_order() is True:
					#WAIT_ORDER -> POSITION
					self.trader.switch_state()

				#決済が反映されたか
				if self.trader.test_is_reflected_position() is True:
					#WAIT_POSITION -> ORDER
					self.trader.switch_state()
			self.count = 0 if self.checking_freq == self.count else (self.count + 1)

	def execute_strategy(self, recv: dict, candlesticks: dict):
		
		"""
		売買の戦略を決定し、売買タイミングを決定する

		Parameter
		---------
		recv : dict
			為替のtickデータが格納された辞書型のデータ
		candlesticks : dict
			1つ、またはそれ以上のローソク足の組

		"""

		for k, v in candlesticks.items():
			if v.can_update(recv) is True:
				v.update_ohlc_()
				print(f'{k} is updated -> total length : {len(v.ohlc)}')

				if k == self.param.entry_freq:

					try:
						#エントリー
						(is_order_created, kind) = self.entry(candlesticks)
						if is_order_created is True:
							self.evaluator.set_order(kind, True)

					except (RuntimeError, ValueError) as e:
						print(f'{e}')

					#決済(クローズ)
					self.settle(candlesticks)

				#時間足が更新されたときにも注文が反映されたかを確認する
				#注文が反映されたか
				if self.trader.test_is_reflected_order() is True:
					#WAIT_ORDER -> POSITION
					self.trader.switch_state()

				#決済が反映されたか
				if self.trader.test_is_reflected_position() is True:
					#WAIT_POSITION -> ORDER
					self.trader.switch_state()
			v.append_tickdata(recv)

	def entry(self, candlesticks: dict) -> 'bool, str':

		"""

		エントリー状態に遷移させる
		is_rise_with_xxx(任意のアルゴリズム)によって戦略を決定
		現状、「買い」(今後上昇するかのみ)のための設計
		
		Parameter
		---------
		candlesticks : dict
			1つ、またはそれ以上のローソク足の組

		Exception
		---------
		各is_rise_with_xxxが投げる例外を参照、基本的にValueErrorを推奨

		Return
		------
		is_order_created : bool
			注文が生成されたかどうか
		kind : str
			注文内容'BUY' or 'SELL'

		"""

		# ORDER状態じゃない場合の例外 here
		if self.trader.state != 'ORDER':
			raise ValueError('#entry -> Exception : trader.state is not "ORDER"')
		# インターフェイスもORDER or not -> order is created & kindへ変更

		#if self.trader.state != 'ORDER':
		#	return False

		is_rises = []
		error_flag = False
		#error_count = 0

		"""

		Template(now)
		-------------
		try:
			is_rises.append(is_rise_with_xxx(arg1, arg2, ...))
		except ValueError as e:
			print(f'{e}')
			error_count += 1

		try:
			is_rises.append(is_rise_with_yyy(arg1, arg2, ...))
		except ValueError as e:
			print(f'{e}')
			error_count += 1

		if error_count > 0:
			print(f'Error count : {error_count}')
			raise RuntimeError('entry : error count is not 0')

			|
			v

		 Template(in future)
		 -------------------

		 try:
			is_rises.append(is_rise_with_xxx(arg1, arg2, ...))
			is_rises.append(is_rise_with_yyy(arg1, arg2, ...))
		 except ValueError as e:
			print(f'{e}')
			error_flag = True

		if error_flag is True:
			raise RuntimeError('entry : message')

		"""

		try:
			is_rises.append(is_rise_with_xxx(self.param.target, candlesticks))
			is_rises.append(is_rise_with_yyy(self.param.target, candlesticks))
		except ValueError as e:
			print(f'{e}')
			error_flag = True

		if error_flag is True:
			raise RuntimeError('entry : One or more entry algorythm(is_rise_with_xxx) throw exception')

#			if error_count > 0:
#				print(f'Error count : {error_count}')
#				raise RuntimeError('entry : error count is not 0')

		if (all(is_rises) is True or any(is_rises) is False) is False:
			raise ValueError('entry : is_rises is not [All True] or [All False]')

		is_rise = all(is_rises)

		#売買両方取り扱う場合(現時点ではオフ)
		#kind = 'BUY' if True is is_rise else 'SELL'

		#買いの場合のみ取り扱う
		kind = 'BUY' if True is is_rise else None
		is_order_created = self.trader.test_create_order(is_rise)

		if True is is_order_created:
			#self.evaluator.set_order(kind, True)
			#ORDER状態からORDERWAITINGに状態遷移
			self.trader.switch_state()

		return is_order_created, kind

	def settle(self, candlesticks):
		threshold = 8
		if self.trader.state == 'POSITION':
			#ポジションを決済可能か
			if self.trader.can_close_position(threshold) is True:
				#決済の注文を発行する
				is_position_closed = self.trader.test_close_position()

				x = {}
				correct = {}
				for k, v in candlesticks.items():
					x[k] = v.normalize_by('close').values
					#or x[k] = v.normalize_by('close' raw=True)
					correct[k] = np.mean(x[k][-threshold:])

				self.evaluator.set_close(True)

				#LINE notification
				#timeframes = list(candlesticks.keys())
				plothelper = PlotHelper()
				plothelper.begin_plotter()
				plothelper.add_candlestick(candlesticks)
				plothelper.end_plotter('close.png', True)

				self.evaluator.log_score()

				#決済の注文が発行されたか
				if True is is_position_closed:
					#ORDER -> WAIT_ORDER
					self.trader.switch_state()

			else:
				print('Position can not be closed in this update')
			#決済するかを判断するアルゴリズムを更新
			self.trader.update_whether_closing_position(threshold)
Example #22
0
 def __init__(self):
     self.trader = Trader()
     self.action_space = [0, 1]
     self.steps_till_done = 0
     self.steps_todo_done = 20
Example #23
0
 def create_trader(self, dict_arguments):
     self.__trader = Trader(dict_arguments)
     self.__trader_id = self.__trader.get_trader_id()
Example #24
0
from Trader import Trader
from Types import PreOrder
from Constants import trd
from _converter import _converter
from _twilio import _twilio
from asserts import assert_is_not_none, assert_is_none, assert_boolean_true, assert_equal

import pytest
import pandas as pd
import logging

# trader
oar, oac, twilio = Trader.get_dependencies()
trader = Trader(oar, oac, twilio)
logger = logging.getLogger(__name__)


def test_open_trade():
    # trader = Trader()
    # result = trader.open_trade('EURUSD2')
    assert True


def test_calculate_short():
    ask = 1.0010
    bid = 1.0008
    position_size = 500
    take_profit_pips = 0.0007
    stop_loss_pips = 0.0003
    open_price, stop_loss, take_profit, position_size = trader.calculate_short(
        PreOrder(instrument="EUR_USD",
Example #25
0
class CTPManager(QtCore.QObject):
    signal_UI_remove_strategy = QtCore.pyqtSignal(object)  # 定义信号:删除界面策略
    signal_insert_strategy = QtCore.pyqtSignal(object)  # 定义信号:添加界面策略
    signal_hide_QNewStrategy = QtCore.pyqtSignal()  # 定义信号:隐藏创建策略的小弹窗
    signal_UI_update_pushButton_start_strategy = QtCore.pyqtSignal(dict)  # 定义信号:更新界面“开始策略”按钮
    signal_create_QAccountWidget = QtCore.pyqtSignal()  # 定义信号:创建QAccountWidget窗口
    signal_update_pushButton_start_strategy = QtCore.pyqtSignal()  # 定义信号:内核设置交易员交易开关 -> 更新窗口“开始策略”按钮状态
    signal_remove_strategy = QtCore.pyqtSignal(object)  # 定义信号:内核删除策略 -> 窗口删除策略
    signal_label_login_error_text = QtCore.pyqtSignal(str)  # 定义信号:设置登录界面的消息框文本
    signal_show_QMessageBox = QtCore.pyqtSignal(list)  # 定义信号:CTPManager初始化过程中(子线程)需要弹窗 -> ClientMain(主线程)中槽函数调用弹窗
    signal_update_panel_show_account = QtCore.pyqtSignal(dict)  # 定义信号:更新界面账户资金信息

    def __init__(self, parent=None):
        super(CTPManager, self).__init__(parent)  # 显示调用父类初始化方法,使用其信号槽机制
        # self.__DBManager = DBManger()  # 创建数据库连接
        self.__MarketManager = None  # 行情管理实例,MarketManager
        self.__trader = None  # 交易员实例
        self.__list_user = list()  # 存放user对象的list
        # 字典结构 {'063802': {'connect_trade_front': 0, 'QryTrade': 0, 'QryTradingAccount': 0, 'QryOrder': 0, 'QryInvestorPosition': 0, 'login_trade_account': 0}}
        self.__dict_create_user_status = dict()  # 所有user对象创建状态的dict{'user_id':{'connect_trade_front': 0或错误信息},'user_id':{}}
        self.__list_strategy = list()  # 交易策略实例list
        self.__list_instrument_info = list()  # 期货合约信息
        self.__got_list_instrument_info = False  # 获得了期货合约信息
        self.__on_off = 0  # 交易员的交易开关,初始值为关
        self.__only_close = 0  # 交易员的只平,初始值为关
        self.__init_finished = False  # 内核初始化状态,False未完成、True完成
        self.__init_UI_finished = False  # 界面初始化状态,False未完成、True完成
        self.__list_QAccountWidget = list()  # 存放窗口对象的list
        # self.__thread_init = threading.Thread(target=self.start_init)  # 创建初始化内核方法线程
        self.signal_create_QAccountWidget.connect(self.create_QAccountWidget)  # 定义信号:调用本类的槽函数(因信号是在子进程里发出)
        self.__list_user_info = list()  # 从服务端收到的user信息list初始值
        self.__list_user_will_create = list()  # 将要创建成功的期货账户信息列表
        self.__list_strategy_info = list()  # 从服务端收到的策略信息list初始值
        self.__list_strategy_will_create = list()  # 创建成功期货账户的策略列表初始值
        self.__dict_total_user_process = Manager().dict()  # 结构实例:{"user_id": [process, Queue_in, Queue_out], }

        """所有期货账户的和"""
        self.__capital = 0  # 动态权益
        self.__pre_balance = 0  # 静态权益
        self.__profit_position = 0  # 持仓盈亏
        self.__profit_close = 0  # 平仓盈亏
        self.__commission = 0  # 手续费
        self.__available = 0  # 可用资金
        self.__current_margin = 0  # 占用保证金
        self.__risk = 0  # 风险度
        self.__deposit = 0  # 今日入金
        self.__withdraw = 0  # 今日出金
        self.__dict_panel_show_account = dict()  # 总账户资金信息dict

    @QtCore.pyqtSlot()
    def init(self):
        self.__thread_init.start()

    # 初始化(独立线程)
    def start_init(self):
        thread = threading.current_thread()
        print("CTPManager.start_init() thread.getName()=", thread.getName())
        
        """创建行情实例"""
        self.signal_label_login_error_text.emit("登录行情")
        if len(self.__socket_manager.get_list_market_info()) > 0:
            result_create_md = self.create_md(self.__socket_manager.get_list_market_info()[0])
            if result_create_md is False:
                # QMessageBox().showMessage("警告", "创建行情失败")
                self.signal_show_QMessageBox.emit(["警告", "创建行情失败"])
                return  # 结束程序:创建行情失败
        else:
            # QMessageBox().showMessage("警告", "没有行情地址")
            self.signal_show_QMessageBox.emit(["警告", "没有行情地址"])

        """创建期货账户"""
        # 如果期货账户数量为0,向界面弹窗
        users = len(self.__socket_manager.get_list_user_info())  # 将要创建期货账户数量
        if users == 0:
            self.signal_show_QMessageBox.emit(["警告", "将要创建期货账户数量为0"])
            return  # 退出程序
        for i in self.__socket_manager.get_list_user_info():
            self.signal_label_login_error_text.emit("创建期货账户"+i['userid'])
            # self.create_user(i)  # 创建期货账户
            self.__dict_total_user_process[i['userid']] = list()
            print(">>> self.__dict_total_user_process =", self.__dict_total_user_process, type(self.__dict_total_user_process))
            # self.__dict_total_user_process[i['userid']][0] = Queue()  # user进程get操作的Queue结构
            # self.__dict_total_user_process[i['userid']].append(Queue())  # user进程get操作的Queue结构
            # self.__dict_total_user_process[i['userid']].append(Queue())  # user进程put操作的Queue结构
            # p = Process(target=self.create_user, args=(i, self.__dict_total_user_process,))  # 创建user独立进程
            print(">>> self.i =", i)
            p = Process(target=global_create_user, args=(i,))  #  self.__dict_total_user_process,))  # 创建user独立进程
            # p = Process(target=pro_f, args=(i,))  #  self.__dict_total_user_process,))  # 创建user独立进程
            # self.__dict_total_user_process[i['userid']].append(p)  # user独立进程
            p.start()  # 开始进程
            # p.join()

        """创建策略"""
        self.signal_label_login_error_text.emit("创建策略")
        self.__list_strategy_info = self.__socket_manager.get_list_strategy_info()  # 获取所有策略信息列表
        if len(self.__list_strategy_info) > 0:
            # 过滤出创建成功的期货账户的策略
            for i_strategy in self.__list_strategy_info:
                for i_user in self.__list_user:
                    if i_strategy['user_id'] == i_user.get_user_id().decode():
                        self.__list_strategy_will_create.append(i_strategy)
                        break
        if len(self.__list_strategy_will_create) > 0:
            for i in self.__list_strategy_will_create:
                self.create_strategy(i)  # 创建策略
                self.signal_label_login_error_text.emit("创建策略"+i['user_id']+' '+i['strategy_id'])

        """登录期货账户,调用TD API方法"""
        for i_user in self.__list_user:
            self.signal_label_login_error_text.emit("登录期货账户" + i_user.get_user_id().decode())
            i_user.login_trade_account()  # 登录期货账户,期货账户登录成功一刻开始OnRtnOrder、OnRtnTrade就开始返回历史数据
            i_user.qry_trading_account()  # 查询资金账户
            i_user.qry_investor_position()  # 查询投资者持仓
            i_user.qry_inverstor_position_detail()  # 查询投资者持仓明细
            i_user.qry_instrument_info()  # 查询合约信息

        """检查期货账户调用API方法的状态"""
        # 有任何一个方法调用失败,则认为初始化期货账户失败
        create_user_failed_count = 0  # 创建期货账户失败数量
        self.__dict_create_user_failed = {}  # 保存创建失败的期货账户信息
        # 遍历期货账户登录状态dict,将登录失败的user信息存放到self.__dict_create_user_failed
        self.__dict_create_user_status = {
            '078681': {'QryInvestorPosition': 0, 'QryInvestorPositionDetail': 0, 'connect_trade_front': 0,
                    'QryTradingAccount': 0, 'login_trade_account': 0},
            '083778': {'QryInvestorPosition': 0, 'QryInvestorPositionDetail': 0, 'connect_trade_front': 0,
                       'QryTradingAccount': 0, 'login_trade_account': 0}
            }
        # print(">>> self.__dict_create_user_status =", len(self.__dict_create_user_status), self.__dict_create_user_status)
        for i in self.__dict_create_user_status:
            # 样本数据{'078681': {'connect_trade_front': 0, 'QryInvestorPosition': 0, 'QryInvestorPositionDetail': 0, 'QryTradingAccount': -4, 'login_trade_account': 0}}
            # i为键名'078681',str类型
            for j in self.__dict_create_user_status[i]:
                if self.__dict_create_user_status[i][j] != 0:
                    users -= 1  # 成功创建期货账户数量减一
                    create_user_failed_count += 1  # 创建期货账户失败数量加一
                    self.__dict_create_user_failed[i] = self.__dict_create_user_status[i]
                    break

        """删除创建失败的期货账户对象"""
        # 存在创建失败的期货账户,则从期货账户对象列表里删除对象
        if len(self.__dict_create_user_failed) > 0:
            for i_user_id in self.__dict_create_user_failed:  # i为键名,内容为期货账号
                for obj_user in self.__list_user:
                    if i_user_id == obj_user.get_user_id().decode():  # 创建失败的user_id等于 对象的user_id
                        self.__list_user.remove(obj_user)  # 从对象列表中删除对象
                        break

        """删除创建失败的期货账户对象所属的策略对象"""
        # 从CTPManager类中self.__list_strategy中删除strategy对象即可,user类已经被删除,所以不用删除user类中的strategy
        # print(">>> self.__dict_create_user_failed =", len(self.__dict_create_user_failed), self.__dict_create_user_failed)
        # 遍历创建失败的期货账户信息dict
        for i_user_id in self.__dict_create_user_failed:
            # 遍历ctp_manager中的策略对象列表
            shift = 0
            for i_strategy in range(len(self.__list_strategy)):
                if self.__list_strategy[i_strategy-shift].get_user_id() == i_user_id:
                    self.__list_strategy.remove(self.__list_strategy[i_strategy-shift])
                    shift += 1  # 游标调整值

        """user装载从xml获取的数据"""
        for obj_user in self.__list_user:
            obj_user.load_xml()  # 将xml读取的数据赋值给user对象和strategy对象

        """继续完成strategy对象初始化工作"""
        for obj_strategy in self.__list_strategy:
            obj_strategy.get_td_api_arguments()  # 将期货账户api查询参数赋值给strategy对象
            obj_strategy.load_xml()  # strategy装载xml
            obj_strategy.start_run_count()  # 开始核心统计运算线程
            # 遍历strategy初始化完成之前的order和trade回调记录,完成strategy初始化工作,遍历queue_strategy_order\queue_strategy_trade

        """向界面输出创建失败的期货账户信息"""
        if len(self.__dict_create_user_failed) > 0:
            str_head = "以下期货账户创建失败\n"  # 消息第一行,头
            str_main = ""  # 消息内容,每个期货账户做一行显示
            for i in self.__dict_create_user_failed:  # i为期货账号,str
                for j in self.__dict_create_user_failed[i]:  # j为登录信息dict的键名,即函数方法名称,str
                    if self.__dict_create_user_failed[i][j] != 0:
                        str_main = str_main + i + ":" + j + "原因" + str(self.__dict_create_user_failed[i][j]) + "\n"
            str_out = str_head + str_main
            self.signal_show_QMessageBox.emit(["警告", str_out])
            # 创建成功的期货账户数量为0,向界面弹窗,程序终止
            if len(self.__list_user) == 0:
                # self.signal_show_QMessageBox.emit(["警告", "成功创建期货账户的数量为0"])
                return  # 结束程序:没有创建成功的策略,
            
        self.signal_create_QAccountWidget.emit()  # 创建窗口界面

    # 创建MD
    def create_md(self, dict_arguments):
        # dict_arguments = {'front_address': 'tcp://180.168.146.187:10010', 'broker_id': '9999'}
        # 创建行情管理实例MarketManager
        self.__MarketManager = MarketManager(dict_arguments['frontaddress'],
                                             dict_arguments['brokerid'],
                                             dict_arguments['userid'],
                                             dict_arguments['password']
                                             )
        self.__MarketManager.get_market().set_strategy(self.__list_strategy)  # 将策略列表设置为Market_API类的属性
        if self.__MarketManager.get_result_market_connect() == 0 and self.__MarketManager.get_result_market_login() == 0:
            self.__TradingDay = self.__MarketManager.get_TradingDay()
            print("CTPManager.create_md() 创建行情成功,交易日:", self.__TradingDay)  # 行情API中获取到的交易日
            return True
        else:
            print("CTPManager.create_md() 创建行情失败")
            return False

    # 创建trader
    def create_trader(self, dict_arguments):
        self.__trader = Trader(dict_arguments)
        self.__trader_id = self.__trader.get_trader_id()

    # 创建user(期货账户)
    def create_user(self, dict_arguments):
        # 不允许重复创建期货账户实例
        # if len(self.__list_user) > 0:
        #     for i in self.__list_user:
        #         if i.get_user_id() == dict_arguments['userid']:
        #             print("MultiUserTraderSys.create_user()已经存在user_id为", dict_arguments['userid'], "的实例,不允许重复创建")
        #             return

        obj_user = User(dict_arguments, ctp_manager=self)

        while True:
            pass
            print("CTPManager.create_user() user_id =", dict_arguments['userid'], ", process_id =", os.getpid())
            time.sleep(2.0)

        # 将创建成功的期货账户对象存放到self.__list_user
        # for i in self.__dict_create_user_status:
        #     if i == obj_user.get_user_id().decode():
        #         if self.__dict_create_user_status[i]['connect_trade_front'] == 0:  # 连接交易前置成功
        #                 # and self.__dict_create_user_status[i]['login_trade_account'] == 0 \
        #                 # and self.__dict_create_user_status[i]['QryTradingAccount'] == 0 \
        #                 # and self.__dict_create_user_status[i]['QryInvestorPosition'] == 0:
        #             obj_user.set_CTPManager(self)  # 将CTPManager类设置为user的属性
        #             self.__list_user.append(obj_user)  # user类实例添加到列表存放
        #             # obj_user.qry_api_interval_manager()  # API查询时间间隔管理
        #             # obj_user.qry_instrument_info()  # 查询合约信息
        #             print("CTPManager.create_user() 创建期货账户成功,user_id=", dict_arguments['userid'])
        #         else:
        #             print("CTPManager.create_user() 创建期货账户失败,user_id=", dict_arguments['userid'])


        # if self.__dict_create_user_status[dict_arguments['userid']] == 1:  # 判断是否成功创建期货账户
        #     # obj_user.set_DBManager(self.__DBManager)  # 将数据库管理类设置为user的属性
        #     obj_user.set_CTPManager(self)  # 将CTPManager类设置为user的属性
        #     obj_user.qry_instrument_info()  # 查询合约信息
        #     self.__list_user.append(obj_user)  # user类实例添加到列表存放
        #     print("CTPManager.create_user() 创建期货账户成功,user_id=", dict_arguments['userid'])
        # elif self.__dict_create_user_status[dict_arguments['userid']] == 0:
        #     print("CTPManager.create_user() 创建期货账户失败,user_id=", dict_arguments['userid'])

    # 将strategy对象添加到user里
    def add_strategy_to_user(self, obj_strategy):
        for i in self.__list_user:
            if i.get_user_id() == obj_strategy.get_user_id():
                i.add_strategy()

    # 创建strategy
    def create_strategy(self, dict_arguments):
        # 不允许重复创建策略实例
        if len(self.__list_strategy) > 0:
            for i in self.__list_strategy:
                if i.get_strategy_id() == dict_arguments['strategy_id'] and i.get_user_id() == dict_arguments['user_id']:
                    print("CTPManager.create_strategy() 不能重复创建,已经存在user_id=", dict_arguments['user_id'], "strategy_id=", dict_arguments['strategy_id'])
                    return False

        # 遍历user对象列表,找到将要创建策略所属的user对象
        for i_user in self.__list_user:
            if i_user.get_user_id().decode() == dict_arguments['user_id']:  # 找到策略所属的user实例
                # 创建策略
                obj_strategy = Strategy(dict_arguments, i_user)  # 创建策略实例,user实例和数据库连接实例设置为strategy的属性
                # obj_strategy.set_DBManager(self.__DBManager)
                i_user.add_strategy(obj_strategy)               # 将策略实例添加到user的策略列表
                self.__list_strategy.append(obj_strategy)  # 将策略实例添加到CTP_Manager的策略列表
                print("CTPManager.create_strategy() 创建策略,user_id=", dict_arguments['user_id'], "strategy_id=", dict_arguments['strategy_id'])
                # 为策略订阅行情
                list_instrument_id = list()
                for i in dict_arguments['list_instrument_id']:
                    list_instrument_id.append(i.encode())  # 将合约代码转码为二进制字符串
                self.__MarketManager.sub_market(list_instrument_id, dict_arguments['user_id'], dict_arguments['strategy_id'])

        # 判断内核是否初始化完成(所有策略是否初始化完成)
        if self.__init_finished:  # 内核初始化完成、程序运行中新添加策略,在界面策略列表框内添加一行
            print("CTPManager.create_strategy() 程序运行中添加策略,user_id =", dict_arguments['user_id'], 'strategy_id =', dict_arguments['strategy_id'])
            self.signal_insert_strategy.emit(obj_strategy)  # 内核向界面插入策略
            self.signal_hide_QNewStrategy.emit()  # 隐藏创建策略的小弹窗
        else:  # 内核初始化未完成
            # 最后一个策略初始化完成,将内核初始化完成标志设置为True
            # if self.__list_strategy_info[-1]['user_id'] == dict_arguments['user_id'] and \
            #                 self.__list_strategy_info[-1]['strategy_id'] == dict_arguments['strategy_id']:
            #     self.__init_finished = True  # CTPManager初始化完成
            pass

    # 删除strategy
    def delete_strategy(self, dict_arguments):
        print("CTPManager.delete_strategy() 删除策略对象", dict_arguments)

        # 将obj_strategy从CTPManager的self.__list_strategy中删除
        for i_strategy in self.__list_strategy:
            if i_strategy.get_user_id() == dict_arguments['user_id'] and i_strategy.get_strategy_id() == dict_arguments['strategy_id']:
                # 退订该策略的行情
                self.__MarketManager.un_sub_market(i_strategy.get_list_instrument_id(),
                                                   dict_arguments['user_id'],
                                                   dict_arguments['strategy_id'])
                self.__list_strategy.remove(i_strategy)
                break

        # 将obj_strategy从user中的list_strategy中删除
        for i_user in self.__list_user:
            if i_user.get_user_id().decode() == dict_arguments['user_id']:
                for i_strategy in i_user.get_list_strategy():
                    if i_strategy.get_strategy_id() == dict_arguments['strategy_id']:
                        i_user.get_list_strategy().remove(i_strategy)
                        self.signal_remove_strategy.emit(i_strategy)  # 发送信号,从界面中删除策略
                        break
                break
        for i_strategy in self.__list_strategy:
            print("user_id=", i_strategy.get_user_id(), "strategy_id=", i_strategy.get_strategy_id())

        # 内核删除策略成功,通知界面删除策略
        # self.signal_remove_row_table_widget.emit()  # 在界面策略列表中删除策略

    # 修改策略,(SocketManager收到服务端修改策略参数类回报 -> CTPManager修改策略)
    @QtCore.pyqtSlot(dict)
    def slot_update_strategy(self, dict_arguments):
        # 对收到的消息做筛选,教给对应的策略
        pass

    # 初始化账户窗口
    def create_QAccountWidget(self):
        """
        # QApplication.processEvents()
        print("CTPManager.create_QAccountWidget() 创建“新建策略”窗口,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

        # 创建“新建策略”窗口
        self.create_QNewStrategy()

        print("CTPManager.create_QAccountWidget() 开始创建总账户窗口,",
              time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 创建总账户窗口
        if True:
            QAccountWidget_total = QAccountWidget(str_widget_name='总账户', 
                                                  list_user=self.get_list_user(),
                                                  ClientMain=self.__client_main,
                                                  CTPManager=self,
                                                  SocketManager=self.__socket_manager)
            # 总账户窗口设置为所有user的属性
            for i_user in self.get_list_user():
                # QApplication.processEvents()
                i_user.set_QAccountWidget_total(QAccountWidget_total)
            # 总账户窗口设置为所有strategy的属性
            for i_strategy in self.get_list_strategy():
                # QApplication.processEvents()
                i_strategy.set_QAccountWidget_total(QAccountWidget_total)
                # 信号槽连接:策略对象修改策略 -> 窗口对象更新策略显示(Strategy.signal_update_strategy -> QAccountWidget.slot_update_strategy() )
                i_strategy.signal_update_strategy.connect(QAccountWidget_total.slot_update_strategy)
                # 信号槽连接:策略对象价差值变化 -> 窗口对象更新价差(Strategy.signal_UI_update_spread_total -> QAccountWidget.slot_update_spread())
                # i_strategy.signal_UI_update_spread_total.connect(QAccountWidget_total.slot_update_spread)
            # 所有策略列表设置为窗口属性
            QAccountWidget_total.set_list_strategy(self.__list_strategy)
            self.__list_QAccountWidget.append(QAccountWidget_total)  # 将窗口对象存放到list集合里
            # self.signal_pushButton_set_position_setEnabled.connect(QAccountWidget_total.on_pushButton_set_position_active)
            # QAccountWidget_total.set_signal_pushButton_set_position_setEnabled_connected(True)  # 信号槽绑定标志设置为True

            # 绑定信号槽:设置交易员交易开关 -> 更新总账户窗口“开始策略”按钮状态
            self.signal_update_pushButton_start_strategy.connect(QAccountWidget_total.slot_update_pushButton_start_strategy)
            # 绑定信号槽:更新总期货账户资金信息 -> 界面更新总账户资金信息
            self.signal_update_panel_show_account.connect(QAccountWidget_total.slot_update_panel_show_account)
        print("CTPManager.create_QAccountWidget() 创建单账户窗口,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 创建单账户窗口
        for i_user in self.get_list_user():
            # # QApplication.processEvents()
            QAccountWidget_single = QAccountWidget(str_widget_name=i_user.get_user_id().decode(),
                                                   obj_user=i_user,
                                                   ClientMain=self.__client_main,
                                                   CTPManager=self,
                                                   SocketManager=self.__socket_manager)
            # 单账户窗口设置为对应的user的属性
            i_user.set_QAccountWidget_signal(QAccountWidget_single)

            # 单账户窗口设置为对应期货账户的所有策略的属性
            for i_strategy in i_user.get_list_strategy():
                # QApplication.processEvents()
                i_strategy.set_QAccountWidget_signal(QAccountWidget_single)
                # 信号槽连接:策略对象修改策略 -> 窗口对象更新策略显示(Strategy.signal_update_strategy -> QAccountWidget.slot_update_strategy() )
                i_strategy.signal_update_strategy.connect(QAccountWidget_single.slot_update_strategy)
                # 信号槽连接:策略对象价差值变化 -> 窗口对象更新价差(Strategy.signal_UI_update_spread_signal -> QAccountWidget.slot_update_spread())
                # i_strategy.signal_UI_update_spread_signal.connect(QAccountWidget_single.slot_update_spread)
            # 单期货账户的所有策略列表设置为窗口属性
            QAccountWidget_single.set_list_strategy(i_user.get_list_strategy())
            self.__list_QAccountWidget.append(QAccountWidget_single)  # 将窗口对象存放到list集合里
            # self.signal_pushButton_set_position_setEnabled.connect(QAccountWidget_single.on_pushButton_set_position_active)
            # QAccountWidget_single.set_signal_pushButton_set_position_setEnabled_connected(True)  # 信号槽绑定标志设置为True

            # 绑定信号槽:设置期货账户交易开关 -> 更新单期货账户窗口“开始策略”按钮状态
            i_user.signal_update_pushButton_start_strategy.connect(QAccountWidget_single.slot_update_pushButton_start_strategy)
            # 绑定信号槽:更新期货账户资金信息 -> 界面更新账户资金信息
            i_user.signal_update_panel_show_account.connect(QAccountWidget_single.slot_update_panel_show_account)
            i_user.init_panel_show_account()  # 窗口显示账户初始化资金信息

        self.__client_main.set_list_QAccountWidget(self.__list_QAccountWidget)  # 窗口对象列表设置为ClientMain的属性

        print("CTPManager.create_QAccountWidget() 窗口添加到tab_accounts,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 窗口添加到tab_accounts
        for i_widget in self.__list_QAccountWidget:
            # QApplication.processEvents()
            self.__q_ctp.tab_accounts.addTab(i_widget, i_widget.get_widget_name())  # 将账户窗口添加到tab_accounts窗体里
            # 信号槽连接
            # 下面注释代码位置转移到QAccountWidget.slot_insert_strategy()里,向窗口插入策略的时候动态绑定策略与窗口之间的信号槽关系
            # 信号槽:CTPManager创建策略 -> QAccountWidget插入策略(CTPManager.signal_insert_strategy -> QAccountWidget.slot_insert_strategy())
            self.signal_insert_strategy.connect(i_widget.slot_insert_strategy)
            # 窗口修改策略 -> SocketManager发送修改指令(QAccountWidget.signal_send_msg -> SocketManager.slot_send_msg() )
            i_widget.signal_send_msg.connect(self.__socket_manager.slot_send_msg)
            # 绑定信号槽:收到服务端的查询策略信息 -> groupBox界面状态还原(激活查询按钮、恢复“设置持仓”按钮)
            self.__socket_manager.signal_restore_groupBox.connect(i_widget.slot_restore_groupBox_pushButton)
            # 绑定信号槽:内核删除策略 -> 界面删除策略
            self.signal_remove_strategy.connect(i_widget.slot_remove_strategy)
            # 绑定信号槽:QAccountWidget需要弹窗 -> 调用ClientMain中的槽函数slot_show_QMessageBox
            i_widget.signal_show_QMessageBox.connect(self.__client_main.slot_show_QMessageBox)

        print("CTPManager.create_QAccountWidget() 向界面插入策略,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 向界面插入策略
        for i_strategy in self.get_list_strategy():
            # QApplication.processEvents()
            self.signal_insert_strategy.emit(i_strategy)  # 向界面插入策略

        # 初始化开始策略按钮状态
        self.signal_update_pushButton_start_strategy.emit()  # 向总账户窗口发送信号
        for i_user in self.__list_user:
            i_user.signal_update_pushButton_start_strategy.emit()  # 向单账户窗口发送信号

        self.__init_UI_finished = True  # 界面初始化完成标志位
        self.__client_main.set_init_UI_finished(True)  # 界面初始化完成标志位设置为ClientMain的属性

        self.__q_ctp.show()  # 显示主窗口
        self.__q_login_form.hide()  # 隐藏登录窗口
        print("ClientMain.create_QAccountWidget() 界面初始化完成", time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
        """
        # 创建“新建策略”窗口
        self.create_QNewStrategy()
        # 全局创建一个QAccountWidget实例,分别添加到不同table中

        # self.__q_ctp.tab_accounts.addTab(self.__q_account_widget, "总账户")  # 添加"总账户"tab
        # self.__q_ctp.tab_accounts.addTab(self.__q_account_widget2, "总账户2")  # 添加"总账户"tab
        # self.tabBar.addTab("所有账户")
        # self.__q_ctp.tab_accounts.currentChanged.connect(self.__q_account_widget.tab_changed)  # 连接信号槽
        # self.__q_ctp.signal_on_tab_accounts_currentChanged.connect(self.__q_account_widget.slot_tab_changed)  # 连接信号槽
        print(">>> CTPManager.create_QAccountWidget() len(self.__list_user) =", len(self.__list_user))
        for obj_user in self.__list_user:
            print(">>> CTPManager.create_QAccountWidget() obj_user.get_user_id().decode() =", obj_user.get_user_id().decode())
            self.__q_ctp.widget_QAccountWidget.tabBar.addTab(obj_user.get_user_id().decode())  # 添加单账户tab

        # 创建StrategyDataModel
        self.StrategyDataModel = StrategyDataModel(mylist=self.get_list_strategy_view())
        self.__q_ctp.widget_QAccountWidget.tableView_Trade_Args.setModel(self.StrategyDataModel)

        self.__init_UI_finished = True  # 界面初始化完成标志位
        self.__client_main.set_init_UI_finished(True)  # 界面初始化完成标志位设置为ClientMain的属性
        self.__q_ctp.show()  # 显示主窗口
        self.__q_login_form.hide()  # 隐藏登录窗口
        print("ClientMain.create_QAccountWidget() 界面初始化完成",
              time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

    # 创建“新建策略窗口”
    def create_QNewStrategy(self):
        self.__q_new_strategy = QNewStrategy()
        completer = QCompleter()
        if self.get_got_list_instrument_info():
            model = QStringListModel()
            model.setStringList(self.get_list_instrument_id())
            completer.setModel(model)
        else:
            print(">>> CTPManager.create_QNewStrategy() 查询合约信息失败")
        self.__q_new_strategy.lineEdit_a_instrument.setCompleter(completer)
        self.__q_new_strategy.lineEdit_b_instrument.setCompleter(completer)
        self.__q_new_strategy.set_ClientMain(self.__client_main)  # CTPManager设置为新建策略窗口属性
        self.__q_new_strategy.set_CTPManager(self)  # CTPManager设置为新建策略窗口属性
        self.__q_new_strategy.set_SocketManager(self.__socket_manager)  # SocketManager设置为新建策略窗口属性
        self.__q_new_strategy.set_trader_id(self.__trader_id)  # 设置trade_id属性
        self.set_QNewStrategy(self.__q_new_strategy)  # 新建策略窗口设置为CTPManager属性
        self.__client_main.set_QNewStrategy(self.__q_new_strategy)  # 新建策略窗口设置为ClientMain属性
        self.signal_hide_QNewStrategy.connect(self.get_QNewStrategy().hide)  # 绑定信号槽,新创建策略成功后隐藏“新建策略弹窗”
        # 绑定信号槽:新建策略窗新建策略指令 -> SocketManager.slot_send_msg
        self.__q_new_strategy.signal_send_msg.connect(self.__socket_manager.slot_send_msg)

    # 创建数据库连接实例
    def create_DBManager(self):
        self.__DBManager = DBManger()

    # 设置View视窗所需的data_list
    # def set_list_strategy_view(self, list_data):
    #     self.__list_strategy_view = list_data

    # 获取View视窗所需的data_list
    # def get_list_strategy_view(self):
    #     self.__list_strategy_view = list()  # 初始化view视窗中的数据
    #     index = -1
    #     for obj_strategy in self.__list_strategy:  # 遍历所有策略对象,将所有策略的list_strategy_view合并到一个list显示到界面view
    #         self.__list_strategy_view.append(obj_strategy.get_list_strategy_view())
    #     print(">>> CTPManager.get_list_strategy_view() self.__list_strategy_view =", self.__list_strategy_view)
    #     return self.__list_strategy_view

    # 获取窗口对象
    def get_QAccountWidget(self):
        return self.__q_account_widget

    # 获取trader_id
    def get_trader_id(self):
        return self.__trader_id

    def get_TradingDay(self):
        return self.__TradingDay

    # 获取数据库连接实例
    def get_mdb(self):
        return self.__DBManager

    # 获取行情实例
    def get_md(self):
        return self.__MarketManager

    # 获取trader对象的list
    def get_trader(self):
        return self.__trader

    # 获取user对象的list
    def get_list_user(self):
        return self.__list_user

    # 获取strategy对象的list
    def get_list_strategy(self):
        return self.__list_strategy

    # 获取user对象创建状态的dict
    def get_dict_create_user_status(self):
        return self.__dict_create_user_status

    # 设置CTPManager内核初始化完成
    def set_init_finished(self, bool_input):
        print(">>> CTPManager.set_init_finished() CTPManager内核初始化完成")
        self.__init_finished = bool_input

    # 获取CTPManager内核初始化状态
    def get_init_finished(self):
        return self.__init_finished

    # 设置界面初始化状态
    def set_init_UI_finished(self, bool_input):
        self.__init_UI_finished = bool_input

    def get_init_UI_finished(self):
        return self.__init_UI_finished

    # 从user对象列表里找到指定user_id的user对象
    def find_user(self, user_id):
        for i in self.__list_user:
            if i.get_user_id() == user_id:
                return i

    def set_ClientMain(self, obj_ClientMain):
        self.__client_main = obj_ClientMain

    def get_ClientMain(self):
        return self.__client_main

    def set_SocketManager(self, obj_SocketManager):
        self.__socket_manager = obj_SocketManager

    def get_SocketManager(self):
        return self.__socket_manager

    def set_QLoginForm(self, obj_QLoginForm):
        self.__q_login_form = obj_QLoginForm

    def get_QLoginForm(self):
        return self.__q_login_form

    def set_QCTP(self, obj_QCTP):
        self.__q_ctp = obj_QCTP

    def get_QCTP(self):
        return self.__q_ctp

    def set_XML_Manager(self, obj_XML_Manager):
        self.__xml_manager = obj_XML_Manager

    def get_XML_Manager(self):
        return self.__xml_manager

    def set_QNewStrategy(self, obj_QNewStrategy):
        self.__q_new_strategy = obj_QNewStrategy

    def get_QNewStrategy(self):
        return self.__q_new_strategy

    def set_list_market_info(self, list_input):
        self.__list_market_info = list_input

    def get_list_market_info(self):
        return self.__list_market_info

    def set_list_user_info(self, list_input):
        self.__list_user_info = list_input

    def get_list_user_info(self):
        return self.__list_user_info

    # 所有策略的昨仓保存到一个list,从服务端查询获得
    def set_YesterdayPosition(self, listYesterdayPosition):
        self.__listYesterdayPosition = listYesterdayPosition

    def get_YesterdayPosition(self):
        return self.__listYesterdayPosition

    # 新增trader_id下面的某个期货账户
    def add_user(self, trader_id, broker_id, front_address, user_id, password):
        print('add_user(): trader_id=', trader_id, 'broker_id=', broker_id, 'user_id=', user_id)
        add_user_arguments = {'trader_id': trader_id,
                              'broker_id': broker_id,
                              'UserID': user_id,
                              'Password': password,
                              'front_address': front_address}
        # 新增期货账户,创建TradeApi实例
        return User(add_user_arguments)

    # 删除trader_id下面的某个期货账户
    # 参数说明: user=class User实例名称
    def del_user(self, user, trader_id, broker_id, front_address, user_id):
        print('del_user(): trader_id=', trader_id, 'broker_id=', broker_id, 'user_id=', user_id)
        del_user_arguments = {'trader_id': trader_id,
                              'broker_id': broker_id,
                              'UserID': user_id,
                              'front_address': front_address}
        # 删除期货账户,释放TradeApi实例
        user.UnConnect()
        # 操作MongoDB,删除Operator下面的user_id(期货账户)

    # 交易员登录验证
    def trader_login(self, trader_id, password):
        return self.__DBManager.check_trader(trader_id, password)

    # 设置交易员id
    def set_trader_id(self, str_TraderID):
        self.__trader_id = str_TraderID

    # 获得交易员id
    def get_trader_id(self):
        return self.__trader_id

    def set_trader_name(self, str_trader_name):
        self.__trader_name = str_trader_name

    def get_trader_name(self):
        return self.__trader_name

    # 设置客户端的交易开关,0关、1开
    def set_on_off(self, int_on_off):
        # print(">>> CTPManager.set_on_off()", int_on_off)
        self.__on_off = int_on_off
        self.signal_update_pushButton_start_strategy.emit()  # 触发信号:内核设置交易员交易开关 -> 更新窗口“开始策略”按钮状态

    # 获取客户端的交易开关,0关、1开
    def get_on_off(self):
        return self.__on_off

    # 设置交易开关,0关、1开
    def set_only_close(self, int_only_close):
        self.__only_close = int_only_close

    # 获取交易开关,0关、1开
    def get_only_close(self):
        return self.__only_close

    # 设置“已经获取到合约信息的状态”
    def set_got_list_instrument_info(self, bool_status):
        self.__got_list_instrument_info = bool_status

    # 获取“已经获取到合约信息的状态”
    def get_got_list_instrument_info(self):
        return self.__got_list_instrument_info

    # 设置合约信息
    def set_instrument_info(self, input_list):
        self.__list_instrument_info = input_list
        self.__list_instrument_id = list()
        for i in self.__list_instrument_info:
            self.__list_instrument_id.append(i['InstrumentID'])

    # 获取合约信息
    def get_instrument_info(self):
        return self.__list_instrument_info

    # 获取期货合约代码列表
    def get_list_instrument_id(self):
        return self.__list_instrument_id

    # 更新账户资金信息,并刷新界面
    def update_panel_show_account(self):
        """
        self.__capital = 0  # 动态权益
        self.__pre_balance = 0  # 静态权益
        self.__profit_position = 0  # 持仓盈亏
        self.__profit_close = 0  # 平仓盈亏
        self.__commission = 0  # 手续费
        self.__available = 0  # 可用资金
        self.__current_margin = 0  # 占用保证金
        self.__risk = 0  # 风险度
        self.__deposit = 0  # 今日入金
        self.__withdraw = 0  # 今日出金
        """
        # 遍历期货账户,累加指标
        for i in self.__list_user:
            user_panel_show_account = i.get_panel_show_account()
            self.__capital += user_panel_show_account['Capital']
            self.__pre_balance += user_panel_show_account['PreBalance']
            self.__profit_position += user_panel_show_account['PositionProfit']
            self.__profit_close += user_panel_show_account['CloseProfit']
            self.__commission += user_panel_show_account['Commission']
            self.__available += user_panel_show_account['Available']
            self.__current_margin += user_panel_show_account['CurrMargin']
            self.__risk += user_panel_show_account['Risk']
            self.__deposit += user_panel_show_account['Deposit']
            self.__withdraw += user_panel_show_account['Withdraw']

        # 更新界面显示
        self.signal_update_panel_show_account.emit(self.__dict_panel_show_account)
Example #26
0
class CTPManager(QtCore.QObject):
    signal_UI_remove_strategy = QtCore.pyqtSignal(object)  # 定义信号:删除界面策略
    signal_insert_strategy = QtCore.pyqtSignal(object)  # 定义信号:添加界面策略
    signal_hide_QNewStrategy = QtCore.pyqtSignal()  # 定义信号:隐藏创建策略的小弹窗
    signal_UI_update_pushButton_start_strategy = QtCore.pyqtSignal(
        dict)  # 定义信号:更新界面“开始策略”按钮
    signal_create_QAccountWidget = QtCore.pyqtSignal(
    )  # 定义信号:创建QAccountWidget窗口
    signal_update_pushButton_start_strategy = QtCore.pyqtSignal(
    )  # 定义信号:内核设置交易员交易开关 -> 更新窗口“开始策略”按钮状态
    signal_remove_strategy = QtCore.pyqtSignal(object)  # 定义信号:内核删除策略 -> 窗口删除策略
    signal_label_login_error_text = QtCore.pyqtSignal(str)  # 定义信号:设置登录界面的消息框文本
    signal_show_QMessageBox = QtCore.pyqtSignal(
        list)  # 定义信号:CTPManager初始化过程中(子线程)需要弹窗 -> ClientMain(主线程)中槽函数调用弹窗
    signal_update_panel_show_account = QtCore.pyqtSignal(
        dict)  # 定义信号:更新界面账户资金信息

    def __init__(self, parent=None):
        super(CTPManager, self).__init__(parent)  # 显示调用父类初始化方法,使用其信号槽机制
        # self.__DBManager = DBManger()  # 创建数据库连接
        self.__MarketManager = None  # 行情管理实例,MarketManager
        self.__trader = None  # 交易员实例
        self.__list_user = list()  # 存放user对象的list
        # 字典结构 {'063802': {'connect_trade_front': 0, 'QryTrade': 0, 'QryTradingAccount': 0, 'QryOrder': 0, 'QryInvestorPosition': 0, 'login_trade_account': 0}}
        self.__dict_create_user_status = dict(
        )  # 所有user对象创建状态的dict{'user_id':{'connect_trade_front': 0或错误信息},'user_id':{}}
        self.__list_strategy = list()  # 交易策略实例list
        self.__list_instrument_info = list()  # 期货合约信息
        self.__got_list_instrument_info = False  # 获得了期货合约信息
        self.__on_off = 0  # 交易员的交易开关,初始值为关
        self.__only_close = 0  # 交易员的只平,初始值为关
        self.__init_finished = False  # 内核初始化状态,False未完成、True完成
        self.__init_UI_finished = False  # 界面初始化状态,False未完成、True完成
        self.__list_QAccountWidget = list()  # 存放窗口对象的list
        # self.__thread_init = threading.Thread(target=self.start_init)  # 创建初始化内核方法线程
        self.signal_create_QAccountWidget.connect(
            self.create_QAccountWidget)  # 定义信号:调用本类的槽函数(因信号是在子进程里发出)
        self.__list_user_info = list()  # 从服务端收到的user信息list初始值
        self.__list_user_will_create = list()  # 将要创建成功的期货账户信息列表
        self.__list_strategy_info = list()  # 从服务端收到的策略信息list初始值
        self.__list_strategy_will_create = list()  # 创建成功期货账户的策略列表初始值
        self.__dict_total_user_process = Manager().dict(
        )  # 结构实例:{"user_id": [process, Queue_in, Queue_out], }
        """所有期货账户的和"""
        self.__capital = 0  # 动态权益
        self.__pre_balance = 0  # 静态权益
        self.__profit_position = 0  # 持仓盈亏
        self.__profit_close = 0  # 平仓盈亏
        self.__commission = 0  # 手续费
        self.__available = 0  # 可用资金
        self.__current_margin = 0  # 占用保证金
        self.__risk = 0  # 风险度
        self.__deposit = 0  # 今日入金
        self.__withdraw = 0  # 今日出金
        self.__dict_panel_show_account = dict()  # 总账户资金信息dict

    @QtCore.pyqtSlot()
    def init(self):
        self.__thread_init.start()

    # 初始化(独立线程)
    def start_init(self):
        thread = threading.current_thread()
        print("CTPManager.start_init() thread.getName()=", thread.getName())
        """创建行情实例"""
        self.signal_label_login_error_text.emit("登录行情")
        if len(self.__socket_manager.get_list_market_info()) > 0:
            result_create_md = self.create_md(
                self.__socket_manager.get_list_market_info()[0])
            if result_create_md is False:
                # QMessageBox().showMessage("警告", "创建行情失败")
                self.signal_show_QMessageBox.emit(["警告", "创建行情失败"])
                return  # 结束程序:创建行情失败
        else:
            # QMessageBox().showMessage("警告", "没有行情地址")
            self.signal_show_QMessageBox.emit(["警告", "没有行情地址"])
        """创建期货账户"""
        # 如果期货账户数量为0,向界面弹窗
        users = len(self.__socket_manager.get_list_user_info())  # 将要创建期货账户数量
        if users == 0:
            self.signal_show_QMessageBox.emit(["警告", "将要创建期货账户数量为0"])
            return  # 退出程序
        for i in self.__socket_manager.get_list_user_info():
            self.signal_label_login_error_text.emit("创建期货账户" + i['userid'])
            # self.create_user(i)  # 创建期货账户
            self.__dict_total_user_process[i['userid']] = list()
            print(">>> self.__dict_total_user_process =",
                  self.__dict_total_user_process,
                  type(self.__dict_total_user_process))
            # self.__dict_total_user_process[i['userid']][0] = Queue()  # user进程get操作的Queue结构
            # self.__dict_total_user_process[i['userid']].append(Queue())  # user进程get操作的Queue结构
            # self.__dict_total_user_process[i['userid']].append(Queue())  # user进程put操作的Queue结构
            # p = Process(target=self.create_user, args=(i, self.__dict_total_user_process,))  # 创建user独立进程
            print(">>> self.i =", i)
            p = Process(
                target=global_create_user,
                args=(i, ))  #  self.__dict_total_user_process,))  # 创建user独立进程
            # p = Process(target=pro_f, args=(i,))  #  self.__dict_total_user_process,))  # 创建user独立进程
            # self.__dict_total_user_process[i['userid']].append(p)  # user独立进程
            p.start()  # 开始进程
            # p.join()
        """创建策略"""
        self.signal_label_login_error_text.emit("创建策略")
        self.__list_strategy_info = self.__socket_manager.get_list_strategy_info(
        )  # 获取所有策略信息列表
        if len(self.__list_strategy_info) > 0:
            # 过滤出创建成功的期货账户的策略
            for i_strategy in self.__list_strategy_info:
                for i_user in self.__list_user:
                    if i_strategy['user_id'] == i_user.get_user_id().decode():
                        self.__list_strategy_will_create.append(i_strategy)
                        break
        if len(self.__list_strategy_will_create) > 0:
            for i in self.__list_strategy_will_create:
                self.create_strategy(i)  # 创建策略
                self.signal_label_login_error_text.emit("创建策略" + i['user_id'] +
                                                        ' ' + i['strategy_id'])
        """登录期货账户,调用TD API方法"""
        for i_user in self.__list_user:
            self.signal_label_login_error_text.emit(
                "登录期货账户" + i_user.get_user_id().decode())
            i_user.login_trade_account(
            )  # 登录期货账户,期货账户登录成功一刻开始OnRtnOrder、OnRtnTrade就开始返回历史数据
            i_user.qry_trading_account()  # 查询资金账户
            i_user.qry_investor_position()  # 查询投资者持仓
            i_user.qry_inverstor_position_detail()  # 查询投资者持仓明细
            i_user.qry_instrument_info()  # 查询合约信息
        """检查期货账户调用API方法的状态"""
        # 有任何一个方法调用失败,则认为初始化期货账户失败
        create_user_failed_count = 0  # 创建期货账户失败数量
        self.__dict_create_user_failed = {}  # 保存创建失败的期货账户信息
        # 遍历期货账户登录状态dict,将登录失败的user信息存放到self.__dict_create_user_failed
        self.__dict_create_user_status = {
            '078681': {
                'QryInvestorPosition': 0,
                'QryInvestorPositionDetail': 0,
                'connect_trade_front': 0,
                'QryTradingAccount': 0,
                'login_trade_account': 0
            },
            '083778': {
                'QryInvestorPosition': 0,
                'QryInvestorPositionDetail': 0,
                'connect_trade_front': 0,
                'QryTradingAccount': 0,
                'login_trade_account': 0
            }
        }
        # print(">>> self.__dict_create_user_status =", len(self.__dict_create_user_status), self.__dict_create_user_status)
        for i in self.__dict_create_user_status:
            # 样本数据{'078681': {'connect_trade_front': 0, 'QryInvestorPosition': 0, 'QryInvestorPositionDetail': 0, 'QryTradingAccount': -4, 'login_trade_account': 0}}
            # i为键名'078681',str类型
            for j in self.__dict_create_user_status[i]:
                if self.__dict_create_user_status[i][j] != 0:
                    users -= 1  # 成功创建期货账户数量减一
                    create_user_failed_count += 1  # 创建期货账户失败数量加一
                    self.__dict_create_user_failed[
                        i] = self.__dict_create_user_status[i]
                    break
        """删除创建失败的期货账户对象"""
        # 存在创建失败的期货账户,则从期货账户对象列表里删除对象
        if len(self.__dict_create_user_failed) > 0:
            for i_user_id in self.__dict_create_user_failed:  # i为键名,内容为期货账号
                for obj_user in self.__list_user:
                    if i_user_id == obj_user.get_user_id().decode(
                    ):  # 创建失败的user_id等于 对象的user_id
                        self.__list_user.remove(obj_user)  # 从对象列表中删除对象
                        break
        """删除创建失败的期货账户对象所属的策略对象"""
        # 从CTPManager类中self.__list_strategy中删除strategy对象即可,user类已经被删除,所以不用删除user类中的strategy
        # print(">>> self.__dict_create_user_failed =", len(self.__dict_create_user_failed), self.__dict_create_user_failed)
        # 遍历创建失败的期货账户信息dict
        for i_user_id in self.__dict_create_user_failed:
            # 遍历ctp_manager中的策略对象列表
            shift = 0
            for i_strategy in range(len(self.__list_strategy)):
                if self.__list_strategy[i_strategy -
                                        shift].get_user_id() == i_user_id:
                    self.__list_strategy.remove(
                        self.__list_strategy[i_strategy - shift])
                    shift += 1  # 游标调整值
        """user装载从xml获取的数据"""
        for obj_user in self.__list_user:
            obj_user.load_xml()  # 将xml读取的数据赋值给user对象和strategy对象
        """继续完成strategy对象初始化工作"""
        for obj_strategy in self.__list_strategy:
            obj_strategy.get_td_api_arguments()  # 将期货账户api查询参数赋值给strategy对象
            obj_strategy.load_xml()  # strategy装载xml
            obj_strategy.start_run_count()  # 开始核心统计运算线程
            # 遍历strategy初始化完成之前的order和trade回调记录,完成strategy初始化工作,遍历queue_strategy_order\queue_strategy_trade
        """向界面输出创建失败的期货账户信息"""
        if len(self.__dict_create_user_failed) > 0:
            str_head = "以下期货账户创建失败\n"  # 消息第一行,头
            str_main = ""  # 消息内容,每个期货账户做一行显示
            for i in self.__dict_create_user_failed:  # i为期货账号,str
                for j in self.__dict_create_user_failed[
                        i]:  # j为登录信息dict的键名,即函数方法名称,str
                    if self.__dict_create_user_failed[i][j] != 0:
                        str_main = str_main + i + ":" + j + "原因" + str(
                            self.__dict_create_user_failed[i][j]) + "\n"
            str_out = str_head + str_main
            self.signal_show_QMessageBox.emit(["警告", str_out])
            # 创建成功的期货账户数量为0,向界面弹窗,程序终止
            if len(self.__list_user) == 0:
                # self.signal_show_QMessageBox.emit(["警告", "成功创建期货账户的数量为0"])
                return  # 结束程序:没有创建成功的策略,

        self.signal_create_QAccountWidget.emit()  # 创建窗口界面

    # 创建MD
    def create_md(self, dict_arguments):
        # dict_arguments = {'front_address': 'tcp://180.168.146.187:10010', 'broker_id': '9999'}
        # 创建行情管理实例MarketManager
        self.__MarketManager = MarketManager(dict_arguments['frontaddress'],
                                             dict_arguments['brokerid'],
                                             dict_arguments['userid'],
                                             dict_arguments['password'])
        self.__MarketManager.get_market().set_strategy(
            self.__list_strategy)  # 将策略列表设置为Market_API类的属性
        if self.__MarketManager.get_result_market_connect(
        ) == 0 and self.__MarketManager.get_result_market_login() == 0:
            self.__TradingDay = self.__MarketManager.get_TradingDay()
            print("CTPManager.create_md() 创建行情成功,交易日:",
                  self.__TradingDay)  # 行情API中获取到的交易日
            return True
        else:
            print("CTPManager.create_md() 创建行情失败")
            return False

    # 创建trader
    def create_trader(self, dict_arguments):
        self.__trader = Trader(dict_arguments)
        self.__trader_id = self.__trader.get_trader_id()

    # 创建user(期货账户)
    def create_user(self, dict_arguments):
        # 不允许重复创建期货账户实例
        # if len(self.__list_user) > 0:
        #     for i in self.__list_user:
        #         if i.get_user_id() == dict_arguments['userid']:
        #             print("MultiUserTraderSys.create_user()已经存在user_id为", dict_arguments['userid'], "的实例,不允许重复创建")
        #             return

        obj_user = User(dict_arguments, ctp_manager=self)

        while True:
            pass
            print("CTPManager.create_user() user_id =",
                  dict_arguments['userid'], ", process_id =", os.getpid())
            time.sleep(2.0)

        # 将创建成功的期货账户对象存放到self.__list_user
        # for i in self.__dict_create_user_status:
        #     if i == obj_user.get_user_id().decode():
        #         if self.__dict_create_user_status[i]['connect_trade_front'] == 0:  # 连接交易前置成功
        #                 # and self.__dict_create_user_status[i]['login_trade_account'] == 0 \
        #                 # and self.__dict_create_user_status[i]['QryTradingAccount'] == 0 \
        #                 # and self.__dict_create_user_status[i]['QryInvestorPosition'] == 0:
        #             obj_user.set_CTPManager(self)  # 将CTPManager类设置为user的属性
        #             self.__list_user.append(obj_user)  # user类实例添加到列表存放
        #             # obj_user.qry_api_interval_manager()  # API查询时间间隔管理
        #             # obj_user.qry_instrument_info()  # 查询合约信息
        #             print("CTPManager.create_user() 创建期货账户成功,user_id=", dict_arguments['userid'])
        #         else:
        #             print("CTPManager.create_user() 创建期货账户失败,user_id=", dict_arguments['userid'])

        # if self.__dict_create_user_status[dict_arguments['userid']] == 1:  # 判断是否成功创建期货账户
        #     # obj_user.set_DBManager(self.__DBManager)  # 将数据库管理类设置为user的属性
        #     obj_user.set_CTPManager(self)  # 将CTPManager类设置为user的属性
        #     obj_user.qry_instrument_info()  # 查询合约信息
        #     self.__list_user.append(obj_user)  # user类实例添加到列表存放
        #     print("CTPManager.create_user() 创建期货账户成功,user_id=", dict_arguments['userid'])
        # elif self.__dict_create_user_status[dict_arguments['userid']] == 0:
        #     print("CTPManager.create_user() 创建期货账户失败,user_id=", dict_arguments['userid'])

    # 将strategy对象添加到user里
    def add_strategy_to_user(self, obj_strategy):
        for i in self.__list_user:
            if i.get_user_id() == obj_strategy.get_user_id():
                i.add_strategy()

    # 创建strategy
    def create_strategy(self, dict_arguments):
        # 不允许重复创建策略实例
        if len(self.__list_strategy) > 0:
            for i in self.__list_strategy:
                if i.get_strategy_id(
                ) == dict_arguments['strategy_id'] and i.get_user_id(
                ) == dict_arguments['user_id']:
                    print("CTPManager.create_strategy() 不能重复创建,已经存在user_id=",
                          dict_arguments['user_id'], "strategy_id=",
                          dict_arguments['strategy_id'])
                    return False

        # 遍历user对象列表,找到将要创建策略所属的user对象
        for i_user in self.__list_user:
            if i_user.get_user_id().decode(
            ) == dict_arguments['user_id']:  # 找到策略所属的user实例
                # 创建策略
                obj_strategy = Strategy(
                    dict_arguments,
                    i_user)  # 创建策略实例,user实例和数据库连接实例设置为strategy的属性
                # obj_strategy.set_DBManager(self.__DBManager)
                i_user.add_strategy(obj_strategy)  # 将策略实例添加到user的策略列表
                self.__list_strategy.append(
                    obj_strategy)  # 将策略实例添加到CTP_Manager的策略列表
                print("CTPManager.create_strategy() 创建策略,user_id=",
                      dict_arguments['user_id'], "strategy_id=",
                      dict_arguments['strategy_id'])
                # 为策略订阅行情
                list_instrument_id = list()
                for i in dict_arguments['list_instrument_id']:
                    list_instrument_id.append(i.encode())  # 将合约代码转码为二进制字符串
                self.__MarketManager.sub_market(list_instrument_id,
                                                dict_arguments['user_id'],
                                                dict_arguments['strategy_id'])

        # 判断内核是否初始化完成(所有策略是否初始化完成)
        if self.__init_finished:  # 内核初始化完成、程序运行中新添加策略,在界面策略列表框内添加一行
            print("CTPManager.create_strategy() 程序运行中添加策略,user_id =",
                  dict_arguments['user_id'], 'strategy_id =',
                  dict_arguments['strategy_id'])
            self.signal_insert_strategy.emit(obj_strategy)  # 内核向界面插入策略
            self.signal_hide_QNewStrategy.emit()  # 隐藏创建策略的小弹窗
        else:  # 内核初始化未完成
            # 最后一个策略初始化完成,将内核初始化完成标志设置为True
            # if self.__list_strategy_info[-1]['user_id'] == dict_arguments['user_id'] and \
            #                 self.__list_strategy_info[-1]['strategy_id'] == dict_arguments['strategy_id']:
            #     self.__init_finished = True  # CTPManager初始化完成
            pass

    # 删除strategy
    def delete_strategy(self, dict_arguments):
        print("CTPManager.delete_strategy() 删除策略对象", dict_arguments)

        # 将obj_strategy从CTPManager的self.__list_strategy中删除
        for i_strategy in self.__list_strategy:
            if i_strategy.get_user_id(
            ) == dict_arguments['user_id'] and i_strategy.get_strategy_id(
            ) == dict_arguments['strategy_id']:
                # 退订该策略的行情
                self.__MarketManager.un_sub_market(
                    i_strategy.get_list_instrument_id(),
                    dict_arguments['user_id'], dict_arguments['strategy_id'])
                self.__list_strategy.remove(i_strategy)
                break

        # 将obj_strategy从user中的list_strategy中删除
        for i_user in self.__list_user:
            if i_user.get_user_id().decode() == dict_arguments['user_id']:
                for i_strategy in i_user.get_list_strategy():
                    if i_strategy.get_strategy_id(
                    ) == dict_arguments['strategy_id']:
                        i_user.get_list_strategy().remove(i_strategy)
                        self.signal_remove_strategy.emit(
                            i_strategy)  # 发送信号,从界面中删除策略
                        break
                break
        for i_strategy in self.__list_strategy:
            print("user_id=", i_strategy.get_user_id(), "strategy_id=",
                  i_strategy.get_strategy_id())

        # 内核删除策略成功,通知界面删除策略
        # self.signal_remove_row_table_widget.emit()  # 在界面策略列表中删除策略

    # 修改策略,(SocketManager收到服务端修改策略参数类回报 -> CTPManager修改策略)
    @QtCore.pyqtSlot(dict)
    def slot_update_strategy(self, dict_arguments):
        # 对收到的消息做筛选,教给对应的策略
        pass

    # 初始化账户窗口
    def create_QAccountWidget(self):
        """
        # QApplication.processEvents()
        print("CTPManager.create_QAccountWidget() 创建“新建策略”窗口,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

        # 创建“新建策略”窗口
        self.create_QNewStrategy()

        print("CTPManager.create_QAccountWidget() 开始创建总账户窗口,",
              time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 创建总账户窗口
        if True:
            QAccountWidget_total = QAccountWidget(str_widget_name='总账户', 
                                                  list_user=self.get_list_user(),
                                                  ClientMain=self.__client_main,
                                                  CTPManager=self,
                                                  SocketManager=self.__socket_manager)
            # 总账户窗口设置为所有user的属性
            for i_user in self.get_list_user():
                # QApplication.processEvents()
                i_user.set_QAccountWidget_total(QAccountWidget_total)
            # 总账户窗口设置为所有strategy的属性
            for i_strategy in self.get_list_strategy():
                # QApplication.processEvents()
                i_strategy.set_QAccountWidget_total(QAccountWidget_total)
                # 信号槽连接:策略对象修改策略 -> 窗口对象更新策略显示(Strategy.signal_update_strategy -> QAccountWidget.slot_update_strategy() )
                i_strategy.signal_update_strategy.connect(QAccountWidget_total.slot_update_strategy)
                # 信号槽连接:策略对象价差值变化 -> 窗口对象更新价差(Strategy.signal_UI_update_spread_total -> QAccountWidget.slot_update_spread())
                # i_strategy.signal_UI_update_spread_total.connect(QAccountWidget_total.slot_update_spread)
            # 所有策略列表设置为窗口属性
            QAccountWidget_total.set_list_strategy(self.__list_strategy)
            self.__list_QAccountWidget.append(QAccountWidget_total)  # 将窗口对象存放到list集合里
            # self.signal_pushButton_set_position_setEnabled.connect(QAccountWidget_total.on_pushButton_set_position_active)
            # QAccountWidget_total.set_signal_pushButton_set_position_setEnabled_connected(True)  # 信号槽绑定标志设置为True

            # 绑定信号槽:设置交易员交易开关 -> 更新总账户窗口“开始策略”按钮状态
            self.signal_update_pushButton_start_strategy.connect(QAccountWidget_total.slot_update_pushButton_start_strategy)
            # 绑定信号槽:更新总期货账户资金信息 -> 界面更新总账户资金信息
            self.signal_update_panel_show_account.connect(QAccountWidget_total.slot_update_panel_show_account)
        print("CTPManager.create_QAccountWidget() 创建单账户窗口,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 创建单账户窗口
        for i_user in self.get_list_user():
            # # QApplication.processEvents()
            QAccountWidget_single = QAccountWidget(str_widget_name=i_user.get_user_id().decode(),
                                                   obj_user=i_user,
                                                   ClientMain=self.__client_main,
                                                   CTPManager=self,
                                                   SocketManager=self.__socket_manager)
            # 单账户窗口设置为对应的user的属性
            i_user.set_QAccountWidget_signal(QAccountWidget_single)

            # 单账户窗口设置为对应期货账户的所有策略的属性
            for i_strategy in i_user.get_list_strategy():
                # QApplication.processEvents()
                i_strategy.set_QAccountWidget_signal(QAccountWidget_single)
                # 信号槽连接:策略对象修改策略 -> 窗口对象更新策略显示(Strategy.signal_update_strategy -> QAccountWidget.slot_update_strategy() )
                i_strategy.signal_update_strategy.connect(QAccountWidget_single.slot_update_strategy)
                # 信号槽连接:策略对象价差值变化 -> 窗口对象更新价差(Strategy.signal_UI_update_spread_signal -> QAccountWidget.slot_update_spread())
                # i_strategy.signal_UI_update_spread_signal.connect(QAccountWidget_single.slot_update_spread)
            # 单期货账户的所有策略列表设置为窗口属性
            QAccountWidget_single.set_list_strategy(i_user.get_list_strategy())
            self.__list_QAccountWidget.append(QAccountWidget_single)  # 将窗口对象存放到list集合里
            # self.signal_pushButton_set_position_setEnabled.connect(QAccountWidget_single.on_pushButton_set_position_active)
            # QAccountWidget_single.set_signal_pushButton_set_position_setEnabled_connected(True)  # 信号槽绑定标志设置为True

            # 绑定信号槽:设置期货账户交易开关 -> 更新单期货账户窗口“开始策略”按钮状态
            i_user.signal_update_pushButton_start_strategy.connect(QAccountWidget_single.slot_update_pushButton_start_strategy)
            # 绑定信号槽:更新期货账户资金信息 -> 界面更新账户资金信息
            i_user.signal_update_panel_show_account.connect(QAccountWidget_single.slot_update_panel_show_account)
            i_user.init_panel_show_account()  # 窗口显示账户初始化资金信息

        self.__client_main.set_list_QAccountWidget(self.__list_QAccountWidget)  # 窗口对象列表设置为ClientMain的属性

        print("CTPManager.create_QAccountWidget() 窗口添加到tab_accounts,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 窗口添加到tab_accounts
        for i_widget in self.__list_QAccountWidget:
            # QApplication.processEvents()
            self.__q_ctp.tab_accounts.addTab(i_widget, i_widget.get_widget_name())  # 将账户窗口添加到tab_accounts窗体里
            # 信号槽连接
            # 下面注释代码位置转移到QAccountWidget.slot_insert_strategy()里,向窗口插入策略的时候动态绑定策略与窗口之间的信号槽关系
            # 信号槽:CTPManager创建策略 -> QAccountWidget插入策略(CTPManager.signal_insert_strategy -> QAccountWidget.slot_insert_strategy())
            self.signal_insert_strategy.connect(i_widget.slot_insert_strategy)
            # 窗口修改策略 -> SocketManager发送修改指令(QAccountWidget.signal_send_msg -> SocketManager.slot_send_msg() )
            i_widget.signal_send_msg.connect(self.__socket_manager.slot_send_msg)
            # 绑定信号槽:收到服务端的查询策略信息 -> groupBox界面状态还原(激活查询按钮、恢复“设置持仓”按钮)
            self.__socket_manager.signal_restore_groupBox.connect(i_widget.slot_restore_groupBox_pushButton)
            # 绑定信号槽:内核删除策略 -> 界面删除策略
            self.signal_remove_strategy.connect(i_widget.slot_remove_strategy)
            # 绑定信号槽:QAccountWidget需要弹窗 -> 调用ClientMain中的槽函数slot_show_QMessageBox
            i_widget.signal_show_QMessageBox.connect(self.__client_main.slot_show_QMessageBox)

        print("CTPManager.create_QAccountWidget() 向界面插入策略,", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        # 向界面插入策略
        for i_strategy in self.get_list_strategy():
            # QApplication.processEvents()
            self.signal_insert_strategy.emit(i_strategy)  # 向界面插入策略

        # 初始化开始策略按钮状态
        self.signal_update_pushButton_start_strategy.emit()  # 向总账户窗口发送信号
        for i_user in self.__list_user:
            i_user.signal_update_pushButton_start_strategy.emit()  # 向单账户窗口发送信号

        self.__init_UI_finished = True  # 界面初始化完成标志位
        self.__client_main.set_init_UI_finished(True)  # 界面初始化完成标志位设置为ClientMain的属性

        self.__q_ctp.show()  # 显示主窗口
        self.__q_login_form.hide()  # 隐藏登录窗口
        print("ClientMain.create_QAccountWidget() 界面初始化完成", time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
        """
        # 创建“新建策略”窗口
        self.create_QNewStrategy()
        # 全局创建一个QAccountWidget实例,分别添加到不同table中

        # self.__q_ctp.tab_accounts.addTab(self.__q_account_widget, "总账户")  # 添加"总账户"tab
        # self.__q_ctp.tab_accounts.addTab(self.__q_account_widget2, "总账户2")  # 添加"总账户"tab
        # self.tabBar.addTab("所有账户")
        # self.__q_ctp.tab_accounts.currentChanged.connect(self.__q_account_widget.tab_changed)  # 连接信号槽
        # self.__q_ctp.signal_on_tab_accounts_currentChanged.connect(self.__q_account_widget.slot_tab_changed)  # 连接信号槽
        print(">>> CTPManager.create_QAccountWidget() len(self.__list_user) =",
              len(self.__list_user))
        for obj_user in self.__list_user:
            print(
                ">>> CTPManager.create_QAccountWidget() obj_user.get_user_id().decode() =",
                obj_user.get_user_id().decode())
            self.__q_ctp.widget_QAccountWidget.tabBar.addTab(
                obj_user.get_user_id().decode())  # 添加单账户tab

        # 创建StrategyDataModel
        self.StrategyDataModel = StrategyDataModel(
            mylist=self.get_list_strategy_view())
        self.__q_ctp.widget_QAccountWidget.tableView_Trade_Args.setModel(
            self.StrategyDataModel)

        self.__init_UI_finished = True  # 界面初始化完成标志位
        self.__client_main.set_init_UI_finished(
            True)  # 界面初始化完成标志位设置为ClientMain的属性
        self.__q_ctp.show()  # 显示主窗口
        self.__q_login_form.hide()  # 隐藏登录窗口
        print("ClientMain.create_QAccountWidget() 界面初始化完成",
              time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))

    # 创建“新建策略窗口”
    def create_QNewStrategy(self):
        self.__q_new_strategy = QNewStrategy()
        completer = QCompleter()
        if self.get_got_list_instrument_info():
            model = QStringListModel()
            model.setStringList(self.get_list_instrument_id())
            completer.setModel(model)
        else:
            print(">>> CTPManager.create_QNewStrategy() 查询合约信息失败")
        self.__q_new_strategy.lineEdit_a_instrument.setCompleter(completer)
        self.__q_new_strategy.lineEdit_b_instrument.setCompleter(completer)
        self.__q_new_strategy.set_ClientMain(
            self.__client_main)  # CTPManager设置为新建策略窗口属性
        self.__q_new_strategy.set_CTPManager(self)  # CTPManager设置为新建策略窗口属性
        self.__q_new_strategy.set_SocketManager(
            self.__socket_manager)  # SocketManager设置为新建策略窗口属性
        self.__q_new_strategy.set_trader_id(self.__trader_id)  # 设置trade_id属性
        self.set_QNewStrategy(self.__q_new_strategy)  # 新建策略窗口设置为CTPManager属性
        self.__client_main.set_QNewStrategy(
            self.__q_new_strategy)  # 新建策略窗口设置为ClientMain属性
        self.signal_hide_QNewStrategy.connect(
            self.get_QNewStrategy().hide)  # 绑定信号槽,新创建策略成功后隐藏“新建策略弹窗”
        # 绑定信号槽:新建策略窗新建策略指令 -> SocketManager.slot_send_msg
        self.__q_new_strategy.signal_send_msg.connect(
            self.__socket_manager.slot_send_msg)

    # 创建数据库连接实例
    def create_DBManager(self):
        self.__DBManager = DBManger()

    # 设置View视窗所需的data_list
    # def set_list_strategy_view(self, list_data):
    #     self.__list_strategy_view = list_data

    # 获取View视窗所需的data_list
    # def get_list_strategy_view(self):
    #     self.__list_strategy_view = list()  # 初始化view视窗中的数据
    #     index = -1
    #     for obj_strategy in self.__list_strategy:  # 遍历所有策略对象,将所有策略的list_strategy_view合并到一个list显示到界面view
    #         self.__list_strategy_view.append(obj_strategy.get_list_strategy_view())
    #     print(">>> CTPManager.get_list_strategy_view() self.__list_strategy_view =", self.__list_strategy_view)
    #     return self.__list_strategy_view

    # 获取窗口对象
    def get_QAccountWidget(self):
        return self.__q_account_widget

    # 获取trader_id
    def get_trader_id(self):
        return self.__trader_id

    def get_TradingDay(self):
        return self.__TradingDay

    # 获取数据库连接实例
    def get_mdb(self):
        return self.__DBManager

    # 获取行情实例
    def get_md(self):
        return self.__MarketManager

    # 获取trader对象的list
    def get_trader(self):
        return self.__trader

    # 获取user对象的list
    def get_list_user(self):
        return self.__list_user

    # 获取strategy对象的list
    def get_list_strategy(self):
        return self.__list_strategy

    # 获取user对象创建状态的dict
    def get_dict_create_user_status(self):
        return self.__dict_create_user_status

    # 设置CTPManager内核初始化完成
    def set_init_finished(self, bool_input):
        print(">>> CTPManager.set_init_finished() CTPManager内核初始化完成")
        self.__init_finished = bool_input

    # 获取CTPManager内核初始化状态
    def get_init_finished(self):
        return self.__init_finished

    # 设置界面初始化状态
    def set_init_UI_finished(self, bool_input):
        self.__init_UI_finished = bool_input

    def get_init_UI_finished(self):
        return self.__init_UI_finished

    # 从user对象列表里找到指定user_id的user对象
    def find_user(self, user_id):
        for i in self.__list_user:
            if i.get_user_id() == user_id:
                return i

    def set_ClientMain(self, obj_ClientMain):
        self.__client_main = obj_ClientMain

    def get_ClientMain(self):
        return self.__client_main

    def set_SocketManager(self, obj_SocketManager):
        self.__socket_manager = obj_SocketManager

    def get_SocketManager(self):
        return self.__socket_manager

    def set_QLoginForm(self, obj_QLoginForm):
        self.__q_login_form = obj_QLoginForm

    def get_QLoginForm(self):
        return self.__q_login_form

    def set_QCTP(self, obj_QCTP):
        self.__q_ctp = obj_QCTP

    def get_QCTP(self):
        return self.__q_ctp

    def set_XML_Manager(self, obj_XML_Manager):
        self.__xml_manager = obj_XML_Manager

    def get_XML_Manager(self):
        return self.__xml_manager

    def set_QNewStrategy(self, obj_QNewStrategy):
        self.__q_new_strategy = obj_QNewStrategy

    def get_QNewStrategy(self):
        return self.__q_new_strategy

    def set_list_market_info(self, list_input):
        self.__list_market_info = list_input

    def get_list_market_info(self):
        return self.__list_market_info

    def set_list_user_info(self, list_input):
        self.__list_user_info = list_input

    def get_list_user_info(self):
        return self.__list_user_info

    # 所有策略的昨仓保存到一个list,从服务端查询获得
    def set_YesterdayPosition(self, listYesterdayPosition):
        self.__listYesterdayPosition = listYesterdayPosition

    def get_YesterdayPosition(self):
        return self.__listYesterdayPosition

    # 新增trader_id下面的某个期货账户
    def add_user(self, trader_id, broker_id, front_address, user_id, password):
        print('add_user(): trader_id=', trader_id, 'broker_id=', broker_id,
              'user_id=', user_id)
        add_user_arguments = {
            'trader_id': trader_id,
            'broker_id': broker_id,
            'UserID': user_id,
            'Password': password,
            'front_address': front_address
        }
        # 新增期货账户,创建TradeApi实例
        return User(add_user_arguments)

    # 删除trader_id下面的某个期货账户
    # 参数说明: user=class User实例名称
    def del_user(self, user, trader_id, broker_id, front_address, user_id):
        print('del_user(): trader_id=', trader_id, 'broker_id=', broker_id,
              'user_id=', user_id)
        del_user_arguments = {
            'trader_id': trader_id,
            'broker_id': broker_id,
            'UserID': user_id,
            'front_address': front_address
        }
        # 删除期货账户,释放TradeApi实例
        user.UnConnect()
        # 操作MongoDB,删除Operator下面的user_id(期货账户)

    # 交易员登录验证
    def trader_login(self, trader_id, password):
        return self.__DBManager.check_trader(trader_id, password)

    # 设置交易员id
    def set_trader_id(self, str_TraderID):
        self.__trader_id = str_TraderID

    # 获得交易员id
    def get_trader_id(self):
        return self.__trader_id

    def set_trader_name(self, str_trader_name):
        self.__trader_name = str_trader_name

    def get_trader_name(self):
        return self.__trader_name

    # 设置客户端的交易开关,0关、1开
    def set_on_off(self, int_on_off):
        # print(">>> CTPManager.set_on_off()", int_on_off)
        self.__on_off = int_on_off
        self.signal_update_pushButton_start_strategy.emit(
        )  # 触发信号:内核设置交易员交易开关 -> 更新窗口“开始策略”按钮状态

    # 获取客户端的交易开关,0关、1开
    def get_on_off(self):
        return self.__on_off

    # 设置交易开关,0关、1开
    def set_only_close(self, int_only_close):
        self.__only_close = int_only_close

    # 获取交易开关,0关、1开
    def get_only_close(self):
        return self.__only_close

    # 设置“已经获取到合约信息的状态”
    def set_got_list_instrument_info(self, bool_status):
        self.__got_list_instrument_info = bool_status

    # 获取“已经获取到合约信息的状态”
    def get_got_list_instrument_info(self):
        return self.__got_list_instrument_info

    # 设置合约信息
    def set_instrument_info(self, input_list):
        self.__list_instrument_info = input_list
        self.__list_instrument_id = list()
        for i in self.__list_instrument_info:
            self.__list_instrument_id.append(i['InstrumentID'])

    # 获取合约信息
    def get_instrument_info(self):
        return self.__list_instrument_info

    # 获取期货合约代码列表
    def get_list_instrument_id(self):
        return self.__list_instrument_id

    # 更新账户资金信息,并刷新界面
    def update_panel_show_account(self):
        """
        self.__capital = 0  # 动态权益
        self.__pre_balance = 0  # 静态权益
        self.__profit_position = 0  # 持仓盈亏
        self.__profit_close = 0  # 平仓盈亏
        self.__commission = 0  # 手续费
        self.__available = 0  # 可用资金
        self.__current_margin = 0  # 占用保证金
        self.__risk = 0  # 风险度
        self.__deposit = 0  # 今日入金
        self.__withdraw = 0  # 今日出金
        """
        # 遍历期货账户,累加指标
        for i in self.__list_user:
            user_panel_show_account = i.get_panel_show_account()
            self.__capital += user_panel_show_account['Capital']
            self.__pre_balance += user_panel_show_account['PreBalance']
            self.__profit_position += user_panel_show_account['PositionProfit']
            self.__profit_close += user_panel_show_account['CloseProfit']
            self.__commission += user_panel_show_account['Commission']
            self.__available += user_panel_show_account['Available']
            self.__current_margin += user_panel_show_account['CurrMargin']
            self.__risk += user_panel_show_account['Risk']
            self.__deposit += user_panel_show_account['Deposit']
            self.__withdraw += user_panel_show_account['Withdraw']

        # 更新界面显示
        self.signal_update_panel_show_account.emit(
            self.__dict_panel_show_account)
Example #27
0
    for name, model in models.items():
        title = stock_name.upper() + ' ' + name
        grapher = Grapher(title)
        with open(title.lower().replace(' ', '_') + '.txt', 'w') as f:
            for e in range(EPISODES + 1):
                x_train, y_train = proc.run(span=span)

                model.model.fit(x_train, y_train)
                y_pred = model.model.predict(x_test)

                prev_prices, prices, pred = x_test[:,
                                                   -1], y_test, y_pred.reshape(
                                                       y_pred.shape[0])
                if e % 100 == 0:
                    for mode, action_labels in modes.items():
                        trader = Trader(mode)
                        strategy = trader.to_strategy(prev_prices, pred)
                        optimal = trader.to_strategy(prev_prices, prices)
                        trader.run(strategy, prices, grapher=grapher)

                        # f.write('{} accuracy_score={} balanced_accuracy_score={} average_precision_score={} f1_score={}\n'.format(
                        #     e,
                        #     accuracy_score(strategy, optimal),
                        #     balanced_accuracy_score(strategy, optimal),
                        #     average_precision_score(strategy, optimal),
                        #     f1_score(strategy, optimal)))

                        grapher.action_labels = action_labels
                        grapher.pred = pred[:-1]

                        grapher.show(action_labels=action_labels,
Example #28
0

content = []
for fname in glob.glob('data/*'):
    with open(fname) as fin:
        for line in fin.readlines():
            content.append(process_line(line))

df = pd.DataFrame(content,
                  columns=['date', 'low', 'high', 'open', 'close', 'volume'])
df['date'] = pd.to_datetime(df['date'], format='%Y%m%dT%H')
df.set_index('date', inplace=True)
df.sort_index(inplace=True)

res = []
trader = Trader(10000)
for i, price in enumerate(df['open']):
    r = trader.trade((df.index[i], price))
    if r != []: res += r
    trader.query_portfolio(df.index[i])

fig = df['close'].plot(figsize=(80, 15))
for r in res:
    df1 = pd.DataFrame([[r[0], r[1]], [r[2], r[3]]], columns=['date', 'price'])
    df1['date'] = pd.to_datetime(df1['date'], format='%Y%m%dT')
    df1.set_index('date', inplace=True)

    df1.plot(ax=fig, color='red')
    fig.legend([])

fig.figure.savefig('plots/figure.pdf')
Example #29
0
from World import World
from Trader import Trader
from Town import Town

from Utilities import Utilities

utilities = Utilities()

player = Trader(utilities, "The player", [1, 1], [0, 0], 1000, [], [])
dummy_player = Trader(utilities, "Dumb", [1, 1], [0, 0], 0, [], [])
town1 = Town(utilities, 'Los Mantos', (-2, 0), 500, [10, 10], 'Coastal', [])
town2 = Town(utilities, 'Kallac', (1, 1), 500, [10, 10], 'Karst', [])
town3 = Town(utilities, 'Vinas', (2, -2), 500, [10, 10], 'Hilly', [])

towns = [town1, town2, town3]
traders = [player, dummy_player]

world = World(utilities, 0, towns, traders)

run_game = True

input_action = None


def main_interface():
    player_town = world.player.current_town

    building_unlocked = False
    if player.wallet >= 5000 or "property_owner" in player.properties:
        building_unlocked = True
    sensible = 0
Example #30
0
def main():
    args = parser.parse_args()

    if args.draw:
        # parse arguments and collect data
        # price history
        if args.use_generated:
            gen = args.use_generated[0]
            src = args.use_generated[1]
            (data, _) = calc.generate_theoretical_data(gen, src)
        else:
            data = db.build_price_lut(args.draw[0])
        dates = [date_obj(date) for date in sorted(data.keys())]
        prices = [data[date_str(date)] for date in dates]
        # indicators and plot counts
        if not args.indicators:
            args.indicators = []
        plots = 1
        indicators = {}
        for indicator_code in args.indicators:
            if indicator_code[0:4] == 'MACD':
                plots = 2
            indicators[indicator_code] = calc.get_indicator(indicator_code,
                                                            data, True)

        # plot main price data
        pyplot.subplot(plots * 100 + 11)
        pyplot.plot(dates, prices, label='{} price'.format(args.draw[0]))
        pyplot.legend(loc='upper left')

        # plot indicators
        for (indicator_code, series) in indicators.items():
            code_parts = indicator_code.split('_')
            indicator = code_parts[0]
            if len(code_parts) > 1:
                period_code = code_parts[1]
            if indicator == 'MACD':
                pyplot.subplot(plots * 100 + 12)
                pyplot.plot(dates, series[0], label=indicator_code)
                pyplot.plot(dates, series[1],
                            label='Signal_{}'.format(period_code))
                pyplot.legend(loc='upper left')
            else:
                pyplot.subplot(plots * 100 + 11)
                pyplot.plot(dates, series, label=indicator_code)
                pyplot.legend(loc='upper left')

        pyplot.show()

    if args.generate:
        (part, full) = calc.generate_theoretical_data(args.generate[0],
                                                      args.generate[1])
        tgt_lut = db.build_price_lut(args.generate[0])
        src_lut = db.build_price_lut(args.generate[1])
        tgt_dates = [date_obj(d) for d in sorted(tgt_lut.keys())]
        src_dates = [date_obj(d) for d in sorted(part.keys())]
        tgt_gen_part_prices = [part[date_str(d)] for d in src_dates]
        tgt_gen_full_prices = [full[date_str(d)] for d in src_dates]
        src_prices = [src_lut[date_str(d)] for d in src_dates]

        pyplot.subplot(211)
        pyplot.plot([date_obj(d) for d in tgt_dates],
                    tgt_gen_full_prices[-len(tgt_dates):],
                    label='{}-generated'.format(args.generate[0]))
        pyplot.plot([date_obj(d) for d in tgt_dates],
                    tgt_gen_part_prices[-len(tgt_dates):],
                    label='{}'.format(args.generate[0]))
        pyplot.legend(loc='upper left')

        pyplot.subplot(212)
        pyplot.plot(src_dates, tgt_gen_part_prices, label='{}-generated'.format(args.generate[0]))
        pyplot.plot(src_dates, src_prices, label='{}'.format(args.generate[1]))
        pyplot.legend(loc='upper left')

        pyplot.show()

    if args.portfolio:
        # init main objects
        my_market = Market()
        my_portfolio = Portfolio()
        my_trader = Trader(args.portfolio[0], my_portfolio, my_market)

        # init simulator
        my_monitor = Monitor(my_trader, my_market)
        my_sim = Simulator()
        my_sim.add_trader(my_trader)
        my_sim.use_market(my_market)
        my_sim.use_monitor(my_monitor)

        (strategy, tickers, indicators) = db.build_strategy(args.strategy[0])
        my_trader.add_assets_of_interest(strategy['assets'])
        my_trader.set_strategy(strategy['positions'])
        my_sim.use_stocks(tickers)
        my_sim.use_indicators(indicators)

        if args.contribute:
            my_trader.set_contributions(args.contribute[0], args.contribute[1])

        if args.rebalance:
            my_trader.set_rebalancing_period(args.rebalance[0])

        if args.use_generated:
            for i in range(len(args.use_generated) // 2):
                gen = args.use_generated[i * 2]
                src = args.use_generated[i * 2 + 1]
                (data, _) = calc.generate_theoretical_data(gen, src)
                my_market.inject_stock_data(gen, None, None, data)

        # run simulation
        my_sim.simulate()

        # print some stats
        print('##################################')
        print('# PERFORMANCE SUMMARY')
        print('##################################')
        print('initial: $' + currency(my_trader.starting_cash))
        print('final:   $' + currency(my_trader.portfolio.value()))
        print('trades:  {}'.format(my_portfolio.trades))
        print('---------------------------')
        print('Sharpe Ratio:  {}'.format(
            my_monitor.get_statistic('sharpe_ratio')))
        print('Sortino Ratio: {}'.format(
            my_monitor.get_statistic('sortino_ratio')))
        print('---------------------------')
        print('CAGR:          {}%'.format(
            percent(my_monitor.get_statistic('cagr'))))
        print('Adjusted CAGR: {}%'.format(
            percent(my_monitor.get_statistic('adjusted_cagr'))))
        print('---------------------------')
        print('best year:  {}%'.format(
            percent(max(my_monitor.get_data_series('annual_returns')[1]))))
        print('worst year: {}%'.format(
            percent(min(my_monitor.get_data_series('annual_returns')[1]))))
        print('---------------------------')
        drawdown = my_monitor.get_statistic('max_drawdown')
        print('max drawdown: {}%'.format(percent(drawdown['amount'])))
        print('  between {} and {}, recovered by {}'.format(
            drawdown['from'], drawdown['to'], drawdown['recovered_by']))

        # show plots
        (x, y) = my_monitor.get_data_series('portfolio_values')
        pyplot.subplot(411)
        pyplot.plot(x, y)
        pyplot.grid(b=False, which='major', color='grey', linestyle='-')

        (x, y) = my_monitor.get_data_series('asset_allocations')
        pyplot.subplot(412)
        pyplot.stackplot(x, y, alpha=0.5)
        pyplot.grid(b=True, which='major', color='grey', linestyle='-')
        pyplot.legend(sorted(strategy['assets']), loc='upper left')

        (x, y) = my_monitor.get_data_series('annual_returns')
        ax = pyplot.subplot(413)
        pyplot.bar(list(range(len(x))), y, 0.5, color='blue')
        ax.set_xticks(list(range(len(x))))
        ax.set_xticklabels(x)
        pyplot.grid(b=True, which='major', color='grey', linestyle='-')

        (x, y) = my_monitor.get_data_series('contribution_vs_growth')
        pyplot.subplot(414)
        pyplot.stackplot(x, y, alpha=0.5)
        pyplot.grid(b=True, which='major', color='grey', linestyle='-')
        pyplot.legend(['Contributions', 'Growth'], loc='upper left')

        pyplot.show()

    exit()
Example #31
0
#provide risk adversion in [0,1] where it represets the percentage of 
#portfolio value invested in one trade
    risk_adversion = 0.1  #(exposure)
    comission_per_trade = 0.5/100 #this is variable commission 
    #significance= 0.1 #for statistical test acceptance
    significance= 0.1

##################################################################################

    data = DataHolder(coins,window_ols,window_ma)
    #initialise cointegration and stationarity test
    tester=Tester(significance)
    # Set the strategy, parameters are the entry and exit points of the model
    strategy = Strategy(buy_sell_zscore, close_zscore)
    # Trader holds capital
    trader = Trader(starting_capital,risk_adversion)
    # Backtest iterates over the days.
    backtest = Backtest(comission_per_trade)
    plotter=Plotter()
    
#---------------------------------------------------------------------------------

    # Read coins prices, compute z-srore and beta
    data.get_data()

    # Run the backtest
    backtest.run_backtest(trader,strategy,data,tester,window_ols)

    # Plot results of the backtest
    plotter.plot(trader,data)
Example #32
0
class Manager:
    def __init__(self, param, instrument, environment='demo', mode='test'):
        self.instrument = instrument
        self.environment = environment
        self.param = param
        self.trader = Trader(instrument, environment, mode)
        #self.predictors = {k: Predictor(k) for k in param.timelist}
        #self.fetters = {k: Fetter(k) for k in param.timelist}
        self.evaluator = Evaluator(self.param.timelist, instrument,
                                   environment)

        self.checking_freq = 0
        self.count = 0

    def __del__(self):
        self.trader.clean()

    def has_price(self, msg):
        if msg:
            msg = from_byte_to_dict(msg)
            if msg["type"] == "PRICE":
                return True
            else:
                return False
        else:
            return False

    def has_heartbeat(self, msg):
        if msg:
            msg = from_byte_to_dict(msg)
            if msg["type"] == "HEARTBEAT":
                return True
            else:
                return False
        else:
            return False

    def driver(self, candlesticks):
        """
		ローソク足データの収集、解析、取引を取り扱う

		Parameters
		----------
		candlesticks: dict
			ローソク足データを任意の時間足分格納したdict
		environment: str
			取引を行う環境。バーチャル口座(demo)orリアル口座(live)
		instrument: str
			取引を行う通貨	
		"""
        print('test_driver begin')
        print('trader was created')

        #現在保有しているポジションをすべて決済
        self.trader.clean()
        print('close all position to use trader.clean()')

        while True:
            #指定した通貨のtickをストリーミングで取得する
            pricing_handler = Pricing(self.environment)
            resp = pricing_handler.connect_to_stream(self.instrument)
            try:
                resp.raise_for_status()
            except ConnectionError as e:
                print(f'connect_to_stream : Catch {e}')
                print(f'connect_to_stream : Retry to Connect')
                time.sleep(1)
                continue

            try:
                self.run(resp, candlesticks)
            except requests.exceptions.ChunkedEncodingError as e:
                print(f'run : Catch {e}')
                print(f'run : Retry to Connect')
                time.sleep(1)
                continue

    def run(self, resp, candlesticks):
        """
		raise ValueError
		raise urllib3.exceptions.ProtocolError
		raise requests.exceptions.Chunked EncodingError
		"""
        for line in resp.iter_lines(1):
            if self.has_price(line):
                recv = from_byte_to_dict(line)
                self.execute_strategy(recv, candlesticks)

            #一定時間ごとに注文or決済が反映されたかを確認する
            if self.checking_freq == self.count:
                print(f'heart beat(span): {self.count}')
                #注文が反映されたか
                if self.trader.test_is_reflected_order() is True:
                    #WAIT_ORDER -> POSITION
                    self.trader.switch_state()

                #決済が反映されたか
                if self.trader.test_is_reflected_position() is True:
                    #WAIT_POSITION -> ORDER
                    self.trader.switch_state()
            self.count = 0 if self.checking_freq == self.count else (
                self.count + 1)

    def execute_strategy(self, recv, candlesticks):
        for k, v in candlesticks.items():
            #if can_update(recv, v) is True:
            if v.can_update(recv) is True:
                v.update_ohlc_()
                print(k)
                print(len(v.ohlc))

                if k == self.param.entry_freq:
                    try:
                        #エントリー
                        self.entry(candlesticks)
                    except (RuntimeError, ValueError) as e:
                        print(f'{e}')

                    #決済(クローズ)
                    self.settle(candlesticks)

                #時間足が更新されたときにも注文が反映されたかを確認する
                #注文が反映されたか
                if self.trader.test_is_reflected_order() is True:
                    #WAIT_ORDER -> POSITION
                    self.trader.switch_state()

                #決済が反映されたか
                if self.trader.test_is_reflected_position() is True:
                    #WAIT_POSITION -> ORDER
                    self.trader.switch_state()
            v.append_tickdata(recv)

    def entry(self, candlesticks):
        if self.trader.state == 'ORDER':
            is_rises = []
            error_count = 0
            """
			try:
				length = 10
				is_rises.append(is_rise_with_trendline(self.param.target, candlesticks, length))
			except TypeError as e:
				print(f'{e}')
				error_count += 1

			try:
				is_rises.append(is_rise_with_zebratail(self.param.target, candlesticks))
			except TypeError as e:
				print(f'{e}')
				error_count += 1
			"""
            try:
                is_rises.append(
                    is_rise_with_insidebar(self.param.target, candlesticks,
                                           length))
            except ValueError as e:
                print(f'{e}')
                error_count += 1

            try:
                is_rises.append(
                    is_rise_with_line_touch(self.param.target, candlesticks))
            except ValueError as e:
                print(f'{e}')
                error_count += 1

            try:
                is_rises.append(
                    is_rise_with_trendline_maxarea(self.param.target,
                                                   candlesticks))
            except ValueError as e:
                print(f'{e}')
                error_count += 1

            if error_count > 0:
                print(f'Error count : {error_count}')
                raise RuntimeError('entry : error count is not 0')

            if (all(is_rises) is True or any(is_rises) is False) is False:
                print('Unstable: ENTRY')
                raise ValueError(
                    'entry : is_rises is not [All True] or [All False]')

            is_rise = all(is_rises)
            kind = 'BUY' if True is is_rise else 'SELL'

            is_order_created = self.trader.test_create_order(is_rise)
            self.evaluator.set_order(kind, True)
            print(kind)

            if True is is_order_created:
                #ORDER状態からORDERWAITINGに状態遷移
                self.trader.switch_state()

    def settle(self, candlesticks):
        threshold = 8
        if self.trader.state == 'POSITION':
            #ポジションを決済可能か
            if self.trader.can_close_position(threshold) is True:
                #決済の注文を発行する
                is_position_closed = self.trader.test_close_position()

                x = {}
                correct = {}
                for k, v in candlesticks.items():
                    x[k] = v.normalize_by('close').values
                    #or x[k] = v.normalize_by('close' raw=True)
                    correct[k] = np.mean(x[k][-threshold:])

                self.evaluator.set_close(True)

                #LINE notification
                #timeframes = list(candlesticks.keys())
                plothelper = PlotHelper()
                plothelper.begin_plotter()
                plothelper.add_candlestick(candlesticks)
                plothelper.end_plotter('close.png', True)

                self.evaluator.log_score()

                #決済の注文が発行されたか
                if True is is_position_closed:
                    #ORDER -> WAIT_ORDER
                    self.trader.switch_state()

            else:
                print('Position can not be closed in this update')
            #決済するかを判断するアルゴリズムを更新
            self.trader.update_whether_closing_position(threshold)
Example #33
0
import datetime
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import seaborn as sns
import datetime as dt

from funcoes import *
from Trader import Trader
from model import *

pd.set_option('precision', 6)
pd.set_option('display.float_format', lambda x: '%.6f' % x)

# %%
trader = Trader()
#%%
#trader.loadTrainData('./dolar/negocios/20200220_dolh20')
#print(trader.X_train_df_scaled.tail())

#%% Treinar ou Re-Treinar o modelo
#trader.model.load_weights('./dolar/dolar_oversampled.h5')
trader.buildModel(trader.train_shape)
trader.fit()

# #%%
#trader.loadTestData('./dolar/negocios/20200427_dolk20')
#print(trader.X_test_df_scaled.head())
# #%%
# trader.buildModel(trader.test_shape)
# trader.model.build(trader.test_shape)
Example #34
0
from helper_func import eprint
import sys
if len(sys.argv) != 2:
    eprint("Usage: python test.py platform (opt: redirect to resources/platform/all_paths.txt)")
    exit()

from Trader import Trader
from tree_func import *
from tp_func import *

platform = sys.argv[1]
bot = Trader(platform)

onlinelist = bot.getValidPairs() # """
totalPairs = len(onlinelist)
print("totalPairs: "+str(totalPairs))

reducedList = onlinelist[:totalPairs]

#print("reducedList:\n"+str(reducedList))
#print("onlinelist:\n"+str(onlinelist))
#exit()
nodelist = getAllTPs(platform, reducedList)
#for p in nodelist:    print(p)
#print(len(nodelist))
#exit()

i=0
for r in nodelist:#[7:8]:
    i += 1
    rootPair = r