Skip to content

Instantly share code, notes, and snippets.

@lawrence910426
Created April 6, 2023 01:44
Show Gist options
  • Save lawrence910426/255ffd07117a4e8093e68c7be2058409 to your computer and use it in GitHub Desktop.
Save lawrence910426/255ffd07117a4e8093e68c7be2058409 to your computer and use it in GitHub Desktop.
from collections import defaultdict, deque
from shioaji import BidAskFOPv1, Exchange
import shioaji as sj
import datetime
import pandas as pd
import talib as ta
import time
from math import ceil
import pysimulation
api = sj.Shioaji(simulation=True)
accounts = api.login(
api_key="6YugfETBuBogK1jSTPXR7KQh6eeY8RawEK42QEYCZG8E",
secret_key="CyAMsKj115UJNQuFPujqAxSQJjvGaj3ameZQWjr1CeYS",
)
order = pysimulation.order('') # student id
contract = min(
[
x for x in api.Contracts.Futures.TXF
if x.code[-2:] not in ["R1", "R2"]
],
key=lambda x: x.delivery_date
)
msg_queue = defaultdict(deque)
api.set_context(msg_queue)
@api.on_bidask_fop_v1(bind=True)
def quote_callback(self, exchange: Exchange, bidask: BidAskFOPv1):
# append quote to message queue
self['bidask'].append(bidask)
api.quote.subscribe(
contract,
quote_type=sj.constant.QuoteType.BidAsk,
version=sj.constant.QuoteVersion.v1
)
time.sleep(2.5)
# get maximum strategy kbars to dataframe, extra 30 it's for safety
bars = 65 + 30
# since every day has 60 kbars (only from 8:45 to 13:45), for 5 minuts kbars
days = ceil(bars/60)
df_5min = []
while(len(df_5min) < bars):
kbars = api.kbars(
contract=api.Contracts.Futures.TXF.TXFR1,
start=(datetime.date.today() -
datetime.timedelta(days=days)).strftime("%Y-%m-%d"),
end=datetime.date.today().strftime("%Y-%m-%d"),
)
df = pd.DataFrame({**kbars})
df.ts = pd.to_datetime(df.ts)
df = df.set_index('ts')
df.index.name = None
df = df[['Open', 'High', 'Low', 'Close', 'Volume']]
df = df.between_time('08:44:00', '13:45:01')
df_5min = df.resample('5T', label='right', closed='right').agg(
{'Open': 'first',
'High': 'max',
'Low': 'min',
'Close': 'last',
'Volume': 'sum'
})
df_5min.dropna(axis=0, inplace=True)
days += 1
ts = datetime.datetime.now()
support, resistence = None, None
while datetime.datetime.now().time() < datetime.time(13, 40):
# this place can add stop or limit order
self_list_positions = order.list_positions(msg_queue['bidask'][-1])
self_position = 'None' if len(self_list_positions) == 0 else self_list_positions['direction']
# local time > next kbars time
if(datetime.datetime.now() >= ts):
kbars = api.kbars(
contract=api.Contracts.Futures.TXF.TXFR1,
start=datetime.date.today().strftime("%Y-%m-%d"),
end=datetime.date.today().strftime("%Y-%m-%d"),
)
df = pd.DataFrame({**kbars})
df.ts = pd.to_datetime(df.ts)
df = df.set_index('ts')
df.index.name = None
df = df[['Open', 'High', 'Low', 'Close', 'Volume']]
df = df.between_time('08:44:00', '13:45:01')
df = df.resample('5T', label='right', closed='right').agg({
'Open': 'first',
'High': 'max',
'Low': 'min',
'Close': 'last',
'Volume': 'sum'})
df.dropna(axis=0, inplace=True)
df_5min.update(df)
to_be_added = df.loc[df.index.difference(df_5min.index)]
df_5min = pd.concat([df_5min, to_be_added])
ts = df_5min.iloc[-1].name.to_pydatetime()
# next kbar time update and local time < next kbar time
if (datetime.datetime.now().minute != ts.minute):
# Exit conditions
if self_position == 'Buy':
minimal = min([df_5min["Low":-i] for i in range(2, 5)])
if df_5min['Close':-1] < minimal:
order.place_order(msg_queue['bidask'][-1], 'Sell', 'Close')
if self_position == 'Sell':
maximal = max([df_5min["High":-i] for i in range(2, 5)])
if df_5min['Close':-1] > maximal:
order.place_order(msg_queue['bidask'][-1], 'Buy', 'Close')
# Make df_5min the latest kbar
df_5min = df_5min.iloc[-1]
kbar = {
'Open': df_5min['Open'],
'High': df_5min['High'],
'Low': df_5min['Low'],
'Close': df_5min['Close']
}
print(kbar)
# Caculate the support and resistence
if datetime.datetime.now().time() < datetime.time(9, 30):
support = df_5min['Low'] if support is None else min(df_5min['Low'], support)
resistence = df_5min['High'] if resistence is None else max(df_5min['High'], resistence)
# Entry conditions
if datetime.time(9, 30) <= datetime.datetime.now().time() <= datetime.time(12, 00) and self_position == 'None':
# Breakout then stop order in
if resistence is not None and df_5min['Close'] > resistence:
order.place_order(msg_queue['bidask'][-1], 'Buy', 'New')
support, resistence = None, None
if support is not None and df_5min['Close'] < support:
order.place_order(msg_queue['bidask'][-1], 'Sell', 'New')
support, resistence = None, None
api.quote.unsubscribe(
contract,
quote_type=sj.constant.QuoteType.BidAsk,
version=sj.constant.QuoteVersion.v1
)
api.logout()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment