commit 31ece2e99a2e990815046491997fb0b49dba1064 Author: yuqei Date: Fri Apr 24 13:39:01 2026 +0800 Initialize AI Exchange closed-loop trading system repository. Co-Authored-By: Claude Sonnet 4.6 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..60635a9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +__pycache__/ +*.pyc +*.pyo +*.pyd +.pytest_cache/ +.venv/ +venv/ +tests/ +docs/ +*.pdf +memory/ +.DS_Store diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1875322 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/ai_ict +OKX_BASE_URL=https://www.okx.com +OKX_TIMEOUT=30 +DEFAULT_TIMEZONE=UTC +SESSION_TIMEZONE=America/New_York +LOG_LEVEL=INFO diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..289812f --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Python +__pycache__/ +*.py[cod] +.pytest_cache/ +.venv/ +venv/ + +# Environment and secrets +.env +*.pem +*.key + +# OS/editor +.DS_Store +.idea/ +.vscode/ + +# Claude local state +.claude/ +memory/ + +# Large artifacts and local docs copies +*.pdf diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fff21ca --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM python:3.11-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app + +WORKDIR /app + +COPY pyproject.toml /app/pyproject.toml +RUN pip install --no-cache-dir --upgrade pip && \ + pip install --no-cache-dir \ + "sqlalchemy>=2.0" \ + "psycopg[binary]>=3.1" \ + "pydantic>=2.7" \ + "pydantic-settings>=2.2" \ + "httpx>=0.27" + +COPY src /app/src +COPY scripts /app/scripts +COPY migrations /app/migrations +COPY .env.example /app/.env.example +COPY README.md /app/README.md + +EXPOSE 8000 + +HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD python -c "from urllib.request import urlopen; import sys; sys.exit(0 if urlopen('http://127.0.0.1:8000/health').status == 200 else 1)" + +CMD ["python", "scripts/run_api_server.py"] diff --git a/ICT Concepts.md b/ICT Concepts.md new file mode 100644 index 0000000..b5e65bc --- /dev/null +++ b/ICT Concepts.md @@ -0,0 +1,2477 @@ +# ICT Concepts + +// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/ + +// © LuxAlgo + + + + + +//@version=5 + +indicator("ICT Concepts \[LuxAlgo]",max\_lines\_count=500,max\_boxes\_count=500,max\_labels\_count=500,max\_bars\_back=3000,overlay=true) + +//-----------------------------------------------------------------------------} + +//Strings + +//-----------------------------------------------------------------------------{ + +o='Options' + +sp1=' ' + +sp2=' ' + +hl='High / Low '+sp1 + +ny\_='New York'+sp1 + +lo\_='London Open' + +lc\_='London Close' + +as\_='Asian' + + + + + +//-----------------------------------------------------------------------------} + +//Settings + +//-----------------------------------------------------------------------------{ + +i\_mode=input.string( 'Present',title='Mode',options=\['Present','Historical'] ) + + + + + +//Market Structure Shift + +showMS=input.bool ( true,title='',group='Market Structures',inline='MS' ) + +len=input.int ( 5,title=' Length '+sp2,group='Market Structures',inline='MS',minval=3,maxval=10 ) + + + + + +iMSS=input.bool ( true,title=' MSS'+sp1,group='Market Structures',inline='M1' ) + +cMSSbl=input.color (color.new(#00e6a1,0),title='bullish',group='Market Structures',inline='M1' ) + +cMSSbr=input.color (color.new(#e60400,0),title='bearish',group='Market Structures',inline='M1' ) + + + + + +iBOS=input.bool ( true,title=' BOS'+sp1,group='Market Structures',inline='BS' ) + +cBOSbl=input.color (color.new(#00e6a1,0),title='bullish',group='Market Structures',inline='BS' ) + +cBOSbr=input.color (color.new(#e60400,0),title='bearish',group='Market Structures',inline='BS' ) + + + + + +//Displacement + +sDispl=input.bool ( false,title='Show Displacement',group='Displacement' ) + + + + + +perc\_Body=0.36// input.int( 36, minval=1, maxval=36) / 100 + +bxBack=10// input.int( 10, minval=0, maxval=10) + + + + + +sVimbl=input.bool ( true,title='',group='Volume Imbalance',inline='VI' ) + +visVim=input.int ( 2,title=" # Visible VI's "+sp1,group='Volume Imbalance',inline='VI',minval=2,maxval=100 ) + +cVimbl=input.color (color.new(#06b2d0,0),title='',group='Volume Imbalance',inline='VI' ) + + + + + +//Order Blocks + +showOB=input.bool ( true,title='Show Order Blocks',group='Order Blocks' ) + +length=input.int ( 10,title='Swing Lookback',group='Order Blocks',minval=3 ) + +showBull=input.int ( 1,title='Show Last Bullish OB',group='Order Blocks',minval=0 ) + +showBear=input.int ( 1,title='Show Last Bearish OB',group='Order Blocks',minval=0 ) + +useBody=input.bool ( true,title='Use Candle Body' ) + + + + + +//OB Style + +bullCss=input.color (color.new(#3e89fa,0),title='Bullish OB ',group='Order Blocks',inline='bullcss' ) + +bullBrkCss=input.color (color.new(#4785f9,85),title='Bullish Break ',group='Order Blocks',inline='bullcss' ) + + + + + +bearCss=input.color (color.new(#FF3131,0),title='Bearish OB',group='Order Blocks',inline='bearcss' ) + +bearBrkCss=input.color (color.new(#f9ff57,85),title='Bearish Break',group='Order Blocks',inline='bearcss' ) + + + + + +showLabels=input.bool ( false,title='Show Historical Polarity Changes',group='Order Blocks' ) + + + + + +//Liquidity + +showLq=input.bool ( true,title='Show Liquidity',group='Liquidity' ) + +a=10/input.float ( 4,title='margin',group='Liquidity',step=0.1,minval=2,maxval=7 ) + +visLiq=input.int ( 2,title='# Visible Liq. boxes',group='Liquidity' + +,minval=1,maxval=50,tooltip='In the same direction' ) + +cLIQ\_B=input.color (color.new(#fa451c,0),title='Buyside Liquidity ',group='Liquidity' ) + +cLIQ\_S=input.color (color.new(#1ce4fa,0),title='Sellside Liquidity',group='Liquidity' ) + + + + + +//FVG + +shwFVG=input.bool ( true,title='Show FVGs',group='Fair Value Gaps' ) + +i\_BPR=input.bool ( false,title='Balance Price Range',group='Fair Value Gaps' ) + +i\_FVG=input.string( 'FVG',title=o,group='Fair Value Gaps',options=\['FVG','IFVG'] + +,tooltip='Fair Value Gaps\nor\nImplied Fair Value Gaps' ) + +visBxs=input.int ( 2,title='# Visible FVG\\'s',group='Fair Value Gaps' + +,minval=1,maxval=20,tooltip='In the same direction' ) + + + + + +//FVG Style + +cFVGbl=input.color (color.new(#00e676,0),title='Bullish FVG ',group='Fair Value Gaps',inline='FVGbl' ) + +cFVGblBR=input.color (color.new(#808000,0),title='Break',group='Fair Value Gaps',inline='FVGbl' ) + +cFVGbr=input.color (color.new(#ff5252,0),title='Bearish FVG ',group='Fair Value Gaps',inline='FVGbr' ) + +cFVGbrBR=input.color (color.new(#FF0000,0),title='Break',group='Fair Value Gaps',inline='FVGbr' ) + + + + + +//NWOG/NDOG + +iNWOG=input.bool ( true,title='',inline='NWOG',group='NWOG/NDOG' ) + +cNWOG1=input.color (color.new(#ff5252,28),title='NWOG ',inline='NWOG',group='NWOG/NDOG' ) + +cNWOG2=input.color (color.new(#b2b5be,50),title='',inline='NWOG',group='NWOG/NDOG' ) + +maxNWOG=input.int ( 3,title='Show max',inline='NWOG',group='NWOG/NDOG',minval=0,maxval=50 ) + + + + + +iNDOG=input.bool ( false,title='',inline='NDOG',group='NWOG/NDOG' ) + +cNDOG1=input.color (color.new(#ff9800,20),title='NDOG ',inline='NDOG',group='NWOG/NDOG' ) + +cNDOG2=input.color (color.new(#4dd0e1,65),title='',inline='NDOG',group='NWOG/NDOG' ) + +maxNDOG=input.int ( 1,title='Show max',inline='NDOG',group='NWOG/NDOG',minval=0,maxval=50 ) + + + + + +//Fibonacci + +iFib=input.string( 'NONE',title='Fibonacci between last: ',group='Fibonacci',options=\['FVG','BPR','OB','Liq','VI','NWOG','NONE']) + +iExt=input.bool ( false,title='Extend lines',group='Fibonacci' ) + + + + + +//Killzones + +showKZ=input.bool ( false,title='Show Killzones',group='Killzones' ) + +//New York + +showNy=input.bool ( true,title=ny\_,inline='ny',group='Killzones' ) andshowKZ + +nyCss=input.color (color.new(#ff5d00,93),title='',inline='ny',group='Killzones' ) + +//London Open + +showLdno=input.bool ( true,title=lo\_,inline='lo',group='Killzones' ) andshowKZ + +ldnoCss=input.color (color.new(#00bcd4,93),title='',inline='lo',group='Killzones' ) + +//London Close + +showLdnc=input.bool ( true,title=lc\_,inline='lc',group='Killzones' ) andshowKZ + +ldncCss=input.color (color.new(#2157f3,93),title='',inline='lc',group='Killzones' ) + +//Asian + +showAsia=input.bool ( true,title=as\_+sp2,inline='as',group='Killzones' ) andshowKZ + +asiaCss=input.color (color.new(#e91e63,93),title='',inline='as',group='Killzones' ) + + + + + +//-----------------------------------------------------------------------------} + +//General Calculations + +//-----------------------------------------------------------------------------{ + +n=bar\_index + +hi=high + +lo=low + +tf\_msec=timeframe.in\_seconds(timeframe.period) \*1000 + +maxSize=50 + +atr=ta.atr(10) + +per=i\_mode=='Present'?last\_bar\_index-bar\_index<=500:true + +perB=last\_bar\_index-bar\_index<=1000?true:false + +xloc=iFib=='OB'?xloc.bar\_time:xloc.bar\_index + +ext=iExt?extend.right:extend.none + +plus=iFib=='OB'?tf\_msec\*50:50 + +mx=math.max(close,open) + +mn=math.min(close,open) + +body=math.abs(close-open) + +meanBody=ta.sma (body,len) + +max=useBody?mx:high + +min=useBody?mn:low + +blBrkConf=0 + +brBrkConf=0 + +r=color.r(chart.bg\_color) + +g=color.g(chart.bg\_color) + +b=color.b(chart.bg\_color) + +isDark=r<80andg<80andb<80 + + + + + +//-----------------------------------------------------------------------------} + +//User Defined Types + +//-----------------------------------------------------------------------------{ + +typeZZ + +int \[] d + +int \[] x + +float \[] y + +bool \[] b + + + + + +typeln\_d + +linel + +intd + + + + + +type\_2ln\_lb + +linel1 + +linel2 + +labellb + + + + + +typebx\_ln + +boxb + +linel + + + + + +typebx\_ln\_lb + +boxbx + +lineln + +labellb + + + + + +typemss + +intdir + +line \[] l\_mssBl + +line \[] l\_mssBr + +line \[] l\_bosBl + +line \[] l\_bosBr + +label\[] lbMssBl + +label\[] lbMssBr + +label\[] lbBosBl + +label\[] lbBosBr + + + + + +typeliq + +boxbx + +boolbroken + +boolbrokenTop + +boolbrokenBtm + +lineln + + + + + +typeob + +floattop=na + +floatbtm=na + +intloc=bar\_index + +boolbreaker=false + +intbreak\_loc=na + + + + + +typeswing + +floaty=na + +intx=na + +boolcrossed=false + + + + + +typeFVG + +boxbox + +boolactive + +intpos + + + + + +varmssMSS=mss.new( + +0 + +,array.new\() + +,array.new\() + +,array.new\() + +,array.new\() + +,array.new\